1 # Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not hasattr( geom, "GetShapeType" ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 # def FirstVertexOnCurve(mesh, edge):
324 # the first vertex of a geometrical edge by ignoring orientation
326 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
332 smeshInst is a singleton
338 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
340 This class allows to create, load or manipulate meshes.
341 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
342 It also has methods to get infos and measure meshes.
345 # MirrorType enumeration
346 POINT = SMESH_MeshEditor.POINT
347 AXIS = SMESH_MeshEditor.AXIS
348 PLANE = SMESH_MeshEditor.PLANE
350 # Smooth_Method enumeration
351 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
352 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
354 PrecisionConfusion = smeshPrecisionConfusion
356 # TopAbs_State enumeration
357 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
359 # Methods of splitting a hexahedron into tetrahedra
360 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
362 def __new__(cls, *args):
366 #print("==== __new__", engine, smeshInst, doLcc)
368 if smeshInst is None:
369 # smesh engine is either retrieved from engine, or created
371 # Following test avoids a recursive loop
373 if smeshInst is not None:
374 # smesh engine not created: existing engine found
378 # FindOrLoadComponent called:
379 # 1. CORBA resolution of server
380 # 2. the __new__ method is called again
381 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
382 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
384 # FindOrLoadComponent not called
385 if smeshInst is None:
386 # smeshBuilder instance is created from lcc.FindOrLoadComponent
387 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
388 smeshInst = super(smeshBuilder,cls).__new__(cls)
390 # smesh engine not created: existing engine found
391 #print("==== existing ", engine, smeshInst, doLcc)
393 #print("====1 ", smeshInst)
396 #print("====2 ", smeshInst)
399 def __init__(self, *args):
401 #print("--------------- smeshbuilder __init__ ---", created)
404 SMESH._objref_SMESH_Gen.__init__(self, *args)
407 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
409 Dump component to the Python script.
410 This method overrides IDL function to allow default values for the parameters.
413 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
415 def SetDumpPythonHistorical(self, isHistorical):
417 Set mode of DumpPython(), *historical* or *snapshot*.
418 In the *historical* mode, the Python Dump script includes all commands
419 performed by SMESH engine. In the *snapshot* mode, commands
420 relating to objects removed from the Study are excluded from the script
421 as well as commands not influencing the current state of meshes
424 if isHistorical: val = "true"
426 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
428 def init_smesh(self,geompyD = None):
430 Set Geometry component
433 self.UpdateStudy(geompyD)
434 notebook.myStudy = salome.myStudy
436 def Mesh(self, obj=0, name=0):
438 Create a mesh. This mesh can be either
440 * an empty mesh not bound to geometry, if *obj* == 0
441 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
442 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
447 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
450 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
452 2. a geometrical object for meshing
454 name: the name for the new mesh.
457 an instance of class :class:`Mesh`.
460 if isinstance(obj,str):
462 return Mesh(self, self.geompyD, obj, name)
464 def RemoveMesh( self, mesh ):
468 if isinstance( mesh, Mesh ):
469 mesh = mesh.GetMesh()
471 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
472 raise TypeError("%s is not a mesh" % mesh )
473 so = salome.ObjectToSObject( mesh )
475 sb = salome.myStudy.NewBuilder()
476 sb.RemoveObjectWithChildren( so )
482 def EnumToLong(self,theItem):
484 Return a long value from enumeration
489 def ColorToString(self,c):
491 Convert SALOMEDS.Color to string.
492 To be used with filters.
495 c: color value (SALOMEDS.Color)
498 a string representation of the color.
502 if isinstance(c, SALOMEDS.Color):
503 val = "%s;%s;%s" % (c.R, c.G, c.B)
504 elif isinstance(c, str):
507 raise ValueError("Color value should be of string or SALOMEDS.Color type")
510 def GetPointStruct(self,theVertex):
512 Get :class:`SMESH.PointStruct` from vertex
515 theVertex (GEOM.GEOM_Object): vertex
518 :class:`SMESH.PointStruct`
520 geompyD = theVertex.GetGen()
521 [x, y, z] = geompyD.PointCoordinates(theVertex)
522 return PointStruct(x,y,z)
524 def GetDirStruct(self,theVector):
526 Get :class:`SMESH.DirStruct` from vector
529 theVector (GEOM.GEOM_Object): vector
532 :class:`SMESH.DirStruct`
534 geompyD = theVector.GetGen()
535 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
536 if(len(vertices) != 2):
537 print("Error: vector object is incorrect.")
539 p1 = geompyD.PointCoordinates(vertices[0])
540 p2 = geompyD.PointCoordinates(vertices[1])
541 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
542 dirst = DirStruct(pnt)
545 def MakeDirStruct(self,x,y,z):
547 Make :class:`SMESH.DirStruct` from a triplet of floats
550 x,y,z (float): vector components
553 :class:`SMESH.DirStruct`
556 pnt = PointStruct(x,y,z)
557 return DirStruct(pnt)
559 def GetAxisStruct(self,theObj):
561 Get :class:`SMESH.AxisStruct` from a geometrical object
564 theObj (GEOM.GEOM_Object): line or plane
567 :class:`SMESH.AxisStruct`
570 geompyD = theObj.GetGen()
571 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
574 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
575 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576 vertex1 = geompyD.PointCoordinates(vertex1)
577 vertex2 = geompyD.PointCoordinates(vertex2)
578 vertex3 = geompyD.PointCoordinates(vertex3)
579 vertex4 = geompyD.PointCoordinates(vertex4)
580 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
581 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
582 normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
583 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
584 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
585 elif len(edges) == 1:
586 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
587 p1 = geompyD.PointCoordinates( vertex1 )
588 p2 = geompyD.PointCoordinates( vertex2 )
589 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
590 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
591 elif theObj.GetShapeType() == GEOM.VERTEX:
592 x,y,z = geompyD.PointCoordinates( theObj )
593 axis = AxisStruct( x,y,z, 1,0,0,)
594 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
597 # From SMESH_Gen interface:
598 # ------------------------
600 def SetName(self, obj, name):
602 Set the given name to an object
605 obj: the object to rename
606 name: a new object name
609 if isinstance( obj, Mesh ):
611 elif isinstance( obj, Mesh_Algorithm ):
612 obj = obj.GetAlgorithm()
613 ior = salome.orb.object_to_string(obj)
614 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
616 def SetEmbeddedMode( self,theMode ):
621 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
623 def IsEmbeddedMode(self):
628 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
630 def UpdateStudy( self, geompyD = None ):
632 Update the current study. Calling UpdateStudy() allows to
633 update meshes at switching GEOM->SMESH
637 from salome.geom import geomBuilder
638 geompyD = geomBuilder.geom
640 geompyD = geomBuilder.New()
643 self.SetGeomEngine(geompyD)
644 SMESH._objref_SMESH_Gen.UpdateStudy(self)
645 sb = salome.myStudy.NewBuilder()
646 sc = salome.myStudy.FindComponent("SMESH")
648 sb.LoadWith(sc, self)
651 def SetEnablePublish( self, theIsEnablePublish ):
653 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
654 switch **off** publishing in the Study of mesh objects.
656 #self.SetEnablePublish(theIsEnablePublish)
657 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
659 notebook = salome_notebook.NoteBook( theIsEnablePublish )
662 def CreateMeshesFromUNV( self,theFileName ):
664 Create a Mesh object importing data from the given UNV file
667 an instance of class :class:`Mesh`
670 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
671 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
674 def CreateMeshesFromMED( self,theFileName ):
676 Create a Mesh object(s) importing data from the given MED file
679 a tuple ( list of class :class:`Mesh` instances,
680 :class:`SMESH.DriverMED_ReadStatus` )
683 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
684 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
685 return aMeshes, aStatus
687 def CreateMeshesFromSAUV( self,theFileName ):
689 Create a Mesh object(s) importing data from the given SAUV file
692 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
695 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
696 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
697 return aMeshes, aStatus
699 def CreateMeshesFromSTL( self, theFileName ):
701 Create a Mesh object importing data from the given STL file
704 an instance of class :class:`Mesh`
707 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
708 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
711 def CreateMeshesFromCGNS( self, theFileName ):
713 Create Mesh objects importing data from the given CGNS file
716 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
719 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
720 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
721 return aMeshes, aStatus
723 def CreateMeshesFromGMF( self, theFileName ):
725 Create a Mesh object importing data from the given GMF file.
726 GMF files must have .mesh extension for the ASCII format and .meshb for
730 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
733 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
736 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
737 return Mesh(self, self.geompyD, aSmeshMesh), error
739 def Concatenate( self, meshes, uniteIdenticalGroups,
740 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
741 name = "", meshToAppendTo = None):
743 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
744 All groups of input meshes will be present in the new mesh.
747 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
748 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
749 mergeNodesAndElements: if True, equal nodes and elements are merged
750 mergeTolerance: tolerance for merging nodes
751 allGroups: forces creation of groups corresponding to every input mesh
752 name: name of a new mesh
753 meshToAppendTo: a mesh to append all given meshes
756 an instance of class :class:`Mesh`
762 if not meshes: return None
763 if not isinstance( meshes, list ):
765 for i,m in enumerate( meshes ):
766 if isinstance( m, Mesh ):
767 meshes[i] = m.GetMesh()
768 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
769 if hasattr(meshes[0], "SetParameters"):
770 meshes[0].SetParameters( Parameters )
772 meshes[0].GetMesh().SetParameters( Parameters )
773 if isinstance( meshToAppendTo, Mesh ):
774 meshToAppendTo = meshToAppendTo.GetMesh()
776 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
777 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
778 mergeTolerance,meshToAppendTo )
780 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
781 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
782 mergeTolerance,meshToAppendTo )
784 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
787 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
789 Create a mesh by copying a part of another mesh.
792 meshPart: a part of mesh to copy, either
793 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
794 To copy nodes or elements not forming any mesh object,
795 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
796 meshName: a name of the new mesh
797 toCopyGroups: to create in the new mesh groups the copied elements belongs to
798 toKeepIDs: to preserve order of the copied elements or not
801 an instance of class :class:`Mesh`
804 if isinstance( meshPart, Mesh ):
805 meshPart = meshPart.GetMesh()
806 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
807 return Mesh(self, self.geompyD, mesh)
809 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
810 toReuseHypotheses=True, toCopyElements=True):
812 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
813 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
814 To facilitate and speed up the operation, consider using
815 "Set presentation parameters and sub-shapes from arguments" option in
816 a dialog of geometrical operation used to create the new geometry.
819 sourceMesh: the mesh to copy definition of.
820 newGeom: the new geometry.
821 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
822 toCopyGroups: to create groups in the new mesh.
823 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
824 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
827 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
828 *invalidEntries* are study entries of objects whose
829 counterparts are not found in the *newGeom*, followed by entries
830 of mesh sub-objects that are invalid because they depend on a not found
833 if isinstance( sourceMesh, Mesh ):
834 sourceMesh = sourceMesh.GetMesh()
836 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
837 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
841 return ( ok, Mesh(self, self.geompyD, newMesh),
842 newGroups, newSubMeshes, newHypotheses, invalidEntries )
844 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
846 Return IDs of sub-shapes
849 theMainObject (GEOM.GEOM_Object): a shape
850 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
852 the list of integer values
855 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
857 def GetPattern(self):
859 Create a pattern mapper.
862 an instance of :class:`SMESH.SMESH_Pattern`
864 :ref:`Example of Patterns usage <tui_pattern_mapping>`
867 return SMESH._objref_SMESH_Gen.GetPattern(self)
869 def SetBoundaryBoxSegmentation(self, nbSegments):
871 Set number of segments per diagonal of boundary box of geometry, by which
872 default segment length of appropriate 1D hypotheses is defined in GUI.
876 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
878 # Filtering. Auxiliary functions:
879 # ------------------------------
881 def GetEmptyCriterion(self):
883 Create an empty criterion
886 :class:`SMESH.Filter.Criterion`
889 Type = self.EnumToLong(FT_Undefined)
890 Compare = self.EnumToLong(FT_Undefined)
894 UnaryOp = self.EnumToLong(FT_Undefined)
895 BinaryOp = self.EnumToLong(FT_Undefined)
898 Precision = -1 ##@1e-07
899 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
900 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
902 def GetCriterion(self,elementType,
904 Compare = FT_EqualTo,
906 UnaryOp=FT_Undefined,
907 BinaryOp=FT_Undefined,
910 Create a criterion by the given parameters
911 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
914 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
915 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
916 Note that the items starting from FT_LessThan are not suitable for *CritType*.
917 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
918 Threshold: the threshold value (range of ids as string, shape, numeric)
919 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
920 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
922 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
923 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
926 :class:`SMESH.Filter.Criterion`
928 Example: :ref:`combining_filters`
931 if not CritType in SMESH.FunctorType._items:
932 raise TypeError("CritType should be of SMESH.FunctorType")
933 aCriterion = self.GetEmptyCriterion()
934 aCriterion.TypeOfElement = elementType
935 aCriterion.Type = self.EnumToLong(CritType)
936 aCriterion.Tolerance = Tolerance
938 aThreshold = Threshold
940 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
941 aCriterion.Compare = self.EnumToLong(Compare)
942 elif Compare == "=" or Compare == "==":
943 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
945 aCriterion.Compare = self.EnumToLong(FT_LessThan)
947 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
948 elif Compare != FT_Undefined:
949 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
952 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
953 FT_BelongToCylinder, FT_LyingOnGeom]:
954 # Check that Threshold is GEOM object
955 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
956 aCriterion.ThresholdStr = GetName(aThreshold)
957 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
958 if not aCriterion.ThresholdID:
959 name = aCriterion.ThresholdStr
961 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
962 geompyD = aThreshold.GetGen()
963 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
964 # or a name of GEOM object
965 elif isinstance( aThreshold, str ):
966 aCriterion.ThresholdStr = aThreshold
968 raise TypeError("The Threshold should be a shape.")
969 if isinstance(UnaryOp,float):
970 aCriterion.Tolerance = UnaryOp
971 UnaryOp = FT_Undefined
973 elif CritType == FT_BelongToMeshGroup:
974 # Check that Threshold is a group
975 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
976 if aThreshold.GetType() != elementType:
977 raise ValueError("Group type mismatches Element type")
978 aCriterion.ThresholdStr = aThreshold.GetName()
979 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
980 study = salome.myStudy
982 so = study.FindObjectIOR( aCriterion.ThresholdID )
986 aCriterion.ThresholdID = entry
988 raise TypeError("The Threshold should be a Mesh Group")
989 elif CritType == FT_RangeOfIds:
990 # Check that Threshold is string
991 if isinstance(aThreshold, str):
992 aCriterion.ThresholdStr = aThreshold
994 raise TypeError("The Threshold should be a string.")
995 elif CritType == FT_CoplanarFaces:
996 # Check the Threshold
997 if isinstance(aThreshold, int):
998 aCriterion.ThresholdID = str(aThreshold)
999 elif isinstance(aThreshold, str):
1000 ID = int(aThreshold)
1002 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1003 aCriterion.ThresholdID = aThreshold
1005 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1006 elif CritType == FT_ConnectedElements:
1007 # Check the Threshold
1008 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1009 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1010 if not aCriterion.ThresholdID:
1011 name = aThreshold.GetName()
1013 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1014 geompyD = aThreshold.GetGen()
1015 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1016 elif isinstance(aThreshold, int): # node id
1017 aCriterion.Threshold = aThreshold
1018 elif isinstance(aThreshold, list): # 3 point coordinates
1019 if len( aThreshold ) < 3:
1020 raise ValueError("too few point coordinates, must be 3")
1021 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1022 elif isinstance(aThreshold, str):
1023 if aThreshold.isdigit():
1024 aCriterion.Threshold = aThreshold # node id
1026 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1028 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1029 "or a list of point coordinates and not '%s'"%aThreshold)
1030 elif CritType == FT_ElemGeomType:
1031 # Check the Threshold
1033 aCriterion.Threshold = self.EnumToLong(aThreshold)
1034 assert( aThreshold in SMESH.GeometryType._items )
1036 if isinstance(aThreshold, int):
1037 aCriterion.Threshold = aThreshold
1039 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1042 elif CritType == FT_EntityType:
1043 # Check the Threshold
1045 aCriterion.Threshold = self.EnumToLong(aThreshold)
1046 assert( aThreshold in SMESH.EntityType._items )
1048 if isinstance(aThreshold, int):
1049 aCriterion.Threshold = aThreshold
1051 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1055 elif CritType == FT_GroupColor:
1056 # Check the Threshold
1058 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1060 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1062 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1063 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1064 FT_BareBorderFace, FT_BareBorderVolume,
1065 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1066 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1067 # At this point the Threshold is unnecessary
1068 if aThreshold == FT_LogicalNOT:
1069 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1070 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1071 aCriterion.BinaryOp = aThreshold
1075 aThreshold = float(aThreshold)
1076 aCriterion.Threshold = aThreshold
1078 raise TypeError("The Threshold should be a number.")
1081 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1082 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1084 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1085 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1087 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1088 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1090 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1091 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1095 def GetFilter(self,elementType,
1096 CritType=FT_Undefined,
1099 UnaryOp=FT_Undefined,
1103 Create a filter with the given parameters
1106 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1107 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1108 Note that the items starting from FT_LessThan are not suitable for CritType.
1109 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1110 Threshold: the threshold value (range of ids as string, shape, numeric)
1111 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1112 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1113 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1114 mesh: the mesh to initialize the filter with
1117 :class:`SMESH.Filter`
1120 See :doc:`Filters usage examples <tui_filters>`
1123 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1124 aFilterMgr = self.CreateFilterManager()
1125 aFilter = aFilterMgr.CreateFilter()
1127 aCriteria.append(aCriterion)
1128 aFilter.SetCriteria(aCriteria)
1130 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1131 else : aFilter.SetMesh( mesh )
1132 aFilterMgr.UnRegister()
1135 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1137 Create a filter from criteria
1140 criteria: a list of :class:`SMESH.Filter.Criterion`
1141 binOp: binary operator used when binary operator of criteria is undefined
1144 :class:`SMESH.Filter`
1147 See :doc:`Filters usage examples <tui_filters>`
1150 for i in range( len( criteria ) - 1 ):
1151 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1152 criteria[i].BinaryOp = self.EnumToLong( binOp )
1153 aFilterMgr = self.CreateFilterManager()
1154 aFilter = aFilterMgr.CreateFilter()
1155 aFilter.SetCriteria(criteria)
1156 aFilterMgr.UnRegister()
1159 def GetFunctor(self,theCriterion):
1161 Create a numerical functor by its type
1164 theCriterion (SMESH.FunctorType): functor type.
1165 Note that not all items correspond to numerical functors.
1168 :class:`SMESH.NumericalFunctor`
1171 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1173 aFilterMgr = self.CreateFilterManager()
1175 if theCriterion == FT_AspectRatio:
1176 functor = aFilterMgr.CreateAspectRatio()
1177 elif theCriterion == FT_AspectRatio3D:
1178 functor = aFilterMgr.CreateAspectRatio3D()
1179 elif theCriterion == FT_Warping:
1180 functor = aFilterMgr.CreateWarping()
1181 elif theCriterion == FT_MinimumAngle:
1182 functor = aFilterMgr.CreateMinimumAngle()
1183 elif theCriterion == FT_Taper:
1184 functor = aFilterMgr.CreateTaper()
1185 elif theCriterion == FT_Skew:
1186 functor = aFilterMgr.CreateSkew()
1187 elif theCriterion == FT_Area:
1188 functor = aFilterMgr.CreateArea()
1189 elif theCriterion == FT_Volume3D:
1190 functor = aFilterMgr.CreateVolume3D()
1191 elif theCriterion == FT_MaxElementLength2D:
1192 functor = aFilterMgr.CreateMaxElementLength2D()
1193 elif theCriterion == FT_MaxElementLength3D:
1194 functor = aFilterMgr.CreateMaxElementLength3D()
1195 elif theCriterion == FT_MultiConnection:
1196 functor = aFilterMgr.CreateMultiConnection()
1197 elif theCriterion == FT_MultiConnection2D:
1198 functor = aFilterMgr.CreateMultiConnection2D()
1199 elif theCriterion == FT_Length:
1200 functor = aFilterMgr.CreateLength()
1201 elif theCriterion == FT_Length2D:
1202 functor = aFilterMgr.CreateLength2D()
1203 elif theCriterion == FT_Length3D:
1204 functor = aFilterMgr.CreateLength3D()
1205 elif theCriterion == FT_Deflection2D:
1206 functor = aFilterMgr.CreateDeflection2D()
1207 elif theCriterion == FT_NodeConnectivityNumber:
1208 functor = aFilterMgr.CreateNodeConnectivityNumber()
1209 elif theCriterion == FT_BallDiameter:
1210 functor = aFilterMgr.CreateBallDiameter()
1212 print("Error: given parameter is not numerical functor type.")
1213 aFilterMgr.UnRegister()
1216 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1221 theHType (string): mesh hypothesis type
1222 theLibName (string): mesh plug-in library name
1225 created hypothesis instance
1227 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1229 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1232 # wrap hypothesis methods
1233 for meth_name in dir( hyp.__class__ ):
1234 if not meth_name.startswith("Get") and \
1235 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1236 method = getattr ( hyp.__class__, meth_name )
1237 if callable(method):
1238 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1242 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1244 Create hypothesis initialized according to parameters
1247 hypType (string): hypothesis type
1248 libName (string): plug-in library name
1249 mesh: optional mesh by which a hypotheses can initialize self
1250 shape: optional geometry by size of which a hypotheses can initialize self
1251 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1254 created hypothesis instance
1256 if isinstance( mesh, Mesh ):
1257 mesh = mesh.GetMesh()
1258 if isinstance( initParams, (bool,int)):
1259 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1260 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1261 mesh, shape, initParams )
1263 def GetMeshInfo(self, obj):
1265 Get the mesh statistic.
1268 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1271 if isinstance( obj, Mesh ):
1274 if hasattr(obj, "GetMeshInfo"):
1275 values = obj.GetMeshInfo()
1276 for i in range(SMESH.Entity_Last._v):
1277 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1281 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1283 Get minimum distance between two objects
1285 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1286 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1289 src1 (SMESH.SMESH_IDSource): first source object
1290 src2 (SMESH.SMESH_IDSource): second source object
1291 id1 (int): node/element id from the first source
1292 id2 (int): node/element id from the second (or first) source
1293 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1294 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1297 minimum distance value
1300 :meth:`GetMinDistance`
1303 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1307 result = result.value
1310 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1312 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1314 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1315 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1318 src1 (SMESH.SMESH_IDSource): first source object
1319 src2 (SMESH.SMESH_IDSource): second source object
1320 id1 (int): node/element id from the first source
1321 id2 (int): node/element id from the second (or first) source
1322 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1323 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1326 :class:`SMESH.Measure` structure or None if input data is invalid
1331 if isinstance(src1, Mesh): src1 = src1.mesh
1332 if isinstance(src2, Mesh): src2 = src2.mesh
1333 if src2 is None and id2 != 0: src2 = src1
1334 if not hasattr(src1, "_narrow"): return None
1335 src1 = src1._narrow(SMESH.SMESH_IDSource)
1336 if not src1: return None
1337 unRegister = genObjUnRegister()
1340 e = m.GetMeshEditor()
1342 src1 = e.MakeIDSource([id1], SMESH.FACE)
1344 src1 = e.MakeIDSource([id1], SMESH.NODE)
1345 unRegister.set( src1 )
1347 if hasattr(src2, "_narrow"):
1348 src2 = src2._narrow(SMESH.SMESH_IDSource)
1349 if src2 and id2 != 0:
1351 e = m.GetMeshEditor()
1353 src2 = e.MakeIDSource([id2], SMESH.FACE)
1355 src2 = e.MakeIDSource([id2], SMESH.NODE)
1356 unRegister.set( src2 )
1359 aMeasurements = self.CreateMeasurements()
1360 unRegister.set( aMeasurements )
1361 result = aMeasurements.MinDistance(src1, src2)
1364 def BoundingBox(self, objects):
1366 Get bounding box of the specified object(s)
1369 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1372 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1375 :meth:`GetBoundingBox`
1378 result = self.GetBoundingBox(objects)
1382 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1385 def GetBoundingBox(self, objects):
1387 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1390 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1393 :class:`SMESH.Measure` structure
1399 if isinstance(objects, tuple):
1400 objects = list(objects)
1401 if not isinstance(objects, list):
1405 if isinstance(o, Mesh):
1406 srclist.append(o.mesh)
1407 elif hasattr(o, "_narrow"):
1408 src = o._narrow(SMESH.SMESH_IDSource)
1409 if src: srclist.append(src)
1412 aMeasurements = self.CreateMeasurements()
1413 result = aMeasurements.BoundingBox(srclist)
1414 aMeasurements.UnRegister()
1417 def GetLength(self, obj):
1419 Get sum of lengths of all 1D elements in the mesh object.
1422 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1425 sum of lengths of all 1D elements
1428 if isinstance(obj, Mesh): obj = obj.mesh
1429 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1430 aMeasurements = self.CreateMeasurements()
1431 value = aMeasurements.Length(obj)
1432 aMeasurements.UnRegister()
1435 def GetArea(self, obj):
1437 Get sum of areas of all 2D elements in the mesh object.
1440 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1443 sum of areas of all 2D elements
1446 if isinstance(obj, Mesh): obj = obj.mesh
1447 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1448 aMeasurements = self.CreateMeasurements()
1449 value = aMeasurements.Area(obj)
1450 aMeasurements.UnRegister()
1453 def GetVolume(self, obj):
1455 Get sum of volumes of all 3D elements in the mesh object.
1458 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1461 sum of volumes of all 3D elements
1464 if isinstance(obj, Mesh): obj = obj.mesh
1465 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1466 aMeasurements = self.CreateMeasurements()
1467 value = aMeasurements.Volume(obj)
1468 aMeasurements.UnRegister()
1471 def GetGravityCenter(self, obj):
1473 Get gravity center of all nodes of a mesh object.
1476 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1479 Three components of the gravity center (x,y,z)
1482 :meth:`Mesh.BaryCenter`
1484 if isinstance(obj, Mesh): obj = obj.mesh
1485 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1486 aMeasurements = self.CreateMeasurements()
1487 pointStruct = aMeasurements.GravityCenter(obj)
1488 aMeasurements.UnRegister()
1489 return pointStruct.x, pointStruct.y, pointStruct.z
1491 def GetAngle(self, p1, p2, p3 ):
1493 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1496 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1502 if isinstance( p1, list ): p1 = PointStruct(*p1)
1503 if isinstance( p2, list ): p2 = PointStruct(*p2)
1504 if isinstance( p3, list ): p3 = PointStruct(*p3)
1506 aMeasurements = self.CreateMeasurements()
1507 angle = aMeasurements.Angle(p1,p2,p3)
1508 aMeasurements.UnRegister()
1513 pass # end of class smeshBuilder
1516 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1517 """Registering the new proxy for SMESH.SMESH_Gen"""
1520 def New( instance=None, instanceGeom=None):
1522 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1523 interface to create or load meshes.
1528 salome.salome_init()
1529 from salome.smesh import smeshBuilder
1530 smesh = smeshBuilder.New()
1533 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1534 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1536 :class:`smeshBuilder` instance
1541 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1543 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1548 smeshInst = smeshBuilder()
1549 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1550 smeshInst.init_smesh(instanceGeom)
1554 # Public class: Mesh
1555 # ==================
1558 class Mesh(metaclass = MeshMeta):
1560 This class allows defining and managing a mesh.
1561 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1562 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1563 new nodes and elements and by changing the existing entities), to get information
1564 about a mesh and to export a mesh in different formats.
1571 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1576 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1577 sets the GUI name of this mesh to *name*.
1580 smeshpyD: an instance of smeshBuilder class
1581 geompyD: an instance of geomBuilder class
1582 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1583 name: Study name of the mesh
1586 self.smeshpyD = smeshpyD
1587 self.geompyD = geompyD
1592 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1595 # publish geom of mesh (issue 0021122)
1596 if not self.geom.GetStudyEntry():
1600 geo_name = name + " shape"
1602 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1603 geompyD.addToStudy( self.geom, geo_name )
1604 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1606 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1609 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1611 self.smeshpyD.SetName(self.mesh, name)
1613 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1616 self.geom = self.mesh.GetShapeToMesh()
1618 self.editor = self.mesh.GetMeshEditor()
1619 self.functors = [None] * SMESH.FT_Undefined._v
1621 # set self to algoCreator's
1622 for attrName in dir(self):
1623 attr = getattr( self, attrName )
1624 if isinstance( attr, algoCreator ):
1625 setattr( self, attrName, attr.copy( self ))
1632 Destructor. Clean-up resources
1635 #self.mesh.UnRegister()
1639 def SetMesh(self, theMesh):
1641 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1644 theMesh: a :class:`SMESH.SMESH_Mesh` object
1646 # do not call Register() as this prevents mesh servant deletion at closing study
1647 #if self.mesh: self.mesh.UnRegister()
1650 #self.mesh.Register()
1651 self.geom = self.mesh.GetShapeToMesh()
1653 self.geompyD = self.geom.GetGen()
1659 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1662 a :class:`SMESH.SMESH_Mesh` object
1667 def GetEngine(self):
1669 Return a smeshBuilder instance created this mesh
1671 return self.smeshpyD
1673 def GetGeomEngine(self):
1675 Return a geomBuilder instance
1681 Get the name of the mesh
1684 the name of the mesh as a string
1687 name = GetName(self.GetMesh())
1690 def SetName(self, name):
1692 Set a name to the mesh
1695 name: a new name of the mesh
1698 self.smeshpyD.SetName(self.GetMesh(), name)
1700 def GetSubMesh(self, geom, name):
1702 Get a sub-mesh object associated to a *geom* geometrical object.
1705 geom: a geometrical object (shape)
1706 name: a name for the sub-mesh in the Object Browser
1709 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1710 which lies on the given shape
1713 A sub-mesh is implicitly created when a sub-shape is specified at
1714 creating an algorithm, for example::
1716 algo1D = mesh.Segment(geom=Edge_1)
1718 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1719 The created sub-mesh can be retrieved from the algorithm::
1721 submesh = algo1D.GetSubMesh()
1724 AssureGeomPublished( self, geom, name )
1725 submesh = self.mesh.GetSubMesh( geom, name )
1730 Return the shape associated to the mesh
1738 def SetShape(self, geom):
1740 Associate the given shape to the mesh (entails the recreation of the mesh)
1743 geom: the shape to be meshed (GEOM_Object)
1746 self.mesh = self.smeshpyD.CreateMesh(geom)
1748 def HasShapeToMesh(self):
1750 Return ``True`` if this mesh is based on geometry
1752 return self.mesh.HasShapeToMesh()
1756 Load mesh from the study after opening the study
1760 def IsReadyToCompute(self, theSubObject):
1762 Return true if the hypotheses are defined well
1765 theSubObject: a sub-shape of a mesh shape
1771 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1773 def GetAlgoState(self, theSubObject):
1775 Return errors of hypotheses definition.
1776 The list of errors is empty if everything is OK.
1779 theSubObject: a sub-shape of a mesh shape
1785 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1787 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1789 Return a geometrical object on which the given element was built.
1790 The returned geometrical object, if not nil, is either found in the
1791 study or published by this method with the given name
1794 theElementID: the id of the mesh element
1795 theGeomName: the user-defined name of the geometrical object
1798 GEOM.GEOM_Object instance
1801 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1803 def MeshDimension(self):
1805 Return the mesh dimension depending on the dimension of the underlying shape
1806 or, if the mesh is not based on any shape, basing on deimension of elements
1809 mesh dimension as an integer value [0,3]
1812 if self.mesh.HasShapeToMesh():
1813 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1814 if len( shells ) > 0 :
1816 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1818 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1823 if self.NbVolumes() > 0: return 3
1824 if self.NbFaces() > 0: return 2
1825 if self.NbEdges() > 0: return 1
1828 def Evaluate(self, geom=0):
1830 Evaluate size of prospective mesh on a shape
1833 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1834 To know predicted number of e.g. edges, inquire it this way::
1836 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1839 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1841 geom = self.mesh.GetShapeToMesh()
1844 return self.smeshpyD.Evaluate(self.mesh, geom)
1847 def Compute(self, geom=0, discardModifs=False, refresh=False):
1849 Compute the mesh and return the status of the computation
1852 geom: geomtrical shape on which mesh data should be computed
1853 discardModifs: if True and the mesh has been edited since
1854 a last total re-compute and that may prevent successful partial re-compute,
1855 then the mesh is cleaned before Compute()
1856 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1862 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1863 geom = self.mesh.GetShapeToMesh()
1866 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1868 ok = self.smeshpyD.Compute(self.mesh, geom)
1869 except SALOME.SALOME_Exception as ex:
1870 print("Mesh computation failed, exception caught:")
1871 print(" ", ex.details.text)
1874 print("Mesh computation failed, exception caught:")
1875 traceback.print_exc()
1879 # Treat compute errors
1880 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1882 for err in computeErrors:
1883 if self.mesh.HasShapeToMesh():
1884 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1886 stdErrors = ["OK", #COMPERR_OK
1887 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1888 "std::exception", #COMPERR_STD_EXCEPTION
1889 "OCC exception", #COMPERR_OCC_EXCEPTION
1890 "..", #COMPERR_SLM_EXCEPTION
1891 "Unknown exception", #COMPERR_EXCEPTION
1892 "Memory allocation problem", #COMPERR_MEMORY_PB
1893 "Algorithm failed", #COMPERR_ALGO_FAILED
1894 "Unexpected geometry", #COMPERR_BAD_SHAPE
1895 "Warning", #COMPERR_WARNING
1896 "Computation cancelled",#COMPERR_CANCELED
1897 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1899 if err.code < len(stdErrors): errText = stdErrors[err.code]
1901 errText = "code %s" % -err.code
1902 if errText: errText += ". "
1903 errText += err.comment
1904 if allReasons: allReasons += "\n"
1906 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1908 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1912 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1914 if err.isGlobalAlgo:
1922 reason = '%s %sD algorithm is missing' % (glob, dim)
1923 elif err.state == HYP_MISSING:
1924 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1925 % (glob, dim, name, dim))
1926 elif err.state == HYP_NOTCONFORM:
1927 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1928 elif err.state == HYP_BAD_PARAMETER:
1929 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1930 % ( glob, dim, name ))
1931 elif err.state == HYP_BAD_GEOMETRY:
1932 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1933 'geometry' % ( glob, dim, name ))
1934 elif err.state == HYP_HIDDEN_ALGO:
1935 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1936 'algorithm of upper dimension generating %sD mesh'
1937 % ( glob, dim, name, glob, dim ))
1939 reason = ("For unknown reason. "
1940 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1942 if allReasons: allReasons += "\n"
1943 allReasons += "- " + reason
1945 if not ok or allReasons != "":
1946 msg = '"' + GetName(self.mesh) + '"'
1947 if ok: msg += " has been computed with warnings"
1948 else: msg += " has not been computed"
1949 if allReasons != "": msg += ":"
1954 if salome.sg.hasDesktop():
1955 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1956 if refresh: salome.sg.updateObjBrowser()
1960 def GetComputeErrors(self, shape=0 ):
1962 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1966 shape = self.mesh.GetShapeToMesh()
1967 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1969 def GetSubShapeName(self, subShapeID ):
1971 Return a name of a sub-shape by its ID.
1972 Possible variants (for *subShapeID* == 3):
1974 - **"Face_12"** - published sub-shape
1975 - **FACE #3** - not published sub-shape
1976 - **sub-shape #3** - invalid sub-shape ID
1977 - **#3** - error in this function
1980 subShapeID: a unique ID of a sub-shape
1983 a string describing the sub-shape
1987 if not self.mesh.HasShapeToMesh():
1991 mainIOR = salome.orb.object_to_string( self.GetShape() )
1993 mainSO = s.FindObjectIOR(mainIOR)
1996 shapeText = '"%s"' % mainSO.GetName()
1997 subIt = s.NewChildIterator(mainSO)
1999 subSO = subIt.Value()
2001 obj = subSO.GetObject()
2002 if not obj: continue
2003 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2006 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2009 if ids == subShapeID:
2010 shapeText = '"%s"' % subSO.GetName()
2013 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2015 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2017 shapeText = 'sub-shape #%s' % (subShapeID)
2019 shapeText = "#%s" % (subShapeID)
2022 def GetFailedShapes(self, publish=False):
2024 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2025 error of an algorithm
2028 publish: if *True*, the returned groups will be published in the study
2031 a list of GEOM groups each named after a failed algorithm
2036 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2037 for err in computeErrors:
2038 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2039 if not shape: continue
2040 if err.algoName in algo2shapes:
2041 algo2shapes[ err.algoName ].append( shape )
2043 algo2shapes[ err.algoName ] = [ shape ]
2047 for algoName, shapes in list(algo2shapes.items()):
2049 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2050 otherTypeShapes = []
2052 group = self.geompyD.CreateGroup( self.geom, groupType )
2053 for shape in shapes:
2054 if shape.GetShapeType() == shapes[0].GetShapeType():
2055 sameTypeShapes.append( shape )
2057 otherTypeShapes.append( shape )
2058 self.geompyD.UnionList( group, sameTypeShapes )
2060 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2062 group.SetName( algoName )
2063 groups.append( group )
2064 shapes = otherTypeShapes
2067 for group in groups:
2068 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2071 def GetMeshOrder(self):
2073 Return sub-mesh objects list in meshing order
2076 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2079 return self.mesh.GetMeshOrder()
2081 def SetMeshOrder(self, submeshes):
2083 Set priority of sub-meshes. It works in two ways:
2085 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2086 *several dimensions*, it sets the order in which the sub-meshes are computed.
2087 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2088 when looking for meshing parameters to apply to a sub-shape. To impose the
2089 order in which sub-meshes with uni-dimensional algorithms are computed,
2090 call **submesh.Compute()** in a desired order.
2093 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2095 Warning: the method is for setting the order for all sub-meshes at once:
2096 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2099 return self.mesh.SetMeshOrder(submeshes)
2101 def Clear(self, refresh=False):
2103 Remove all nodes and elements generated on geometry. Imported elements remain.
2106 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2110 if ( salome.sg.hasDesktop() ):
2111 if refresh: salome.sg.updateObjBrowser()
2113 def ClearSubMesh(self, geomId, refresh=False):
2115 Remove all nodes and elements of indicated shape
2118 geomId: the ID of a sub-shape to remove elements on
2119 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 self.mesh.ClearSubMesh(geomId)
2123 if salome.sg.hasDesktop():
2124 if refresh: salome.sg.updateObjBrowser()
2126 def AutomaticTetrahedralization(self, fineness=0):
2128 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2131 fineness: [0.0,1.0] defines mesh fineness
2137 dim = self.MeshDimension()
2139 self.RemoveGlobalHypotheses()
2140 self.Segment().AutomaticLength(fineness)
2142 self.Triangle().LengthFromEdges()
2147 return self.Compute()
2149 def AutomaticHexahedralization(self, fineness=0):
2151 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2154 fineness: [0.0, 1.0] defines mesh fineness
2160 dim = self.MeshDimension()
2161 # assign the hypotheses
2162 self.RemoveGlobalHypotheses()
2163 self.Segment().AutomaticLength(fineness)
2170 return self.Compute()
2172 def AddHypothesis(self, hyp, geom=0):
2177 hyp: a hypothesis to assign
2178 geom: a subhape of mesh geometry
2181 :class:`SMESH.Hypothesis_Status`
2184 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2185 hyp, geom = geom, hyp
2186 if isinstance( hyp, Mesh_Algorithm ):
2187 hyp = hyp.GetAlgorithm()
2192 geom = self.mesh.GetShapeToMesh()
2195 if self.mesh.HasShapeToMesh():
2196 hyp_type = hyp.GetName()
2197 lib_name = hyp.GetLibName()
2198 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2199 # if checkAll and geom:
2200 # checkAll = geom.GetType() == 37
2202 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2204 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2205 status = self.mesh.AddHypothesis(geom, hyp)
2207 status = HYP_BAD_GEOMETRY, ""
2208 hyp_name = GetName( hyp )
2211 geom_name = geom.GetName()
2212 isAlgo = hyp._narrow( SMESH_Algo )
2213 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2216 def IsUsedHypothesis(self, hyp, geom):
2218 Return True if an algorithm or hypothesis is assigned to a given shape
2221 hyp: an algorithm or hypothesis to check
2222 geom: a subhape of mesh geometry
2228 if not hyp: # or not geom
2230 if isinstance( hyp, Mesh_Algorithm ):
2231 hyp = hyp.GetAlgorithm()
2233 hyps = self.GetHypothesisList(geom)
2235 if h.GetId() == hyp.GetId():
2239 def RemoveHypothesis(self, hyp, geom=0):
2241 Unassign a hypothesis
2244 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2245 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2248 :class:`SMESH.Hypothesis_Status`
2253 if isinstance( hyp, Mesh_Algorithm ):
2254 hyp = hyp.GetAlgorithm()
2260 if self.IsUsedHypothesis( hyp, shape ):
2261 return self.mesh.RemoveHypothesis( shape, hyp )
2262 hypName = GetName( hyp )
2263 geoName = GetName( shape )
2264 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2267 def GetHypothesisList(self, geom):
2269 Get the list of hypotheses added on a geometry
2272 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2275 the sequence of :class:`SMESH.SMESH_Hypothesis`
2278 return self.mesh.GetHypothesisList( geom )
2280 def RemoveGlobalHypotheses(self):
2282 Remove all global hypotheses
2285 current_hyps = self.mesh.GetHypothesisList( self.geom )
2286 for hyp in current_hyps:
2287 self.mesh.RemoveHypothesis( self.geom, hyp )
2290 def ExportMED(self, *args, **kwargs):
2292 Export the mesh in a file in MED format
2293 allowing to overwrite the file if it exists or add the exported data to its contents
2296 fileName: is the file name
2297 auto_groups (boolean): parameter for creating/not creating
2298 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2299 the typical use is auto_groups=False.
2300 version (int): define the version (xy, where version is x.y.z) of MED file format.
2301 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2302 The rules of compatibility to write a mesh in an older version than
2303 the current version depend on the current version. For instance,
2304 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2305 or 3.2.1 or 3.3.1 formats.
2306 If the version is equal to -1, the version is not changed (default).
2307 overwrite (boolean): parameter for overwriting/not overwriting the file
2308 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2309 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2311 - 1D if all mesh nodes lie on OX coordinate axis, or
2312 - 2D if all mesh nodes lie on XOY coordinate plane, or
2313 - 3D in the rest cases.
2315 If *autoDimension* is *False*, the space dimension is always 3.
2316 fields: list of GEOM fields defined on the shape to mesh.
2317 geomAssocFields: each character of this string means a need to export a
2318 corresponding field; correspondence between fields and characters
2321 - 'v' stands for "_vertices_" field;
2322 - 'e' stands for "_edges_" field;
2323 - 'f' stands for "_faces_" field;
2324 - 's' stands for "_solids_" field.
2326 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2327 close to zero within a given tolerance, the coordinate is set to zero.
2328 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2330 # process positional arguments
2331 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2333 auto_groups = args[1] if len(args) > 1 else False
2334 version = args[2] if len(args) > 2 else -1
2335 overwrite = args[3] if len(args) > 3 else True
2336 meshPart = args[4] if len(args) > 4 else None
2337 autoDimension = args[5] if len(args) > 5 else True
2338 fields = args[6] if len(args) > 6 else []
2339 geomAssocFields = args[7] if len(args) > 7 else ''
2340 z_tolerance = args[8] if len(args) > 8 else -1.
2341 # process keywords arguments
2342 auto_groups = kwargs.get("auto_groups", auto_groups)
2343 version = kwargs.get("version", version)
2344 version = kwargs.get("minor", version)
2345 overwrite = kwargs.get("overwrite", overwrite)
2346 meshPart = kwargs.get("meshPart", meshPart)
2347 autoDimension = kwargs.get("autoDimension", autoDimension)
2348 fields = kwargs.get("fields", fields)
2349 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2350 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2352 # invoke engine's function
2353 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2354 unRegister = genObjUnRegister()
2355 if isinstance( meshPart, list ):
2356 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2357 unRegister.set( meshPart )
2359 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2360 self.mesh.SetParameters(Parameters)
2362 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2363 version, overwrite, autoDimension,
2364 fields, geomAssocFields, z_tolerance)
2366 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2368 def ExportSAUV(self, f, auto_groups=0):
2370 Export the mesh in a file in SAUV format
2375 auto_groups: boolean parameter for creating/not creating
2376 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2377 the typical use is auto_groups=False.
2380 self.mesh.ExportSAUV(f, auto_groups)
2382 def ExportDAT(self, f, meshPart=None):
2384 Export the mesh in a file in DAT format
2388 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2392 unRegister = genObjUnRegister()
2393 if isinstance( meshPart, list ):
2394 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2395 unRegister.set( meshPart )
2396 self.mesh.ExportPartToDAT( meshPart, f )
2398 self.mesh.ExportDAT(f)
2400 def ExportUNV(self, f, meshPart=None):
2402 Export the mesh in a file in UNV format
2406 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2410 unRegister = genObjUnRegister()
2411 if isinstance( meshPart, list ):
2412 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2413 unRegister.set( meshPart )
2414 self.mesh.ExportPartToUNV( meshPart, f )
2416 self.mesh.ExportUNV(f)
2418 def ExportSTL(self, f, ascii=1, meshPart=None):
2420 Export the mesh in a file in STL format
2424 ascii: defines the file encoding
2425 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2429 unRegister = genObjUnRegister()
2430 if isinstance( meshPart, list ):
2431 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2432 unRegister.set( meshPart )
2433 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2435 self.mesh.ExportSTL(f, ascii)
2437 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2439 Export the mesh in a file in CGNS format
2443 overwrite: boolean parameter for overwriting/not overwriting the file
2444 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2445 groupElemsByType: if True all elements of same entity type are exported at ones,
2446 else elements are exported in order of their IDs which can cause creation
2447 of multiple cgns sections
2450 unRegister = genObjUnRegister()
2451 if isinstance( meshPart, list ):
2452 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2453 unRegister.set( meshPart )
2454 if isinstance( meshPart, Mesh ):
2455 meshPart = meshPart.mesh
2457 meshPart = self.mesh
2458 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2460 def ExportGMF(self, f, meshPart=None):
2462 Export the mesh in a file in GMF format.
2463 GMF files must have .mesh extension for the ASCII format and .meshb for
2464 the bynary format. Other extensions are not allowed.
2468 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2471 unRegister = genObjUnRegister()
2472 if isinstance( meshPart, list ):
2473 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2474 unRegister.set( meshPart )
2475 if isinstance( meshPart, Mesh ):
2476 meshPart = meshPart.mesh
2478 meshPart = self.mesh
2479 self.mesh.ExportGMF(meshPart, f, True)
2481 def ExportToMED(self, *args, **kwargs):
2483 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2484 Export the mesh in a file in MED format
2485 allowing to overwrite the file if it exists or add the exported data to its contents
2488 fileName: the file name
2489 opt (boolean): parameter for creating/not creating
2490 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2491 overwrite: boolean parameter for overwriting/not overwriting the file
2492 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2494 - 1D if all mesh nodes lie on OX coordinate axis, or
2495 - 2D if all mesh nodes lie on XOY coordinate plane, or
2496 - 3D in the rest cases.
2498 If **autoDimension** is *False*, the space dimension is always 3.
2501 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2502 # process positional arguments
2503 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2505 auto_groups = args[1] if len(args) > 1 else False
2506 overwrite = args[2] if len(args) > 2 else True
2507 autoDimension = args[3] if len(args) > 3 else True
2508 # process keywords arguments
2509 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2510 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2511 overwrite = kwargs.get("overwrite", overwrite)
2512 autoDimension = kwargs.get("autoDimension", autoDimension)
2514 # invoke engine's function
2515 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2517 def ExportToMEDX(self, *args, **kwargs):
2519 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2520 Export the mesh in a file in MED format
2523 fileName: the file name
2524 opt (boolean): parameter for creating/not creating
2525 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2526 overwrite: boolean parameter for overwriting/not overwriting the file
2527 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2529 - 1D if all mesh nodes lie on OX coordinate axis, or
2530 - 2D if all mesh nodes lie on XOY coordinate plane, or
2531 - 3D in the rest cases.
2533 If **autoDimension** is *False*, the space dimension is always 3.
2536 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2537 # process positional arguments
2538 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2540 auto_groups = args[1] if len(args) > 1 else False
2541 overwrite = args[2] if len(args) > 2 else True
2542 autoDimension = args[3] if len(args) > 3 else True
2543 # process keywords arguments
2544 auto_groups = kwargs.get("auto_groups", auto_groups)
2545 overwrite = kwargs.get("overwrite", overwrite)
2546 autoDimension = kwargs.get("autoDimension", autoDimension)
2548 # invoke engine's function
2549 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2553 def Append(self, meshes, uniteIdenticalGroups = True,
2554 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2556 Append given meshes into this mesh.
2557 All groups of input meshes will be created in this mesh.
2560 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2561 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2562 mergeNodesAndElements: if True, equal nodes and elements are merged
2563 mergeTolerance: tolerance for merging nodes
2564 allGroups: forces creation of groups corresponding to every input mesh
2566 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2567 mergeNodesAndElements, mergeTolerance, allGroups,
2568 meshToAppendTo = self.GetMesh() )
2570 # Operations with groups:
2571 # ----------------------
2572 def CreateEmptyGroup(self, elementType, name):
2574 Create an empty standalone mesh group
2577 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2578 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2579 name: the name of the mesh group
2582 :class:`SMESH.SMESH_Group`
2585 return self.mesh.CreateGroup(elementType, name)
2587 def Group(self, grp, name=""):
2589 Create a mesh group based on the geometric object *grp*
2590 and give it a *name*.
2591 If *name* is not defined the name of the geometric group is used
2594 Works like :meth:`GroupOnGeom`.
2597 grp: a geometric group, a vertex, an edge, a face or a solid
2598 name: the name of the mesh group
2601 :class:`SMESH.SMESH_GroupOnGeom`
2604 return self.GroupOnGeom(grp, name)
2606 def GroupOnGeom(self, grp, name="", typ=None):
2608 Create a mesh group based on the geometrical object *grp*
2609 and give it a *name*.
2610 if *name* is not defined the name of the geometric group is used
2613 grp: a geometrical group, a vertex, an edge, a face or a solid
2614 name: the name of the mesh group
2615 typ: the type of elements in the group; either of
2616 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2617 automatically detected by the type of the geometry
2620 :class:`SMESH.SMESH_GroupOnGeom`
2623 AssureGeomPublished( self, grp, name )
2625 name = grp.GetName()
2627 typ = self._groupTypeFromShape( grp )
2628 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2630 def _groupTypeFromShape( self, shape ):
2632 Pivate method to get a type of group on geometry
2634 tgeo = str(shape.GetShapeType())
2635 if tgeo == "VERTEX":
2637 elif tgeo == "EDGE" or tgeo == "WIRE":
2639 elif tgeo == "FACE" or tgeo == "SHELL":
2641 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2643 elif tgeo == "COMPOUND":
2645 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2647 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2648 # simplification of access in geomBuilder: omniORB.registerObjref
2649 from SHAPERSTUDY_utils import getEngine
2652 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2654 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2655 return self._groupTypeFromShape( sub[0] )
2657 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2660 def GroupOnFilter(self, typ, name, filter):
2662 Create a mesh group with given *name* based on the *filter*.
2663 It is a special type of group dynamically updating it's contents during
2667 typ: the type of elements in the group; either of
2668 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2669 name: the name of the mesh group
2670 filter (SMESH.Filter): the filter defining group contents
2673 :class:`SMESH.SMESH_GroupOnFilter`
2676 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2678 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2680 Create a mesh group by the given ids of elements
2683 groupName: the name of the mesh group
2684 elementType: the type of elements in the group; either of
2685 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2686 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2689 :class:`SMESH.SMESH_Group`
2692 group = self.mesh.CreateGroup(elementType, groupName)
2693 if isinstance( elemIDs, Mesh ):
2694 elemIDs = elemIDs.GetMesh()
2695 if hasattr( elemIDs, "GetIDs" ):
2696 if hasattr( elemIDs, "SetMesh" ):
2697 elemIDs.SetMesh( self.GetMesh() )
2698 group.AddFrom( elemIDs )
2706 CritType=FT_Undefined,
2709 UnaryOp=FT_Undefined,
2712 Create a mesh group by the given conditions
2715 groupName: the name of the mesh group
2716 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2717 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2718 Note that the items starting from FT_LessThan are not suitable for CritType.
2719 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2720 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2721 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2722 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2723 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2726 :class:`SMESH.SMESH_GroupOnFilter`
2729 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2730 group = self.MakeGroupByCriterion(groupName, aCriterion)
2733 def MakeGroupByCriterion(self, groupName, Criterion):
2735 Create a mesh group by the given criterion
2738 groupName: the name of the mesh group
2739 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2742 :class:`SMESH.SMESH_GroupOnFilter`
2745 :meth:`smeshBuilder.GetCriterion`
2748 return self.MakeGroupByCriteria( groupName, [Criterion] )
2750 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2752 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2755 groupName: the name of the mesh group
2756 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2757 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2760 :class:`SMESH.SMESH_GroupOnFilter`
2763 :meth:`smeshBuilder.GetCriterion`
2766 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2767 group = self.MakeGroupByFilter(groupName, aFilter)
2770 def MakeGroupByFilter(self, groupName, theFilter):
2772 Create a mesh group by the given filter
2775 groupName (string): the name of the mesh group
2776 theFilter (SMESH.Filter): the filter
2779 :class:`SMESH.SMESH_GroupOnFilter`
2782 :meth:`smeshBuilder.GetFilter`
2785 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2786 #theFilter.SetMesh( self.mesh )
2787 #group.AddFrom( theFilter )
2788 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2791 def RemoveGroup(self, group):
2796 group (SMESH.SMESH_GroupBase): group to remove
2799 self.mesh.RemoveGroup(group)
2801 def RemoveGroupWithContents(self, group):
2803 Remove a group with its contents
2806 group (SMESH.SMESH_GroupBase): group to remove
2809 This operation can create gaps in numeration of nodes or elements.
2810 Call :meth:`RenumberElements` to remove the gaps.
2813 self.mesh.RemoveGroupWithContents(group)
2815 def GetGroups(self, elemType = SMESH.ALL):
2817 Get the list of groups existing in the mesh in the order of creation
2818 (starting from the oldest one)
2821 elemType (SMESH.ElementType): type of elements the groups contain;
2822 by default groups of elements of all types are returned
2825 a list of :class:`SMESH.SMESH_GroupBase`
2828 groups = self.mesh.GetGroups()
2829 if elemType == SMESH.ALL:
2833 if g.GetType() == elemType:
2834 typedGroups.append( g )
2841 Get the number of groups existing in the mesh
2844 the quantity of groups as an integer value
2847 return self.mesh.NbGroups()
2849 def GetGroupNames(self):
2851 Get the list of names of groups existing in the mesh
2857 groups = self.GetGroups()
2859 for group in groups:
2860 names.append(group.GetName())
2863 def GetGroupByName(self, name, elemType = None):
2865 Find groups by name and type
2868 name (string): name of the group of interest
2869 elemType (SMESH.ElementType): type of elements the groups contain;
2870 by default one group of any type is returned;
2871 if elemType == SMESH.ALL then all groups of any type are returned
2874 a list of :class:`SMESH.SMESH_GroupBase`
2878 for group in self.GetGroups():
2879 if group.GetName() == name:
2880 if elemType is None:
2882 if ( elemType == SMESH.ALL or
2883 group.GetType() == elemType ):
2884 groups.append( group )
2887 def UnionGroups(self, group1, group2, name):
2889 Produce a union of two groups.
2890 A new group is created. All mesh elements that are
2891 present in the initial groups are added to the new one
2894 group1 (SMESH.SMESH_GroupBase): a group
2895 group2 (SMESH.SMESH_GroupBase): another group
2898 instance of :class:`SMESH.SMESH_Group`
2901 return self.mesh.UnionGroups(group1, group2, name)
2903 def UnionListOfGroups(self, groups, name):
2905 Produce a union list of groups.
2906 New group is created. All mesh elements that are present in
2907 initial groups are added to the new one
2910 groups: list of :class:`SMESH.SMESH_GroupBase`
2913 instance of :class:`SMESH.SMESH_Group`
2915 return self.mesh.UnionListOfGroups(groups, name)
2917 def IntersectGroups(self, group1, group2, name):
2919 Prodice an intersection of two groups.
2920 A new group is created. All mesh elements that are common
2921 for the two initial groups are added to the new one.
2924 group1 (SMESH.SMESH_GroupBase): a group
2925 group2 (SMESH.SMESH_GroupBase): another group
2928 instance of :class:`SMESH.SMESH_Group`
2931 return self.mesh.IntersectGroups(group1, group2, name)
2933 def IntersectListOfGroups(self, groups, name):
2935 Produce an intersection of groups.
2936 New group is created. All mesh elements that are present in all
2937 initial groups simultaneously are added to the new one
2940 groups: a list of :class:`SMESH.SMESH_GroupBase`
2943 instance of :class:`SMESH.SMESH_Group`
2945 return self.mesh.IntersectListOfGroups(groups, name)
2947 def CutGroups(self, main_group, tool_group, name):
2949 Produce a cut of two groups.
2950 A new group is created. All mesh elements that are present in
2951 the main group but are not present in the tool group are added to the new one
2954 main_group (SMESH.SMESH_GroupBase): a group to cut from
2955 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2958 an instance of :class:`SMESH.SMESH_Group`
2961 return self.mesh.CutGroups(main_group, tool_group, name)
2963 def CutListOfGroups(self, main_groups, tool_groups, name):
2965 Produce a cut of groups.
2966 A new group is created. All mesh elements that are present in main groups
2967 but do not present in tool groups are added to the new one
2970 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2971 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2974 an instance of :class:`SMESH.SMESH_Group`
2977 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2979 def CreateDimGroup(self, groups, elemType, name,
2980 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2982 Create a standalone group of entities basing on nodes of other groups.
2985 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2986 elemType: a type of elements to include to the new group; either of
2987 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2988 name: a name of the new group.
2989 nbCommonNodes: a criterion of inclusion of an element to the new group
2990 basing on number of element nodes common with reference *groups*.
2991 Meaning of possible values are:
2993 - SMESH.ALL_NODES - include if all nodes are common,
2994 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2995 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2996 - SMEHS.MAJORITY - include if half of nodes or more are common.
2997 underlyingOnly: if *True* (default), an element is included to the
2998 new group provided that it is based on nodes of an element of *groups*;
2999 in this case the reference *groups* are supposed to be of higher dimension
3000 than *elemType*, which can be useful for example to get all faces lying on
3001 volumes of the reference *groups*.
3004 an instance of :class:`SMESH.SMESH_Group`
3007 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3009 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3011 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3013 Distribute all faces of the mesh among groups using sharp edges and optionally
3014 existing 1D elements as group boundaries.
3017 sharpAngle: edge is considered sharp if an angle between normals of
3018 adjacent faces is more than \a sharpAngle in degrees.
3019 createEdges (boolean): to create 1D elements for detected sharp edges.
3020 useExistingEdges (boolean): to use existing edges as group boundaries
3022 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3024 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3025 self.mesh.SetParameters(Parameters)
3026 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3028 def ConvertToStandalone(self, group):
3030 Convert group on geom into standalone group
3033 return self.mesh.ConvertToStandalone(group)
3035 # Get some info about mesh:
3036 # ------------------------
3038 def GetLog(self, clearAfterGet):
3040 Return the log of nodes and elements added or removed
3041 since the previous clear of the log.
3044 clearAfterGet: log is emptied after Get (safe if concurrents access)
3047 list of SMESH.log_block structures { commandType, number, coords, indexes }
3050 return self.mesh.GetLog(clearAfterGet)
3054 Clear the log of nodes and elements added or removed since the previous
3055 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3058 self.mesh.ClearLog()
3060 def SetAutoColor(self, theAutoColor):
3062 Toggle auto color mode on the object.
3063 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3066 theAutoColor (boolean): the flag which toggles auto color mode.
3069 self.mesh.SetAutoColor(theAutoColor)
3071 def GetAutoColor(self):
3073 Get flag of object auto color mode.
3079 return self.mesh.GetAutoColor()
3086 integer value, which is the internal Id of the mesh
3089 return self.mesh.GetId()
3091 def HasDuplicatedGroupNamesMED(self):
3093 Check the group names for duplications.
3094 Consider the maximum group name length stored in MED file.
3100 return self.mesh.HasDuplicatedGroupNamesMED()
3102 def GetMeshEditor(self):
3104 Obtain the mesh editor tool
3107 an instance of :class:`SMESH.SMESH_MeshEditor`
3112 def GetIDSource(self, ids, elemType = SMESH.ALL):
3114 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3115 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3119 elemType: type of elements; this parameter is used to distinguish
3120 IDs of nodes from IDs of elements; by default ids are treated as
3121 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3124 an instance of :class:`SMESH.SMESH_IDSource`
3127 call UnRegister() for the returned object as soon as it is no more useful::
3129 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3130 mesh.DoSomething( idSrc )
3134 if isinstance( ids, int ):
3136 return self.editor.MakeIDSource(ids, elemType)
3139 # Get information about mesh contents:
3140 # ------------------------------------
3142 def GetMeshInfo(self, obj = None):
3144 Get the mesh statistic.
3147 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3150 if not obj: obj = self.mesh
3151 return self.smeshpyD.GetMeshInfo(obj)
3155 Return the number of nodes in the mesh
3161 return self.mesh.NbNodes()
3163 def NbElements(self):
3165 Return the number of elements in the mesh
3171 return self.mesh.NbElements()
3173 def Nb0DElements(self):
3175 Return the number of 0d elements in the mesh
3181 return self.mesh.Nb0DElements()
3185 Return the number of ball discrete elements in the mesh
3191 return self.mesh.NbBalls()
3195 Return the number of edges in the mesh
3201 return self.mesh.NbEdges()
3203 def NbEdgesOfOrder(self, elementOrder):
3205 Return the number of edges with the given order in the mesh
3208 elementOrder: the order of elements
3209 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3215 return self.mesh.NbEdgesOfOrder(elementOrder)
3219 Return the number of faces in the mesh
3225 return self.mesh.NbFaces()
3227 def NbFacesOfOrder(self, elementOrder):
3229 Return the number of faces with the given order in the mesh
3232 elementOrder: the order of elements
3233 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3239 return self.mesh.NbFacesOfOrder(elementOrder)
3241 def NbTriangles(self):
3243 Return the number of triangles in the mesh
3249 return self.mesh.NbTriangles()
3251 def NbTrianglesOfOrder(self, elementOrder):
3253 Return the number of triangles with the given order in the mesh
3256 elementOrder: is the order of elements
3257 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3263 return self.mesh.NbTrianglesOfOrder(elementOrder)
3265 def NbBiQuadTriangles(self):
3267 Return the number of biquadratic triangles in the mesh
3273 return self.mesh.NbBiQuadTriangles()
3275 def NbQuadrangles(self):
3277 Return the number of quadrangles in the mesh
3283 return self.mesh.NbQuadrangles()
3285 def NbQuadranglesOfOrder(self, elementOrder):
3287 Return the number of quadrangles with the given order in the mesh
3290 elementOrder: the order of elements
3291 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3297 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3299 def NbBiQuadQuadrangles(self):
3301 Return the number of biquadratic quadrangles in the mesh
3307 return self.mesh.NbBiQuadQuadrangles()
3309 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3311 Return the number of polygons of given order in the mesh
3314 elementOrder: the order of elements
3315 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3321 return self.mesh.NbPolygonsOfOrder(elementOrder)
3323 def NbVolumes(self):
3325 Return the number of volumes in the mesh
3331 return self.mesh.NbVolumes()
3334 def NbVolumesOfOrder(self, elementOrder):
3336 Return the number of volumes with the given order in the mesh
3339 elementOrder: the order of elements
3340 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346 return self.mesh.NbVolumesOfOrder(elementOrder)
3350 Return the number of tetrahedrons in the mesh
3356 return self.mesh.NbTetras()
3358 def NbTetrasOfOrder(self, elementOrder):
3360 Return the number of tetrahedrons with the given order in the mesh
3363 elementOrder: the order of elements
3364 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370 return self.mesh.NbTetrasOfOrder(elementOrder)
3374 Return the number of hexahedrons in the mesh
3380 return self.mesh.NbHexas()
3382 def NbHexasOfOrder(self, elementOrder):
3384 Return the number of hexahedrons 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.NbHexasOfOrder(elementOrder)
3396 def NbTriQuadraticHexas(self):
3398 Return the number of triquadratic hexahedrons in the mesh
3404 return self.mesh.NbTriQuadraticHexas()
3406 def NbPyramids(self):
3408 Return the number of pyramids in the mesh
3414 return self.mesh.NbPyramids()
3416 def NbPyramidsOfOrder(self, elementOrder):
3418 Return the number of pyramids with the given order in the mesh
3421 elementOrder: the order of elements
3422 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428 return self.mesh.NbPyramidsOfOrder(elementOrder)
3432 Return the number of prisms in the mesh
3438 return self.mesh.NbPrisms()
3440 def NbPrismsOfOrder(self, elementOrder):
3442 Return the number of prisms with the given order in the mesh
3445 elementOrder: the order of elements
3446 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3452 return self.mesh.NbPrismsOfOrder(elementOrder)
3454 def NbHexagonalPrisms(self):
3456 Return the number of hexagonal prisms in the mesh
3462 return self.mesh.NbHexagonalPrisms()
3464 def NbPolyhedrons(self):
3466 Return the number of polyhedrons in the mesh
3472 return self.mesh.NbPolyhedrons()
3474 def NbSubMesh(self):
3476 Return the number of submeshes in the mesh
3482 return self.mesh.NbSubMesh()
3484 def GetElementsId(self):
3486 Return the list of all mesh elements IDs
3489 the list of integer values
3492 :meth:`GetElementsByType`
3495 return self.mesh.GetElementsId()
3497 def GetElementsByType(self, elementType):
3499 Return the list of IDs of mesh elements with the given type
3502 elementType (SMESH.ElementType): the required type of elements
3505 list of integer values
3508 return self.mesh.GetElementsByType(elementType)
3510 def GetNodesId(self):
3512 Return the list of mesh nodes IDs
3515 the list of integer values
3518 return self.mesh.GetNodesId()
3520 # Get the information about mesh elements:
3521 # ------------------------------------
3523 def GetElementType(self, id, iselem=True):
3525 Return the type of mesh element or node
3528 the value from :class:`SMESH.ElementType` enumeration.
3529 Return SMESH.ALL if element or node with the given ID does not exist
3532 return self.mesh.GetElementType(id, iselem)
3534 def GetElementGeomType(self, id):
3536 Return the geometric type of mesh element
3539 the value from :class:`SMESH.EntityType` enumeration.
3542 return self.mesh.GetElementGeomType(id)
3544 def GetElementShape(self, id):
3546 Return the shape type of mesh element
3549 the value from :class:`SMESH.GeometryType` enumeration.
3552 return self.mesh.GetElementShape(id)
3554 def GetSubMeshElementsId(self, Shape):
3556 Return the list of sub-mesh elements IDs
3559 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3560 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3563 list of integer values
3566 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3567 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3570 return self.mesh.GetSubMeshElementsId(ShapeID)
3572 def GetSubMeshNodesId(self, Shape, all):
3574 Return the list of sub-mesh nodes IDs
3577 Shape: a geom object (sub-shape).
3578 *Shape* must be the sub-shape of a :meth:`GetShape`
3579 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3582 list of integer values
3585 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3586 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3589 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3591 def GetSubMeshElementType(self, Shape):
3593 Return type of elements on given shape
3596 Shape: a geom object (sub-shape).
3597 *Shape* must be a sub-shape of a ShapeToMesh()
3600 :class:`SMESH.ElementType`
3603 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3604 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3607 return self.mesh.GetSubMeshElementType(ShapeID)
3611 Get the mesh description
3617 return self.mesh.Dump()
3620 # Get the information about nodes and elements of a mesh by its IDs:
3621 # -----------------------------------------------------------
3623 def GetNodeXYZ(self, id):
3625 Get XYZ coordinates of a node.
3626 If there is no node for the given ID - return an empty list
3629 list of float values
3632 return self.mesh.GetNodeXYZ(id)
3634 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3636 Return list of IDs of inverse elements for the given node.
3637 If there is no node for the given ID - return an empty list
3641 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3644 list of integer values
3647 return self.mesh.GetNodeInverseElements(id,elemType)
3649 def GetNodePosition(self,NodeID):
3651 Return the position of a node on the shape
3654 :class:`SMESH.NodePosition`
3657 return self.mesh.GetNodePosition(NodeID)
3659 def GetElementPosition(self,ElemID):
3661 Return the position of an element on the shape
3664 :class:`SMESH.ElementPosition`
3667 return self.mesh.GetElementPosition(ElemID)
3669 def GetShapeID(self, id):
3671 Return the ID of the shape, on which the given node was generated.
3674 an integer value > 0 or -1 if there is no node for the given
3675 ID or the node is not assigned to any geometry
3678 return self.mesh.GetShapeID(id)
3680 def GetShapeIDForElem(self,id):
3682 Return the ID of the shape, on which the given element was generated.
3685 an integer value > 0 or -1 if there is no element for the given
3686 ID or the element is not assigned to any geometry
3689 return self.mesh.GetShapeIDForElem(id)
3691 def GetElemNbNodes(self, id):
3693 Return the number of nodes of the given element
3696 an integer value > 0 or -1 if there is no element for the given ID
3699 return self.mesh.GetElemNbNodes(id)
3701 def GetElemNode(self, id, index):
3703 Return the node ID the given (zero based) index for the given element.
3705 * If there is no element for the given ID - return -1.
3706 * If there is no node for the given index - return -2.
3709 id (int): element ID
3710 index (int): node index within the element
3713 an integer value (ID)
3716 :meth:`GetElemNodes`
3719 return self.mesh.GetElemNode(id, index)
3721 def GetElemNodes(self, id):
3723 Return the IDs of nodes of the given element
3726 a list of integer values
3729 return self.mesh.GetElemNodes(id)
3731 def IsMediumNode(self, elementID, nodeID):
3733 Return true if the given node is the medium node in the given quadratic element
3736 return self.mesh.IsMediumNode(elementID, nodeID)
3738 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3740 Return true if the given node is the medium node in one of quadratic elements
3743 nodeID: ID of the node
3744 elementType: the type of elements to check a state of the node, either of
3745 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3748 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3750 def ElemNbEdges(self, id):
3752 Return the number of edges for the given element
3755 return self.mesh.ElemNbEdges(id)
3757 def ElemNbFaces(self, id):
3759 Return the number of faces for the given element
3762 return self.mesh.ElemNbFaces(id)
3764 def GetElemFaceNodes(self,elemId, faceIndex):
3766 Return nodes of given face (counted from zero) for given volumic element.
3769 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3771 def GetFaceNormal(self, faceId, normalized=False):
3773 Return three components of normal of given mesh face
3774 (or an empty array in KO case)
3777 return self.mesh.GetFaceNormal(faceId,normalized)
3779 def FindElementByNodes(self, nodes):
3781 Return an element based on all given nodes.
3784 return self.mesh.FindElementByNodes(nodes)
3786 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3788 Return elements including all given nodes.
3791 return self.mesh.GetElementsByNodes( nodes, elemType )
3793 def IsPoly(self, id):
3795 Return true if the given element is a polygon
3798 return self.mesh.IsPoly(id)
3800 def IsQuadratic(self, id):
3802 Return true if the given element is quadratic
3805 return self.mesh.IsQuadratic(id)
3807 def GetBallDiameter(self, id):
3809 Return diameter of a ball discrete element or zero in case of an invalid *id*
3812 return self.mesh.GetBallDiameter(id)
3814 def BaryCenter(self, id):
3816 Return XYZ coordinates of the barycenter of the given element.
3817 If there is no element for the given ID - return an empty list
3820 a list of three double values
3823 :meth:`smeshBuilder.GetGravityCenter`
3826 return self.mesh.BaryCenter(id)
3828 def GetIdsFromFilter(self, filter, meshParts=[] ):
3830 Pass mesh elements through the given filter and return IDs of fitting elements
3833 filter: :class:`SMESH.Filter`
3834 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3840 :meth:`SMESH.Filter.GetIDs`
3841 :meth:`SMESH.Filter.GetElementsIdFromParts`
3844 filter.SetMesh( self.mesh )
3847 if isinstance( meshParts, Mesh ):
3848 filter.SetMesh( meshParts.GetMesh() )
3849 return theFilter.GetIDs()
3850 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3851 meshParts = [ meshParts ]
3852 return filter.GetElementsIdFromParts( meshParts )
3854 return filter.GetIDs()
3856 # Get mesh measurements information:
3857 # ------------------------------------
3859 def GetFreeBorders(self):
3861 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3862 Return a list of special structures (borders).
3865 a list of :class:`SMESH.FreeEdges.Border`
3868 aFilterMgr = self.smeshpyD.CreateFilterManager()
3869 aPredicate = aFilterMgr.CreateFreeEdges()
3870 aPredicate.SetMesh(self.mesh)
3871 aBorders = aPredicate.GetBorders()
3872 aFilterMgr.UnRegister()
3875 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3877 Get minimum distance between two nodes, elements or distance to the origin
3880 id1: first node/element id
3881 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3882 isElem1: *True* if *id1* is element id, *False* if it is node id
3883 isElem2: *True* if *id2* is element id, *False* if it is node id
3886 minimum distance value
3888 :meth:`GetMinDistance`
3891 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3892 return aMeasure.value
3894 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3896 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3899 id1: first node/element id
3900 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3901 isElem1: *True* if *id1* is element id, *False* if it is node id
3902 isElem2: *True* if *id2* is element id, *False* if it is node id
3905 :class:`SMESH.Measure` structure
3911 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3913 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3916 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3918 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3923 aMeasurements = self.smeshpyD.CreateMeasurements()
3924 aMeasure = aMeasurements.MinDistance(id1, id2)
3925 genObjUnRegister([aMeasurements,id1, id2])
3928 def BoundingBox(self, objects=None, isElem=False):
3930 Get bounding box of the specified object(s)
3933 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3934 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3935 *False* specifies that *objects* are nodes
3938 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3941 :meth:`GetBoundingBox()`
3944 result = self.GetBoundingBox(objects, isElem)
3948 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3951 def GetBoundingBox(self, objects=None, isElem=False):
3953 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3956 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3957 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3958 False means that *objects* are nodes
3961 :class:`SMESH.Measure` structure
3964 :meth:`BoundingBox()`
3968 objects = [self.mesh]
3969 elif isinstance(objects, tuple):
3970 objects = list(objects)
3971 if not isinstance(objects, list):
3973 if len(objects) > 0 and isinstance(objects[0], int):
3976 unRegister = genObjUnRegister()
3978 if isinstance(o, Mesh):
3979 srclist.append(o.mesh)
3980 elif hasattr(o, "_narrow"):
3981 src = o._narrow(SMESH.SMESH_IDSource)
3982 if src: srclist.append(src)
3984 elif isinstance(o, list):
3986 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3988 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3989 unRegister.set( srclist[-1] )
3992 aMeasurements = self.smeshpyD.CreateMeasurements()
3993 unRegister.set( aMeasurements )
3994 aMeasure = aMeasurements.BoundingBox(srclist)
3997 # Mesh edition (SMESH_MeshEditor functionality):
3998 # ---------------------------------------------
4000 def RemoveElements(self, IDsOfElements):
4002 Remove the elements from the mesh by ids
4005 IDsOfElements: is a list of ids of elements to remove
4011 This operation can create gaps in numeration of elements.
4012 Call :meth:`RenumberElements` to remove the gaps.
4015 return self.editor.RemoveElements(IDsOfElements)
4017 def RemoveNodes(self, IDsOfNodes):
4019 Remove nodes from mesh by ids
4022 IDsOfNodes: is a list of ids of nodes to remove
4028 This operation can create gaps in numeration of nodes.
4029 Call :meth:`RenumberElements` to remove the gaps.
4032 return self.editor.RemoveNodes(IDsOfNodes)
4034 def RemoveOrphanNodes(self):
4036 Remove all orphan (free) nodes from mesh
4039 number of the removed nodes
4042 This operation can create gaps in numeration of nodes.
4043 Call :meth:`RenumberElements` to remove the gaps.
4046 return self.editor.RemoveOrphanNodes()
4048 def AddNode(self, x, y, z):
4050 Add a node to the mesh by coordinates
4056 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4057 if hasVars: self.mesh.SetParameters(Parameters)
4058 return self.editor.AddNode( x, y, z)
4060 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4062 Create a 0D element on a node with given number.
4065 IDOfNode: the ID of node for creation of the element.
4066 DuplicateElements: to add one more 0D element to a node or not
4069 ID of the new 0D element
4072 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4074 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4076 Create 0D elements on all nodes of the given elements except those
4077 nodes on which a 0D element already exists.
4080 theObject: an object on whose nodes 0D elements will be created.
4081 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4082 theGroupName: optional name of a group to add 0D elements created
4083 and/or found on nodes of *theObject*.
4084 DuplicateElements: to add one more 0D element to a node or not
4087 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4088 IDs of new and/or found 0D elements. IDs of 0D elements
4089 can be retrieved from the returned object by
4090 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4093 unRegister = genObjUnRegister()
4094 if isinstance( theObject, Mesh ):
4095 theObject = theObject.GetMesh()
4096 elif isinstance( theObject, list ):
4097 theObject = self.GetIDSource( theObject, SMESH.ALL )
4098 unRegister.set( theObject )
4099 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4101 def AddBall(self, IDOfNode, diameter):
4103 Create a ball element on a node with given ID.
4106 IDOfNode: the ID of node for creation of the element.
4107 diameter: the bal diameter.
4110 ID of the new ball element
4113 return self.editor.AddBall( IDOfNode, diameter )
4115 def AddEdge(self, IDsOfNodes):
4117 Create a linear or quadratic edge (this is determined
4118 by the number of given nodes).
4121 IDsOfNodes: list of node IDs for creation of the element.
4122 The order of nodes in this list should correspond to
4123 the :ref:`connectivity convention <connectivity_page>`.
4129 return self.editor.AddEdge(IDsOfNodes)
4131 def AddFace(self, IDsOfNodes):
4133 Create a linear or quadratic face (this is determined
4134 by the number of given nodes).
4137 IDsOfNodes: list of node IDs for creation of the element.
4138 The order of nodes in this list should correspond to
4139 the :ref:`connectivity convention <connectivity_page>`.
4145 return self.editor.AddFace(IDsOfNodes)
4147 def AddPolygonalFace(self, IdsOfNodes):
4149 Add a polygonal face defined by a list of node IDs
4152 IdsOfNodes: the list of node IDs for creation of the element.
4158 return self.editor.AddPolygonalFace(IdsOfNodes)
4160 def AddQuadPolygonalFace(self, IdsOfNodes):
4162 Add a quadratic polygonal face defined by a list of node IDs
4165 IdsOfNodes: the list of node IDs for creation of the element;
4166 corner nodes follow first.
4172 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4174 def AddVolume(self, IDsOfNodes):
4176 Create both simple and quadratic volume (this is determined
4177 by the number of given nodes).
4180 IDsOfNodes: list of node IDs for creation of the element.
4181 The order of nodes in this list should correspond to
4182 the :ref:`connectivity convention <connectivity_page>`.
4185 ID of the new volumic element
4188 return self.editor.AddVolume(IDsOfNodes)
4190 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4192 Create a volume of many faces, giving nodes for each face.
4195 IdsOfNodes: list of node IDs for volume creation, face by face.
4196 Quantities: list of integer values, Quantities[i]
4197 gives the quantity of nodes in face number i.
4200 ID of the new volumic element
4203 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4205 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4207 Create a volume of many faces, giving the IDs of the existing faces.
4210 The created volume will refer only to the nodes
4211 of the given faces, not to the faces themselves.
4214 IdsOfFaces: the list of face IDs for volume creation.
4217 ID of the new volumic element
4220 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4223 def SetNodeOnVertex(self, NodeID, Vertex):
4225 Bind a node to a vertex
4229 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4232 True if succeed else raises an exception
4235 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4236 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4240 self.editor.SetNodeOnVertex(NodeID, VertexID)
4241 except SALOME.SALOME_Exception as inst:
4242 raise ValueError(inst.details.text)
4246 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4248 Store the node position on an edge
4252 Edge: an edge (GEOM.GEOM_Object) or edge ID
4253 paramOnEdge: a parameter on the edge where the node is located
4256 True if succeed else raises an exception
4259 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4260 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4264 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4265 except SALOME.SALOME_Exception as inst:
4266 raise ValueError(inst.details.text)
4269 def SetNodeOnFace(self, NodeID, Face, u, v):
4271 Store node position on a face
4275 Face: a face (GEOM.GEOM_Object) or face ID
4276 u: U parameter on the face where the node is located
4277 v: V parameter on the face where the node is located
4280 True if succeed else raises an exception
4283 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4284 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4288 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4289 except SALOME.SALOME_Exception as inst:
4290 raise ValueError(inst.details.text)
4293 def SetNodeInVolume(self, NodeID, Solid):
4295 Bind a node to a solid
4299 Solid: a solid (GEOM.GEOM_Object) or solid ID
4302 True if succeed else raises an exception
4305 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4306 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4310 self.editor.SetNodeInVolume(NodeID, SolidID)
4311 except SALOME.SALOME_Exception as inst:
4312 raise ValueError(inst.details.text)
4315 def SetMeshElementOnShape(self, ElementID, Shape):
4317 Bind an element to a shape
4320 ElementID: an element ID
4321 Shape: a shape (GEOM.GEOM_Object) or shape ID
4324 True if succeed else raises an exception
4327 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4328 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4332 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4333 except SALOME.SALOME_Exception as inst:
4334 raise ValueError(inst.details.text)
4338 def MoveNode(self, NodeID, x, y, z):
4340 Move the node with the given id
4343 NodeID: the id of the node
4344 x: a new X coordinate
4345 y: a new Y coordinate
4346 z: a new Z coordinate
4349 True if succeed else False
4352 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4353 if hasVars: self.mesh.SetParameters(Parameters)
4354 return self.editor.MoveNode(NodeID, x, y, z)
4356 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4358 Find the node closest to a point and moves it to a point location
4361 x: the X coordinate of a point
4362 y: the Y coordinate of a point
4363 z: the Z coordinate of a point
4364 NodeID: if specified (>0), the node with this ID is moved,
4365 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4368 the ID of a moved node
4371 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4372 if hasVars: self.mesh.SetParameters(Parameters)
4373 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4375 def FindNodeClosestTo(self, x, y, z):
4377 Find the node closest to a point
4380 x: the X coordinate of a point
4381 y: the Y coordinate of a point
4382 z: the Z coordinate of a point
4388 return self.editor.FindNodeClosestTo(x, y, z)
4390 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4392 Find the elements where a point lays IN or ON
4395 x,y,z (float): coordinates of the point
4396 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4397 means elements of any type excluding nodes, discrete and 0D elements.
4398 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4401 list of IDs of found elements
4404 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4406 return self.editor.FindElementsByPoint(x, y, z, elementType)
4408 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4410 Project a point to a mesh object.
4411 Return ID of an element of given type where the given point is projected
4412 and coordinates of the projection point.
4413 In the case if nothing found, return -1 and []
4415 if isinstance( meshObject, Mesh ):
4416 meshObject = meshObject.GetMesh()
4418 meshObject = self.GetMesh()
4419 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4421 def GetPointState(self, x, y, z):
4423 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4424 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4425 UNKNOWN state means that either mesh is wrong or the analysis fails.
4428 return self.editor.GetPointState(x, y, z)
4430 def IsManifold(self):
4432 Check if a 2D mesh is manifold
4435 return self.editor.IsManifold()
4437 def IsCoherentOrientation2D(self):
4439 Check if orientation of 2D elements is coherent
4442 return self.editor.IsCoherentOrientation2D()
4444 def Get1DBranches( self, edges, startNode = 0 ):
4446 Partition given 1D elements into groups of contiguous edges.
4447 A node where number of meeting edges != 2 is a group end.
4448 An optional startNode is used to orient groups it belongs to.
4451 A list of edge groups and a list of corresponding node groups,
4452 where the group is a list of IDs of edges or elements, like follows
4453 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4454 If a group is closed, the first and last nodes of the group are same.
4456 if isinstance( edges, Mesh ):
4457 edges = edges.GetMesh()
4458 unRegister = genObjUnRegister()
4459 if isinstance( edges, list ):
4460 edges = self.GetIDSource( edges, SMESH.EDGE )
4461 unRegister.set( edges )
4462 return self.editor.Get1DBranches( edges, startNode )
4464 def FindSharpEdges( self, angle, addExisting=False ):
4466 Return sharp edges of faces and non-manifold ones.
4467 Optionally add existing edges.
4470 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4471 addExisting: to return existing edges (1D elements) as well
4474 list of FaceEdge structures
4476 angle = ParseParameters( angle )[0]
4477 return self.editor.FindSharpEdges( angle, addExisting )
4479 def MeshToPassThroughAPoint(self, x, y, z):
4481 Find the node closest to a point and moves it to a point location
4484 x: the X coordinate of a point
4485 y: the Y coordinate of a point
4486 z: the Z coordinate of a point
4489 the ID of a moved node
4492 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4494 def InverseDiag(self, NodeID1, NodeID2):
4496 Replace two neighbour triangles sharing Node1-Node2 link
4497 with the triangles built on the same 4 nodes but having other common link.
4500 NodeID1: the ID of the first node
4501 NodeID2: the ID of the second node
4504 False if proper faces were not found
4506 return self.editor.InverseDiag(NodeID1, NodeID2)
4508 def DeleteDiag(self, NodeID1, NodeID2):
4510 Replace two neighbour triangles sharing *Node1-Node2* link
4511 with a quadrangle built on the same 4 nodes.
4514 NodeID1: ID of the first node
4515 NodeID2: ID of the second node
4518 False if proper faces were not found
4521 This operation can create gaps in numeration of elements.
4522 Call :meth:`RenumberElements` to remove the gaps.
4525 return self.editor.DeleteDiag(NodeID1, NodeID2)
4527 def Reorient(self, IDsOfElements=None):
4529 Reorient elements by ids
4532 IDsOfElements: if undefined reorients all mesh elements
4535 True if succeed else False
4538 if IDsOfElements == None:
4539 IDsOfElements = self.GetElementsId()
4540 return self.editor.Reorient(IDsOfElements)
4542 def ReorientObject(self, theObject):
4544 Reorient all elements of the object
4547 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4550 True if succeed else False
4553 if ( isinstance( theObject, Mesh )):
4554 theObject = theObject.GetMesh()
4555 return self.editor.ReorientObject(theObject)
4557 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4559 Reorient faces contained in *the2DObject*.
4562 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4563 theDirection: a desired direction of normal of *theFace*.
4564 It can be either a GEOM vector or a list of coordinates [x,y,z].
4565 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4566 compared with theDirection. It can be either ID of face or a point
4567 by which the face will be found. The point can be given as either
4568 a GEOM vertex or a list of point coordinates.
4571 number of reoriented faces
4574 unRegister = genObjUnRegister()
4576 if isinstance( the2DObject, Mesh ):
4577 the2DObject = the2DObject.GetMesh()
4578 if isinstance( the2DObject, list ):
4579 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4580 unRegister.set( the2DObject )
4581 # check theDirection
4582 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4583 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4584 if isinstance( theDirection, list ):
4585 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4586 # prepare theFace and thePoint
4587 theFace = theFaceOrPoint
4588 thePoint = PointStruct(0,0,0)
4589 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4590 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4592 if isinstance( theFaceOrPoint, list ):
4593 thePoint = PointStruct( *theFaceOrPoint )
4595 if isinstance( theFaceOrPoint, PointStruct ):
4596 thePoint = theFaceOrPoint
4598 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4600 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4602 Reorient faces according to adjacent volumes.
4605 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4606 either IDs of faces or face groups.
4607 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4608 theOutsideNormal: to orient faces to have their normals
4609 pointing either *outside* or *inside* the adjacent volumes.
4612 number of reoriented faces.
4615 unRegister = genObjUnRegister()
4617 if not isinstance( the2DObject, list ):
4618 the2DObject = [ the2DObject ]
4619 elif the2DObject and isinstance( the2DObject[0], int ):
4620 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4621 unRegister.set( the2DObject )
4622 the2DObject = [ the2DObject ]
4623 for i,obj2D in enumerate( the2DObject ):
4624 if isinstance( obj2D, Mesh ):
4625 the2DObject[i] = obj2D.GetMesh()
4626 if isinstance( obj2D, list ):
4627 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4628 unRegister.set( the2DObject[i] )
4630 if isinstance( the3DObject, Mesh ):
4631 the3DObject = the3DObject.GetMesh()
4632 if isinstance( the3DObject, list ):
4633 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4634 unRegister.set( the3DObject )
4635 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4637 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4639 Fuse the neighbouring triangles into quadrangles.
4642 IDsOfElements: The triangles to be fused.
4643 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4644 applied to possible quadrangles to choose a neighbour to fuse with.
4645 Note that not all items of :class:`SMESH.FunctorType` corresponds
4646 to numerical functors.
4647 MaxAngle: is the maximum angle between element normals at which the fusion
4648 is still performed; theMaxAngle is measured in radians.
4649 Also it could be a name of variable which defines angle in degrees.
4652 True in case of success, False otherwise.
4655 This operation can create gaps in numeration of elements.
4656 Call :meth:`RenumberElements` to remove the gaps.
4659 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4660 self.mesh.SetParameters(Parameters)
4661 if not IDsOfElements:
4662 IDsOfElements = self.GetElementsId()
4663 Functor = self.smeshpyD.GetFunctor(theCriterion)
4664 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4666 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4668 Fuse the neighbouring triangles of the object into quadrangles
4671 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4672 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4673 applied to possible quadrangles to choose a neighbour to fuse with.
4674 Note that not all items of :class:`SMESH.FunctorType` corresponds
4675 to numerical functors.
4676 MaxAngle: a max angle between element normals at which the fusion
4677 is still performed; theMaxAngle is measured in radians.
4680 True in case of success, False otherwise.
4683 This operation can create gaps in numeration of elements.
4684 Call :meth:`RenumberElements` to remove the gaps.
4687 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4688 self.mesh.SetParameters(Parameters)
4689 if isinstance( theObject, Mesh ):
4690 theObject = theObject.GetMesh()
4691 Functor = self.smeshpyD.GetFunctor(theCriterion)
4692 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4694 def QuadToTri (self, IDsOfElements, theCriterion = None):
4696 Split quadrangles into triangles.
4699 IDsOfElements: the faces to be splitted.
4700 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4701 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4702 value, then quadrangles will be split by the smallest diagonal.
4703 Note that not all items of :class:`SMESH.FunctorType` corresponds
4704 to numerical functors.
4707 True in case of success, False otherwise.
4710 This operation can create gaps in numeration of elements.
4711 Call :meth:`RenumberElements` to remove the gaps.
4713 if IDsOfElements == []:
4714 IDsOfElements = self.GetElementsId()
4715 if theCriterion is None:
4716 theCriterion = FT_MaxElementLength2D
4717 Functor = self.smeshpyD.GetFunctor(theCriterion)
4718 return self.editor.QuadToTri(IDsOfElements, Functor)
4720 def QuadToTriObject (self, theObject, theCriterion = None):
4722 Split quadrangles into triangles.
4725 theObject: the object from which the list of elements is taken,
4726 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4727 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4728 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4729 value, then quadrangles will be split by the smallest diagonal.
4730 Note that not all items of :class:`SMESH.FunctorType` corresponds
4731 to numerical functors.
4734 True in case of success, False otherwise.
4737 This operation can create gaps in numeration of elements.
4738 Call :meth:`RenumberElements` to remove the gaps.
4740 if ( isinstance( theObject, Mesh )):
4741 theObject = theObject.GetMesh()
4742 if theCriterion is None:
4743 theCriterion = FT_MaxElementLength2D
4744 Functor = self.smeshpyD.GetFunctor(theCriterion)
4745 return self.editor.QuadToTriObject(theObject, Functor)
4747 def QuadTo4Tri (self, theElements=[]):
4749 Split each of given quadrangles into 4 triangles. A node is added at the center of
4753 theElements: the faces to be splitted. This can be either
4754 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4755 or a list of face IDs. By default all quadrangles are split
4758 This operation can create gaps in numeration of elements.
4759 Call :meth:`RenumberElements` to remove the gaps.
4761 unRegister = genObjUnRegister()
4762 if isinstance( theElements, Mesh ):
4763 theElements = theElements.mesh
4764 elif not theElements:
4765 theElements = self.mesh
4766 elif isinstance( theElements, list ):
4767 theElements = self.GetIDSource( theElements, SMESH.FACE )
4768 unRegister.set( theElements )
4769 return self.editor.QuadTo4Tri( theElements )
4771 def SplitQuad (self, IDsOfElements, Diag13):
4773 Split quadrangles into triangles.
4776 IDsOfElements: the faces to be splitted
4777 Diag13 (boolean): is used to choose a diagonal for splitting.
4780 True in case of success, False otherwise.
4783 This operation can create gaps in numeration of elements.
4784 Call :meth:`RenumberElements` to remove the gaps.
4786 if IDsOfElements == []:
4787 IDsOfElements = self.GetElementsId()
4788 return self.editor.SplitQuad(IDsOfElements, Diag13)
4790 def SplitQuadObject (self, theObject, Diag13):
4792 Split quadrangles into triangles.
4795 theObject: the object from which the list of elements is taken,
4796 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4797 Diag13 (boolean): is used to choose a diagonal for splitting.
4800 True in case of success, False otherwise.
4803 This operation can create gaps in numeration of elements.
4804 Call :meth:`RenumberElements` to remove the gaps.
4806 if ( isinstance( theObject, Mesh )):
4807 theObject = theObject.GetMesh()
4808 return self.editor.SplitQuadObject(theObject, Diag13)
4810 def BestSplit (self, IDOfQuad, theCriterion):
4812 Find a better splitting of the given quadrangle.
4815 IDOfQuad: the ID of the quadrangle to be splitted.
4816 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4817 choose a diagonal for splitting.
4818 Note that not all items of :class:`SMESH.FunctorType` corresponds
4819 to numerical functors.
4822 * 1 if 1-3 diagonal is better,
4823 * 2 if 2-4 diagonal is better,
4824 * 0 if error occurs.
4827 This operation can create gaps in numeration of elements.
4828 Call :meth:`RenumberElements` to remove the gaps.
4830 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4832 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4834 Split volumic elements into tetrahedrons
4837 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4838 method: flags passing splitting method:
4839 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4840 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4843 This operation can create gaps in numeration of elements.
4844 Call :meth:`RenumberElements` to remove the gaps.
4846 unRegister = genObjUnRegister()
4847 if isinstance( elems, Mesh ):
4848 elems = elems.GetMesh()
4849 if ( isinstance( elems, list )):
4850 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4851 unRegister.set( elems )
4852 self.editor.SplitVolumesIntoTetra(elems, method)
4855 def SplitBiQuadraticIntoLinear(self, elems=None):
4857 Split bi-quadratic elements into linear ones without creation of additional nodes:
4859 - bi-quadratic triangle will be split into 3 linear quadrangles;
4860 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4861 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4863 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4864 will be split in order to keep the mesh conformal.
4867 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4868 if None (default), all bi-quadratic elements will be split
4871 This operation can create gaps in numeration of elements.
4872 Call :meth:`RenumberElements` to remove the gaps.
4874 unRegister = genObjUnRegister()
4875 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4876 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4877 unRegister.set( elems )
4879 elems = [ self.GetMesh() ]
4880 if isinstance( elems, Mesh ):
4881 elems = [ elems.GetMesh() ]
4882 if not isinstance( elems, list ):
4884 self.editor.SplitBiQuadraticIntoLinear( elems )
4886 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4887 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4889 Split hexahedra into prisms
4892 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4893 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4894 gives a normal vector defining facets to split into triangles.
4895 *startHexPoint* can be either a triple of coordinates or a vertex.
4896 facetNormal: a normal to a facet to split into triangles of a
4897 hexahedron found by *startHexPoint*.
4898 *facetNormal* can be either a triple of coordinates or an edge.
4899 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4900 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4901 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4902 to *startHexPoint* are split, else *startHexPoint*
4903 is used to find the facet to split in all domains present in *elems*.
4906 This operation can create gaps in numeration of elements.
4907 Call :meth:`RenumberElements` to remove the gaps.
4910 unRegister = genObjUnRegister()
4911 if isinstance( elems, Mesh ):
4912 elems = elems.GetMesh()
4913 if ( isinstance( elems, list )):
4914 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4915 unRegister.set( elems )
4918 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4919 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4920 elif isinstance( startHexPoint, list ):
4921 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4924 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4925 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4926 elif isinstance( facetNormal, list ):
4927 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4930 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4932 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4934 def SplitQuadsNearTriangularFacets(self):
4936 Split quadrangle faces near triangular facets of volumes
4939 This operation can create gaps in numeration of elements.
4940 Call :meth:`RenumberElements` to remove the gaps.
4942 faces_array = self.GetElementsByType(SMESH.FACE)
4943 for face_id in faces_array:
4944 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4945 quad_nodes = self.mesh.GetElemNodes(face_id)
4946 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4947 isVolumeFound = False
4948 for node1_elem in node1_elems:
4949 if not isVolumeFound:
4950 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4951 nb_nodes = self.GetElemNbNodes(node1_elem)
4952 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4953 volume_elem = node1_elem
4954 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4955 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4956 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4957 isVolumeFound = True
4958 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4959 self.SplitQuad([face_id], False) # diagonal 2-4
4960 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4961 isVolumeFound = True
4962 self.SplitQuad([face_id], True) # diagonal 1-3
4963 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4964 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4965 isVolumeFound = True
4966 self.SplitQuad([face_id], True) # diagonal 1-3
4968 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4970 Split hexahedrons into tetrahedrons.
4972 This operation uses :doc:`pattern_mapping` functionality for splitting.
4975 theObject: the object from which the list of hexahedrons is taken;
4976 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4977 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4978 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4979 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4980 key-point will be mapped into *theNode001*-th node of each volume.
4981 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4984 True in case of success, False otherwise.
4987 This operation can create gaps in numeration of elements.
4988 Call :meth:`RenumberElements` to remove the gaps.
4996 # (0,0,1) 4.---------.7 * |
5003 # (0,0,0) 0.---------.3
5004 pattern_tetra = "!!! Nb of points: \n 8 \n\
5014 !!! Indices of points of 6 tetras: \n\
5022 pattern = self.smeshpyD.GetPattern()
5023 isDone = pattern.LoadFromFile(pattern_tetra)
5025 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5028 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5029 isDone = pattern.MakeMesh(self.mesh, False, False)
5030 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5032 # split quafrangle faces near triangular facets of volumes
5033 self.SplitQuadsNearTriangularFacets()
5037 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5039 Split hexahedrons into prisms.
5041 Uses the :doc:`pattern_mapping` functionality for splitting.
5044 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5045 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5046 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5047 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5048 will be mapped into the *theNode001* -th node of each volume.
5049 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5052 True in case of success, False otherwise.
5055 This operation can create gaps in numeration of elements.
5056 Call :meth:`RenumberElements` to remove the gaps.
5058 # Pattern: 5.---------.6
5063 # (0,0,1) 4.---------.7 |
5070 # (0,0,0) 0.---------.3
5071 pattern_prism = "!!! Nb of points: \n 8 \n\
5081 !!! Indices of points of 2 prisms: \n\
5085 pattern = self.smeshpyD.GetPattern()
5086 isDone = pattern.LoadFromFile(pattern_prism)
5088 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5091 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5092 isDone = pattern.MakeMesh(self.mesh, False, False)
5093 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5095 # Split quafrangle faces near triangular facets of volumes
5096 self.SplitQuadsNearTriangularFacets()
5100 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5101 MaxNbOfIterations, MaxAspectRatio, Method):
5106 IDsOfElements: the list if ids of elements to smooth
5107 IDsOfFixedNodes: the list of ids of fixed nodes.
5108 Note that nodes built on edges and boundary nodes are always fixed.
5109 MaxNbOfIterations: the maximum number of iterations
5110 MaxAspectRatio: varies in range [1.0, inf]
5111 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5112 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5115 True in case of success, False otherwise.
5118 if IDsOfElements == []:
5119 IDsOfElements = self.GetElementsId()
5120 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5121 self.mesh.SetParameters(Parameters)
5122 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5123 MaxNbOfIterations, MaxAspectRatio, Method)
5125 def SmoothObject(self, theObject, IDsOfFixedNodes,
5126 MaxNbOfIterations, MaxAspectRatio, Method):
5128 Smooth elements which belong to the given object
5131 theObject: the object to smooth
5132 IDsOfFixedNodes: the list of ids of fixed nodes.
5133 Note that nodes built on edges and boundary nodes are always fixed.
5134 MaxNbOfIterations: the maximum number of iterations
5135 MaxAspectRatio: varies in range [1.0, inf]
5136 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5137 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5140 True in case of success, False otherwise.
5143 if ( isinstance( theObject, Mesh )):
5144 theObject = theObject.GetMesh()
5145 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5146 MaxNbOfIterations, MaxAspectRatio, Method)
5148 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5149 MaxNbOfIterations, MaxAspectRatio, Method):
5151 Parametrically smooth the given elements
5154 IDsOfElements: the list if ids of elements to smooth
5155 IDsOfFixedNodes: the list of ids of fixed nodes.
5156 Note that nodes built on edges and boundary nodes are always fixed.
5157 MaxNbOfIterations: the maximum number of iterations
5158 MaxAspectRatio: varies in range [1.0, inf]
5159 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5160 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5163 True in case of success, False otherwise.
5166 if IDsOfElements == []:
5167 IDsOfElements = self.GetElementsId()
5168 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5169 self.mesh.SetParameters(Parameters)
5170 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5171 MaxNbOfIterations, MaxAspectRatio, Method)
5173 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5174 MaxNbOfIterations, MaxAspectRatio, Method):
5176 Parametrically smooth the elements which belong to the given object
5179 theObject: the object to smooth
5180 IDsOfFixedNodes: the list of ids of fixed nodes.
5181 Note that nodes built on edges and boundary nodes are always fixed.
5182 MaxNbOfIterations: the maximum number of iterations
5183 MaxAspectRatio: varies in range [1.0, inf]
5184 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5185 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5188 True in case of success, False otherwise.
5191 if ( isinstance( theObject, Mesh )):
5192 theObject = theObject.GetMesh()
5193 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5194 MaxNbOfIterations, MaxAspectRatio, Method)
5196 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5198 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5199 them with quadratic with the same id.
5202 theForce3d: method of new node creation:
5204 * False - the medium node lies at the geometrical entity from which the mesh element is built
5205 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5206 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5207 theToBiQuad: If True, converts the mesh to bi-quadratic
5210 :class:`SMESH.ComputeError` which can hold a warning
5213 If *theSubMesh* is provided, the mesh can become non-conformal
5216 This operation can create gaps in numeration of nodes or elements.
5217 Call :meth:`RenumberElements` to remove the gaps.
5220 if isinstance( theSubMesh, Mesh ):
5221 theSubMesh = theSubMesh.mesh
5223 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5226 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5228 self.editor.ConvertToQuadratic(theForce3d)
5229 error = self.editor.GetLastError()
5230 if error and error.comment:
5231 print(error.comment)
5234 def ConvertFromQuadratic(self, theSubMesh=None):
5236 Convert the mesh from quadratic to ordinary,
5237 deletes old quadratic elements,
5238 replacing them with ordinary mesh elements with the same id.
5241 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5244 If *theSubMesh* is provided, the mesh can become non-conformal
5247 This operation can create gaps in numeration of nodes or elements.
5248 Call :meth:`RenumberElements` to remove the gaps.
5252 self.editor.ConvertFromQuadraticObject(theSubMesh)
5254 return self.editor.ConvertFromQuadratic()
5256 def Make2DMeshFrom3D(self):
5258 Create 2D mesh as skin on boundary faces of a 3D mesh
5261 True if operation has been completed successfully, False otherwise
5264 return self.editor.Make2DMeshFrom3D()
5266 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5267 toCopyElements=False, toCopyExistingBondary=False):
5269 Create missing boundary elements
5272 elements: elements whose boundary is to be checked:
5273 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5274 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5275 dimension: defines type of boundary elements to create, either of
5276 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5277 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5278 groupName: a name of group to store created boundary elements in,
5279 "" means not to create the group
5280 meshName: a name of new mesh to store created boundary elements in,
5281 "" means not to create the new mesh
5282 toCopyElements: if True, the checked elements will be copied into
5283 the new mesh else only boundary elements will be copied into the new mesh
5284 toCopyExistingBondary: if True, not only new but also pre-existing
5285 boundary elements will be copied into the new mesh
5288 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5291 unRegister = genObjUnRegister()
5292 if isinstance( elements, Mesh ):
5293 elements = elements.GetMesh()
5294 if ( isinstance( elements, list )):
5295 elemType = SMESH.ALL
5296 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5297 elements = self.editor.MakeIDSource(elements, elemType)
5298 unRegister.set( elements )
5299 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5300 toCopyElements,toCopyExistingBondary)
5301 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5304 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5305 toCopyAll=False, groups=[]):
5307 Create missing boundary elements around either the whole mesh or
5311 dimension: defines type of boundary elements to create, either of
5312 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5313 groupName: a name of group to store all boundary elements in,
5314 "" means not to create the group
5315 meshName: a name of a new mesh, which is a copy of the initial
5316 mesh + created boundary elements; "" means not to create the new mesh
5317 toCopyAll: if True, the whole initial mesh will be copied into
5318 the new mesh else only boundary elements will be copied into the new mesh
5319 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5322 tuple( long, mesh, group )
5323 - long - number of added boundary elements
5324 - mesh - the :class:`Mesh` where elements were added to
5325 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5328 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5330 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5331 return nb, mesh, group
5333 def RenumberNodes(self):
5335 Renumber mesh nodes to remove unused node IDs
5337 self.editor.RenumberNodes()
5339 def RenumberElements(self):
5341 Renumber mesh elements to remove unused element IDs
5343 self.editor.RenumberElements()
5345 def _getIdSourceList(self, arg, idType, unRegister):
5347 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5349 if arg and isinstance( arg, list ):
5350 if isinstance( arg[0], int ):
5351 arg = self.GetIDSource( arg, idType )
5352 unRegister.set( arg )
5353 elif isinstance( arg[0], Mesh ):
5354 arg[0] = arg[0].GetMesh()
5355 elif isinstance( arg, Mesh ):
5357 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5361 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5362 MakeGroups=False, TotalAngle=False):
5364 Generate new elements by rotation of the given elements and nodes around the axis
5367 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5368 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5369 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5370 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5371 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5372 which defines angle in degrees
5373 NbOfSteps: the number of steps
5374 Tolerance: tolerance
5375 MakeGroups: forces the generation of new groups from existing ones
5376 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5377 of all steps, else - size of each step
5380 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5383 unRegister = genObjUnRegister()
5384 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5385 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5386 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5388 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5389 Axis = self.smeshpyD.GetAxisStruct( Axis )
5390 if isinstance( Axis, list ):
5391 Axis = SMESH.AxisStruct( *Axis )
5393 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5394 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5395 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5396 self.mesh.SetParameters(Parameters)
5397 if TotalAngle and NbOfSteps:
5398 AngleInRadians /= NbOfSteps
5399 return self.editor.RotationSweepObjects( nodes, edges, faces,
5400 Axis, AngleInRadians,
5401 NbOfSteps, Tolerance, MakeGroups)
5403 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5404 MakeGroups=False, TotalAngle=False):
5406 Generate new elements by rotation of the elements around the axis
5409 IDsOfElements: the list of ids of elements to sweep
5410 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5411 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5412 NbOfSteps: the number of steps
5413 Tolerance: tolerance
5414 MakeGroups: forces the generation of new groups from existing ones
5415 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5416 of all steps, else - size of each step
5419 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5422 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5423 AngleInRadians, NbOfSteps, Tolerance,
5424 MakeGroups, TotalAngle)
5426 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5427 MakeGroups=False, TotalAngle=False):
5429 Generate new elements by rotation of the elements of object around the axis
5430 theObject object which elements should be sweeped.
5431 It can be a mesh, a sub mesh or a group.
5434 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5435 AngleInRadians: the angle of Rotation
5436 NbOfSteps: number of steps
5437 Tolerance: tolerance
5438 MakeGroups: forces the generation of new groups from existing ones
5439 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5440 of all steps, else - size of each step
5443 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5446 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5447 AngleInRadians, NbOfSteps, Tolerance,
5448 MakeGroups, TotalAngle )
5450 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5451 MakeGroups=False, TotalAngle=False):
5453 Generate new elements by rotation of the elements of object around the axis
5454 theObject object which elements should be sweeped.
5455 It can be a mesh, a sub mesh or a group.
5458 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5459 AngleInRadians: the angle of Rotation
5460 NbOfSteps: number of steps
5461 Tolerance: tolerance
5462 MakeGroups: forces the generation of new groups from existing ones
5463 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5464 of all steps, else - size of each step
5467 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5468 empty list otherwise
5471 return self.RotationSweepObjects([],theObject,[], Axis,
5472 AngleInRadians, NbOfSteps, Tolerance,
5473 MakeGroups, TotalAngle)
5475 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5476 MakeGroups=False, TotalAngle=False):
5478 Generate new elements by rotation of the elements of object around the axis
5479 theObject object which elements should be sweeped.
5480 It can be a mesh, a sub mesh or a group.
5483 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5484 AngleInRadians: the angle of Rotation
5485 NbOfSteps: number of steps
5486 Tolerance: tolerance
5487 MakeGroups: forces the generation of new groups from existing ones
5488 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5489 of all steps, else - size of each step
5492 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5495 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5496 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5498 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5499 scaleFactors=[], linearVariation=False, basePoint=[],
5500 angles=[], anglesVariation=False):
5502 Generate new elements by extrusion of the given elements and nodes
5505 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5506 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5507 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5508 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5509 the direction and value of extrusion for one step (the total extrusion
5510 length will be NbOfSteps * ||StepVector||)
5511 NbOfSteps: the number of steps
5512 MakeGroups: forces the generation of new groups from existing ones
5513 scaleFactors: optional scale factors to apply during extrusion
5514 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5515 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5516 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5517 nodes and elements being extruded is used as the scaling center.
5520 - a list of tree components of the point or
5523 angles: list of angles in radians. Nodes at each extrusion step are rotated
5524 around *basePoint*, additionally to previous steps.
5525 anglesVariation: forces the computation of rotation angles as linear
5526 variation of the given *angles* along path steps
5528 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5530 Example: :ref:`tui_extrusion`
5532 unRegister = genObjUnRegister()
5533 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5534 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5535 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5537 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5538 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5539 if isinstance( StepVector, list ):
5540 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5542 if isinstance( basePoint, int):
5543 xyz = self.GetNodeXYZ( basePoint )
5545 raise RuntimeError("Invalid node ID: %s" % basePoint)
5547 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5548 basePoint = self.geompyD.PointCoordinates( basePoint )
5550 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5551 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5552 angles,angleParameters,hasVars = ParseAngles(angles)
5553 Parameters = StepVector.PS.parameters + var_separator + \
5554 Parameters + var_separator + \
5555 scaleParameters + var_separator + angleParameters
5556 self.mesh.SetParameters(Parameters)
5558 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5559 StepVector, NbOfSteps, MakeGroups,
5560 scaleFactors, linearVariation, basePoint,
5561 angles, anglesVariation )
5564 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5566 Generate new elements by extrusion of the elements with given ids
5569 IDsOfElements: the list of ids of elements or nodes for extrusion
5570 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5571 the direction and value of extrusion for one step (the total extrusion
5572 length will be NbOfSteps * ||StepVector||)
5573 NbOfSteps: the number of steps
5574 MakeGroups: forces the generation of new groups from existing ones
5575 IsNodes: is True if elements with given ids are nodes
5578 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5580 Example: :ref:`tui_extrusion`
5583 if IsNodes: n = IDsOfElements
5584 else : e,f, = IDsOfElements,IDsOfElements
5585 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5587 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5588 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5590 Generate new elements by extrusion along the normal to a discretized surface or wire
5593 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5594 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5595 StepSize: length of one extrusion step (the total extrusion
5596 length will be *NbOfSteps* *StepSize*).
5597 NbOfSteps: number of extrusion steps.
5598 ByAverageNormal: if True each node is translated by *StepSize*
5599 along the average of the normal vectors to the faces sharing the node;
5600 else each node is translated along the same average normal till
5601 intersection with the plane got by translation of the face sharing
5602 the node along its own normal by *StepSize*.
5603 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5604 for every node of *Elements*.
5605 MakeGroups: forces generation of new groups from existing ones.
5606 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5607 is not yet implemented. This parameter is used if *Elements* contains
5608 both faces and edges, i.e. *Elements* is a Mesh.
5611 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5612 empty list otherwise.
5613 Example: :ref:`tui_extrusion`
5616 unRegister = genObjUnRegister()
5617 if isinstance( Elements, Mesh ):
5618 Elements = [ Elements.GetMesh() ]
5619 if isinstance( Elements, list ):
5621 raise RuntimeError("Elements empty!")
5622 if isinstance( Elements[0], Mesh ):
5623 Elements = [ Elements[0].GetMesh() ]
5624 if isinstance( Elements[0], int ):
5625 Elements = self.GetIDSource( Elements, SMESH.ALL )
5626 unRegister.set( Elements )
5627 if not isinstance( Elements, list ):
5628 Elements = [ Elements ]
5629 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5630 self.mesh.SetParameters(Parameters)
5631 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5632 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5634 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5636 Generate new elements by extrusion of the elements or nodes which belong to the object
5639 theObject: the object whose elements or nodes should be processed.
5640 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5641 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5642 the direction and value of extrusion for one step (the total extrusion
5643 length will be NbOfSteps * ||StepVector||)
5644 NbOfSteps: the number of steps
5645 MakeGroups: forces the generation of new groups from existing ones
5646 IsNodes: is True if elements to extrude are nodes
5649 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5650 Example: :ref:`tui_extrusion`
5654 if IsNodes: n = theObject
5655 else : e,f, = theObject,theObject
5656 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5658 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5660 Generate new elements by extrusion of edges which belong to the object
5663 theObject: object whose 1D elements should be processed.
5664 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5665 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5666 the direction and value of extrusion for one step (the total extrusion
5667 length will be NbOfSteps * ||StepVector||)
5668 NbOfSteps: the number of steps
5669 MakeGroups: to generate new groups from existing ones
5672 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5673 Example: :ref:`tui_extrusion`
5676 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5678 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5680 Generate new elements by extrusion of faces which belong to the object
5683 theObject: object whose 2D elements should be processed.
5684 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5685 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5686 the direction and value of extrusion for one step (the total extrusion
5687 length will be NbOfSteps * ||StepVector||)
5688 NbOfSteps: the number of steps
5689 MakeGroups: forces the generation of new groups from existing ones
5692 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5693 Example: :ref:`tui_extrusion`
5696 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5698 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5699 ExtrFlags, SewTolerance, MakeGroups=False):
5701 Generate new elements by extrusion of the elements with given ids
5704 IDsOfElements: is ids of elements
5705 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5706 the direction and value of extrusion for one step (the total extrusion
5707 length will be NbOfSteps * ||StepVector||)
5708 NbOfSteps: the number of steps
5709 ExtrFlags: sets flags for extrusion
5710 SewTolerance: uses for comparing locations of nodes if flag
5711 EXTRUSION_FLAG_SEW is set
5712 MakeGroups: forces the generation of new groups from existing ones
5715 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5718 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5719 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5720 if isinstance( StepVector, list ):
5721 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5722 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5723 ExtrFlags, SewTolerance, MakeGroups)
5725 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5726 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5727 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5728 ScaleFactors=[], ScalesVariation=False):
5730 Generate new elements by extrusion of the given elements and nodes along the path.
5731 The path of extrusion must be a meshed edge.
5734 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5735 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5736 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5737 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5738 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
5739 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5740 HasAngles: not used obsolete
5741 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5742 around *basePoint*, additionally to previous steps.
5743 LinearVariation: forces the computation of rotation angles as linear
5744 variation of the given Angles along path steps
5745 HasRefPoint: allows using the reference point
5746 RefPoint: optional scaling and rotation center (mass center of the extruded
5747 elements by default). The User can specify any point as the Reference Point.
5748 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5749 MakeGroups: forces the generation of new groups from existing ones
5750 ScaleFactors: optional scale factors to apply during extrusion
5751 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5752 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5755 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5756 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5757 Example: :ref:`tui_extrusion_along_path`
5760 unRegister = genObjUnRegister()
5761 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5762 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5763 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5765 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5766 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5767 if isinstance( RefPoint, list ):
5768 if not RefPoint: RefPoint = [0,0,0]
5769 RefPoint = SMESH.PointStruct( *RefPoint )
5770 if isinstance( PathObject, Mesh ):
5771 PathObject = PathObject.GetMesh()
5772 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5773 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5774 Parameters = AnglesParameters + var_separator + \
5775 RefPoint.parameters + var_separator + ScalesParameters
5776 self.mesh.SetParameters(Parameters)
5777 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5778 PathObject, PathShape, NodeStart,
5779 HasAngles, Angles, LinearVariation,
5780 HasRefPoint, RefPoint, MakeGroups,
5781 ScaleFactors, ScalesVariation)
5783 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5784 HasAngles=False, Angles=[], LinearVariation=False,
5785 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5786 ElemType=SMESH.FACE):
5788 Generate new elements by extrusion of the given elements.
5789 The path of extrusion must be a meshed edge.
5792 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5793 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5794 NodeStart: the start node from Path. Defines the direction of extrusion
5795 HasAngles: not used obsolete
5796 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5797 around *basePoint*, additionally to previous steps.
5798 LinearVariation: forces the computation of rotation angles as linear
5799 variation of the given Angles along path steps
5800 HasRefPoint: allows using the reference point
5801 RefPoint: the reference point around which the elements are rotated (the mass
5802 center of the elements by default).
5803 The User can specify any point as the Reference Point.
5804 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5805 MakeGroups: forces the generation of new groups from existing ones
5806 ElemType: type of elements for extrusion (if param Base is a mesh)
5809 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5810 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5811 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5813 Example: :ref:`tui_extrusion_along_path`
5817 if ElemType == SMESH.NODE: n = Base
5818 if ElemType == SMESH.EDGE: e = Base
5819 if ElemType == SMESH.FACE: f = Base
5820 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5821 HasAngles, Angles, LinearVariation,
5822 HasRefPoint, RefPoint, MakeGroups)
5823 if MakeGroups: return gr,er
5826 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5827 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5828 MakeGroups=False, LinearVariation=False):
5830 Generate new elements by extrusion of the given elements.
5831 The path of extrusion must be a meshed edge.
5834 IDsOfElements: ids of elements
5835 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5836 PathShape: shape (edge) defines the sub-mesh for the path
5837 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5838 HasAngles: not used obsolete
5839 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5840 around *basePoint*, additionally to previous steps.
5841 HasRefPoint: allows using the reference point
5842 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5843 The User can specify any point as the Reference Point.
5844 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5845 MakeGroups: forces the generation of new groups from existing ones
5846 LinearVariation: forces the computation of rotation angles as linear
5847 variation of the given Angles along path steps
5850 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5851 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5852 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5853 Example: :ref:`tui_extrusion_along_path`
5856 if not IDsOfElements:
5857 IDsOfElements = [ self.GetMesh() ]
5858 n,e,f = [],IDsOfElements,IDsOfElements
5859 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5860 NodeStart, HasAngles, Angles,
5862 HasRefPoint, RefPoint, MakeGroups)
5863 if MakeGroups: return gr,er
5866 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5867 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5868 MakeGroups=False, LinearVariation=False):
5870 Generate new elements by extrusion of the elements which belong to the object.
5871 The path of extrusion must be a meshed edge.
5874 theObject: the object whose elements should be processed.
5875 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5876 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5877 PathShape: shape (edge) defines the sub-mesh for the path
5878 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5879 HasAngles: not used obsolete
5880 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5881 around *basePoint*, additionally to previous steps.
5882 HasRefPoint: allows using the reference point
5883 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5884 The User can specify any point as the Reference Point.
5885 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5886 MakeGroups: forces the generation of new groups from existing ones
5887 LinearVariation: forces the computation of rotation angles as linear
5888 variation of the given Angles along path steps
5891 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5892 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5893 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5894 Example: :ref:`tui_extrusion_along_path`
5897 n,e,f = [],theObject,theObject
5898 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5899 HasAngles, Angles, LinearVariation,
5900 HasRefPoint, RefPoint, MakeGroups)
5901 if MakeGroups: return gr,er
5904 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5905 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5906 MakeGroups=False, LinearVariation=False):
5908 Generate new elements by extrusion of mesh segments which belong to the object.
5909 The path of extrusion must be a meshed edge.
5912 theObject: the object whose 1D elements should be processed.
5913 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5914 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5915 PathShape: shape (edge) defines the sub-mesh for the path
5916 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5917 HasAngles: not used obsolete
5918 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5919 around *basePoint*, additionally to previous steps.
5920 HasRefPoint: allows using the reference point
5921 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5922 The User can specify any point as the Reference Point.
5923 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5924 MakeGroups: forces the generation of new groups from existing ones
5925 LinearVariation: forces the computation of rotation angles as linear
5926 variation of the given Angles along path steps
5929 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5930 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5931 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5932 Example: :ref:`tui_extrusion_along_path`
5935 n,e,f = [],theObject,[]
5936 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5937 HasAngles, Angles, LinearVariation,
5938 HasRefPoint, RefPoint, MakeGroups)
5939 if MakeGroups: return gr,er
5942 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5943 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5944 MakeGroups=False, LinearVariation=False):
5946 Generate new elements by extrusion of faces which belong to the object.
5947 The path of extrusion must be a meshed edge.
5950 theObject: the object whose 2D elements should be processed.
5951 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5952 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5953 PathShape: shape (edge) defines the sub-mesh for the path
5954 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5955 HasAngles: not used obsolete
5956 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5957 around *basePoint*, additionally to previous steps.
5958 HasRefPoint: allows using the reference point
5959 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5960 The User can specify any point as the Reference Point.
5961 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5962 MakeGroups: forces the generation of new groups from existing ones
5963 LinearVariation: forces the computation of rotation angles as linear
5964 variation of the given Angles along path steps
5967 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5968 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5969 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5970 Example: :ref:`tui_extrusion_along_path`
5973 n,e,f = [],[],theObject
5974 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5975 HasAngles, Angles, LinearVariation,
5976 HasRefPoint, RefPoint, MakeGroups)
5977 if MakeGroups: return gr,er
5980 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5982 Create a symmetrical copy of mesh elements
5985 IDsOfElements: list of elements ids
5986 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5987 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5988 If the *Mirror* is a geom object this parameter is unnecessary
5989 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5990 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5993 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5996 if IDsOfElements == []:
5997 IDsOfElements = self.GetElementsId()
5998 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5999 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6000 theMirrorType = Mirror._mirrorType
6002 self.mesh.SetParameters(Mirror.parameters)
6003 if Copy and MakeGroups:
6004 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6005 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6008 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6010 Create a new mesh by a symmetrical copy of mesh elements
6013 IDsOfElements: the list of elements ids
6014 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6015 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6016 If the *Mirror* is a geom object this parameter is unnecessary
6017 MakeGroups: to generate new groups from existing ones
6018 NewMeshName: a name of the new mesh to create
6021 instance of class :class:`Mesh`
6024 if IDsOfElements == []:
6025 IDsOfElements = self.GetElementsId()
6026 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6027 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6028 theMirrorType = Mirror._mirrorType
6030 self.mesh.SetParameters(Mirror.parameters)
6031 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6032 MakeGroups, NewMeshName)
6033 return Mesh(self.smeshpyD,self.geompyD,mesh)
6035 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6037 Create a symmetrical copy of the object
6040 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6041 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6042 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6043 If the *Mirror* is a geom object this parameter is unnecessary
6044 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6045 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6048 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6051 if ( isinstance( theObject, Mesh )):
6052 theObject = theObject.GetMesh()
6053 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6054 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6055 theMirrorType = Mirror._mirrorType
6057 self.mesh.SetParameters(Mirror.parameters)
6058 if Copy and MakeGroups:
6059 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6060 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6063 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6065 Create a new mesh by a symmetrical copy of the object
6068 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6069 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6070 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6071 If the *Mirror* is a geom object this parameter is unnecessary
6072 MakeGroups: forces the generation of new groups from existing ones
6073 NewMeshName: the name of the new mesh to create
6076 instance of class :class:`Mesh`
6079 if ( isinstance( theObject, Mesh )):
6080 theObject = theObject.GetMesh()
6081 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6082 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6083 theMirrorType = Mirror._mirrorType
6085 self.mesh.SetParameters(Mirror.parameters)
6086 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6087 MakeGroups, NewMeshName)
6088 return Mesh( self.smeshpyD,self.geompyD,mesh )
6090 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6092 Translate the elements
6095 IDsOfElements: list of elements ids
6096 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6097 Copy: allows copying the translated elements
6098 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6101 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6104 if IDsOfElements == []:
6105 IDsOfElements = self.GetElementsId()
6106 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6107 Vector = self.smeshpyD.GetDirStruct(Vector)
6108 if isinstance( Vector, list ):
6109 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6110 self.mesh.SetParameters(Vector.PS.parameters)
6111 if Copy and MakeGroups:
6112 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6113 self.editor.Translate(IDsOfElements, Vector, Copy)
6116 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6118 Create a new mesh of translated elements
6121 IDsOfElements: list of elements ids
6122 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6123 MakeGroups: forces the generation of new groups from existing ones
6124 NewMeshName: the name of the newly created mesh
6127 instance of class :class:`Mesh`
6130 if IDsOfElements == []:
6131 IDsOfElements = self.GetElementsId()
6132 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6133 Vector = self.smeshpyD.GetDirStruct(Vector)
6134 if isinstance( Vector, list ):
6135 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6136 self.mesh.SetParameters(Vector.PS.parameters)
6137 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6138 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6140 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6142 Translate the object
6145 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6146 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6147 Copy: allows copying the translated elements
6148 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6151 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6154 if ( isinstance( theObject, Mesh )):
6155 theObject = theObject.GetMesh()
6156 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6157 Vector = self.smeshpyD.GetDirStruct(Vector)
6158 if isinstance( Vector, list ):
6159 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6160 self.mesh.SetParameters(Vector.PS.parameters)
6161 if Copy and MakeGroups:
6162 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6163 self.editor.TranslateObject(theObject, Vector, Copy)
6166 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6168 Create a new mesh from the translated object
6171 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6172 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6173 MakeGroups: forces the generation of new groups from existing ones
6174 NewMeshName: the name of the newly created mesh
6177 instance of class :class:`Mesh`
6180 if isinstance( theObject, Mesh ):
6181 theObject = theObject.GetMesh()
6182 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6183 Vector = self.smeshpyD.GetDirStruct(Vector)
6184 if isinstance( Vector, list ):
6185 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6186 self.mesh.SetParameters(Vector.PS.parameters)
6187 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6188 return Mesh( self.smeshpyD, self.geompyD, mesh )
6192 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6197 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6198 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6199 theScaleFact: list of 1-3 scale factors for axises
6200 Copy: allows copying the translated elements
6201 MakeGroups: forces the generation of new groups from existing
6205 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6206 empty list otherwise
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)
6223 if Copy and MakeGroups:
6224 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6225 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6228 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6230 Create a new mesh from the translated object
6233 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6234 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6235 theScaleFact: list of 1-3 scale factors for axises
6236 MakeGroups: forces the generation of new groups from existing ones
6237 NewMeshName: the name of the newly created mesh
6240 instance of class :class:`Mesh`
6242 unRegister = genObjUnRegister()
6243 if (isinstance(theObject, Mesh)):
6244 theObject = theObject.GetMesh()
6245 if ( isinstance( theObject, list )):
6246 theObject = self.GetIDSource(theObject,SMESH.ALL)
6247 unRegister.set( theObject )
6248 if ( isinstance( thePoint, list )):
6249 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6250 if ( isinstance( theScaleFact, float )):
6251 theScaleFact = [theScaleFact]
6252 if ( isinstance( theScaleFact, int )):
6253 theScaleFact = [ float(theScaleFact)]
6255 self.mesh.SetParameters(thePoint.parameters)
6256 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6257 MakeGroups, NewMeshName)
6258 return Mesh( self.smeshpyD, self.geompyD, mesh )
6262 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6267 IDsOfElements: list of elements ids
6268 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6269 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6270 Copy: allows copying the rotated elements
6271 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6274 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6278 if IDsOfElements == []:
6279 IDsOfElements = self.GetElementsId()
6280 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6281 Axis = self.smeshpyD.GetAxisStruct(Axis)
6282 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6283 Parameters = Axis.parameters + var_separator + Parameters
6284 self.mesh.SetParameters(Parameters)
6285 if Copy and MakeGroups:
6286 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6287 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6290 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6292 Create a new mesh of rotated elements
6295 IDsOfElements: list of element ids
6296 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6297 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6298 MakeGroups: forces the generation of new groups from existing ones
6299 NewMeshName: the name of the newly created mesh
6302 instance of class :class:`Mesh`
6305 if IDsOfElements == []:
6306 IDsOfElements = self.GetElementsId()
6307 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6308 Axis = self.smeshpyD.GetAxisStruct(Axis)
6309 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6310 Parameters = Axis.parameters + var_separator + Parameters
6311 self.mesh.SetParameters(Parameters)
6312 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6313 MakeGroups, NewMeshName)
6314 return Mesh( self.smeshpyD, self.geompyD, mesh )
6316 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6321 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6322 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6323 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6324 Copy: allows copying the rotated elements
6325 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6328 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6331 if (isinstance(theObject, Mesh)):
6332 theObject = theObject.GetMesh()
6333 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6334 Axis = self.smeshpyD.GetAxisStruct(Axis)
6335 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6336 Parameters = Axis.parameters + ":" + Parameters
6337 self.mesh.SetParameters(Parameters)
6338 if Copy and MakeGroups:
6339 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6340 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6343 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6345 Create a new mesh from the rotated object
6348 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6349 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6350 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6351 MakeGroups: forces the generation of new groups from existing ones
6352 NewMeshName: the name of the newly created mesh
6355 instance of class :class:`Mesh`
6358 if (isinstance( theObject, Mesh )):
6359 theObject = theObject.GetMesh()
6360 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6361 Axis = self.smeshpyD.GetAxisStruct(Axis)
6362 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6363 Parameters = Axis.parameters + ":" + Parameters
6364 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6365 MakeGroups, NewMeshName)
6366 self.mesh.SetParameters(Parameters)
6367 return Mesh( self.smeshpyD, self.geompyD, mesh )
6369 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6371 Create an offset mesh from the given 2D object
6374 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6375 theValue (float): signed offset size
6376 MakeGroups (boolean): forces the generation of new groups from existing ones
6377 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6378 False means to remove original elements.
6379 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6382 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6385 if isinstance( theObject, Mesh ):
6386 theObject = theObject.GetMesh()
6387 theValue,Parameters,hasVars = ParseParameters(Value)
6388 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6389 self.mesh.SetParameters(Parameters)
6391 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6394 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6396 Find groups of adjacent nodes within Tolerance.
6399 Tolerance (float): the value of tolerance
6400 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6401 corner and medium nodes in separate groups thus preventing
6402 their further merge.
6405 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6408 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6410 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6411 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6413 Find groups of adjacent nodes within Tolerance.
6416 Tolerance: the value of tolerance
6417 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6418 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6419 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6420 corner and medium nodes in separate groups thus preventing
6421 their further merge.
6424 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6427 unRegister = genObjUnRegister()
6428 if not isinstance( SubMeshOrGroup, list ):
6429 SubMeshOrGroup = [ SubMeshOrGroup ]
6430 for i,obj in enumerate( SubMeshOrGroup ):
6431 if isinstance( obj, Mesh ):
6432 SubMeshOrGroup = [ obj.GetMesh() ]
6434 if isinstance( obj, int ):
6435 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6436 unRegister.set( SubMeshOrGroup )
6439 if not isinstance( exceptNodes, list ):
6440 exceptNodes = [ exceptNodes ]
6441 if exceptNodes and isinstance( exceptNodes[0], int ):
6442 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6443 unRegister.set( exceptNodes )
6445 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6446 exceptNodes, SeparateCornerAndMediumNodes)
6448 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6453 GroupsOfNodes: a list of groups of nodes IDs for merging.
6454 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6455 in all elements and mesh groups by nodes 1 and 25 correspondingly
6456 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6457 If *NodesToKeep* does not include a node to keep for some group to merge,
6458 then the first node in the group is kept.
6459 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6463 This operation can create gaps in numeration of nodes or elements.
6464 Call :meth:`RenumberElements` to remove the gaps.
6466 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6468 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6470 Find the elements built on the same nodes.
6473 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6474 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6478 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6481 unRegister = genObjUnRegister()
6482 if MeshOrSubMeshOrGroup is None:
6483 MeshOrSubMeshOrGroup = [ self.mesh ]
6484 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6485 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6486 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6487 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6488 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6489 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6490 unRegister.set( MeshOrSubMeshOrGroup )
6491 for item in MeshOrSubMeshOrGroup:
6492 if isinstance( item, Mesh ):
6493 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6495 if not isinstance( exceptElements, list ):
6496 exceptElements = [ exceptElements ]
6497 if exceptElements and isinstance( exceptElements[0], int ):
6498 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6499 unRegister.set( exceptElements )
6501 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6503 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6505 Merge elements in each given group.
6508 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6509 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6510 replaced in all mesh groups by elements 1 and 25)
6511 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6512 If *ElementsToKeep* does not include an element to keep for some group to merge,
6513 then the first element in the group is kept.
6516 This operation can create gaps in numeration of elements.
6517 Call :meth:`RenumberElements` to remove the gaps.
6520 unRegister = genObjUnRegister()
6522 if not isinstance( ElementsToKeep, list ):
6523 ElementsToKeep = [ ElementsToKeep ]
6524 if isinstance( ElementsToKeep[0], int ):
6525 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6526 unRegister.set( ElementsToKeep )
6528 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6530 def MergeEqualElements(self):
6532 Leave one element and remove all other elements built on the same nodes.
6535 This operation can create gaps in numeration of elements.
6536 Call :meth:`RenumberElements` to remove the gaps.
6539 self.editor.MergeEqualElements()
6541 def FindFreeBorders(self, ClosedOnly=True):
6543 Returns all or only closed free borders
6546 list of SMESH.FreeBorder's
6549 return self.editor.FindFreeBorders( ClosedOnly )
6551 def FillHole(self, holeNodes, groupName=""):
6553 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6556 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6557 must describe all sequential nodes of the hole border. The first and the last
6558 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6559 groupName (string): name of a group to add new faces
6561 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6565 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6566 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6567 if not isinstance( holeNodes, SMESH.FreeBorder ):
6568 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6569 return self.editor.FillHole( holeNodes, groupName )
6571 def FindCoincidentFreeBorders (self, tolerance=0.):
6573 Return groups of FreeBorder's coincident within the given tolerance.
6576 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6577 size of elements adjacent to free borders being compared is used.
6580 SMESH.CoincidentFreeBorders structure
6583 return self.editor.FindCoincidentFreeBorders( tolerance )
6585 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6587 Sew FreeBorder's of each group
6590 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6591 where each enclosed list contains node IDs of a group of coincident free
6592 borders such that each consequent triple of IDs within a group describes
6593 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6594 last node of a border.
6595 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6596 groups of coincident free borders, each group including two borders.
6597 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6598 polygons if a node of opposite border falls on a face edge, else such
6599 faces are split into several ones.
6600 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6601 polyhedra if a node of opposite border falls on a volume edge, else such
6602 volumes, if any, remain intact and the mesh becomes non-conformal.
6605 a number of successfully sewed groups
6608 This operation can create gaps in numeration of nodes or elements.
6609 Call :meth:`RenumberElements` to remove the gaps.
6612 if freeBorders and isinstance( freeBorders, list ):
6613 # construct SMESH.CoincidentFreeBorders
6614 if isinstance( freeBorders[0], int ):
6615 freeBorders = [freeBorders]
6617 coincidentGroups = []
6618 for nodeList in freeBorders:
6619 if not nodeList or len( nodeList ) % 3:
6620 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6623 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6624 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6625 nodeList = nodeList[3:]
6627 coincidentGroups.append( group )
6629 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6631 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6633 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6634 FirstNodeID2, SecondNodeID2, LastNodeID2,
6635 CreatePolygons, CreatePolyedrs):
6640 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6643 This operation can create gaps in numeration of nodes or elements.
6644 Call :meth:`RenumberElements` to remove the gaps.
6647 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6648 FirstNodeID2, SecondNodeID2, LastNodeID2,
6649 CreatePolygons, CreatePolyedrs)
6651 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6652 FirstNodeID2, SecondNodeID2):
6654 Sew conform free borders
6657 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6660 This operation can create gaps in numeration of elements.
6661 Call :meth:`RenumberElements` to remove the gaps.
6664 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6665 FirstNodeID2, SecondNodeID2)
6667 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6668 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6673 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6676 This operation can create gaps in numeration of elements.
6677 Call :meth:`RenumberElements` to remove the gaps.
6680 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6681 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6683 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6684 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6685 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6687 Sew two sides of a mesh. The nodes belonging to Side1 are
6688 merged with the nodes of elements of Side2.
6689 The number of elements in theSide1 and in theSide2 must be
6690 equal and they should have similar nodal connectivity.
6691 The nodes to merge should belong to side borders and
6692 the first node should be linked to the second.
6695 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6698 This operation can create gaps in numeration of nodes.
6699 Call :meth:`RenumberElements` to remove the gaps.
6702 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6703 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6704 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6706 def ChangeElemNodes(self, ide, newIDs):
6708 Set new nodes for the given element. Number of nodes should be kept.
6715 False if the number of nodes does not correspond to the type of element
6718 return self.editor.ChangeElemNodes(ide, newIDs)
6720 def GetLastCreatedNodes(self):
6722 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6723 created, this method return the list of their IDs.
6724 If new nodes were not created - return empty list
6727 the list of integer values (can be empty)
6730 return self.editor.GetLastCreatedNodes()
6732 def GetLastCreatedElems(self):
6734 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6735 created this method return the list of their IDs.
6736 If new elements were not created - return empty list
6739 the list of integer values (can be empty)
6742 return self.editor.GetLastCreatedElems()
6744 def ClearLastCreated(self):
6746 Forget what nodes and elements were created by the last mesh edition operation
6749 self.editor.ClearLastCreated()
6751 def DoubleElements(self, theElements, theGroupName=""):
6753 Create duplicates of given elements, i.e. create new elements based on the
6754 same nodes as the given ones.
6757 theElements: container of elements to duplicate. It can be a
6758 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6759 or a list of element IDs. If *theElements* is
6760 a :class:`Mesh`, elements of highest dimension are duplicated
6761 theGroupName: a name of group to contain the generated elements.
6762 If a group with such a name already exists, the new elements
6763 are added to the existing group, else a new group is created.
6764 If *theGroupName* is empty, new elements are not added
6768 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6769 None if *theGroupName* == "".
6772 unRegister = genObjUnRegister()
6773 if isinstance( theElements, Mesh ):
6774 theElements = theElements.mesh
6775 elif isinstance( theElements, list ):
6776 theElements = self.GetIDSource( theElements, SMESH.ALL )
6777 unRegister.set( theElements )
6778 return self.editor.DoubleElements(theElements, theGroupName)
6780 def DoubleNodes(self, theNodes, theModifiedElems):
6782 Create a hole in a mesh by doubling the nodes of some particular elements
6785 theNodes: IDs of nodes to be doubled
6786 theModifiedElems: IDs of elements to be updated by the new (doubled)
6787 nodes. If list of element identifiers is empty then nodes are doubled but
6788 they not assigned to elements
6791 True if operation has been completed successfully, False otherwise
6794 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6796 def DoubleNode(self, theNodeId, theModifiedElems):
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 theNodeId: IDs of node to double
6803 theModifiedElems: IDs of elements to update
6806 True if operation has been completed successfully, False otherwise
6809 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6811 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6813 Create a hole in a mesh by doubling the nodes of some particular elements.
6814 This method provided for convenience works as :meth:`DoubleNodes`.
6817 theNodes: group of nodes to double.
6818 theModifiedElems: group of elements to update.
6819 theMakeGroup: forces the generation of a group containing new nodes.
6822 True or a created group if operation has been completed successfully,
6823 False or None otherwise
6827 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6828 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6830 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6832 Create a hole in a mesh by doubling the nodes of some particular elements.
6833 This method provided for convenience works as :meth:`DoubleNodes`.
6836 theNodes: list of groups of nodes to double.
6837 theModifiedElems: list of groups of elements to update.
6838 theMakeGroup: forces the generation of a group containing new nodes.
6841 True if operation has been completed successfully, False otherwise
6845 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6846 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6848 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6850 Create a hole in a mesh by doubling the nodes of some particular elements
6853 theElems: the list of elements (edges or faces) to replicate.
6854 The nodes for duplication could be found from these elements
6855 theNodesNot: list of nodes NOT to replicate
6856 theAffectedElems: the list of elements (cells and edges) to which the
6857 replicated nodes should be associated to
6860 True if operation has been completed successfully, False otherwise
6863 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6865 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6867 Create a hole in a mesh by doubling the nodes of some particular elements
6870 theElems: the list of elements (edges or faces) to replicate.
6871 The nodes for duplication could be found from these elements
6872 theNodesNot: list of nodes NOT to replicate
6873 theShape: shape to detect affected elements (element which geometric center
6874 located on or inside shape).
6875 The replicated nodes should be associated to affected elements.
6878 True if operation has been completed successfully, False otherwise
6881 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6883 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6884 theMakeGroup=False, theMakeNodeGroup=False):
6886 Create a hole in a mesh by doubling the nodes of some particular elements.
6887 This method provided for convenience works as :meth:`DoubleNodes`.
6890 theElems: group of of elements (edges or faces) to replicate.
6891 theNodesNot: group of nodes NOT to replicate.
6892 theAffectedElems: group of elements to which the replicated nodes
6893 should be associated to.
6894 theMakeGroup: forces the generation of a group containing new elements.
6895 theMakeNodeGroup: forces the generation of a group containing new nodes.
6898 True or created groups (one or two) if operation has been completed successfully,
6899 False or None otherwise
6902 if theMakeGroup or theMakeNodeGroup:
6903 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6905 theMakeGroup, theMakeNodeGroup)
6906 if theMakeGroup and theMakeNodeGroup:
6909 return twoGroups[ int(theMakeNodeGroup) ]
6910 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6912 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6914 Create a hole in a mesh by doubling the nodes of some particular elements.
6915 This method provided for convenience works as :meth:`DoubleNodes`.
6918 theElems: group of of elements (edges or faces) to replicate
6919 theNodesNot: group of nodes not to replicate
6920 theShape: shape to detect affected elements (element which geometric center
6921 located on or inside shape).
6922 The replicated nodes should be associated to affected elements
6925 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6927 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6928 theMakeGroup=False, theMakeNodeGroup=False):
6930 Create a hole in a mesh by doubling the nodes of some particular elements.
6931 This method provided for convenience works as :meth:`DoubleNodes`.
6934 theElems: list of groups of elements (edges or faces) to replicate
6935 theNodesNot: list of groups of nodes NOT to replicate
6936 theAffectedElems: group of elements to which the replicated nodes
6937 should be associated to
6938 theMakeGroup: forces generation of a group containing new elements.
6939 theMakeNodeGroup: forces generation of a group containing new nodes
6942 True or created groups (one or two) if operation has been completed successfully,
6943 False or None otherwise
6946 if theMakeGroup or theMakeNodeGroup:
6947 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6949 theMakeGroup, theMakeNodeGroup)
6950 if theMakeGroup and theMakeNodeGroup:
6953 return twoGroups[ int(theMakeNodeGroup) ]
6954 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6956 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6958 Create a hole in a mesh by doubling the nodes of some particular elements.
6959 This method provided for convenience works as :meth:`DoubleNodes`.
6962 theElems: list of groups of elements (edges or faces) to replicate
6963 theNodesNot: list of groups of nodes NOT to replicate
6964 theShape: shape to detect affected elements (element which geometric center
6965 located on or inside shape).
6966 The replicated nodes should be associated to affected elements
6969 True if operation has been completed successfully, False otherwise
6972 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6974 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6976 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6977 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6980 theElems: list of groups of nodes or elements (edges or faces) to replicate
6981 theNodesNot: list of groups of nodes NOT to replicate
6982 theShape: shape to detect affected elements (element which geometric center
6983 located on or inside shape).
6984 The replicated nodes should be associated to affected elements
6987 groups of affected elements in order: volumes, faces, edges
6990 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6992 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6995 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6996 The list of groups must describe a partition of the mesh volumes.
6997 The nodes of the internal faces at the boundaries of the groups are doubled.
6998 In option, the internal faces are replaced by flat elements.
6999 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7002 theDomains: list of groups of volumes
7003 createJointElems: if True, create the elements
7004 onAllBoundaries: if True, the nodes and elements are also created on
7005 the boundary between *theDomains* and the rest mesh
7008 True if operation has been completed successfully, False otherwise
7011 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7013 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7015 Double nodes on some external faces and create flat elements.
7016 Flat elements are mainly used by some types of mechanic calculations.
7018 Each group of the list must be constituted of faces.
7019 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7022 theGroupsOfFaces: list of groups of faces
7025 True if operation has been completed successfully, False otherwise
7028 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7030 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7032 Identify all the elements around a geom shape, get the faces delimiting the hole
7034 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7036 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7038 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7039 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7040 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7041 If there are several paths connecting a pair of points, the shortest path is
7042 selected by the module. Position of the cutting plane is defined by the two
7043 points and an optional vector lying on the plane specified by a PolySegment.
7044 By default the vector is defined by Mesh module as following. A middle point
7045 of the two given points is computed. The middle point is projected to the mesh.
7046 The vector goes from the middle point to the projection point. In case of planar
7047 mesh, the vector is normal to the mesh.
7049 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7052 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7053 groupName: optional name of a group where created mesh segments will be added.
7056 editor = self.editor
7058 editor = self.mesh.GetMeshEditPreviewer()
7059 segmentsRes = editor.MakePolyLine( segments, groupName )
7060 for i, seg in enumerate( segmentsRes ):
7061 segments[i].vector = seg.vector
7063 return editor.GetPreviewData()
7066 def MakeSlot(self, segmentGroup, width ):
7068 Create a slot of given width around given 1D elements lying on a triangle mesh.
7069 The slot is constructed by cutting faces by cylindrical surfaces made
7070 around each segment. Segments are expected to be created by MakePolyLine().
7073 FaceEdge's located at the slot boundary
7075 return self.editor.MakeSlot( segmentGroup, width )
7077 def GetFunctor(self, funcType ):
7079 Return a cached numerical functor by its type.
7082 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7083 Note that not all items correspond to numerical functors.
7086 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7089 fn = self.functors[ funcType._v ]
7091 fn = self.smeshpyD.GetFunctor(funcType)
7092 fn.SetMesh(self.mesh)
7093 self.functors[ funcType._v ] = fn
7096 def FunctorValue(self, funcType, elemId, isElem=True):
7098 Return value of a functor for a given element
7101 funcType: an item of :class:`SMESH.FunctorType` enum.
7102 elemId: element or node ID
7103 isElem: *elemId* is ID of element or node
7106 the functor value or zero in case of invalid arguments
7109 fn = self.GetFunctor( funcType )
7110 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7111 val = fn.GetValue(elemId)
7116 def GetLength(self, elemId=None):
7118 Get length of given 1D elements or of all 1D mesh elements
7121 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.
7124 Sum of lengths of given elements
7129 length = self.smeshpyD.GetLength(self)
7130 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7131 length = self.smeshpyD.GetLength(elemId)
7134 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7136 length += self.smeshpyD.GetLength(obj)
7137 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7138 unRegister = genObjUnRegister()
7139 obj = self.GetIDSource( elemId )
7140 unRegister.set( obj )
7141 length = self.smeshpyD.GetLength( obj )
7143 length = self.FunctorValue(SMESH.FT_Length, elemId)
7146 def GetArea(self, elemId=None):
7148 Get area of given 2D elements or of all 2D mesh elements
7151 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.
7154 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7159 area = self.smeshpyD.GetArea(self)
7160 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7161 area = self.smeshpyD.GetArea(elemId)
7164 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7166 area += self.smeshpyD.GetArea(obj)
7167 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7168 unRegister = genObjUnRegister()
7169 obj = self.GetIDSource( elemId )
7170 unRegister.set( obj )
7171 area = self.smeshpyD.GetArea( obj )
7173 area = self.FunctorValue(SMESH.FT_Area, elemId)
7176 def GetVolume(self, elemId=None):
7178 Get volume of given 3D elements or of all 3D mesh elements
7181 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.
7184 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7189 volume= self.smeshpyD.GetVolume(self)
7190 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7191 volume= self.smeshpyD.GetVolume(elemId)
7194 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7196 volume+= self.smeshpyD.GetVolume(obj)
7197 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7198 unRegister = genObjUnRegister()
7199 obj = self.GetIDSource( elemId )
7200 unRegister.set( obj )
7201 volume= self.smeshpyD.GetVolume( obj )
7203 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7206 def GetAngle(self, node1, node2, node3 ):
7208 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7211 node1,node2,node3: IDs of the three nodes
7214 Angle in radians [0,PI]. -1 if failure case.
7216 p1 = self.GetNodeXYZ( node1 )
7217 p2 = self.GetNodeXYZ( node2 )
7218 p3 = self.GetNodeXYZ( node3 )
7219 if p1 and p2 and p3:
7220 return self.smeshpyD.GetAngle( p1,p2,p3 )
7224 def GetMaxElementLength(self, elemId):
7226 Get maximum element length.
7229 elemId: mesh element ID
7232 element's maximum length value
7235 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7236 ftype = SMESH.FT_MaxElementLength3D
7238 ftype = SMESH.FT_MaxElementLength2D
7239 return self.FunctorValue(ftype, elemId)
7241 def GetAspectRatio(self, elemId):
7243 Get aspect ratio of 2D or 3D element.
7246 elemId: mesh element ID
7249 element's aspect ratio value
7252 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7253 ftype = SMESH.FT_AspectRatio3D
7255 ftype = SMESH.FT_AspectRatio
7256 return self.FunctorValue(ftype, elemId)
7258 def GetWarping(self, elemId):
7260 Get warping angle of 2D element.
7263 elemId: mesh element ID
7266 element's warping angle value
7269 return self.FunctorValue(SMESH.FT_Warping, elemId)
7271 def GetMinimumAngle(self, elemId):
7273 Get minimum angle of 2D element.
7276 elemId: mesh element ID
7279 element's minimum angle value
7282 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7284 def GetTaper(self, elemId):
7286 Get taper of 2D element.
7289 elemId: mesh element ID
7292 element's taper value
7295 return self.FunctorValue(SMESH.FT_Taper, elemId)
7297 def GetSkew(self, elemId):
7299 Get skew of 2D element.
7302 elemId: mesh element ID
7305 element's skew value
7308 return self.FunctorValue(SMESH.FT_Skew, elemId)
7310 def GetMinMax(self, funType, meshPart=None):
7312 Return minimal and maximal value of a given functor.
7315 funType (SMESH.FunctorType): a functor type.
7316 Note that not all items of :class:`SMESH.FunctorType` corresponds
7317 to numerical functors.
7318 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7324 unRegister = genObjUnRegister()
7325 if isinstance( meshPart, list ):
7326 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7327 unRegister.set( meshPart )
7328 if isinstance( meshPart, Mesh ):
7329 meshPart = meshPart.mesh
7330 fun = self.GetFunctor( funType )
7333 if hasattr( meshPart, "SetMesh" ):
7334 meshPart.SetMesh( self.mesh ) # set mesh to filter
7335 hist = fun.GetLocalHistogram( 1, False, meshPart )
7337 hist = fun.GetHistogram( 1, False )
7339 return hist[0].min, hist[0].max
7342 pass # end of Mesh class
7345 class meshProxy(SMESH._objref_SMESH_Mesh):
7347 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7348 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7350 def __init__(self,*args):
7351 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7352 def __deepcopy__(self, memo=None):
7353 new = self.__class__(self)
7355 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7356 if len( args ) == 3:
7357 args += SMESH.ALL_NODES, True
7358 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7359 def ExportToMEDX(self, *args): # function removed
7360 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7361 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7362 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7363 def ExportToMED(self, *args): # function removed
7364 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7365 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7367 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7369 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7370 def ExportPartToMED(self, *args): # 'version' parameter removed
7371 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7372 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7373 def ExportMED(self, *args): # signature of method changed
7374 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7376 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7378 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7380 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7383 class submeshProxy(SMESH._objref_SMESH_subMesh):
7386 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7388 def __init__(self,*args):
7389 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7391 def __deepcopy__(self, memo=None):
7392 new = self.__class__(self)
7395 def Compute(self,refresh=False):
7397 Compute the sub-mesh and return the status of the computation
7400 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7405 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7406 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7410 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7412 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7414 if salome.sg.hasDesktop():
7415 if refresh: salome.sg.updateObjBrowser()
7420 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7423 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7425 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7426 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7429 def __init__(self,*args):
7430 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7432 def __getattr__(self, name ): # method called if an attribute not found
7433 if not self.mesh: # look for name() method in Mesh class
7434 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7435 if hasattr( self.mesh, name ):
7436 return getattr( self.mesh, name )
7437 if name == "ExtrusionAlongPathObjX":
7438 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7439 print("meshEditor: attribute '%s' NOT FOUND" % name)
7441 def __deepcopy__(self, memo=None):
7442 new = self.__class__(self)
7444 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7445 if len( args ) == 1: args += False,
7446 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7447 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7448 if len( args ) == 2: args += False,
7449 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7450 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7451 if len( args ) == 1:
7452 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7453 NodesToKeep = args[1]
7454 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7455 unRegister = genObjUnRegister()
7457 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7458 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7459 if not isinstance( NodesToKeep, list ):
7460 NodesToKeep = [ NodesToKeep ]
7461 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7463 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7465 class Pattern(SMESH._objref_SMESH_Pattern):
7467 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7468 variables in some methods
7471 def LoadFromFile(self, patternTextOrFile ):
7472 text = patternTextOrFile
7473 if os.path.exists( text ):
7474 text = open( patternTextOrFile ).read()
7476 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7478 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7479 decrFun = lambda i: i-1
7480 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7481 theMesh.SetParameters(Parameters)
7482 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7484 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7485 decrFun = lambda i: i-1
7486 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7487 theMesh.SetParameters(Parameters)
7488 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7490 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7491 if isinstance( mesh, Mesh ):
7492 mesh = mesh.GetMesh()
7493 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7495 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7497 Registering the new proxy for Pattern
7502 Private class used to bind methods creating algorithms to the class Mesh
7505 def __init__(self, method):
7507 self.defaultAlgoType = ""
7508 self.algoTypeToClass = {}
7509 self.method = method
7511 def add(self, algoClass):
7513 Store a python class of algorithm
7515 if inspect.isclass(algoClass) and \
7516 hasattr( algoClass, "algoType"):
7517 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7518 if not self.defaultAlgoType and \
7519 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7520 self.defaultAlgoType = algoClass.algoType
7521 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7523 def copy(self, mesh):
7525 Create a copy of self and assign mesh to the copy
7528 other = algoCreator( self.method )
7529 other.defaultAlgoType = self.defaultAlgoType
7530 other.algoTypeToClass = self.algoTypeToClass
7534 def __call__(self,algo="",geom=0,*args):
7536 Create an instance of algorithm
7540 if isinstance( algo, str ):
7542 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7543 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7548 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7550 elif not algoType and isinstance( geom, str ):
7555 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7557 elif isinstance( arg, str ) and not algoType:
7560 import traceback, sys
7561 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7562 sys.stderr.write( msg + '\n' )
7563 tb = traceback.extract_stack(None,2)
7564 traceback.print_list( [tb[0]] )
7566 algoType = self.defaultAlgoType
7567 if not algoType and self.algoTypeToClass:
7568 algoType = sorted( self.algoTypeToClass.keys() )[0]
7569 if algoType in self.algoTypeToClass:
7570 #print("Create algo",algoType)
7571 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7572 raise RuntimeError( "No class found for algo type %s" % algoType)
7575 class hypMethodWrapper:
7577 Private class used to substitute and store variable parameters of hypotheses.
7580 def __init__(self, hyp, method):
7582 self.method = method
7583 #print("REBIND:", method.__name__)
7586 def __call__(self,*args):
7588 call a method of hypothesis with calling SetVarParameter() before
7592 return self.method( self.hyp, *args ) # hypothesis method with no args
7594 #print("MethWrapper.__call__", self.method.__name__, args)
7596 parsed = ParseParameters(*args) # replace variables with their values
7597 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7598 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7599 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7600 # maybe there is a replaced string arg which is not variable
7601 result = self.method( self.hyp, *args )
7602 except ValueError as detail: # raised by ParseParameters()
7604 result = self.method( self.hyp, *args )
7605 except omniORB.CORBA.BAD_PARAM:
7606 raise ValueError(detail) # wrong variable name
7611 class genObjUnRegister:
7613 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7616 def __init__(self, genObj=None):
7617 self.genObjList = []
7621 def set(self, genObj):
7622 "Store one or a list of of SALOME.GenericObj'es"
7623 if isinstance( genObj, list ):
7624 self.genObjList.extend( genObj )
7626 self.genObjList.append( genObj )
7630 for genObj in self.genObjList:
7631 if genObj and hasattr( genObj, "UnRegister" ):
7634 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7636 Bind methods creating mesher plug-ins to the Mesh class
7639 # print("pluginName: ", pluginName)
7640 pluginBuilderName = pluginName + "Builder"
7642 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7643 except Exception as e:
7644 from salome_utils import verbose
7645 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7647 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7648 plugin = eval( pluginBuilderName )
7649 # print(" plugin:" , str(plugin))
7651 # add methods creating algorithms to Mesh
7652 for k in dir( plugin ):
7653 if k[0] == '_': continue
7654 algo = getattr( plugin, k )
7655 #print(" algo:", str(algo))
7656 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7657 #print(" meshMethod:" , str(algo.meshMethod))
7658 if not hasattr( Mesh, algo.meshMethod ):
7659 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7661 _mmethod = getattr( Mesh, algo.meshMethod )
7662 if hasattr( _mmethod, "add" ):