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
43 from StdMeshers import BlockCS
50 # In case the omniORBpy EnumItem class does not fully support Python 3
51 # (for instance in version 4.2.1-2), the comparison ordering methods must be
55 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
57 def enumitem_eq(self, other):
59 if isinstance(other, omniORB.EnumItem):
60 if other._parent_id == self._parent_id:
61 return self._v == other._v
63 return self._parent_id == other._parent_id
65 return id(self) == id(other)
67 return id(self) == id(other)
69 def enumitem_lt(self, other):
71 if isinstance(other, omniORB.EnumItem):
72 if other._parent_id == self._parent_id:
73 return self._v < other._v
75 return self._parent_id < other._parent_id
77 return id(self) < id(other)
79 return id(self) < id(other)
81 def enumitem_le(self, other):
83 if isinstance(other, omniORB.EnumItem):
84 if other._parent_id == self._parent_id:
85 return self._v <= other._v
87 return self._parent_id <= other._parent_id
89 return id(self) <= id(other)
91 return id(self) <= id(other)
93 def enumitem_gt(self, other):
95 if isinstance(other, omniORB.EnumItem):
96 if other._parent_id == self._parent_id:
97 return self._v > other._v
99 return self._parent_id > other._parent_id
101 return id(self) > id(other)
103 return id(self) > id(other)
105 def enumitem_ge(self, other):
107 if isinstance(other, omniORB.EnumItem):
108 if other._parent_id == self._parent_id:
109 return self._v >= other._v
111 return self._parent_id >= other._parent_id
113 return id(self) >= id(other)
115 return id(self) >= id(other)
117 omniORB.EnumItem.__eq__ = enumitem_eq
118 omniORB.EnumItem.__lt__ = enumitem_lt
119 omniORB.EnumItem.__le__ = enumitem_le
120 omniORB.EnumItem.__gt__ = enumitem_gt
121 omniORB.EnumItem.__ge__ = enumitem_ge
124 class MeshMeta(type):
125 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
127 def __instancecheck__(cls, inst):
128 """Implement isinstance(inst, cls)."""
129 return any(cls.__subclasscheck__(c)
130 for c in {type(inst), inst.__class__})
132 def __subclasscheck__(cls, sub):
133 """Implement issubclass(sub, cls)."""
134 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
136 def DegreesToRadians(AngleInDegrees):
137 """Convert an angle from degrees to radians
140 return AngleInDegrees * pi / 180.0
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
147 def ParseParameters(*args):
149 Return list of variable values from salome notebook.
150 The last argument, if is callable, is used to modify values got from notebook
156 if args and callable(args[-1]):
157 args, varModifFun = args[:-1], args[-1]
158 for parameter in args:
160 Parameters += str(parameter) + var_separator
162 if isinstance(parameter,str):
163 # check if there is an inexistent variable name
164 if not notebook.isVariable(parameter):
165 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
166 parameter = notebook.get(parameter)
169 parameter = varModifFun(parameter)
172 Result.append(parameter)
175 Parameters = Parameters[:-1]
176 Result.append( Parameters )
177 Result.append( hasVariables )
180 def ParseAngles(*args):
182 Parse parameters while converting variables to radians
184 return ParseParameters( *( args + (DegreesToRadians, )))
186 def __initPointStruct(point,*args):
188 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189 Parameters are stored in PointStruct.parameters attribute
191 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
193 SMESH.PointStruct.__init__ = __initPointStruct
195 def __initAxisStruct(ax,*args):
197 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198 Parameters are stored in AxisStruct.parameters attribute
201 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
202 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
204 SMESH.AxisStruct.__init__ = __initAxisStruct
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208 """Compare real values using smeshPrecisionConfusion as tolerance
210 if abs(val1 - val2) < tol:
218 Return a name of an object
225 if isinstance(obj, SALOMEDS._objref_SObject):
229 ior = salome.orb.object_to_string(obj)
233 sobj = salome.myStudy.FindObjectIOR(ior)
235 return sobj.GetName()
236 if hasattr(obj, "GetName"):
237 # unknown CORBA object, having GetName() method
240 # unknown CORBA object, no GetName() method
243 if hasattr(obj, "GetName"):
244 # unknown non-CORBA object, having GetName() method
247 raise RuntimeError("Null or invalid object")
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
251 Print error message if a hypothesis was not assigned.
254 hypType = "algorithm"
256 hypType = "hypothesis"
259 if hasattr( status, "__getitem__" ):
260 status, reason = status[0], status[1]
261 if status == HYP_UNKNOWN_FATAL:
262 reason = "for unknown reason"
263 elif status == HYP_INCOMPATIBLE:
264 reason = "this hypothesis mismatches the algorithm"
265 elif status == HYP_NOTCONFORM:
266 reason = "a non-conform mesh would be built"
267 elif status == HYP_ALREADY_EXIST:
268 if isAlgo: return # it does not influence anything
269 reason = hypType + " of the same dimension is already assigned to this shape"
270 elif status == HYP_BAD_DIM:
271 reason = hypType + " mismatches the shape"
272 elif status == HYP_CONCURRENT :
273 reason = "there are concurrent hypotheses on sub-shapes"
274 elif status == HYP_BAD_SUBSHAPE:
275 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
276 elif status == HYP_BAD_GEOMETRY:
277 reason = "the algorithm is not applicable to this geometry"
278 elif status == HYP_HIDDEN_ALGO:
279 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
280 elif status == HYP_HIDING_ALGO:
281 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
282 elif status == HYP_NEED_SHAPE:
283 reason = "algorithm can't work without shape"
284 elif status == HYP_INCOMPAT_HYPS:
290 where = '"%s"' % geomName
292 meshName = GetName( mesh )
293 if meshName and meshName != NO_NAME:
294 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
295 if status < HYP_UNKNOWN_FATAL and where:
296 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
298 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
300 print('"%s" was not assigned : %s' %( hypName, reason ))
303 def AssureGeomPublished(mesh, geom, name=''):
305 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
307 if not mesh.smeshpyD.IsEnablePublish():
309 if not hasattr( geom, "GetShapeType" ):
311 if not geom.GetStudyEntry():
313 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
314 # for all groups SubShapeName() return "Compound_-1"
315 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
317 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
319 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
322 # def FirstVertexOnCurve(mesh, edge):
325 # the first vertex of a geometrical edge by ignoring orientation
327 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
333 smeshInst is a singleton
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
341 This class allows to create, load or manipulate meshes.
342 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
343 It also has methods to get infos and measure meshes.
346 # MirrorType enumeration
347 POINT = SMESH_MeshEditor.POINT
348 AXIS = SMESH_MeshEditor.AXIS
349 PLANE = SMESH_MeshEditor.PLANE
351 # Smooth_Method enumeration
352 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
355 PrecisionConfusion = smeshPrecisionConfusion
357 # TopAbs_State enumeration
358 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
360 # Methods of splitting a hexahedron into tetrahedra
361 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
363 def __new__(cls, *args):
367 #print("==== __new__", engine, smeshInst, doLcc)
369 if smeshInst is None:
370 # smesh engine is either retrieved from engine, or created
372 # Following test avoids a recursive loop
374 if smeshInst is not None:
375 # smesh engine not created: existing engine found
379 # FindOrLoadComponent called:
380 # 1. CORBA resolution of server
381 # 2. the __new__ method is called again
382 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
383 #smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
385 smesh_ior = SMeshHelper.BuildSMESHInstance()
388 orb=CORBA.ORB_init([''])
389 smeshInst = orb.string_to_object(smesh_ior)
391 # FindOrLoadComponent not called
392 if smeshInst is None:
393 # smeshBuilder instance is created from lcc.FindOrLoadComponent
394 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
395 smeshInst = super(smeshBuilder,cls).__new__(cls)
397 # smesh engine not created: existing engine found
398 #print("==== existing ", engine, smeshInst, doLcc)
400 #print("====1 ", smeshInst)
403 #print("====2 ", smeshInst)
406 def __init__(self, *args):
408 #print("--------------- smeshbuilder __init__ ---", created)
411 SMESH._objref_SMESH_Gen.__init__(self, *args)
414 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
416 Dump component to the Python script.
417 This method overrides IDL function to allow default values for the parameters.
420 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
422 def SetDumpPythonHistorical(self, isHistorical):
424 Set mode of DumpPython(), *historical* or *snapshot*.
425 In the *historical* mode, the Python Dump script includes all commands
426 performed by SMESH engine. In the *snapshot* mode, commands
427 relating to objects removed from the Study are excluded from the script
428 as well as commands not influencing the current state of meshes
431 if isHistorical: val = "true"
433 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
435 def init_smesh(self,geompyD = None):
437 Set Geometry component
440 self.UpdateStudy(geompyD)
441 notebook.myStudy = salome.myStudy
443 def Mesh(self, obj=0, name=0):
445 Create a mesh. This mesh can be either
447 * an empty mesh not bound to geometry, if *obj* == 0
448 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
449 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
454 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
457 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
459 2. a geometrical object for meshing
461 name: the name for the new mesh.
464 an instance of class :class:`Mesh`.
467 if isinstance(obj,str):
469 return Mesh(self, self.geompyD, obj, name)
471 def RemoveMesh( self, mesh ):
475 if isinstance( mesh, Mesh ):
476 mesh = mesh.GetMesh()
478 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
479 raise TypeError("%s is not a mesh" % mesh )
480 so = salome.ObjectToSObject( mesh )
482 sb = salome.myStudy.NewBuilder()
483 sb.RemoveObjectWithChildren( so )
489 def EnumToLong(self,theItem):
491 Return a long value from enumeration
496 def ColorToString(self,c):
498 Convert SALOMEDS.Color to string.
499 To be used with filters.
502 c: color value (SALOMEDS.Color)
505 a string representation of the color.
509 if isinstance(c, SALOMEDS.Color):
510 val = "%s;%s;%s" % (c.R, c.G, c.B)
511 elif isinstance(c, str):
514 raise ValueError("Color value should be of string or SALOMEDS.Color type")
517 def GetPointStruct(self,theVertex):
519 Get :class:`SMESH.PointStruct` from vertex
522 theVertex (GEOM.GEOM_Object): vertex
525 :class:`SMESH.PointStruct`
527 geompyD = theVertex.GetGen()
528 [x, y, z] = geompyD.PointCoordinates(theVertex)
529 return PointStruct(x,y,z)
531 def GetDirStruct(self,theVector):
533 Get :class:`SMESH.DirStruct` from vector
536 theVector (GEOM.GEOM_Object): vector
539 :class:`SMESH.DirStruct`
541 geompyD = theVector.GetGen()
542 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
543 if(len(vertices) != 2):
544 print("Error: vector object is incorrect.")
546 p1 = geompyD.PointCoordinates(vertices[0])
547 p2 = geompyD.PointCoordinates(vertices[1])
548 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
549 dirst = DirStruct(pnt)
552 def MakeDirStruct(self,x,y,z):
554 Make :class:`SMESH.DirStruct` from a triplet of floats
557 x,y,z (float): vector components
560 :class:`SMESH.DirStruct`
563 pnt = PointStruct(x,y,z)
564 return DirStruct(pnt)
566 def GetAxisStruct(self,theObj):
568 Get :class:`SMESH.AxisStruct` from a geometrical object
571 theObj (GEOM.GEOM_Object): line or plane
574 :class:`SMESH.AxisStruct`
577 geompyD = theObj.GetGen()
578 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
581 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
583 vertex1 = geompyD.PointCoordinates(vertex1)
584 vertex2 = geompyD.PointCoordinates(vertex2)
585 vertex3 = geompyD.PointCoordinates(vertex3)
586 vertex4 = geompyD.PointCoordinates(vertex4)
587 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
588 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
589 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] ]
590 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
591 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
592 elif len(edges) == 1:
593 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
594 p1 = geompyD.PointCoordinates( vertex1 )
595 p2 = geompyD.PointCoordinates( vertex2 )
596 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
597 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
598 elif theObj.GetShapeType() == GEOM.VERTEX:
599 x,y,z = geompyD.PointCoordinates( theObj )
600 axis = AxisStruct( x,y,z, 1,0,0,)
601 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
604 # From SMESH_Gen interface:
605 # ------------------------
607 def SetName(self, obj, name):
609 Set the given name to an object
612 obj: the object to rename
613 name: a new object name
616 if isinstance( obj, Mesh ):
618 elif isinstance( obj, Mesh_Algorithm ):
619 obj = obj.GetAlgorithm()
620 ior = salome.orb.object_to_string(obj)
621 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
623 def SetEmbeddedMode( self,theMode ):
628 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
630 def IsEmbeddedMode(self):
635 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
637 def UpdateStudy( self, geompyD = None ):
639 Update the current study. Calling UpdateStudy() allows to
640 update meshes at switching GEOM->SMESH
644 from salome.geom import geomBuilder
645 geompyD = geomBuilder.geom
647 geompyD = geomBuilder.New()
650 self.SetGeomEngine(geompyD)
651 SMESH._objref_SMESH_Gen.UpdateStudy(self)
652 sb = salome.myStudy.NewBuilder()
653 sc = salome.myStudy.FindComponent("SMESH")
655 sb.LoadWith(sc, self)
658 def SetEnablePublish( self, theIsEnablePublish ):
660 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
661 switch **off** publishing in the Study of mesh objects.
663 #self.SetEnablePublish(theIsEnablePublish)
664 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
666 notebook = salome_notebook.NoteBook( theIsEnablePublish )
669 def CreateMeshesFromUNV( self,theFileName ):
671 Create a Mesh object importing data from the given UNV file
674 an instance of class :class:`Mesh`
677 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
678 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
681 def CreateMeshesFromMED( self,theFileName ):
683 Create a Mesh object(s) importing data from the given MED file
686 a tuple ( list of class :class:`Mesh` instances,
687 :class:`SMESH.DriverMED_ReadStatus` )
690 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
691 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692 return aMeshes, aStatus
694 def CreateMeshesFromSAUV( self,theFileName ):
696 Create a Mesh object(s) importing data from the given SAUV file
699 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
702 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
703 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
704 return aMeshes, aStatus
706 def CreateMeshesFromSTL( self, theFileName ):
708 Create a Mesh object importing data from the given STL file
711 an instance of class :class:`Mesh`
714 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
715 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
718 def CreateMeshesFromCGNS( self, theFileName ):
720 Create Mesh objects importing data from the given CGNS file
723 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
726 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
727 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
728 return aMeshes, aStatus
730 def CreateMeshesFromGMF( self, theFileName ):
732 Create a Mesh object importing data from the given GMF file.
733 GMF files must have .mesh extension for the ASCII format and .meshb for
737 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
740 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
743 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
744 return Mesh(self, self.geompyD, aSmeshMesh), error
746 def Concatenate( self, meshes, uniteIdenticalGroups,
747 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
748 name = "", meshToAppendTo = None):
750 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
751 All groups of input meshes will be present in the new mesh.
754 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
755 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
756 mergeNodesAndElements: if True, equal nodes and elements are merged
757 mergeTolerance: tolerance for merging nodes
758 allGroups: forces creation of groups corresponding to every input mesh
759 name: name of a new mesh
760 meshToAppendTo: a mesh to append all given meshes
763 an instance of class :class:`Mesh`
769 if not meshes: return None
770 if not isinstance( meshes, list ):
772 for i,m in enumerate( meshes ):
773 if isinstance( m, Mesh ):
774 meshes[i] = m.GetMesh()
775 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
776 if hasattr(meshes[0], "SetParameters"):
777 meshes[0].SetParameters( Parameters )
779 meshes[0].GetMesh().SetParameters( Parameters )
780 if isinstance( meshToAppendTo, Mesh ):
781 meshToAppendTo = meshToAppendTo.GetMesh()
783 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
784 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
785 mergeTolerance,meshToAppendTo )
787 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
788 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
789 mergeTolerance,meshToAppendTo )
791 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
794 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
796 Create a mesh by copying a part of another mesh.
799 meshPart: a part of mesh to copy, either
800 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
801 To copy nodes or elements not forming any mesh object,
802 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
803 meshName: a name of the new mesh
804 toCopyGroups: to create in the new mesh groups the copied elements belongs to
805 toKeepIDs: to preserve order of the copied elements or not
808 an instance of class :class:`Mesh`
811 if isinstance( meshPart, Mesh ):
812 meshPart = meshPart.GetMesh()
813 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
814 return Mesh(self, self.geompyD, mesh)
816 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
817 toReuseHypotheses=True, toCopyElements=True):
819 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
820 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
821 To facilitate and speed up the operation, consider using
822 "Set presentation parameters and sub-shapes from arguments" option in
823 a dialog of geometrical operation used to create the new geometry.
826 sourceMesh: the mesh to copy definition of.
827 newGeom: the new geometry.
828 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
829 toCopyGroups: to create groups in the new mesh.
830 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
831 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
834 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
835 *invalidEntries* are study entries of objects whose
836 counterparts are not found in the *newGeom*, followed by entries
837 of mesh sub-objects that are invalid because they depend on a not found
840 if isinstance( sourceMesh, Mesh ):
841 sourceMesh = sourceMesh.GetMesh()
843 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
844 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
848 return ( ok, Mesh(self, self.geompyD, newMesh),
849 newGroups, newSubMeshes, newHypotheses, invalidEntries )
851 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
853 Return IDs of sub-shapes
856 theMainObject (GEOM.GEOM_Object): a shape
857 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
859 the list of integer values
862 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
864 def GetPattern(self):
866 Create a pattern mapper.
869 an instance of :class:`SMESH.SMESH_Pattern`
871 :ref:`Example of Patterns usage <tui_pattern_mapping>`
874 return SMESH._objref_SMESH_Gen.GetPattern(self)
876 def SetBoundaryBoxSegmentation(self, nbSegments):
878 Set number of segments per diagonal of boundary box of geometry, by which
879 default segment length of appropriate 1D hypotheses is defined in GUI.
883 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
885 # Filtering. Auxiliary functions:
886 # ------------------------------
888 def GetEmptyCriterion(self):
890 Create an empty criterion
893 :class:`SMESH.Filter.Criterion`
896 Type = self.EnumToLong(FT_Undefined)
897 Compare = self.EnumToLong(FT_Undefined)
901 UnaryOp = self.EnumToLong(FT_Undefined)
902 BinaryOp = self.EnumToLong(FT_Undefined)
905 Precision = -1 ##@1e-07
906 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
907 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
909 def GetCriterion(self,elementType,
911 Compare = FT_EqualTo,
913 UnaryOp=FT_Undefined,
914 BinaryOp=FT_Undefined,
917 Create a criterion by the given parameters
918 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
921 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
922 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
923 Note that the items starting from FT_LessThan are not suitable for *CritType*.
924 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
925 Threshold: the threshold value (range of ids as string, shape, numeric)
926 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
927 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
929 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
930 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
933 :class:`SMESH.Filter.Criterion`
935 Example: :ref:`combining_filters`
938 if not CritType in SMESH.FunctorType._items:
939 raise TypeError("CritType should be of SMESH.FunctorType")
940 aCriterion = self.GetEmptyCriterion()
941 aCriterion.TypeOfElement = elementType
942 aCriterion.Type = self.EnumToLong(CritType)
943 aCriterion.Tolerance = Tolerance
945 aThreshold = Threshold
947 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
948 aCriterion.Compare = self.EnumToLong(Compare)
949 elif Compare == "=" or Compare == "==":
950 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
952 aCriterion.Compare = self.EnumToLong(FT_LessThan)
954 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
955 elif Compare != FT_Undefined:
956 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
959 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
960 FT_BelongToCylinder, FT_LyingOnGeom]:
961 # Check that Threshold is GEOM object
962 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
963 aCriterion.ThresholdStr = GetName(aThreshold)
964 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
965 if not aCriterion.ThresholdID:
966 name = aCriterion.ThresholdStr
968 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
969 geompyD = aThreshold.GetGen()
970 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
971 # or a name of GEOM object
972 elif isinstance( aThreshold, str ):
973 aCriterion.ThresholdStr = aThreshold
975 raise TypeError("The Threshold should be a shape.")
976 if isinstance(UnaryOp,float):
977 aCriterion.Tolerance = UnaryOp
978 UnaryOp = FT_Undefined
980 elif CritType == FT_BelongToMeshGroup:
981 # Check that Threshold is a group
982 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
983 if aThreshold.GetType() != elementType:
984 raise ValueError("Group type mismatches Element type")
985 aCriterion.ThresholdStr = aThreshold.GetName()
986 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
987 study = salome.myStudy
989 so = study.FindObjectIOR( aCriterion.ThresholdID )
993 aCriterion.ThresholdID = entry
995 raise TypeError("The Threshold should be a Mesh Group")
996 elif CritType == FT_RangeOfIds:
997 # Check that Threshold is string
998 if isinstance(aThreshold, str):
999 aCriterion.ThresholdStr = aThreshold
1001 raise TypeError("The Threshold should be a string.")
1002 elif CritType == FT_CoplanarFaces:
1003 # Check the Threshold
1004 if isinstance(aThreshold, int):
1005 aCriterion.ThresholdID = str(aThreshold)
1006 elif isinstance(aThreshold, str):
1007 ID = int(aThreshold)
1009 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1010 aCriterion.ThresholdID = aThreshold
1012 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1013 elif CritType == FT_ConnectedElements:
1014 # Check the Threshold
1015 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1016 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1017 if not aCriterion.ThresholdID:
1018 name = aThreshold.GetName()
1020 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1021 geompyD = aThreshold.GetGen()
1022 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1023 elif isinstance(aThreshold, int): # node id
1024 aCriterion.Threshold = aThreshold
1025 elif isinstance(aThreshold, list): # 3 point coordinates
1026 if len( aThreshold ) < 3:
1027 raise ValueError("too few point coordinates, must be 3")
1028 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1029 elif isinstance(aThreshold, str):
1030 if aThreshold.isdigit():
1031 aCriterion.Threshold = aThreshold # node id
1033 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1035 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1036 "or a list of point coordinates and not '%s'"%aThreshold)
1037 elif CritType == FT_ElemGeomType:
1038 # Check the Threshold
1040 aCriterion.Threshold = self.EnumToLong(aThreshold)
1041 assert( aThreshold in SMESH.GeometryType._items )
1043 if isinstance(aThreshold, int):
1044 aCriterion.Threshold = aThreshold
1046 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1049 elif CritType == FT_EntityType:
1050 # Check the Threshold
1052 aCriterion.Threshold = self.EnumToLong(aThreshold)
1053 assert( aThreshold in SMESH.EntityType._items )
1055 if isinstance(aThreshold, int):
1056 aCriterion.Threshold = aThreshold
1058 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1062 elif CritType == FT_GroupColor:
1063 # Check the Threshold
1065 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1067 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1069 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1070 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1071 FT_BareBorderFace, FT_BareBorderVolume,
1072 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1073 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1074 # At this point the Threshold is unnecessary
1075 if aThreshold == FT_LogicalNOT:
1076 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1077 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1078 aCriterion.BinaryOp = aThreshold
1082 aThreshold = float(aThreshold)
1083 aCriterion.Threshold = aThreshold
1085 raise TypeError("The Threshold should be a number.")
1088 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1089 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1091 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1092 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1094 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1095 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1097 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1098 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1102 def GetFilter(self,elementType,
1103 CritType=FT_Undefined,
1106 UnaryOp=FT_Undefined,
1110 Create a filter with the given parameters
1113 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1114 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1115 Note that the items starting from FT_LessThan are not suitable for CritType.
1116 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1117 Threshold: the threshold value (range of ids as string, shape, numeric)
1118 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1119 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1120 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1121 mesh: the mesh to initialize the filter with
1124 :class:`SMESH.Filter`
1127 See :doc:`Filters usage examples <tui_filters>`
1130 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1131 aFilterMgr = self.CreateFilterManager()
1132 aFilter = aFilterMgr.CreateFilter()
1134 aCriteria.append(aCriterion)
1135 aFilter.SetCriteria(aCriteria)
1137 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1138 else : aFilter.SetMesh( mesh )
1139 aFilterMgr.UnRegister()
1142 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1144 Create a filter from criteria
1147 criteria: a list of :class:`SMESH.Filter.Criterion`
1148 binOp: binary operator used when binary operator of criteria is undefined
1151 :class:`SMESH.Filter`
1154 See :doc:`Filters usage examples <tui_filters>`
1157 for i in range( len( criteria ) - 1 ):
1158 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1159 criteria[i].BinaryOp = self.EnumToLong( binOp )
1160 aFilterMgr = self.CreateFilterManager()
1161 aFilter = aFilterMgr.CreateFilter()
1162 aFilter.SetCriteria(criteria)
1163 aFilterMgr.UnRegister()
1166 def GetFunctor(self,theCriterion):
1168 Create a numerical functor by its type
1171 theCriterion (SMESH.FunctorType): functor type.
1172 Note that not all items correspond to numerical functors.
1175 :class:`SMESH.NumericalFunctor`
1178 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1180 aFilterMgr = self.CreateFilterManager()
1182 if theCriterion == FT_AspectRatio:
1183 functor = aFilterMgr.CreateAspectRatio()
1184 elif theCriterion == FT_AspectRatio3D:
1185 functor = aFilterMgr.CreateAspectRatio3D()
1186 elif theCriterion == FT_Warping:
1187 functor = aFilterMgr.CreateWarping()
1188 elif theCriterion == FT_MinimumAngle:
1189 functor = aFilterMgr.CreateMinimumAngle()
1190 elif theCriterion == FT_Taper:
1191 functor = aFilterMgr.CreateTaper()
1192 elif theCriterion == FT_Skew:
1193 functor = aFilterMgr.CreateSkew()
1194 elif theCriterion == FT_Area:
1195 functor = aFilterMgr.CreateArea()
1196 elif theCriterion == FT_Volume3D:
1197 functor = aFilterMgr.CreateVolume3D()
1198 elif theCriterion == FT_MaxElementLength2D:
1199 functor = aFilterMgr.CreateMaxElementLength2D()
1200 elif theCriterion == FT_MaxElementLength3D:
1201 functor = aFilterMgr.CreateMaxElementLength3D()
1202 elif theCriterion == FT_MultiConnection:
1203 functor = aFilterMgr.CreateMultiConnection()
1204 elif theCriterion == FT_MultiConnection2D:
1205 functor = aFilterMgr.CreateMultiConnection2D()
1206 elif theCriterion == FT_Length:
1207 functor = aFilterMgr.CreateLength()
1208 elif theCriterion == FT_Length2D:
1209 functor = aFilterMgr.CreateLength2D()
1210 elif theCriterion == FT_Length3D:
1211 functor = aFilterMgr.CreateLength3D()
1212 elif theCriterion == FT_Deflection2D:
1213 functor = aFilterMgr.CreateDeflection2D()
1214 elif theCriterion == FT_NodeConnectivityNumber:
1215 functor = aFilterMgr.CreateNodeConnectivityNumber()
1216 elif theCriterion == FT_BallDiameter:
1217 functor = aFilterMgr.CreateBallDiameter()
1219 print("Error: given parameter is not numerical functor type.")
1220 aFilterMgr.UnRegister()
1223 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1228 theHType (string): mesh hypothesis type
1229 theLibName (string): mesh plug-in library name
1232 created hypothesis instance
1234 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1236 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1239 # wrap hypothesis methods
1240 for meth_name in dir( hyp.__class__ ):
1241 if not meth_name.startswith("Get") and \
1242 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1243 method = getattr ( hyp.__class__, meth_name )
1244 if callable(method):
1245 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1249 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1251 Create hypothesis initialized according to parameters
1254 hypType (string): hypothesis type
1255 libName (string): plug-in library name
1256 mesh: optional mesh by which a hypotheses can initialize self
1257 shape: optional geometry by size of which a hypotheses can initialize self
1258 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1261 created hypothesis instance
1263 if isinstance( mesh, Mesh ):
1264 mesh = mesh.GetMesh()
1265 if isinstance( initParams, (bool,int)):
1266 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1267 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1268 mesh, shape, initParams )
1270 def GetMeshInfo(self, obj):
1272 Get the mesh statistic.
1275 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1278 if isinstance( obj, Mesh ):
1281 if hasattr(obj, "GetMeshInfo"):
1282 values = obj.GetMeshInfo()
1283 for i in range(SMESH.Entity_Last._v):
1284 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1288 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1290 Get minimum distance between two objects
1292 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1293 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1296 src1 (SMESH.SMESH_IDSource): first source object
1297 src2 (SMESH.SMESH_IDSource): second source object
1298 id1 (int): node/element id from the first source
1299 id2 (int): node/element id from the second (or first) source
1300 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1301 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1304 minimum distance value
1307 :meth:`GetMinDistance`
1310 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1314 result = result.value
1317 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1319 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1321 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1322 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1325 src1 (SMESH.SMESH_IDSource): first source object
1326 src2 (SMESH.SMESH_IDSource): second source object
1327 id1 (int): node/element id from the first source
1328 id2 (int): node/element id from the second (or first) source
1329 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1330 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1333 :class:`SMESH.Measure` structure or None if input data is invalid
1338 if isinstance(src1, Mesh): src1 = src1.mesh
1339 if isinstance(src2, Mesh): src2 = src2.mesh
1340 if src2 is None and id2 != 0: src2 = src1
1341 if not hasattr(src1, "_narrow"): return None
1342 src1 = src1._narrow(SMESH.SMESH_IDSource)
1343 if not src1: return None
1344 unRegister = genObjUnRegister()
1347 e = m.GetMeshEditor()
1349 src1 = e.MakeIDSource([id1], SMESH.FACE)
1351 src1 = e.MakeIDSource([id1], SMESH.NODE)
1352 unRegister.set( src1 )
1354 if hasattr(src2, "_narrow"):
1355 src2 = src2._narrow(SMESH.SMESH_IDSource)
1356 if src2 and id2 != 0:
1358 e = m.GetMeshEditor()
1360 src2 = e.MakeIDSource([id2], SMESH.FACE)
1362 src2 = e.MakeIDSource([id2], SMESH.NODE)
1363 unRegister.set( src2 )
1366 aMeasurements = self.CreateMeasurements()
1367 unRegister.set( aMeasurements )
1368 result = aMeasurements.MinDistance(src1, src2)
1371 def BoundingBox(self, objects):
1373 Get bounding box of the specified object(s)
1376 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1379 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1382 :meth:`GetBoundingBox`
1385 result = self.GetBoundingBox(objects)
1389 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1392 def GetBoundingBox(self, objects):
1394 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1397 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1400 :class:`SMESH.Measure` structure
1406 if isinstance(objects, tuple):
1407 objects = list(objects)
1408 if not isinstance(objects, list):
1412 if isinstance(o, Mesh):
1413 srclist.append(o.mesh)
1414 elif hasattr(o, "_narrow"):
1415 src = o._narrow(SMESH.SMESH_IDSource)
1416 if src: srclist.append(src)
1419 aMeasurements = self.CreateMeasurements()
1420 result = aMeasurements.BoundingBox(srclist)
1421 aMeasurements.UnRegister()
1424 def GetLength(self, obj):
1426 Get sum of lengths of all 1D elements in the mesh object.
1429 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1432 sum of lengths of all 1D elements
1435 if isinstance(obj, Mesh): obj = obj.mesh
1436 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1437 aMeasurements = self.CreateMeasurements()
1438 value = aMeasurements.Length(obj)
1439 aMeasurements.UnRegister()
1442 def GetArea(self, obj):
1444 Get sum of areas of all 2D elements in the mesh object.
1447 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1450 sum of areas of all 2D elements
1453 if isinstance(obj, Mesh): obj = obj.mesh
1454 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1455 aMeasurements = self.CreateMeasurements()
1456 value = aMeasurements.Area(obj)
1457 aMeasurements.UnRegister()
1460 def GetVolume(self, obj):
1462 Get sum of volumes of all 3D elements in the mesh object.
1465 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1468 sum of volumes of all 3D elements
1471 if isinstance(obj, Mesh): obj = obj.mesh
1472 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1473 aMeasurements = self.CreateMeasurements()
1474 value = aMeasurements.Volume(obj)
1475 aMeasurements.UnRegister()
1478 def GetGravityCenter(self, obj):
1480 Get gravity center of all nodes of a mesh object.
1483 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1486 Three components of the gravity center (x,y,z)
1489 :meth:`Mesh.BaryCenter`
1491 if isinstance(obj, Mesh): obj = obj.mesh
1492 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1493 aMeasurements = self.CreateMeasurements()
1494 pointStruct = aMeasurements.GravityCenter(obj)
1495 aMeasurements.UnRegister()
1496 return pointStruct.x, pointStruct.y, pointStruct.z
1498 def GetAngle(self, p1, p2, p3 ):
1500 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1503 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1509 if isinstance( p1, list ): p1 = PointStruct(*p1)
1510 if isinstance( p2, list ): p2 = PointStruct(*p2)
1511 if isinstance( p3, list ): p3 = PointStruct(*p3)
1513 aMeasurements = self.CreateMeasurements()
1514 angle = aMeasurements.Angle(p1,p2,p3)
1515 aMeasurements.UnRegister()
1520 pass # end of class smeshBuilder
1523 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1524 """Registering the new proxy for SMESH.SMESH_Gen"""
1527 def New( instance=None, instanceGeom=None):
1529 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1530 interface to create or load meshes.
1535 salome.salome_init()
1536 from salome.smesh import smeshBuilder
1537 smesh = smeshBuilder.New()
1540 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1541 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1543 :class:`smeshBuilder` instance
1548 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1550 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1555 smeshInst = smeshBuilder()
1556 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1557 smeshInst.init_smesh(instanceGeom)
1561 # Public class: Mesh
1562 # ==================
1565 class Mesh(metaclass = MeshMeta):
1567 This class allows defining and managing a mesh.
1568 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1569 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1570 new nodes and elements and by changing the existing entities), to get information
1571 about a mesh and to export a mesh in different formats.
1578 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1583 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1584 sets the GUI name of this mesh to *name*.
1587 smeshpyD: an instance of smeshBuilder class
1588 geompyD: an instance of geomBuilder class
1589 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1590 name: Study name of the mesh
1593 self.smeshpyD = smeshpyD
1594 self.geompyD = geompyD
1599 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1602 # publish geom of mesh (issue 0021122)
1603 if not self.geom.GetStudyEntry():
1607 geo_name = name + " shape"
1609 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1610 geompyD.addToStudy( self.geom, geo_name )
1611 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1613 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1616 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1618 self.smeshpyD.SetName(self.mesh, name)
1620 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1623 self.geom = self.mesh.GetShapeToMesh()
1625 self.editor = self.mesh.GetMeshEditor()
1626 self.functors = [None] * SMESH.FT_Undefined._v
1628 # set self to algoCreator's
1629 for attrName in dir(self):
1630 attr = getattr( self, attrName )
1631 if isinstance( attr, algoCreator ):
1632 setattr( self, attrName, attr.copy( self ))
1639 Destructor. Clean-up resources
1642 #self.mesh.UnRegister()
1646 def SetMesh(self, theMesh):
1648 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1651 theMesh: a :class:`SMESH.SMESH_Mesh` object
1653 # do not call Register() as this prevents mesh servant deletion at closing study
1654 #if self.mesh: self.mesh.UnRegister()
1657 #self.mesh.Register()
1658 self.geom = self.mesh.GetShapeToMesh()
1660 self.geompyD = self.geom.GetGen()
1666 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1669 a :class:`SMESH.SMESH_Mesh` object
1674 def GetEngine(self):
1676 Return a smeshBuilder instance created this mesh
1678 return self.smeshpyD
1680 def GetGeomEngine(self):
1682 Return a geomBuilder instance
1688 Get the name of the mesh
1691 the name of the mesh as a string
1694 name = GetName(self.GetMesh())
1697 def SetName(self, name):
1699 Set a name to the mesh
1702 name: a new name of the mesh
1705 self.smeshpyD.SetName(self.GetMesh(), name)
1707 def GetSubMesh(self, geom, name):
1709 Get a sub-mesh object associated to a *geom* geometrical object.
1712 geom: a geometrical object (shape)
1713 name: a name for the sub-mesh in the Object Browser
1716 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1717 which lies on the given shape
1720 A sub-mesh is implicitly created when a sub-shape is specified at
1721 creating an algorithm, for example::
1723 algo1D = mesh.Segment(geom=Edge_1)
1725 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1726 The created sub-mesh can be retrieved from the algorithm::
1728 submesh = algo1D.GetSubMesh()
1731 AssureGeomPublished( self, geom, name )
1732 submesh = self.mesh.GetSubMesh( geom, name )
1737 Return the shape associated to the mesh
1745 def SetShape(self, geom):
1747 Associate the given shape to the mesh (entails the recreation of the mesh)
1750 geom: the shape to be meshed (GEOM_Object)
1753 self.mesh = self.smeshpyD.CreateMesh(geom)
1755 def HasShapeToMesh(self):
1757 Return ``True`` if this mesh is based on geometry
1759 return self.mesh.HasShapeToMesh()
1763 Load mesh from the study after opening the study
1767 def IsReadyToCompute(self, theSubObject):
1769 Return true if the hypotheses are defined well
1772 theSubObject: a sub-shape of a mesh shape
1778 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1780 def GetAlgoState(self, theSubObject):
1782 Return errors of hypotheses definition.
1783 The list of errors is empty if everything is OK.
1786 theSubObject: a sub-shape of a mesh shape
1792 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1794 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1796 Return a geometrical object on which the given element was built.
1797 The returned geometrical object, if not nil, is either found in the
1798 study or published by this method with the given name
1801 theElementID: the id of the mesh element
1802 theGeomName: the user-defined name of the geometrical object
1805 GEOM.GEOM_Object instance
1808 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1810 def MeshDimension(self):
1812 Return the mesh dimension depending on the dimension of the underlying shape
1813 or, if the mesh is not based on any shape, basing on deimension of elements
1816 mesh dimension as an integer value [0,3]
1819 if self.mesh.HasShapeToMesh():
1820 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1821 if len( shells ) > 0 :
1823 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1825 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1830 if self.NbVolumes() > 0: return 3
1831 if self.NbFaces() > 0: return 2
1832 if self.NbEdges() > 0: return 1
1835 def Evaluate(self, geom=0):
1837 Evaluate size of prospective mesh on a shape
1840 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1841 To know predicted number of e.g. edges, inquire it this way::
1843 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1846 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1848 geom = self.mesh.GetShapeToMesh()
1851 return self.smeshpyD.Evaluate(self.mesh, geom)
1854 def Compute(self, geom=0, discardModifs=False, refresh=False):
1856 Compute the mesh and return the status of the computation
1859 geom: geomtrical shape on which mesh data should be computed
1860 discardModifs: if True and the mesh has been edited since
1861 a last total re-compute and that may prevent successful partial re-compute,
1862 then the mesh is cleaned before Compute()
1863 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1869 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1870 geom = self.mesh.GetShapeToMesh()
1873 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1875 ok = self.smeshpyD.Compute(self.mesh, geom)
1876 except SALOME.SALOME_Exception as ex:
1877 print("Mesh computation failed, exception caught:")
1878 print(" ", ex.details.text)
1881 print("Mesh computation failed, exception caught:")
1882 traceback.print_exc()
1886 # Treat compute errors
1887 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1889 for err in computeErrors:
1890 if self.mesh.HasShapeToMesh():
1891 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1893 stdErrors = ["OK", #COMPERR_OK
1894 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1895 "std::exception", #COMPERR_STD_EXCEPTION
1896 "OCC exception", #COMPERR_OCC_EXCEPTION
1897 "..", #COMPERR_SLM_EXCEPTION
1898 "Unknown exception", #COMPERR_EXCEPTION
1899 "Memory allocation problem", #COMPERR_MEMORY_PB
1900 "Algorithm failed", #COMPERR_ALGO_FAILED
1901 "Unexpected geometry", #COMPERR_BAD_SHAPE
1902 "Warning", #COMPERR_WARNING
1903 "Computation cancelled",#COMPERR_CANCELED
1904 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1906 if err.code < len(stdErrors): errText = stdErrors[err.code]
1908 errText = "code %s" % -err.code
1909 if errText: errText += ". "
1910 errText += err.comment
1911 if allReasons: allReasons += "\n"
1913 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1915 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1919 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1921 if err.isGlobalAlgo:
1929 reason = '%s %sD algorithm is missing' % (glob, dim)
1930 elif err.state == HYP_MISSING:
1931 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1932 % (glob, dim, name, dim))
1933 elif err.state == HYP_NOTCONFORM:
1934 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1935 elif err.state == HYP_BAD_PARAMETER:
1936 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1937 % ( glob, dim, name ))
1938 elif err.state == HYP_BAD_GEOMETRY:
1939 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1940 'geometry' % ( glob, dim, name ))
1941 elif err.state == HYP_HIDDEN_ALGO:
1942 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1943 'algorithm of upper dimension generating %sD mesh'
1944 % ( glob, dim, name, glob, dim ))
1946 reason = ("For unknown reason. "
1947 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1949 if allReasons: allReasons += "\n"
1950 allReasons += "- " + reason
1952 if not ok or allReasons != "":
1953 msg = '"' + GetName(self.mesh) + '"'
1954 if ok: msg += " has been computed with warnings"
1955 else: msg += " has not been computed"
1956 if allReasons != "": msg += ":"
1961 if salome.sg.hasDesktop():
1962 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1963 if refresh: salome.sg.updateObjBrowser()
1967 def GetComputeErrors(self, shape=0 ):
1969 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1973 shape = self.mesh.GetShapeToMesh()
1974 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1976 def GetSubShapeName(self, subShapeID ):
1978 Return a name of a sub-shape by its ID.
1979 Possible variants (for *subShapeID* == 3):
1981 - **"Face_12"** - published sub-shape
1982 - **FACE #3** - not published sub-shape
1983 - **sub-shape #3** - invalid sub-shape ID
1984 - **#3** - error in this function
1987 subShapeID: a unique ID of a sub-shape
1990 a string describing the sub-shape
1994 if not self.mesh.HasShapeToMesh():
1998 mainIOR = salome.orb.object_to_string( self.GetShape() )
2000 mainSO = s.FindObjectIOR(mainIOR)
2003 shapeText = '"%s"' % mainSO.GetName()
2004 subIt = s.NewChildIterator(mainSO)
2006 subSO = subIt.Value()
2008 obj = subSO.GetObject()
2009 if not obj: continue
2010 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2013 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2016 if ids == subShapeID:
2017 shapeText = '"%s"' % subSO.GetName()
2020 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2022 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2024 shapeText = 'sub-shape #%s' % (subShapeID)
2026 shapeText = "#%s" % (subShapeID)
2029 def GetFailedShapes(self, publish=False):
2031 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2032 error of an algorithm
2035 publish: if *True*, the returned groups will be published in the study
2038 a list of GEOM groups each named after a failed algorithm
2043 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2044 for err in computeErrors:
2045 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2046 if not shape: continue
2047 if err.algoName in algo2shapes:
2048 algo2shapes[ err.algoName ].append( shape )
2050 algo2shapes[ err.algoName ] = [ shape ]
2054 for algoName, shapes in list(algo2shapes.items()):
2056 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2057 otherTypeShapes = []
2059 group = self.geompyD.CreateGroup( self.geom, groupType )
2060 for shape in shapes:
2061 if shape.GetShapeType() == shapes[0].GetShapeType():
2062 sameTypeShapes.append( shape )
2064 otherTypeShapes.append( shape )
2065 self.geompyD.UnionList( group, sameTypeShapes )
2067 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2069 group.SetName( algoName )
2070 groups.append( group )
2071 shapes = otherTypeShapes
2074 for group in groups:
2075 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2078 def GetMeshOrder(self):
2080 Return sub-mesh objects list in meshing order
2083 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2086 return self.mesh.GetMeshOrder()
2088 def SetMeshOrder(self, submeshes):
2090 Set priority of sub-meshes. It works in two ways:
2092 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2093 *several dimensions*, it sets the order in which the sub-meshes are computed.
2094 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2095 when looking for meshing parameters to apply to a sub-shape. To impose the
2096 order in which sub-meshes with uni-dimensional algorithms are computed,
2097 call **submesh.Compute()** in a desired order.
2100 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2102 Warning: the method is for setting the order for all sub-meshes at once:
2103 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2106 return self.mesh.SetMeshOrder(submeshes)
2108 def Clear(self, refresh=False):
2110 Remove all nodes and elements generated on geometry. Imported elements remain.
2113 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2117 if ( salome.sg.hasDesktop() ):
2118 if refresh: salome.sg.updateObjBrowser()
2120 def ClearSubMesh(self, geomId, refresh=False):
2122 Remove all nodes and elements of indicated shape
2125 geomId: the ID of a sub-shape to remove elements on
2126 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2129 self.mesh.ClearSubMesh(geomId)
2130 if salome.sg.hasDesktop():
2131 if refresh: salome.sg.updateObjBrowser()
2133 def AutomaticTetrahedralization(self, fineness=0):
2135 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2138 fineness: [0.0,1.0] defines mesh fineness
2144 dim = self.MeshDimension()
2146 self.RemoveGlobalHypotheses()
2147 self.Segment().AutomaticLength(fineness)
2149 self.Triangle().LengthFromEdges()
2154 return self.Compute()
2156 def AutomaticHexahedralization(self, fineness=0):
2158 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2161 fineness: [0.0, 1.0] defines mesh fineness
2167 dim = self.MeshDimension()
2168 # assign the hypotheses
2169 self.RemoveGlobalHypotheses()
2170 self.Segment().AutomaticLength(fineness)
2177 return self.Compute()
2179 def AddHypothesis(self, hyp, geom=0):
2184 hyp: a hypothesis to assign
2185 geom: a subhape of mesh geometry
2188 :class:`SMESH.Hypothesis_Status`
2191 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2192 hyp, geom = geom, hyp
2193 if isinstance( hyp, Mesh_Algorithm ):
2194 hyp = hyp.GetAlgorithm()
2199 geom = self.mesh.GetShapeToMesh()
2202 if self.mesh.HasShapeToMesh():
2203 hyp_type = hyp.GetName()
2204 lib_name = hyp.GetLibName()
2205 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2206 # if checkAll and geom:
2207 # checkAll = geom.GetType() == 37
2209 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2211 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2212 status = self.mesh.AddHypothesis(geom, hyp)
2214 status = HYP_BAD_GEOMETRY, ""
2215 hyp_name = GetName( hyp )
2218 geom_name = geom.GetName()
2219 isAlgo = hyp._narrow( SMESH_Algo )
2220 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2223 def IsUsedHypothesis(self, hyp, geom):
2225 Return True if an algorithm or hypothesis is assigned to a given shape
2228 hyp: an algorithm or hypothesis to check
2229 geom: a subhape of mesh geometry
2235 if not hyp: # or not geom
2237 if isinstance( hyp, Mesh_Algorithm ):
2238 hyp = hyp.GetAlgorithm()
2240 hyps = self.GetHypothesisList(geom)
2242 if h.GetId() == hyp.GetId():
2246 def RemoveHypothesis(self, hyp, geom=0):
2248 Unassign a hypothesis
2251 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2252 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2255 :class:`SMESH.Hypothesis_Status`
2260 if isinstance( hyp, Mesh_Algorithm ):
2261 hyp = hyp.GetAlgorithm()
2267 if self.IsUsedHypothesis( hyp, shape ):
2268 return self.mesh.RemoveHypothesis( shape, hyp )
2269 hypName = GetName( hyp )
2270 geoName = GetName( shape )
2271 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2274 def GetHypothesisList(self, geom):
2276 Get the list of hypotheses added on a geometry
2279 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2282 the sequence of :class:`SMESH.SMESH_Hypothesis`
2285 return self.mesh.GetHypothesisList( geom )
2287 def RemoveGlobalHypotheses(self):
2289 Remove all global hypotheses
2292 current_hyps = self.mesh.GetHypothesisList( self.geom )
2293 for hyp in current_hyps:
2294 self.mesh.RemoveHypothesis( self.geom, hyp )
2297 def ExportMED(self, *args, **kwargs):
2299 Export the mesh in a file in MED format
2300 allowing to overwrite the file if it exists or add the exported data to its contents
2303 fileName: is the file name
2304 auto_groups (boolean): parameter for creating/not creating
2305 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2306 the typical use is auto_groups=False.
2307 version (int): define the version (xy, where version is x.y.z) of MED file format.
2308 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2309 The rules of compatibility to write a mesh in an older version than
2310 the current version depend on the current version. For instance,
2311 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2312 or 3.2.1 or 3.3.1 formats.
2313 If the version is equal to -1, the version is not changed (default).
2314 overwrite (boolean): parameter for overwriting/not overwriting the file
2315 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2316 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2318 - 1D if all mesh nodes lie on OX coordinate axis, or
2319 - 2D if all mesh nodes lie on XOY coordinate plane, or
2320 - 3D in the rest cases.
2322 If *autoDimension* is *False*, the space dimension is always 3.
2323 fields: list of GEOM fields defined on the shape to mesh.
2324 geomAssocFields: each character of this string means a need to export a
2325 corresponding field; correspondence between fields and characters
2328 - 'v' stands for "_vertices_" field;
2329 - 'e' stands for "_edges_" field;
2330 - 'f' stands for "_faces_" field;
2331 - 's' stands for "_solids_" field.
2333 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2334 close to zero within a given tolerance, the coordinate is set to zero.
2335 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2337 # process positional arguments
2338 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2340 auto_groups = args[1] if len(args) > 1 else False
2341 version = args[2] if len(args) > 2 else -1
2342 overwrite = args[3] if len(args) > 3 else True
2343 meshPart = args[4] if len(args) > 4 else None
2344 autoDimension = args[5] if len(args) > 5 else True
2345 fields = args[6] if len(args) > 6 else []
2346 geomAssocFields = args[7] if len(args) > 7 else ''
2347 z_tolerance = args[8] if len(args) > 8 else -1.
2348 # process keywords arguments
2349 auto_groups = kwargs.get("auto_groups", auto_groups)
2350 version = kwargs.get("version", version)
2351 version = kwargs.get("minor", version)
2352 overwrite = kwargs.get("overwrite", overwrite)
2353 meshPart = kwargs.get("meshPart", meshPart)
2354 autoDimension = kwargs.get("autoDimension", autoDimension)
2355 fields = kwargs.get("fields", fields)
2356 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2357 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2359 # invoke engine's function
2360 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2361 unRegister = genObjUnRegister()
2362 if isinstance( meshPart, list ):
2363 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2364 unRegister.set( meshPart )
2366 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2367 self.mesh.SetParameters(Parameters)
2369 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2370 version, overwrite, autoDimension,
2371 fields, geomAssocFields, z_tolerance)
2373 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2375 def ExportSAUV(self, f, auto_groups=0):
2377 Export the mesh in a file in SAUV format
2382 auto_groups: boolean parameter for creating/not creating
2383 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2384 the typical use is auto_groups=False.
2387 self.mesh.ExportSAUV(f, auto_groups)
2389 def ExportDAT(self, f, meshPart=None):
2391 Export the mesh in a file in DAT format
2395 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2399 unRegister = genObjUnRegister()
2400 if isinstance( meshPart, list ):
2401 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2402 unRegister.set( meshPart )
2403 self.mesh.ExportPartToDAT( meshPart, f )
2405 self.mesh.ExportDAT(f)
2407 def ExportUNV(self, f, meshPart=None):
2409 Export the mesh in a file in UNV format
2413 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2417 unRegister = genObjUnRegister()
2418 if isinstance( meshPart, list ):
2419 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2420 unRegister.set( meshPart )
2421 self.mesh.ExportPartToUNV( meshPart, f )
2423 self.mesh.ExportUNV(f)
2425 def ExportSTL(self, f, ascii=1, meshPart=None):
2427 Export the mesh in a file in STL format
2431 ascii: defines the file encoding
2432 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2436 unRegister = genObjUnRegister()
2437 if isinstance( meshPart, list ):
2438 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2439 unRegister.set( meshPart )
2440 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2442 self.mesh.ExportSTL(f, ascii)
2444 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2446 Export the mesh in a file in CGNS format
2450 overwrite: boolean parameter for overwriting/not overwriting the file
2451 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2452 groupElemsByType: if True all elements of same entity type are exported at ones,
2453 else elements are exported in order of their IDs which can cause creation
2454 of multiple cgns sections
2457 unRegister = genObjUnRegister()
2458 if isinstance( meshPart, list ):
2459 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2460 unRegister.set( meshPart )
2461 if isinstance( meshPart, Mesh ):
2462 meshPart = meshPart.mesh
2464 meshPart = self.mesh
2465 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2467 def ExportGMF(self, f, meshPart=None):
2469 Export the mesh in a file in GMF format.
2470 GMF files must have .mesh extension for the ASCII format and .meshb for
2471 the bynary format. Other extensions are not allowed.
2475 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2478 unRegister = genObjUnRegister()
2479 if isinstance( meshPart, list ):
2480 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2481 unRegister.set( meshPart )
2482 if isinstance( meshPart, Mesh ):
2483 meshPart = meshPart.mesh
2485 meshPart = self.mesh
2486 self.mesh.ExportGMF(meshPart, f, True)
2488 def ExportToMED(self, *args, **kwargs):
2490 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2491 Export the mesh in a file in MED format
2492 allowing to overwrite the file if it exists or add the exported data to its contents
2495 fileName: the file name
2496 opt (boolean): parameter for creating/not creating
2497 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2498 overwrite: boolean parameter for overwriting/not overwriting the file
2499 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2501 - 1D if all mesh nodes lie on OX coordinate axis, or
2502 - 2D if all mesh nodes lie on XOY coordinate plane, or
2503 - 3D in the rest cases.
2505 If **autoDimension** is *False*, the space dimension is always 3.
2508 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2509 # process positional arguments
2510 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2512 auto_groups = args[1] if len(args) > 1 else False
2513 overwrite = args[2] if len(args) > 2 else True
2514 autoDimension = args[3] if len(args) > 3 else True
2515 # process keywords arguments
2516 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2517 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2518 overwrite = kwargs.get("overwrite", overwrite)
2519 autoDimension = kwargs.get("autoDimension", autoDimension)
2521 # invoke engine's function
2522 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2524 def ExportToMEDX(self, *args, **kwargs):
2526 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2527 Export the mesh in a file in MED format
2530 fileName: the file name
2531 opt (boolean): parameter for creating/not creating
2532 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2533 overwrite: boolean parameter for overwriting/not overwriting the file
2534 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2536 - 1D if all mesh nodes lie on OX coordinate axis, or
2537 - 2D if all mesh nodes lie on XOY coordinate plane, or
2538 - 3D in the rest cases.
2540 If **autoDimension** is *False*, the space dimension is always 3.
2543 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2544 # process positional arguments
2545 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2547 auto_groups = args[1] if len(args) > 1 else False
2548 overwrite = args[2] if len(args) > 2 else True
2549 autoDimension = args[3] if len(args) > 3 else True
2550 # process keywords arguments
2551 auto_groups = kwargs.get("auto_groups", auto_groups)
2552 overwrite = kwargs.get("overwrite", overwrite)
2553 autoDimension = kwargs.get("autoDimension", autoDimension)
2555 # invoke engine's function
2556 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2560 def Append(self, meshes, uniteIdenticalGroups = True,
2561 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2563 Append given meshes into this mesh.
2564 All groups of input meshes will be created in this mesh.
2567 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2568 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2569 mergeNodesAndElements: if True, equal nodes and elements are merged
2570 mergeTolerance: tolerance for merging nodes
2571 allGroups: forces creation of groups corresponding to every input mesh
2573 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2574 mergeNodesAndElements, mergeTolerance, allGroups,
2575 meshToAppendTo = self.GetMesh() )
2577 # Operations with groups:
2578 # ----------------------
2579 def CreateEmptyGroup(self, elementType, name):
2581 Create an empty standalone mesh group
2584 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2585 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2586 name: the name of the mesh group
2589 :class:`SMESH.SMESH_Group`
2592 return self.mesh.CreateGroup(elementType, name)
2594 def Group(self, grp, name=""):
2596 Create a mesh group based on the geometric object *grp*
2597 and give it a *name*.
2598 If *name* is not defined the name of the geometric group is used
2601 Works like :meth:`GroupOnGeom`.
2604 grp: a geometric group, a vertex, an edge, a face or a solid
2605 name: the name of the mesh group
2608 :class:`SMESH.SMESH_GroupOnGeom`
2611 return self.GroupOnGeom(grp, name)
2613 def GroupOnGeom(self, grp, name="", typ=None):
2615 Create a mesh group based on the geometrical object *grp*
2616 and give it a *name*.
2617 if *name* is not defined the name of the geometric group is used
2620 grp: a geometrical group, a vertex, an edge, a face or a solid
2621 name: the name of the mesh group
2622 typ: the type of elements in the group; either of
2623 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2624 automatically detected by the type of the geometry
2627 :class:`SMESH.SMESH_GroupOnGeom`
2630 AssureGeomPublished( self, grp, name )
2632 name = grp.GetName()
2634 typ = self._groupTypeFromShape( grp )
2635 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2637 def _groupTypeFromShape( self, shape ):
2639 Pivate method to get a type of group on geometry
2641 tgeo = str(shape.GetShapeType())
2642 if tgeo == "VERTEX":
2644 elif tgeo == "EDGE" or tgeo == "WIRE":
2646 elif tgeo == "FACE" or tgeo == "SHELL":
2648 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2650 elif tgeo == "COMPOUND":
2652 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2654 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2655 # simplification of access in geomBuilder: omniORB.registerObjref
2656 from SHAPERSTUDY_utils import getEngine
2659 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2661 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2662 return self._groupTypeFromShape( sub[0] )
2664 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2667 def GroupOnFilter(self, typ, name, filter):
2669 Create a mesh group with given *name* based on the *filter*.
2670 It is a special type of group dynamically updating it's contents during
2674 typ: the type of elements in the group; either of
2675 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2676 name: the name of the mesh group
2677 filter (SMESH.Filter): the filter defining group contents
2680 :class:`SMESH.SMESH_GroupOnFilter`
2683 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2685 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2687 Create a mesh group by the given ids of elements
2690 groupName: the name of the mesh group
2691 elementType: the type of elements in the group; either of
2692 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2693 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2696 :class:`SMESH.SMESH_Group`
2699 group = self.mesh.CreateGroup(elementType, groupName)
2700 if isinstance( elemIDs, Mesh ):
2701 elemIDs = elemIDs.GetMesh()
2702 if hasattr( elemIDs, "GetIDs" ):
2703 if hasattr( elemIDs, "SetMesh" ):
2704 elemIDs.SetMesh( self.GetMesh() )
2705 group.AddFrom( elemIDs )
2713 CritType=FT_Undefined,
2716 UnaryOp=FT_Undefined,
2719 Create a mesh group by the given conditions
2722 groupName: the name of the mesh group
2723 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2724 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2725 Note that the items starting from FT_LessThan are not suitable for CritType.
2726 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2727 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2728 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2729 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2730 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2733 :class:`SMESH.SMESH_GroupOnFilter`
2736 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2737 group = self.MakeGroupByCriterion(groupName, aCriterion)
2740 def MakeGroupByCriterion(self, groupName, Criterion):
2742 Create a mesh group by the given criterion
2745 groupName: the name of the mesh group
2746 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2749 :class:`SMESH.SMESH_GroupOnFilter`
2752 :meth:`smeshBuilder.GetCriterion`
2755 return self.MakeGroupByCriteria( groupName, [Criterion] )
2757 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2759 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2762 groupName: the name of the mesh group
2763 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2764 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2767 :class:`SMESH.SMESH_GroupOnFilter`
2770 :meth:`smeshBuilder.GetCriterion`
2773 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2774 group = self.MakeGroupByFilter(groupName, aFilter)
2777 def MakeGroupByFilter(self, groupName, theFilter):
2779 Create a mesh group by the given filter
2782 groupName (string): the name of the mesh group
2783 theFilter (SMESH.Filter): the filter
2786 :class:`SMESH.SMESH_GroupOnFilter`
2789 :meth:`smeshBuilder.GetFilter`
2792 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2793 #theFilter.SetMesh( self.mesh )
2794 #group.AddFrom( theFilter )
2795 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2798 def RemoveGroup(self, group):
2803 group (SMESH.SMESH_GroupBase): group to remove
2806 self.mesh.RemoveGroup(group)
2808 def RemoveGroupWithContents(self, group):
2810 Remove a group with its contents
2813 group (SMESH.SMESH_GroupBase): group to remove
2816 This operation can create gaps in numeration of nodes or elements.
2817 Call :meth:`RenumberElements` to remove the gaps.
2820 self.mesh.RemoveGroupWithContents(group)
2822 def GetGroups(self, elemType = SMESH.ALL):
2824 Get the list of groups existing in the mesh in the order of creation
2825 (starting from the oldest one)
2828 elemType (SMESH.ElementType): type of elements the groups contain;
2829 by default groups of elements of all types are returned
2832 a list of :class:`SMESH.SMESH_GroupBase`
2835 groups = self.mesh.GetGroups()
2836 if elemType == SMESH.ALL:
2840 if g.GetType() == elemType:
2841 typedGroups.append( g )
2848 Get the number of groups existing in the mesh
2851 the quantity of groups as an integer value
2854 return self.mesh.NbGroups()
2856 def GetGroupNames(self):
2858 Get the list of names of groups existing in the mesh
2864 groups = self.GetGroups()
2866 for group in groups:
2867 names.append(group.GetName())
2870 def GetGroupByName(self, name, elemType = None):
2872 Find groups by name and type
2875 name (string): name of the group of interest
2876 elemType (SMESH.ElementType): type of elements the groups contain;
2877 by default one group of any type is returned;
2878 if elemType == SMESH.ALL then all groups of any type are returned
2881 a list of :class:`SMESH.SMESH_GroupBase`
2885 for group in self.GetGroups():
2886 if group.GetName() == name:
2887 if elemType is None:
2889 if ( elemType == SMESH.ALL or
2890 group.GetType() == elemType ):
2891 groups.append( group )
2894 def UnionGroups(self, group1, group2, name):
2896 Produce a union of two groups.
2897 A new group is created. All mesh elements that are
2898 present in the initial groups are added to the new one
2901 group1 (SMESH.SMESH_GroupBase): a group
2902 group2 (SMESH.SMESH_GroupBase): another group
2905 instance of :class:`SMESH.SMESH_Group`
2908 return self.mesh.UnionGroups(group1, group2, name)
2910 def UnionListOfGroups(self, groups, name):
2912 Produce a union list of groups.
2913 New group is created. All mesh elements that are present in
2914 initial groups are added to the new one
2917 groups: list of :class:`SMESH.SMESH_GroupBase`
2920 instance of :class:`SMESH.SMESH_Group`
2922 return self.mesh.UnionListOfGroups(groups, name)
2924 def IntersectGroups(self, group1, group2, name):
2926 Prodice an intersection of two groups.
2927 A new group is created. All mesh elements that are common
2928 for the two initial groups are added to the new one.
2931 group1 (SMESH.SMESH_GroupBase): a group
2932 group2 (SMESH.SMESH_GroupBase): another group
2935 instance of :class:`SMESH.SMESH_Group`
2938 return self.mesh.IntersectGroups(group1, group2, name)
2940 def IntersectListOfGroups(self, groups, name):
2942 Produce an intersection of groups.
2943 New group is created. All mesh elements that are present in all
2944 initial groups simultaneously are added to the new one
2947 groups: a list of :class:`SMESH.SMESH_GroupBase`
2950 instance of :class:`SMESH.SMESH_Group`
2952 return self.mesh.IntersectListOfGroups(groups, name)
2954 def CutGroups(self, main_group, tool_group, name):
2956 Produce a cut of two groups.
2957 A new group is created. All mesh elements that are present in
2958 the main group but are not present in the tool group are added to the new one
2961 main_group (SMESH.SMESH_GroupBase): a group to cut from
2962 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2965 an instance of :class:`SMESH.SMESH_Group`
2968 return self.mesh.CutGroups(main_group, tool_group, name)
2970 def CutListOfGroups(self, main_groups, tool_groups, name):
2972 Produce a cut of groups.
2973 A new group is created. All mesh elements that are present in main groups
2974 but do not present in tool groups are added to the new one
2977 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2978 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2981 an instance of :class:`SMESH.SMESH_Group`
2984 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2986 def CreateDimGroup(self, groups, elemType, name,
2987 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2989 Create a standalone group of entities basing on nodes of other groups.
2992 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2993 elemType: a type of elements to include to the new group; either of
2994 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2995 name: a name of the new group.
2996 nbCommonNodes: a criterion of inclusion of an element to the new group
2997 basing on number of element nodes common with reference *groups*.
2998 Meaning of possible values are:
3000 - SMESH.ALL_NODES - include if all nodes are common,
3001 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3002 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3003 - SMEHS.MAJORITY - include if half of nodes or more are common.
3004 underlyingOnly: if *True* (default), an element is included to the
3005 new group provided that it is based on nodes of an element of *groups*;
3006 in this case the reference *groups* are supposed to be of higher dimension
3007 than *elemType*, which can be useful for example to get all faces lying on
3008 volumes of the reference *groups*.
3011 an instance of :class:`SMESH.SMESH_Group`
3014 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3016 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3018 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3020 Distribute all faces of the mesh among groups using sharp edges and optionally
3021 existing 1D elements as group boundaries.
3024 sharpAngle: edge is considered sharp if an angle between normals of
3025 adjacent faces is more than \a sharpAngle in degrees.
3026 createEdges (boolean): to create 1D elements for detected sharp edges.
3027 useExistingEdges (boolean): to use existing edges as group boundaries
3029 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3031 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3032 self.mesh.SetParameters(Parameters)
3033 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3035 def ConvertToStandalone(self, group):
3037 Convert group on geom into standalone group
3040 return self.mesh.ConvertToStandalone(group)
3042 # Get some info about mesh:
3043 # ------------------------
3045 def GetLog(self, clearAfterGet):
3047 Return the log of nodes and elements added or removed
3048 since the previous clear of the log.
3051 clearAfterGet: log is emptied after Get (safe if concurrents access)
3054 list of SMESH.log_block structures { commandType, number, coords, indexes }
3057 return self.mesh.GetLog(clearAfterGet)
3061 Clear the log of nodes and elements added or removed since the previous
3062 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3065 self.mesh.ClearLog()
3067 def SetAutoColor(self, theAutoColor):
3069 Toggle auto color mode on the object.
3070 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3073 theAutoColor (boolean): the flag which toggles auto color mode.
3076 self.mesh.SetAutoColor(theAutoColor)
3078 def GetAutoColor(self):
3080 Get flag of object auto color mode.
3086 return self.mesh.GetAutoColor()
3093 integer value, which is the internal Id of the mesh
3096 return self.mesh.GetId()
3098 def HasDuplicatedGroupNamesMED(self):
3100 Check the group names for duplications.
3101 Consider the maximum group name length stored in MED file.
3107 return self.mesh.HasDuplicatedGroupNamesMED()
3109 def GetMeshEditor(self):
3111 Obtain the mesh editor tool
3114 an instance of :class:`SMESH.SMESH_MeshEditor`
3119 def GetIDSource(self, ids, elemType = SMESH.ALL):
3121 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3122 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3126 elemType: type of elements; this parameter is used to distinguish
3127 IDs of nodes from IDs of elements; by default ids are treated as
3128 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3131 an instance of :class:`SMESH.SMESH_IDSource`
3134 call UnRegister() for the returned object as soon as it is no more useful::
3136 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3137 mesh.DoSomething( idSrc )
3141 if isinstance( ids, int ):
3143 return self.editor.MakeIDSource(ids, elemType)
3146 # Get information about mesh contents:
3147 # ------------------------------------
3149 def GetMeshInfo(self, obj = None):
3151 Get the mesh statistic.
3154 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3157 if not obj: obj = self.mesh
3158 return self.smeshpyD.GetMeshInfo(obj)
3162 Return the number of nodes in the mesh
3168 return self.mesh.NbNodes()
3170 def NbElements(self):
3172 Return the number of elements in the mesh
3178 return self.mesh.NbElements()
3180 def Nb0DElements(self):
3182 Return the number of 0d elements in the mesh
3188 return self.mesh.Nb0DElements()
3192 Return the number of ball discrete elements in the mesh
3198 return self.mesh.NbBalls()
3202 Return the number of edges in the mesh
3208 return self.mesh.NbEdges()
3210 def NbEdgesOfOrder(self, elementOrder):
3212 Return the number of edges with the given order in the mesh
3215 elementOrder: the order of elements
3216 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3222 return self.mesh.NbEdgesOfOrder(elementOrder)
3226 Return the number of faces in the mesh
3232 return self.mesh.NbFaces()
3234 def NbFacesOfOrder(self, elementOrder):
3236 Return the number of faces with the given order in the mesh
3239 elementOrder: the order of elements
3240 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3246 return self.mesh.NbFacesOfOrder(elementOrder)
3248 def NbTriangles(self):
3250 Return the number of triangles in the mesh
3256 return self.mesh.NbTriangles()
3258 def NbTrianglesOfOrder(self, elementOrder):
3260 Return the number of triangles with the given order in the mesh
3263 elementOrder: is the order of elements
3264 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3270 return self.mesh.NbTrianglesOfOrder(elementOrder)
3272 def NbBiQuadTriangles(self):
3274 Return the number of biquadratic triangles in the mesh
3280 return self.mesh.NbBiQuadTriangles()
3282 def NbQuadrangles(self):
3284 Return the number of quadrangles in the mesh
3290 return self.mesh.NbQuadrangles()
3292 def NbQuadranglesOfOrder(self, elementOrder):
3294 Return the number of quadrangles with the given order in the mesh
3297 elementOrder: the order of elements
3298 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3304 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3306 def NbBiQuadQuadrangles(self):
3308 Return the number of biquadratic quadrangles in the mesh
3314 return self.mesh.NbBiQuadQuadrangles()
3316 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3318 Return the number of polygons of given order in the mesh
3321 elementOrder: the order of elements
3322 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3328 return self.mesh.NbPolygonsOfOrder(elementOrder)
3330 def NbVolumes(self):
3332 Return the number of volumes in the mesh
3338 return self.mesh.NbVolumes()
3341 def NbVolumesOfOrder(self, elementOrder):
3343 Return the number of volumes with the given order in the mesh
3346 elementOrder: the order of elements
3347 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3353 return self.mesh.NbVolumesOfOrder(elementOrder)
3357 Return the number of tetrahedrons in the mesh
3363 return self.mesh.NbTetras()
3365 def NbTetrasOfOrder(self, elementOrder):
3367 Return the number of tetrahedrons with the given order in the mesh
3370 elementOrder: the order of elements
3371 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3377 return self.mesh.NbTetrasOfOrder(elementOrder)
3381 Return the number of hexahedrons in the mesh
3387 return self.mesh.NbHexas()
3389 def NbHexasOfOrder(self, elementOrder):
3391 Return the number of hexahedrons with the given order in the mesh
3394 elementOrder: the order of elements
3395 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3401 return self.mesh.NbHexasOfOrder(elementOrder)
3403 def NbTriQuadraticHexas(self):
3405 Return the number of triquadratic hexahedrons in the mesh
3411 return self.mesh.NbTriQuadraticHexas()
3413 def NbPyramids(self):
3415 Return the number of pyramids in the mesh
3421 return self.mesh.NbPyramids()
3423 def NbPyramidsOfOrder(self, elementOrder):
3425 Return the number of pyramids with the given order in the mesh
3428 elementOrder: the order of elements
3429 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3435 return self.mesh.NbPyramidsOfOrder(elementOrder)
3439 Return the number of prisms in the mesh
3445 return self.mesh.NbPrisms()
3447 def NbPrismsOfOrder(self, elementOrder):
3449 Return the number of prisms with the given order in the mesh
3452 elementOrder: the order of elements
3453 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3459 return self.mesh.NbPrismsOfOrder(elementOrder)
3461 def NbHexagonalPrisms(self):
3463 Return the number of hexagonal prisms in the mesh
3469 return self.mesh.NbHexagonalPrisms()
3471 def NbPolyhedrons(self):
3473 Return the number of polyhedrons in the mesh
3479 return self.mesh.NbPolyhedrons()
3481 def NbSubMesh(self):
3483 Return the number of submeshes in the mesh
3489 return self.mesh.NbSubMesh()
3491 def GetElementsId(self):
3493 Return the list of all mesh elements IDs
3496 the list of integer values
3499 :meth:`GetElementsByType`
3502 return self.mesh.GetElementsId()
3504 def GetElementsByType(self, elementType):
3506 Return the list of IDs of mesh elements with the given type
3509 elementType (SMESH.ElementType): the required type of elements
3512 list of integer values
3515 return self.mesh.GetElementsByType(elementType)
3517 def GetNodesId(self):
3519 Return the list of mesh nodes IDs
3522 the list of integer values
3525 return self.mesh.GetNodesId()
3527 # Get the information about mesh elements:
3528 # ------------------------------------
3530 def GetElementType(self, id, iselem=True):
3532 Return the type of mesh element or node
3535 the value from :class:`SMESH.ElementType` enumeration.
3536 Return SMESH.ALL if element or node with the given ID does not exist
3539 return self.mesh.GetElementType(id, iselem)
3541 def GetElementGeomType(self, id):
3543 Return the geometric type of mesh element
3546 the value from :class:`SMESH.EntityType` enumeration.
3549 return self.mesh.GetElementGeomType(id)
3551 def GetElementShape(self, id):
3553 Return the shape type of mesh element
3556 the value from :class:`SMESH.GeometryType` enumeration.
3559 return self.mesh.GetElementShape(id)
3561 def GetSubMeshElementsId(self, Shape):
3563 Return the list of sub-mesh elements IDs
3566 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3567 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3570 list of integer values
3573 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3574 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3577 return self.mesh.GetSubMeshElementsId(ShapeID)
3579 def GetSubMeshNodesId(self, Shape, all):
3581 Return the list of sub-mesh nodes IDs
3584 Shape: a geom object (sub-shape).
3585 *Shape* must be the sub-shape of a :meth:`GetShape`
3586 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3589 list of integer values
3592 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3593 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3596 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3598 def GetSubMeshElementType(self, Shape):
3600 Return type of elements on given shape
3603 Shape: a geom object (sub-shape).
3604 *Shape* must be a sub-shape of a ShapeToMesh()
3607 :class:`SMESH.ElementType`
3610 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3611 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3614 return self.mesh.GetSubMeshElementType(ShapeID)
3618 Get the mesh description
3624 return self.mesh.Dump()
3627 # Get the information about nodes and elements of a mesh by its IDs:
3628 # -----------------------------------------------------------
3630 def GetNodeXYZ(self, id):
3632 Get XYZ coordinates of a node.
3633 If there is no node for the given ID - return an empty list
3636 list of float values
3639 return self.mesh.GetNodeXYZ(id)
3641 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3643 Return list of IDs of inverse elements for the given node.
3644 If there is no node for the given ID - return an empty list
3648 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3651 list of integer values
3654 return self.mesh.GetNodeInverseElements(id,elemType)
3656 def GetNodePosition(self,NodeID):
3658 Return the position of a node on the shape
3661 :class:`SMESH.NodePosition`
3664 return self.mesh.GetNodePosition(NodeID)
3666 def GetElementPosition(self,ElemID):
3668 Return the position of an element on the shape
3671 :class:`SMESH.ElementPosition`
3674 return self.mesh.GetElementPosition(ElemID)
3676 def GetShapeID(self, id):
3678 Return the ID of the shape, on which the given node was generated.
3681 an integer value > 0 or -1 if there is no node for the given
3682 ID or the node is not assigned to any geometry
3685 return self.mesh.GetShapeID(id)
3687 def GetShapeIDForElem(self,id):
3689 Return the ID of the shape, on which the given element was generated.
3692 an integer value > 0 or -1 if there is no element for the given
3693 ID or the element is not assigned to any geometry
3696 return self.mesh.GetShapeIDForElem(id)
3698 def GetElemNbNodes(self, id):
3700 Return the number of nodes of the given element
3703 an integer value > 0 or -1 if there is no element for the given ID
3706 return self.mesh.GetElemNbNodes(id)
3708 def GetElemNode(self, id, index):
3710 Return the node ID the given (zero based) index for the given element.
3712 * If there is no element for the given ID - return -1.
3713 * If there is no node for the given index - return -2.
3716 id (int): element ID
3717 index (int): node index within the element
3720 an integer value (ID)
3723 :meth:`GetElemNodes`
3726 return self.mesh.GetElemNode(id, index)
3728 def GetElemNodes(self, id):
3730 Return the IDs of nodes of the given element
3733 a list of integer values
3736 return self.mesh.GetElemNodes(id)
3738 def IsMediumNode(self, elementID, nodeID):
3740 Return true if the given node is the medium node in the given quadratic element
3743 return self.mesh.IsMediumNode(elementID, nodeID)
3745 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3747 Return true if the given node is the medium node in one of quadratic elements
3750 nodeID: ID of the node
3751 elementType: the type of elements to check a state of the node, either of
3752 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3755 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3757 def ElemNbEdges(self, id):
3759 Return the number of edges for the given element
3762 return self.mesh.ElemNbEdges(id)
3764 def ElemNbFaces(self, id):
3766 Return the number of faces for the given element
3769 return self.mesh.ElemNbFaces(id)
3771 def GetElemFaceNodes(self,elemId, faceIndex):
3773 Return nodes of given face (counted from zero) for given volumic element.
3776 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3778 def GetFaceNormal(self, faceId, normalized=False):
3780 Return three components of normal of given mesh face
3781 (or an empty array in KO case)
3784 return self.mesh.GetFaceNormal(faceId,normalized)
3786 def FindElementByNodes(self, nodes):
3788 Return an element based on all given nodes.
3791 return self.mesh.FindElementByNodes(nodes)
3793 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3795 Return elements including all given nodes.
3798 return self.mesh.GetElementsByNodes( nodes, elemType )
3800 def IsPoly(self, id):
3802 Return true if the given element is a polygon
3805 return self.mesh.IsPoly(id)
3807 def IsQuadratic(self, id):
3809 Return true if the given element is quadratic
3812 return self.mesh.IsQuadratic(id)
3814 def GetBallDiameter(self, id):
3816 Return diameter of a ball discrete element or zero in case of an invalid *id*
3819 return self.mesh.GetBallDiameter(id)
3821 def BaryCenter(self, id):
3823 Return XYZ coordinates of the barycenter of the given element.
3824 If there is no element for the given ID - return an empty list
3827 a list of three double values
3830 :meth:`smeshBuilder.GetGravityCenter`
3833 return self.mesh.BaryCenter(id)
3835 def GetIdsFromFilter(self, filter, meshParts=[] ):
3837 Pass mesh elements through the given filter and return IDs of fitting elements
3840 filter: :class:`SMESH.Filter`
3841 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3847 :meth:`SMESH.Filter.GetIDs`
3848 :meth:`SMESH.Filter.GetElementsIdFromParts`
3851 filter.SetMesh( self.mesh )
3854 if isinstance( meshParts, Mesh ):
3855 filter.SetMesh( meshParts.GetMesh() )
3856 return theFilter.GetIDs()
3857 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3858 meshParts = [ meshParts ]
3859 return filter.GetElementsIdFromParts( meshParts )
3861 return filter.GetIDs()
3863 # Get mesh measurements information:
3864 # ------------------------------------
3866 def GetFreeBorders(self):
3868 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3869 Return a list of special structures (borders).
3872 a list of :class:`SMESH.FreeEdges.Border`
3875 aFilterMgr = self.smeshpyD.CreateFilterManager()
3876 aPredicate = aFilterMgr.CreateFreeEdges()
3877 aPredicate.SetMesh(self.mesh)
3878 aBorders = aPredicate.GetBorders()
3879 aFilterMgr.UnRegister()
3882 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3884 Get minimum distance between two nodes, elements or distance to the origin
3887 id1: first node/element id
3888 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3889 isElem1: *True* if *id1* is element id, *False* if it is node id
3890 isElem2: *True* if *id2* is element id, *False* if it is node id
3893 minimum distance value
3895 :meth:`GetMinDistance`
3898 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3899 return aMeasure.value
3901 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3903 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3906 id1: first node/element id
3907 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3908 isElem1: *True* if *id1* is element id, *False* if it is node id
3909 isElem2: *True* if *id2* is element id, *False* if it is node id
3912 :class:`SMESH.Measure` structure
3918 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3920 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3923 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3925 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3930 aMeasurements = self.smeshpyD.CreateMeasurements()
3931 aMeasure = aMeasurements.MinDistance(id1, id2)
3932 genObjUnRegister([aMeasurements,id1, id2])
3935 def BoundingBox(self, objects=None, isElem=False):
3937 Get bounding box of the specified object(s)
3940 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3941 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3942 *False* specifies that *objects* are nodes
3945 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3948 :meth:`GetBoundingBox()`
3951 result = self.GetBoundingBox(objects, isElem)
3955 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3958 def GetBoundingBox(self, objects=None, isElem=False):
3960 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3963 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3964 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3965 False means that *objects* are nodes
3968 :class:`SMESH.Measure` structure
3971 :meth:`BoundingBox()`
3975 objects = [self.mesh]
3976 elif isinstance(objects, tuple):
3977 objects = list(objects)
3978 if not isinstance(objects, list):
3980 if len(objects) > 0 and isinstance(objects[0], int):
3983 unRegister = genObjUnRegister()
3985 if isinstance(o, Mesh):
3986 srclist.append(o.mesh)
3987 elif hasattr(o, "_narrow"):
3988 src = o._narrow(SMESH.SMESH_IDSource)
3989 if src: srclist.append(src)
3991 elif isinstance(o, list):
3993 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3995 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3996 unRegister.set( srclist[-1] )
3999 aMeasurements = self.smeshpyD.CreateMeasurements()
4000 unRegister.set( aMeasurements )
4001 aMeasure = aMeasurements.BoundingBox(srclist)
4004 # Mesh edition (SMESH_MeshEditor functionality):
4005 # ---------------------------------------------
4007 def RemoveElements(self, IDsOfElements):
4009 Remove the elements from the mesh by ids
4012 IDsOfElements: is a list of ids of elements to remove
4018 This operation can create gaps in numeration of elements.
4019 Call :meth:`RenumberElements` to remove the gaps.
4022 return self.editor.RemoveElements(IDsOfElements)
4024 def RemoveNodes(self, IDsOfNodes):
4026 Remove nodes from mesh by ids
4029 IDsOfNodes: is a list of ids of nodes to remove
4035 This operation can create gaps in numeration of nodes.
4036 Call :meth:`RenumberElements` to remove the gaps.
4039 return self.editor.RemoveNodes(IDsOfNodes)
4041 def RemoveOrphanNodes(self):
4043 Remove all orphan (free) nodes from mesh
4046 number of the removed nodes
4049 This operation can create gaps in numeration of nodes.
4050 Call :meth:`RenumberElements` to remove the gaps.
4053 return self.editor.RemoveOrphanNodes()
4055 def AddNode(self, x, y, z):
4057 Add a node to the mesh by coordinates
4063 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4064 if hasVars: self.mesh.SetParameters(Parameters)
4065 return self.editor.AddNode( x, y, z)
4067 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4069 Create a 0D element on a node with given number.
4072 IDOfNode: the ID of node for creation of the element.
4073 DuplicateElements: to add one more 0D element to a node or not
4076 ID of the new 0D element
4079 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4081 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4083 Create 0D elements on all nodes of the given elements except those
4084 nodes on which a 0D element already exists.
4087 theObject: an object on whose nodes 0D elements will be created.
4088 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4089 theGroupName: optional name of a group to add 0D elements created
4090 and/or found on nodes of *theObject*.
4091 DuplicateElements: to add one more 0D element to a node or not
4094 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4095 IDs of new and/or found 0D elements. IDs of 0D elements
4096 can be retrieved from the returned object by
4097 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4100 unRegister = genObjUnRegister()
4101 if isinstance( theObject, Mesh ):
4102 theObject = theObject.GetMesh()
4103 elif isinstance( theObject, list ):
4104 theObject = self.GetIDSource( theObject, SMESH.ALL )
4105 unRegister.set( theObject )
4106 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4108 def AddBall(self, IDOfNode, diameter):
4110 Create a ball element on a node with given ID.
4113 IDOfNode: the ID of node for creation of the element.
4114 diameter: the bal diameter.
4117 ID of the new ball element
4120 return self.editor.AddBall( IDOfNode, diameter )
4122 def AddEdge(self, IDsOfNodes):
4124 Create a linear or quadratic edge (this is determined
4125 by the number of given nodes).
4128 IDsOfNodes: list of node IDs for creation of the element.
4129 The order of nodes in this list should correspond to
4130 the :ref:`connectivity convention <connectivity_page>`.
4136 return self.editor.AddEdge(IDsOfNodes)
4138 def AddFace(self, IDsOfNodes):
4140 Create a linear or quadratic face (this is determined
4141 by the number of given nodes).
4144 IDsOfNodes: list of node IDs for creation of the element.
4145 The order of nodes in this list should correspond to
4146 the :ref:`connectivity convention <connectivity_page>`.
4152 return self.editor.AddFace(IDsOfNodes)
4154 def AddPolygonalFace(self, IdsOfNodes):
4156 Add a polygonal face defined by a list of node IDs
4159 IdsOfNodes: the list of node IDs for creation of the element.
4165 return self.editor.AddPolygonalFace(IdsOfNodes)
4167 def AddQuadPolygonalFace(self, IdsOfNodes):
4169 Add a quadratic polygonal face defined by a list of node IDs
4172 IdsOfNodes: the list of node IDs for creation of the element;
4173 corner nodes follow first.
4179 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4181 def AddVolume(self, IDsOfNodes):
4183 Create both simple and quadratic volume (this is determined
4184 by the number of given nodes).
4187 IDsOfNodes: list of node IDs for creation of the element.
4188 The order of nodes in this list should correspond to
4189 the :ref:`connectivity convention <connectivity_page>`.
4192 ID of the new volumic element
4195 return self.editor.AddVolume(IDsOfNodes)
4197 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4199 Create a volume of many faces, giving nodes for each face.
4202 IdsOfNodes: list of node IDs for volume creation, face by face.
4203 Quantities: list of integer values, Quantities[i]
4204 gives the quantity of nodes in face number i.
4207 ID of the new volumic element
4210 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4212 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4214 Create a volume of many faces, giving the IDs of the existing faces.
4217 The created volume will refer only to the nodes
4218 of the given faces, not to the faces themselves.
4221 IdsOfFaces: the list of face IDs for volume creation.
4224 ID of the new volumic element
4227 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4230 def SetNodeOnVertex(self, NodeID, Vertex):
4232 Bind a node to a vertex
4236 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4239 True if succeed else raises an exception
4242 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4243 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4247 self.editor.SetNodeOnVertex(NodeID, VertexID)
4248 except SALOME.SALOME_Exception as inst:
4249 raise ValueError(inst.details.text)
4253 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4255 Store the node position on an edge
4259 Edge: an edge (GEOM.GEOM_Object) or edge ID
4260 paramOnEdge: a parameter on the edge where the node is located
4263 True if succeed else raises an exception
4266 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4267 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4271 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4272 except SALOME.SALOME_Exception as inst:
4273 raise ValueError(inst.details.text)
4276 def SetNodeOnFace(self, NodeID, Face, u, v):
4278 Store node position on a face
4282 Face: a face (GEOM.GEOM_Object) or face ID
4283 u: U parameter on the face where the node is located
4284 v: V parameter on the face where the node is located
4287 True if succeed else raises an exception
4290 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4291 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4295 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4296 except SALOME.SALOME_Exception as inst:
4297 raise ValueError(inst.details.text)
4300 def SetNodeInVolume(self, NodeID, Solid):
4302 Bind a node to a solid
4306 Solid: a solid (GEOM.GEOM_Object) or solid ID
4309 True if succeed else raises an exception
4312 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4313 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4317 self.editor.SetNodeInVolume(NodeID, SolidID)
4318 except SALOME.SALOME_Exception as inst:
4319 raise ValueError(inst.details.text)
4322 def SetMeshElementOnShape(self, ElementID, Shape):
4324 Bind an element to a shape
4327 ElementID: an element ID
4328 Shape: a shape (GEOM.GEOM_Object) or shape ID
4331 True if succeed else raises an exception
4334 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4335 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4339 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4340 except SALOME.SALOME_Exception as inst:
4341 raise ValueError(inst.details.text)
4345 def MoveNode(self, NodeID, x, y, z):
4347 Move the node with the given id
4350 NodeID: the id of the node
4351 x: a new X coordinate
4352 y: a new Y coordinate
4353 z: a new Z coordinate
4356 True if succeed else False
4359 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4360 if hasVars: self.mesh.SetParameters(Parameters)
4361 return self.editor.MoveNode(NodeID, x, y, z)
4363 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4365 Find the node closest to a point and moves it to a point location
4368 x: the X coordinate of a point
4369 y: the Y coordinate of a point
4370 z: the Z coordinate of a point
4371 NodeID: if specified (>0), the node with this ID is moved,
4372 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4375 the ID of a moved node
4378 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4379 if hasVars: self.mesh.SetParameters(Parameters)
4380 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4382 def FindNodeClosestTo(self, x, y, z):
4384 Find the node closest to a point
4387 x: the X coordinate of a point
4388 y: the Y coordinate of a point
4389 z: the Z coordinate of a point
4395 return self.editor.FindNodeClosestTo(x, y, z)
4397 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4399 Find the elements where a point lays IN or ON
4402 x,y,z (float): coordinates of the point
4403 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4404 means elements of any type excluding nodes, discrete and 0D elements.
4405 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4408 list of IDs of found elements
4411 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4413 return self.editor.FindElementsByPoint(x, y, z, elementType)
4415 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4417 Project a point to a mesh object.
4418 Return ID of an element of given type where the given point is projected
4419 and coordinates of the projection point.
4420 In the case if nothing found, return -1 and []
4422 if isinstance( meshObject, Mesh ):
4423 meshObject = meshObject.GetMesh()
4425 meshObject = self.GetMesh()
4426 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4428 def GetPointState(self, x, y, z):
4430 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4431 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4432 UNKNOWN state means that either mesh is wrong or the analysis fails.
4435 return self.editor.GetPointState(x, y, z)
4437 def IsManifold(self):
4439 Check if a 2D mesh is manifold
4442 return self.editor.IsManifold()
4444 def IsCoherentOrientation2D(self):
4446 Check if orientation of 2D elements is coherent
4449 return self.editor.IsCoherentOrientation2D()
4451 def Get1DBranches( self, edges, startNode = 0 ):
4453 Partition given 1D elements into groups of contiguous edges.
4454 A node where number of meeting edges != 2 is a group end.
4455 An optional startNode is used to orient groups it belongs to.
4458 A list of edge groups and a list of corresponding node groups,
4459 where the group is a list of IDs of edges or nodes, like follows
4460 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4461 If a group is closed, the first and last nodes of the group are same.
4463 if isinstance( edges, Mesh ):
4464 edges = edges.GetMesh()
4465 unRegister = genObjUnRegister()
4466 if isinstance( edges, list ):
4467 edges = self.GetIDSource( edges, SMESH.EDGE )
4468 unRegister.set( edges )
4469 return self.editor.Get1DBranches( edges, startNode )
4471 def FindSharpEdges( self, angle, addExisting=False ):
4473 Return sharp edges of faces and non-manifold ones.
4474 Optionally add existing edges.
4477 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4478 addExisting: to return existing edges (1D elements) as well
4481 list of FaceEdge structures
4483 angle = ParseParameters( angle )[0]
4484 return self.editor.FindSharpEdges( angle, addExisting )
4486 def MeshToPassThroughAPoint(self, x, y, z):
4488 Find the node closest to a point and moves it to a point location
4491 x: the X coordinate of a point
4492 y: the Y coordinate of a point
4493 z: the Z coordinate of a point
4496 the ID of a moved node
4499 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4501 def InverseDiag(self, NodeID1, NodeID2):
4503 Replace two neighbour triangles sharing Node1-Node2 link
4504 with the triangles built on the same 4 nodes but having other common link.
4507 NodeID1: the ID of the first node
4508 NodeID2: the ID of the second node
4511 False if proper faces were not found
4513 return self.editor.InverseDiag(NodeID1, NodeID2)
4515 def DeleteDiag(self, NodeID1, NodeID2):
4517 Replace two neighbour triangles sharing *Node1-Node2* link
4518 with a quadrangle built on the same 4 nodes.
4521 NodeID1: ID of the first node
4522 NodeID2: ID of the second node
4525 False if proper faces were not found
4528 This operation can create gaps in numeration of elements.
4529 Call :meth:`RenumberElements` to remove the gaps.
4532 return self.editor.DeleteDiag(NodeID1, NodeID2)
4534 def Reorient(self, IDsOfElements=None):
4536 Reorient elements by ids
4539 IDsOfElements: if undefined reorients all mesh elements
4542 True if succeed else False
4545 if IDsOfElements == None:
4546 IDsOfElements = self.GetElementsId()
4547 return self.editor.Reorient(IDsOfElements)
4549 def ReorientObject(self, theObject):
4551 Reorient all elements of the object
4554 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4557 True if succeed else False
4560 if ( isinstance( theObject, Mesh )):
4561 theObject = theObject.GetMesh()
4562 return self.editor.ReorientObject(theObject)
4564 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4566 Reorient faces contained in *the2DObject*.
4569 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4570 theDirection: a desired direction of normal of *theFace*.
4571 It can be either a GEOM vector or a list of coordinates [x,y,z].
4572 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4573 compared with theDirection. It can be either ID of face or a point
4574 by which the face will be found. The point can be given as either
4575 a GEOM vertex or a list of point coordinates.
4578 number of reoriented faces
4581 unRegister = genObjUnRegister()
4583 if isinstance( the2DObject, Mesh ):
4584 the2DObject = the2DObject.GetMesh()
4585 if isinstance( the2DObject, list ):
4586 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4587 unRegister.set( the2DObject )
4588 # check theDirection
4589 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4590 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4591 if isinstance( theDirection, list ):
4592 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4593 # prepare theFace and thePoint
4594 theFace = theFaceOrPoint
4595 thePoint = PointStruct(0,0,0)
4596 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4597 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4599 if isinstance( theFaceOrPoint, list ):
4600 thePoint = PointStruct( *theFaceOrPoint )
4602 if isinstance( theFaceOrPoint, PointStruct ):
4603 thePoint = theFaceOrPoint
4605 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4607 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4609 Reorient faces according to adjacent volumes.
4612 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4613 either IDs of faces or face groups.
4614 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4615 theOutsideNormal: to orient faces to have their normals
4616 pointing either *outside* or *inside* the adjacent volumes.
4619 number of reoriented faces.
4622 unRegister = genObjUnRegister()
4624 if not isinstance( the2DObject, list ):
4625 the2DObject = [ the2DObject ]
4626 elif the2DObject and isinstance( the2DObject[0], int ):
4627 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4628 unRegister.set( the2DObject )
4629 the2DObject = [ the2DObject ]
4630 for i,obj2D in enumerate( the2DObject ):
4631 if isinstance( obj2D, Mesh ):
4632 the2DObject[i] = obj2D.GetMesh()
4633 if isinstance( obj2D, list ):
4634 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4635 unRegister.set( the2DObject[i] )
4637 if isinstance( the3DObject, Mesh ):
4638 the3DObject = the3DObject.GetMesh()
4639 if isinstance( the3DObject, list ):
4640 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4641 unRegister.set( the3DObject )
4642 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4644 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4646 Fuse the neighbouring triangles into quadrangles.
4649 IDsOfElements: The triangles to be fused.
4650 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4651 applied to possible quadrangles to choose a neighbour to fuse with.
4652 Note that not all items of :class:`SMESH.FunctorType` corresponds
4653 to numerical functors.
4654 MaxAngle: is the maximum angle between element normals at which the fusion
4655 is still performed; theMaxAngle is measured in radians.
4656 Also it could be a name of variable which defines angle in degrees.
4659 True in case of success, False otherwise.
4662 This operation can create gaps in numeration of elements.
4663 Call :meth:`RenumberElements` to remove the gaps.
4666 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4667 self.mesh.SetParameters(Parameters)
4668 if not IDsOfElements:
4669 IDsOfElements = self.GetElementsId()
4670 Functor = self.smeshpyD.GetFunctor(theCriterion)
4671 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4673 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4675 Fuse the neighbouring triangles of the object into quadrangles
4678 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4679 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4680 applied to possible quadrangles to choose a neighbour to fuse with.
4681 Note that not all items of :class:`SMESH.FunctorType` corresponds
4682 to numerical functors.
4683 MaxAngle: a max angle between element normals at which the fusion
4684 is still performed; theMaxAngle is measured in radians.
4687 True in case of success, False otherwise.
4690 This operation can create gaps in numeration of elements.
4691 Call :meth:`RenumberElements` to remove the gaps.
4694 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4695 self.mesh.SetParameters(Parameters)
4696 if isinstance( theObject, Mesh ):
4697 theObject = theObject.GetMesh()
4698 Functor = self.smeshpyD.GetFunctor(theCriterion)
4699 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4701 def QuadToTri (self, IDsOfElements, theCriterion = None):
4703 Split quadrangles into triangles.
4706 IDsOfElements: the faces to be splitted.
4707 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4708 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4709 value, then quadrangles will be split by the smallest diagonal.
4710 Note that not all items of :class:`SMESH.FunctorType` corresponds
4711 to numerical functors.
4714 True in case of success, False otherwise.
4717 This operation can create gaps in numeration of elements.
4718 Call :meth:`RenumberElements` to remove the gaps.
4720 if IDsOfElements == []:
4721 IDsOfElements = self.GetElementsId()
4722 if theCriterion is None:
4723 theCriterion = FT_MaxElementLength2D
4724 Functor = self.smeshpyD.GetFunctor(theCriterion)
4725 return self.editor.QuadToTri(IDsOfElements, Functor)
4727 def QuadToTriObject (self, theObject, theCriterion = None):
4729 Split quadrangles into triangles.
4732 theObject: the object from which the list of elements is taken,
4733 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4734 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4735 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4736 value, then quadrangles will be split by the smallest diagonal.
4737 Note that not all items of :class:`SMESH.FunctorType` corresponds
4738 to numerical functors.
4741 True in case of success, False otherwise.
4744 This operation can create gaps in numeration of elements.
4745 Call :meth:`RenumberElements` to remove the gaps.
4747 if ( isinstance( theObject, Mesh )):
4748 theObject = theObject.GetMesh()
4749 if theCriterion is None:
4750 theCriterion = FT_MaxElementLength2D
4751 Functor = self.smeshpyD.GetFunctor(theCriterion)
4752 return self.editor.QuadToTriObject(theObject, Functor)
4754 def QuadTo4Tri (self, theElements=[]):
4756 Split each of given quadrangles into 4 triangles. A node is added at the center of
4760 theElements: the faces to be splitted. This can be either
4761 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4762 or a list of face IDs. By default all quadrangles are split
4765 This operation can create gaps in numeration of elements.
4766 Call :meth:`RenumberElements` to remove the gaps.
4768 unRegister = genObjUnRegister()
4769 if isinstance( theElements, Mesh ):
4770 theElements = theElements.mesh
4771 elif not theElements:
4772 theElements = self.mesh
4773 elif isinstance( theElements, list ):
4774 theElements = self.GetIDSource( theElements, SMESH.FACE )
4775 unRegister.set( theElements )
4776 return self.editor.QuadTo4Tri( theElements )
4778 def SplitQuad (self, IDsOfElements, Diag13):
4780 Split quadrangles into triangles.
4783 IDsOfElements: the faces to be splitted
4784 Diag13 (boolean): is used to choose a diagonal for splitting.
4787 True in case of success, False otherwise.
4790 This operation can create gaps in numeration of elements.
4791 Call :meth:`RenumberElements` to remove the gaps.
4793 if IDsOfElements == []:
4794 IDsOfElements = self.GetElementsId()
4795 return self.editor.SplitQuad(IDsOfElements, Diag13)
4797 def SplitQuadObject (self, theObject, Diag13):
4799 Split quadrangles into triangles.
4802 theObject: the object from which the list of elements is taken,
4803 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4804 Diag13 (boolean): is used to choose a diagonal for splitting.
4807 True in case of success, False otherwise.
4810 This operation can create gaps in numeration of elements.
4811 Call :meth:`RenumberElements` to remove the gaps.
4813 if ( isinstance( theObject, Mesh )):
4814 theObject = theObject.GetMesh()
4815 return self.editor.SplitQuadObject(theObject, Diag13)
4817 def BestSplit (self, IDOfQuad, theCriterion):
4819 Find a better splitting of the given quadrangle.
4822 IDOfQuad: the ID of the quadrangle to be splitted.
4823 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4824 choose a diagonal for splitting.
4825 Note that not all items of :class:`SMESH.FunctorType` corresponds
4826 to numerical functors.
4829 * 1 if 1-3 diagonal is better,
4830 * 2 if 2-4 diagonal is better,
4831 * 0 if error occurs.
4834 This operation can create gaps in numeration of elements.
4835 Call :meth:`RenumberElements` to remove the gaps.
4837 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4839 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4841 Split volumic elements into tetrahedrons
4844 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4845 method: flags passing splitting method:
4846 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4847 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4850 This operation can create gaps in numeration of elements.
4851 Call :meth:`RenumberElements` to remove the gaps.
4853 unRegister = genObjUnRegister()
4854 if isinstance( elems, Mesh ):
4855 elems = elems.GetMesh()
4856 if ( isinstance( elems, list )):
4857 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4858 unRegister.set( elems )
4859 self.editor.SplitVolumesIntoTetra(elems, method)
4862 def SplitBiQuadraticIntoLinear(self, elems=None):
4864 Split bi-quadratic elements into linear ones without creation of additional nodes:
4866 - bi-quadratic triangle will be split into 3 linear quadrangles;
4867 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4868 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4870 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4871 will be split in order to keep the mesh conformal.
4874 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4875 if None (default), all bi-quadratic elements will be split
4878 This operation can create gaps in numeration of elements.
4879 Call :meth:`RenumberElements` to remove the gaps.
4881 unRegister = genObjUnRegister()
4882 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4883 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4884 unRegister.set( elems )
4886 elems = [ self.GetMesh() ]
4887 if isinstance( elems, Mesh ):
4888 elems = [ elems.GetMesh() ]
4889 if not isinstance( elems, list ):
4891 self.editor.SplitBiQuadraticIntoLinear( elems )
4893 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4894 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4896 Split hexahedra into prisms
4899 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4900 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4901 gives a normal vector defining facets to split into triangles.
4902 *startHexPoint* can be either a triple of coordinates or a vertex.
4903 facetNormal: a normal to a facet to split into triangles of a
4904 hexahedron found by *startHexPoint*.
4905 *facetNormal* can be either a triple of coordinates or an edge.
4906 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4907 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4908 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4909 to *startHexPoint* are split, else *startHexPoint*
4910 is used to find the facet to split in all domains present in *elems*.
4913 This operation can create gaps in numeration of elements.
4914 Call :meth:`RenumberElements` to remove the gaps.
4917 unRegister = genObjUnRegister()
4918 if isinstance( elems, Mesh ):
4919 elems = elems.GetMesh()
4920 if ( isinstance( elems, list )):
4921 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4922 unRegister.set( elems )
4925 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4926 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4927 elif isinstance( startHexPoint, list ):
4928 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4931 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4932 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4933 elif isinstance( facetNormal, list ):
4934 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4937 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4939 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4941 def SplitQuadsNearTriangularFacets(self):
4943 Split quadrangle faces near triangular facets of volumes
4946 This operation can create gaps in numeration of elements.
4947 Call :meth:`RenumberElements` to remove the gaps.
4949 faces_array = self.GetElementsByType(SMESH.FACE)
4950 for face_id in faces_array:
4951 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4952 quad_nodes = self.mesh.GetElemNodes(face_id)
4953 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4954 isVolumeFound = False
4955 for node1_elem in node1_elems:
4956 if not isVolumeFound:
4957 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4958 nb_nodes = self.GetElemNbNodes(node1_elem)
4959 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4960 volume_elem = node1_elem
4961 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4962 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4963 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4964 isVolumeFound = True
4965 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4966 self.SplitQuad([face_id], False) # diagonal 2-4
4967 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4968 isVolumeFound = True
4969 self.SplitQuad([face_id], True) # diagonal 1-3
4970 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4971 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4972 isVolumeFound = True
4973 self.SplitQuad([face_id], True) # diagonal 1-3
4975 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4977 Split hexahedrons into tetrahedrons.
4979 This operation uses :doc:`pattern_mapping` functionality for splitting.
4982 theObject: the object from which the list of hexahedrons is taken;
4983 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4984 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4985 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4986 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4987 key-point will be mapped into *theNode001*-th node of each volume.
4988 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4991 True in case of success, False otherwise.
4994 This operation can create gaps in numeration of elements.
4995 Call :meth:`RenumberElements` to remove the gaps.
5003 # (0,0,1) 4.---------.7 * |
5010 # (0,0,0) 0.---------.3
5011 pattern_tetra = "!!! Nb of points: \n 8 \n\
5021 !!! Indices of points of 6 tetras: \n\
5029 pattern = self.smeshpyD.GetPattern()
5030 isDone = pattern.LoadFromFile(pattern_tetra)
5032 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5035 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5036 isDone = pattern.MakeMesh(self.mesh, False, False)
5037 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5039 # split quafrangle faces near triangular facets of volumes
5040 self.SplitQuadsNearTriangularFacets()
5044 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5046 Split hexahedrons into prisms.
5048 Uses the :doc:`pattern_mapping` functionality for splitting.
5051 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5052 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5053 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5054 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5055 will be mapped into the *theNode001* -th node of each volume.
5056 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5059 True in case of success, False otherwise.
5062 This operation can create gaps in numeration of elements.
5063 Call :meth:`RenumberElements` to remove the gaps.
5065 # Pattern: 5.---------.6
5070 # (0,0,1) 4.---------.7 |
5077 # (0,0,0) 0.---------.3
5078 pattern_prism = "!!! Nb of points: \n 8 \n\
5088 !!! Indices of points of 2 prisms: \n\
5092 pattern = self.smeshpyD.GetPattern()
5093 isDone = pattern.LoadFromFile(pattern_prism)
5095 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5098 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5099 isDone = pattern.MakeMesh(self.mesh, False, False)
5100 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5102 # Split quafrangle faces near triangular facets of volumes
5103 self.SplitQuadsNearTriangularFacets()
5107 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5108 MaxNbOfIterations, MaxAspectRatio, Method):
5113 IDsOfElements: the list if ids of elements to smooth
5114 IDsOfFixedNodes: the list of ids of fixed nodes.
5115 Note that nodes built on edges and boundary nodes are always fixed.
5116 MaxNbOfIterations: the maximum number of iterations
5117 MaxAspectRatio: varies in range [1.0, inf]
5118 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5119 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5122 True in case of success, False otherwise.
5125 if IDsOfElements == []:
5126 IDsOfElements = self.GetElementsId()
5127 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5128 self.mesh.SetParameters(Parameters)
5129 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5130 MaxNbOfIterations, MaxAspectRatio, Method)
5132 def SmoothObject(self, theObject, IDsOfFixedNodes,
5133 MaxNbOfIterations, MaxAspectRatio, Method):
5135 Smooth elements which belong to the given object
5138 theObject: the object to smooth
5139 IDsOfFixedNodes: the list of ids of fixed nodes.
5140 Note that nodes built on edges and boundary nodes are always fixed.
5141 MaxNbOfIterations: the maximum number of iterations
5142 MaxAspectRatio: varies in range [1.0, inf]
5143 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5144 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5147 True in case of success, False otherwise.
5150 if ( isinstance( theObject, Mesh )):
5151 theObject = theObject.GetMesh()
5152 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5153 MaxNbOfIterations, MaxAspectRatio, Method)
5155 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5156 MaxNbOfIterations, MaxAspectRatio, Method):
5158 Parametrically smooth the given elements
5161 IDsOfElements: the list if ids of elements to smooth
5162 IDsOfFixedNodes: the list of ids of fixed nodes.
5163 Note that nodes built on edges and boundary nodes are always fixed.
5164 MaxNbOfIterations: the maximum number of iterations
5165 MaxAspectRatio: varies in range [1.0, inf]
5166 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5167 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5170 True in case of success, False otherwise.
5173 if IDsOfElements == []:
5174 IDsOfElements = self.GetElementsId()
5175 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5176 self.mesh.SetParameters(Parameters)
5177 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5178 MaxNbOfIterations, MaxAspectRatio, Method)
5180 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5181 MaxNbOfIterations, MaxAspectRatio, Method):
5183 Parametrically smooth the elements which belong to the given object
5186 theObject: the object to smooth
5187 IDsOfFixedNodes: the list of ids of fixed nodes.
5188 Note that nodes built on edges and boundary nodes are always fixed.
5189 MaxNbOfIterations: the maximum number of iterations
5190 MaxAspectRatio: varies in range [1.0, inf]
5191 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5192 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5195 True in case of success, False otherwise.
5198 if ( isinstance( theObject, Mesh )):
5199 theObject = theObject.GetMesh()
5200 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5201 MaxNbOfIterations, MaxAspectRatio, Method)
5203 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5205 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5206 them with quadratic with the same id.
5209 theForce3d: method of new node creation:
5211 * False - the medium node lies at the geometrical entity from which the mesh element is built
5212 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5213 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5214 theToBiQuad: If True, converts the mesh to bi-quadratic
5217 :class:`SMESH.ComputeError` which can hold a warning
5220 If *theSubMesh* is provided, the mesh can become non-conformal
5223 This operation can create gaps in numeration of nodes or elements.
5224 Call :meth:`RenumberElements` to remove the gaps.
5227 if isinstance( theSubMesh, Mesh ):
5228 theSubMesh = theSubMesh.mesh
5230 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5233 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5235 self.editor.ConvertToQuadratic(theForce3d)
5236 error = self.editor.GetLastError()
5237 if error and error.comment:
5238 print(error.comment)
5241 def ConvertFromQuadratic(self, theSubMesh=None):
5243 Convert the mesh from quadratic to ordinary,
5244 deletes old quadratic elements,
5245 replacing them with ordinary mesh elements with the same id.
5248 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5251 If *theSubMesh* is provided, the mesh can become non-conformal
5254 This operation can create gaps in numeration of nodes or elements.
5255 Call :meth:`RenumberElements` to remove the gaps.
5259 self.editor.ConvertFromQuadraticObject(theSubMesh)
5261 return self.editor.ConvertFromQuadratic()
5263 def Make2DMeshFrom3D(self):
5265 Create 2D mesh as skin on boundary faces of a 3D mesh
5268 True if operation has been completed successfully, False otherwise
5271 return self.editor.Make2DMeshFrom3D()
5273 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5274 toCopyElements=False, toCopyExistingBondary=False):
5276 Create missing boundary elements
5279 elements: elements whose boundary is to be checked:
5280 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5281 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5282 dimension: defines type of boundary elements to create, either of
5283 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5284 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5285 groupName: a name of group to store created boundary elements in,
5286 "" means not to create the group
5287 meshName: a name of new mesh to store created boundary elements in,
5288 "" means not to create the new mesh
5289 toCopyElements: if True, the checked elements will be copied into
5290 the new mesh else only boundary elements will be copied into the new mesh
5291 toCopyExistingBondary: if True, not only new but also pre-existing
5292 boundary elements will be copied into the new mesh
5295 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5298 unRegister = genObjUnRegister()
5299 if isinstance( elements, Mesh ):
5300 elements = elements.GetMesh()
5301 if ( isinstance( elements, list )):
5302 elemType = SMESH.ALL
5303 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5304 elements = self.editor.MakeIDSource(elements, elemType)
5305 unRegister.set( elements )
5306 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5307 toCopyElements,toCopyExistingBondary)
5308 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5311 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5312 toCopyAll=False, groups=[]):
5314 Create missing boundary elements around either the whole mesh or
5318 dimension: defines type of boundary elements to create, either of
5319 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5320 groupName: a name of group to store all boundary elements in,
5321 "" means not to create the group
5322 meshName: a name of a new mesh, which is a copy of the initial
5323 mesh + created boundary elements; "" means not to create the new mesh
5324 toCopyAll: if True, the whole initial mesh will be copied into
5325 the new mesh else only boundary elements will be copied into the new mesh
5326 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5329 tuple( long, mesh, group )
5330 - long - number of added boundary elements
5331 - mesh - the :class:`Mesh` where elements were added to
5332 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5335 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5337 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5338 return nb, mesh, group
5340 def RenumberNodes(self):
5342 Renumber mesh nodes to remove unused node IDs
5344 self.editor.RenumberNodes()
5346 def RenumberElements(self):
5348 Renumber mesh elements to remove unused element IDs
5350 self.editor.RenumberElements()
5352 def _getIdSourceList(self, arg, idType, unRegister):
5354 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5356 if arg and isinstance( arg, list ):
5357 if isinstance( arg[0], int ):
5358 arg = self.GetIDSource( arg, idType )
5359 unRegister.set( arg )
5360 elif isinstance( arg[0], Mesh ):
5361 arg[0] = arg[0].GetMesh()
5362 elif isinstance( arg, Mesh ):
5364 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5368 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5369 MakeGroups=False, TotalAngle=False):
5371 Generate new elements by rotation of the given elements and nodes around the axis
5374 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5375 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5376 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5377 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5378 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5379 which defines angle in degrees
5380 NbOfSteps: the number of steps
5381 Tolerance: tolerance
5382 MakeGroups: forces the generation of new groups from existing ones
5383 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5384 of all steps, else - size of each step
5387 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5390 unRegister = genObjUnRegister()
5391 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5392 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5393 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5395 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5396 Axis = self.smeshpyD.GetAxisStruct( Axis )
5397 if isinstance( Axis, list ):
5398 Axis = SMESH.AxisStruct( *Axis )
5400 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5401 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5402 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5403 self.mesh.SetParameters(Parameters)
5404 if TotalAngle and NbOfSteps:
5405 AngleInRadians /= NbOfSteps
5406 return self.editor.RotationSweepObjects( nodes, edges, faces,
5407 Axis, AngleInRadians,
5408 NbOfSteps, Tolerance, MakeGroups)
5410 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5411 MakeGroups=False, TotalAngle=False):
5413 Generate new elements by rotation of the elements around the axis
5416 IDsOfElements: the list of ids of elements to sweep
5417 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5418 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5419 NbOfSteps: the number of steps
5420 Tolerance: tolerance
5421 MakeGroups: forces the generation of new groups from existing ones
5422 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5423 of all steps, else - size of each step
5426 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5429 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5430 AngleInRadians, NbOfSteps, Tolerance,
5431 MakeGroups, TotalAngle)
5433 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5434 MakeGroups=False, TotalAngle=False):
5436 Generate new elements by rotation of the elements of object around the axis
5437 theObject object which elements should be sweeped.
5438 It can be a mesh, a sub mesh or a group.
5441 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5442 AngleInRadians: the angle of Rotation
5443 NbOfSteps: number of steps
5444 Tolerance: tolerance
5445 MakeGroups: forces the generation of new groups from existing ones
5446 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5447 of all steps, else - size of each step
5450 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5453 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5454 AngleInRadians, NbOfSteps, Tolerance,
5455 MakeGroups, TotalAngle )
5457 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5458 MakeGroups=False, TotalAngle=False):
5460 Generate new elements by rotation of the elements of object around the axis
5461 theObject object which elements should be sweeped.
5462 It can be a mesh, a sub mesh or a group.
5465 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5466 AngleInRadians: the angle of Rotation
5467 NbOfSteps: number of steps
5468 Tolerance: tolerance
5469 MakeGroups: forces the generation of new groups from existing ones
5470 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5471 of all steps, else - size of each step
5474 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5475 empty list otherwise
5478 return self.RotationSweepObjects([],theObject,[], Axis,
5479 AngleInRadians, NbOfSteps, Tolerance,
5480 MakeGroups, TotalAngle)
5482 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5483 MakeGroups=False, TotalAngle=False):
5485 Generate new elements by rotation of the elements of object around the axis
5486 theObject object which elements should be sweeped.
5487 It can be a mesh, a sub mesh or a group.
5490 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5491 AngleInRadians: the angle of Rotation
5492 NbOfSteps: number of steps
5493 Tolerance: tolerance
5494 MakeGroups: forces the generation of new groups from existing ones
5495 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5496 of all steps, else - size of each step
5499 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5502 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5503 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5505 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5506 scaleFactors=[], linearVariation=False, basePoint=[],
5507 angles=[], anglesVariation=False):
5509 Generate new elements by extrusion of the given elements and nodes
5512 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5513 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5514 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5515 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5516 the direction and value of extrusion for one step (the total extrusion
5517 length will be NbOfSteps * ||StepVector||)
5518 NbOfSteps: the number of steps
5519 MakeGroups: forces the generation of new groups from existing ones
5520 scaleFactors: optional scale factors to apply during extrusion
5521 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5522 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5523 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5524 nodes and elements being extruded is used as the scaling center.
5527 - a list of tree components of the point or
5530 angles: list of angles in radians. Nodes at each extrusion step are rotated
5531 around *basePoint*, additionally to previous steps.
5532 anglesVariation: forces the computation of rotation angles as linear
5533 variation of the given *angles* along path steps
5535 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5537 Example: :ref:`tui_extrusion`
5539 unRegister = genObjUnRegister()
5540 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5541 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5542 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5544 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5545 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5546 if isinstance( StepVector, list ):
5547 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5549 if isinstance( basePoint, int):
5550 xyz = self.GetNodeXYZ( basePoint )
5552 raise RuntimeError("Invalid node ID: %s" % basePoint)
5554 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5555 basePoint = self.geompyD.PointCoordinates( basePoint )
5557 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5558 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5559 angles,angleParameters,hasVars = ParseAngles(angles)
5560 Parameters = StepVector.PS.parameters + var_separator + \
5561 Parameters + var_separator + \
5562 scaleParameters + var_separator + angleParameters
5563 self.mesh.SetParameters(Parameters)
5565 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5566 StepVector, NbOfSteps, MakeGroups,
5567 scaleFactors, linearVariation, basePoint,
5568 angles, anglesVariation )
5571 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5573 Generate new elements by extrusion of the elements with given ids
5576 IDsOfElements: the list of ids of elements or nodes for extrusion
5577 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5578 the direction and value of extrusion for one step (the total extrusion
5579 length will be NbOfSteps * ||StepVector||)
5580 NbOfSteps: the number of steps
5581 MakeGroups: forces the generation of new groups from existing ones
5582 IsNodes: is True if elements with given ids are nodes
5585 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5587 Example: :ref:`tui_extrusion`
5590 if IsNodes: n = IDsOfElements
5591 else : e,f, = IDsOfElements,IDsOfElements
5592 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5594 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5595 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5597 Generate new elements by extrusion along the normal to a discretized surface or wire
5600 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5601 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5602 StepSize: length of one extrusion step (the total extrusion
5603 length will be *NbOfSteps* *StepSize*).
5604 NbOfSteps: number of extrusion steps.
5605 ByAverageNormal: if True each node is translated by *StepSize*
5606 along the average of the normal vectors to the faces sharing the node;
5607 else each node is translated along the same average normal till
5608 intersection with the plane got by translation of the face sharing
5609 the node along its own normal by *StepSize*.
5610 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5611 for every node of *Elements*.
5612 MakeGroups: forces generation of new groups from existing ones.
5613 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5614 is not yet implemented. This parameter is used if *Elements* contains
5615 both faces and edges, i.e. *Elements* is a Mesh.
5618 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5619 empty list otherwise.
5620 Example: :ref:`tui_extrusion`
5623 unRegister = genObjUnRegister()
5624 if isinstance( Elements, Mesh ):
5625 Elements = [ Elements.GetMesh() ]
5626 if isinstance( Elements, list ):
5628 raise RuntimeError("Elements empty!")
5629 if isinstance( Elements[0], Mesh ):
5630 Elements = [ Elements[0].GetMesh() ]
5631 if isinstance( Elements[0], int ):
5632 Elements = self.GetIDSource( Elements, SMESH.ALL )
5633 unRegister.set( Elements )
5634 if not isinstance( Elements, list ):
5635 Elements = [ Elements ]
5636 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5637 self.mesh.SetParameters(Parameters)
5638 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5639 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5641 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5643 Generate new elements by extrusion of the elements or nodes which belong to the object
5646 theObject: the object whose elements or nodes should be processed.
5647 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5648 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5649 the direction and value of extrusion for one step (the total extrusion
5650 length will be NbOfSteps * ||StepVector||)
5651 NbOfSteps: the number of steps
5652 MakeGroups: forces the generation of new groups from existing ones
5653 IsNodes: is True if elements to extrude are nodes
5656 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5657 Example: :ref:`tui_extrusion`
5661 if IsNodes: n = theObject
5662 else : e,f, = theObject,theObject
5663 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5665 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5667 Generate new elements by extrusion of edges which belong to the object
5670 theObject: object whose 1D elements should be processed.
5671 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5672 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5673 the direction and value of extrusion for one step (the total extrusion
5674 length will be NbOfSteps * ||StepVector||)
5675 NbOfSteps: the number of steps
5676 MakeGroups: to generate new groups from existing ones
5679 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5680 Example: :ref:`tui_extrusion`
5683 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5685 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5687 Generate new elements by extrusion of faces which belong to the object
5690 theObject: object whose 2D elements should be processed.
5691 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5692 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5693 the direction and value of extrusion for one step (the total extrusion
5694 length will be NbOfSteps * ||StepVector||)
5695 NbOfSteps: the number of steps
5696 MakeGroups: forces the generation of new groups from existing ones
5699 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5700 Example: :ref:`tui_extrusion`
5703 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5705 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5706 ExtrFlags, SewTolerance, MakeGroups=False):
5708 Generate new elements by extrusion of the elements with given ids
5711 IDsOfElements: is ids of elements
5712 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5713 the direction and value of extrusion for one step (the total extrusion
5714 length will be NbOfSteps * ||StepVector||)
5715 NbOfSteps: the number of steps
5716 ExtrFlags: sets flags for extrusion
5717 SewTolerance: uses for comparing locations of nodes if flag
5718 EXTRUSION_FLAG_SEW is set
5719 MakeGroups: forces the generation of new groups from existing ones
5722 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5725 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5726 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5727 if isinstance( StepVector, list ):
5728 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5729 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5730 ExtrFlags, SewTolerance, MakeGroups)
5732 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5733 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5734 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5735 ScaleFactors=[], ScalesVariation=False):
5737 Generate new elements by extrusion of the given elements and nodes along the path.
5738 The path of extrusion must be a meshed edge.
5741 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5742 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5743 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5744 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5745 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
5746 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5747 HasAngles: not used obsolete
5748 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5749 around *basePoint*, additionally to previous steps.
5750 LinearVariation: forces the computation of rotation angles as linear
5751 variation of the given Angles along path steps
5752 HasRefPoint: allows using the reference point
5753 RefPoint: optional scaling and rotation center (mass center of the extruded
5754 elements by default). The User can specify any point as the Reference Point.
5755 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5756 MakeGroups: forces the generation of new groups from existing ones
5757 ScaleFactors: optional scale factors to apply during extrusion
5758 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5759 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5762 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5763 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5764 Example: :ref:`tui_extrusion_along_path`
5767 unRegister = genObjUnRegister()
5768 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5769 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5770 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5772 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5773 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5774 if isinstance( RefPoint, list ):
5775 if not RefPoint: RefPoint = [0,0,0]
5776 RefPoint = SMESH.PointStruct( *RefPoint )
5777 if isinstance( PathObject, Mesh ):
5778 PathObject = PathObject.GetMesh()
5779 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5780 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5781 Parameters = AnglesParameters + var_separator + \
5782 RefPoint.parameters + var_separator + ScalesParameters
5783 self.mesh.SetParameters(Parameters)
5784 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5785 PathObject, PathShape, NodeStart,
5786 HasAngles, Angles, LinearVariation,
5787 HasRefPoint, RefPoint, MakeGroups,
5788 ScaleFactors, ScalesVariation)
5790 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5791 HasAngles=False, Angles=[], LinearVariation=False,
5792 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5793 ElemType=SMESH.FACE):
5795 Generate new elements by extrusion of the given elements.
5796 The path of extrusion must be a meshed edge.
5799 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5800 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5801 NodeStart: the start node from Path. Defines the direction of extrusion
5802 HasAngles: not used obsolete
5803 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5804 around *basePoint*, additionally to previous steps.
5805 LinearVariation: forces the computation of rotation angles as linear
5806 variation of the given Angles along path steps
5807 HasRefPoint: allows using the reference point
5808 RefPoint: the reference point around which the elements are rotated (the mass
5809 center of the elements by default).
5810 The User can specify any point as the Reference Point.
5811 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5812 MakeGroups: forces the generation of new groups from existing ones
5813 ElemType: type of elements for extrusion (if param Base is a mesh)
5816 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5817 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5818 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5820 Example: :ref:`tui_extrusion_along_path`
5824 if ElemType == SMESH.NODE: n = Base
5825 if ElemType == SMESH.EDGE: e = Base
5826 if ElemType == SMESH.FACE: f = Base
5827 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5828 HasAngles, Angles, LinearVariation,
5829 HasRefPoint, RefPoint, MakeGroups)
5830 if MakeGroups: return gr,er
5833 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5834 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5835 MakeGroups=False, LinearVariation=False):
5837 Generate new elements by extrusion of the given elements.
5838 The path of extrusion must be a meshed edge.
5841 IDsOfElements: ids of elements
5842 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5843 PathShape: shape (edge) defines the sub-mesh for the path
5844 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5845 HasAngles: not used obsolete
5846 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5847 around *basePoint*, additionally to previous steps.
5848 HasRefPoint: allows using the reference point
5849 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5850 The User can specify any point as the Reference Point.
5851 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5852 MakeGroups: forces the generation of new groups from existing ones
5853 LinearVariation: forces the computation of rotation angles as linear
5854 variation of the given Angles along path steps
5857 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5858 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5859 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5860 Example: :ref:`tui_extrusion_along_path`
5863 if not IDsOfElements:
5864 IDsOfElements = [ self.GetMesh() ]
5865 n,e,f = [],IDsOfElements,IDsOfElements
5866 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5867 NodeStart, HasAngles, Angles,
5869 HasRefPoint, RefPoint, MakeGroups)
5870 if MakeGroups: return gr,er
5873 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5874 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5875 MakeGroups=False, LinearVariation=False):
5877 Generate new elements by extrusion of the elements which belong to the object.
5878 The path of extrusion must be a meshed edge.
5881 theObject: the object whose elements should be processed.
5882 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5883 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5884 PathShape: shape (edge) defines the sub-mesh for the path
5885 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5886 HasAngles: not used obsolete
5887 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5888 around *basePoint*, additionally to previous steps.
5889 HasRefPoint: allows using the reference point
5890 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5891 The User can specify any point as the Reference Point.
5892 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5893 MakeGroups: forces the generation of new groups from existing ones
5894 LinearVariation: forces the computation of rotation angles as linear
5895 variation of the given Angles along path steps
5898 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5899 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5900 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5901 Example: :ref:`tui_extrusion_along_path`
5904 n,e,f = [],theObject,theObject
5905 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5906 HasAngles, Angles, LinearVariation,
5907 HasRefPoint, RefPoint, MakeGroups)
5908 if MakeGroups: return gr,er
5911 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5912 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5913 MakeGroups=False, LinearVariation=False):
5915 Generate new elements by extrusion of mesh segments which belong to the object.
5916 The path of extrusion must be a meshed edge.
5919 theObject: the object whose 1D elements should be processed.
5920 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5921 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5922 PathShape: shape (edge) defines the sub-mesh for the path
5923 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5924 HasAngles: not used obsolete
5925 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5926 around *basePoint*, additionally to previous steps.
5927 HasRefPoint: allows using the reference point
5928 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5929 The User can specify any point as the Reference Point.
5930 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5931 MakeGroups: forces the generation of new groups from existing ones
5932 LinearVariation: forces the computation of rotation angles as linear
5933 variation of the given Angles along path steps
5936 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5937 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5938 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5939 Example: :ref:`tui_extrusion_along_path`
5942 n,e,f = [],theObject,[]
5943 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5944 HasAngles, Angles, LinearVariation,
5945 HasRefPoint, RefPoint, MakeGroups)
5946 if MakeGroups: return gr,er
5949 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5950 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5951 MakeGroups=False, LinearVariation=False):
5953 Generate new elements by extrusion of faces which belong to the object.
5954 The path of extrusion must be a meshed edge.
5957 theObject: the object whose 2D elements should be processed.
5958 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5959 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5960 PathShape: shape (edge) defines the sub-mesh for the path
5961 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5962 HasAngles: not used obsolete
5963 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5964 around *basePoint*, additionally to previous steps.
5965 HasRefPoint: allows using the reference point
5966 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5967 The User can specify any point as the Reference Point.
5968 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5969 MakeGroups: forces the generation of new groups from existing ones
5970 LinearVariation: forces the computation of rotation angles as linear
5971 variation of the given Angles along path steps
5974 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5975 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5976 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5977 Example: :ref:`tui_extrusion_along_path`
5980 n,e,f = [],[],theObject
5981 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5982 HasAngles, Angles, LinearVariation,
5983 HasRefPoint, RefPoint, MakeGroups)
5984 if MakeGroups: return gr,er
5987 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5989 Create a symmetrical copy of mesh elements
5992 IDsOfElements: list of elements ids
5993 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5994 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5995 If the *Mirror* is a geom object this parameter is unnecessary
5996 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5997 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6000 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6003 if IDsOfElements == []:
6004 IDsOfElements = self.GetElementsId()
6005 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6006 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6007 theMirrorType = Mirror._mirrorType
6009 self.mesh.SetParameters(Mirror.parameters)
6010 if Copy and MakeGroups:
6011 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6012 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6015 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6017 Create a new mesh by a symmetrical copy of mesh elements
6020 IDsOfElements: the list of elements ids
6021 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6022 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6023 If the *Mirror* is a geom object this parameter is unnecessary
6024 MakeGroups: to generate new groups from existing ones
6025 NewMeshName: a name of the new mesh to create
6028 instance of class :class:`Mesh`
6031 if IDsOfElements == []:
6032 IDsOfElements = self.GetElementsId()
6033 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6034 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6035 theMirrorType = Mirror._mirrorType
6037 self.mesh.SetParameters(Mirror.parameters)
6038 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6039 MakeGroups, NewMeshName)
6040 return Mesh(self.smeshpyD,self.geompyD,mesh)
6042 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6044 Create a symmetrical copy of the object
6047 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6048 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6049 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6050 If the *Mirror* is a geom object this parameter is unnecessary
6051 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6052 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6055 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6058 if ( isinstance( theObject, Mesh )):
6059 theObject = theObject.GetMesh()
6060 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6061 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6062 theMirrorType = Mirror._mirrorType
6064 self.mesh.SetParameters(Mirror.parameters)
6065 if Copy and MakeGroups:
6066 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6067 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6070 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6072 Create a new mesh by a symmetrical copy of the object
6075 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6076 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6077 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6078 If the *Mirror* is a geom object this parameter is unnecessary
6079 MakeGroups: forces the generation of new groups from existing ones
6080 NewMeshName: the name of the new mesh to create
6083 instance of class :class:`Mesh`
6086 if ( isinstance( theObject, Mesh )):
6087 theObject = theObject.GetMesh()
6088 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6089 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6090 theMirrorType = Mirror._mirrorType
6092 self.mesh.SetParameters(Mirror.parameters)
6093 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6094 MakeGroups, NewMeshName)
6095 return Mesh( self.smeshpyD,self.geompyD,mesh )
6097 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6099 Translate the elements
6102 IDsOfElements: list of elements ids
6103 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6104 Copy: allows copying the translated elements
6105 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6108 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6111 if IDsOfElements == []:
6112 IDsOfElements = self.GetElementsId()
6113 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6114 Vector = self.smeshpyD.GetDirStruct(Vector)
6115 if isinstance( Vector, list ):
6116 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6117 self.mesh.SetParameters(Vector.PS.parameters)
6118 if Copy and MakeGroups:
6119 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6120 self.editor.Translate(IDsOfElements, Vector, Copy)
6123 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6125 Create a new mesh of translated elements
6128 IDsOfElements: list of elements ids
6129 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6130 MakeGroups: forces the generation of new groups from existing ones
6131 NewMeshName: the name of the newly created mesh
6134 instance of class :class:`Mesh`
6137 if IDsOfElements == []:
6138 IDsOfElements = self.GetElementsId()
6139 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6140 Vector = self.smeshpyD.GetDirStruct(Vector)
6141 if isinstance( Vector, list ):
6142 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6143 self.mesh.SetParameters(Vector.PS.parameters)
6144 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6145 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6147 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6149 Translate the object
6152 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6153 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6154 Copy: allows copying the translated elements
6155 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6158 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6161 if ( isinstance( theObject, Mesh )):
6162 theObject = theObject.GetMesh()
6163 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6164 Vector = self.smeshpyD.GetDirStruct(Vector)
6165 if isinstance( Vector, list ):
6166 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6167 self.mesh.SetParameters(Vector.PS.parameters)
6168 if Copy and MakeGroups:
6169 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6170 self.editor.TranslateObject(theObject, Vector, Copy)
6173 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6175 Create a new mesh from the translated object
6178 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6179 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6180 MakeGroups: forces the generation of new groups from existing ones
6181 NewMeshName: the name of the newly created mesh
6184 instance of class :class:`Mesh`
6187 if isinstance( theObject, Mesh ):
6188 theObject = theObject.GetMesh()
6189 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6190 Vector = self.smeshpyD.GetDirStruct(Vector)
6191 if isinstance( Vector, list ):
6192 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6193 self.mesh.SetParameters(Vector.PS.parameters)
6194 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6195 return Mesh( self.smeshpyD, self.geompyD, mesh )
6199 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6204 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6205 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6206 theScaleFact: list of 1-3 scale factors for axises
6207 Copy: allows copying the translated elements
6208 MakeGroups: forces the generation of new groups from existing
6212 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6213 empty list otherwise
6215 unRegister = genObjUnRegister()
6216 if ( isinstance( theObject, Mesh )):
6217 theObject = theObject.GetMesh()
6218 if ( isinstance( theObject, list )):
6219 theObject = self.GetIDSource(theObject, SMESH.ALL)
6220 unRegister.set( theObject )
6221 if ( isinstance( thePoint, list )):
6222 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6223 if ( isinstance( theScaleFact, float )):
6224 theScaleFact = [theScaleFact]
6225 if ( isinstance( theScaleFact, int )):
6226 theScaleFact = [ float(theScaleFact)]
6228 self.mesh.SetParameters(thePoint.parameters)
6230 if Copy and MakeGroups:
6231 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6232 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6235 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6237 Create a new mesh from the translated object
6240 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6241 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6242 theScaleFact: list of 1-3 scale factors for axises
6243 MakeGroups: forces the generation of new groups from existing ones
6244 NewMeshName: the name of the newly created mesh
6247 instance of class :class:`Mesh`
6249 unRegister = genObjUnRegister()
6250 if (isinstance(theObject, Mesh)):
6251 theObject = theObject.GetMesh()
6252 if ( isinstance( theObject, list )):
6253 theObject = self.GetIDSource(theObject,SMESH.ALL)
6254 unRegister.set( theObject )
6255 if ( isinstance( thePoint, list )):
6256 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6257 if ( isinstance( theScaleFact, float )):
6258 theScaleFact = [theScaleFact]
6259 if ( isinstance( theScaleFact, int )):
6260 theScaleFact = [ float(theScaleFact)]
6262 self.mesh.SetParameters(thePoint.parameters)
6263 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6264 MakeGroups, NewMeshName)
6265 return Mesh( self.smeshpyD, self.geompyD, mesh )
6269 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6274 IDsOfElements: list of elements ids
6275 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6276 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6277 Copy: allows copying the rotated elements
6278 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6281 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6285 if IDsOfElements == []:
6286 IDsOfElements = self.GetElementsId()
6287 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6288 Axis = self.smeshpyD.GetAxisStruct(Axis)
6289 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6290 Parameters = Axis.parameters + var_separator + Parameters
6291 self.mesh.SetParameters(Parameters)
6292 if Copy and MakeGroups:
6293 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6294 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6297 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6299 Create a new mesh of rotated elements
6302 IDsOfElements: list of element ids
6303 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6304 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6305 MakeGroups: forces the generation of new groups from existing ones
6306 NewMeshName: the name of the newly created mesh
6309 instance of class :class:`Mesh`
6312 if IDsOfElements == []:
6313 IDsOfElements = self.GetElementsId()
6314 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6315 Axis = self.smeshpyD.GetAxisStruct(Axis)
6316 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6317 Parameters = Axis.parameters + var_separator + Parameters
6318 self.mesh.SetParameters(Parameters)
6319 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6320 MakeGroups, NewMeshName)
6321 return Mesh( self.smeshpyD, self.geompyD, mesh )
6323 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6328 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6329 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6330 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6331 Copy: allows copying the rotated elements
6332 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6335 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6338 if (isinstance(theObject, Mesh)):
6339 theObject = theObject.GetMesh()
6340 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6341 Axis = self.smeshpyD.GetAxisStruct(Axis)
6342 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6343 Parameters = Axis.parameters + ":" + Parameters
6344 self.mesh.SetParameters(Parameters)
6345 if Copy and MakeGroups:
6346 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6347 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6350 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6352 Create a new mesh from the rotated object
6355 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6356 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6357 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6358 MakeGroups: forces the generation of new groups from existing ones
6359 NewMeshName: the name of the newly created mesh
6362 instance of class :class:`Mesh`
6365 if (isinstance( theObject, Mesh )):
6366 theObject = theObject.GetMesh()
6367 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6368 Axis = self.smeshpyD.GetAxisStruct(Axis)
6369 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6370 Parameters = Axis.parameters + ":" + Parameters
6371 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6372 MakeGroups, NewMeshName)
6373 self.mesh.SetParameters(Parameters)
6374 return Mesh( self.smeshpyD, self.geompyD, mesh )
6376 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6378 Create an offset mesh from the given 2D object
6381 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6382 theValue (float): signed offset size
6383 MakeGroups (boolean): forces the generation of new groups from existing ones
6384 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6385 False means to remove original elements.
6386 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6389 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6392 if isinstance( theObject, Mesh ):
6393 theObject = theObject.GetMesh()
6394 theValue,Parameters,hasVars = ParseParameters(Value)
6395 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6396 self.mesh.SetParameters(Parameters)
6398 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6401 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6403 Find groups of adjacent nodes within Tolerance.
6406 Tolerance (float): the value of tolerance
6407 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6408 corner and medium nodes in separate groups thus preventing
6409 their further merge.
6412 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6415 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6417 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6418 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6420 Find groups of adjacent nodes within Tolerance.
6423 Tolerance: the value of tolerance
6424 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6425 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6426 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6427 corner and medium nodes in separate groups thus preventing
6428 their further merge.
6431 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6434 unRegister = genObjUnRegister()
6435 if not isinstance( SubMeshOrGroup, list ):
6436 SubMeshOrGroup = [ SubMeshOrGroup ]
6437 for i,obj in enumerate( SubMeshOrGroup ):
6438 if isinstance( obj, Mesh ):
6439 SubMeshOrGroup = [ obj.GetMesh() ]
6441 if isinstance( obj, int ):
6442 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6443 unRegister.set( SubMeshOrGroup )
6446 if not isinstance( exceptNodes, list ):
6447 exceptNodes = [ exceptNodes ]
6448 if exceptNodes and isinstance( exceptNodes[0], int ):
6449 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6450 unRegister.set( exceptNodes )
6452 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6453 exceptNodes, SeparateCornerAndMediumNodes)
6455 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6460 GroupsOfNodes: a list of groups of nodes IDs for merging.
6461 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6462 in all elements and mesh groups by nodes 1 and 25 correspondingly
6463 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6464 If *NodesToKeep* does not include a node to keep for some group to merge,
6465 then the first node in the group is kept.
6466 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6470 This operation can create gaps in numeration of nodes or elements.
6471 Call :meth:`RenumberElements` to remove the gaps.
6473 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6475 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6477 Find the elements built on the same nodes.
6480 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6481 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6485 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6488 unRegister = genObjUnRegister()
6489 if MeshOrSubMeshOrGroup is None:
6490 MeshOrSubMeshOrGroup = [ self.mesh ]
6491 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6492 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6493 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6494 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6495 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6496 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6497 unRegister.set( MeshOrSubMeshOrGroup )
6498 for item in MeshOrSubMeshOrGroup:
6499 if isinstance( item, Mesh ):
6500 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6502 if not isinstance( exceptElements, list ):
6503 exceptElements = [ exceptElements ]
6504 if exceptElements and isinstance( exceptElements[0], int ):
6505 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6506 unRegister.set( exceptElements )
6508 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6510 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6512 Merge elements in each given group.
6515 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6516 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6517 replaced in all mesh groups by elements 1 and 25)
6518 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6519 If *ElementsToKeep* does not include an element to keep for some group to merge,
6520 then the first element in the group is kept.
6523 This operation can create gaps in numeration of elements.
6524 Call :meth:`RenumberElements` to remove the gaps.
6527 unRegister = genObjUnRegister()
6529 if not isinstance( ElementsToKeep, list ):
6530 ElementsToKeep = [ ElementsToKeep ]
6531 if isinstance( ElementsToKeep[0], int ):
6532 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6533 unRegister.set( ElementsToKeep )
6535 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6537 def MergeEqualElements(self):
6539 Leave one element and remove all other elements built on the same nodes.
6542 This operation can create gaps in numeration of elements.
6543 Call :meth:`RenumberElements` to remove the gaps.
6546 self.editor.MergeEqualElements()
6548 def FindFreeBorders(self, ClosedOnly=True):
6550 Returns all or only closed free borders
6553 list of SMESH.FreeBorder's
6556 return self.editor.FindFreeBorders( ClosedOnly )
6558 def FillHole(self, holeNodes, groupName=""):
6560 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6563 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6564 must describe all sequential nodes of the hole border. The first and the last
6565 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6566 groupName (string): name of a group to add new faces
6568 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6572 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6573 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6574 if not isinstance( holeNodes, SMESH.FreeBorder ):
6575 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6576 return self.editor.FillHole( holeNodes, groupName )
6578 def FindCoincidentFreeBorders (self, tolerance=0.):
6580 Return groups of FreeBorder's coincident within the given tolerance.
6583 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6584 size of elements adjacent to free borders being compared is used.
6587 SMESH.CoincidentFreeBorders structure
6590 return self.editor.FindCoincidentFreeBorders( tolerance )
6592 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6594 Sew FreeBorder's of each group
6597 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6598 where each enclosed list contains node IDs of a group of coincident free
6599 borders such that each consequent triple of IDs within a group describes
6600 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6601 last node of a border.
6602 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6603 groups of coincident free borders, each group including two borders.
6604 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6605 polygons if a node of opposite border falls on a face edge, else such
6606 faces are split into several ones.
6607 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6608 polyhedra if a node of opposite border falls on a volume edge, else such
6609 volumes, if any, remain intact and the mesh becomes non-conformal.
6612 a number of successfully sewed groups
6615 This operation can create gaps in numeration of nodes or elements.
6616 Call :meth:`RenumberElements` to remove the gaps.
6619 if freeBorders and isinstance( freeBorders, list ):
6620 # construct SMESH.CoincidentFreeBorders
6621 if isinstance( freeBorders[0], int ):
6622 freeBorders = [freeBorders]
6624 coincidentGroups = []
6625 for nodeList in freeBorders:
6626 if not nodeList or len( nodeList ) % 3:
6627 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6630 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6631 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6632 nodeList = nodeList[3:]
6634 coincidentGroups.append( group )
6636 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6638 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6640 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6641 FirstNodeID2, SecondNodeID2, LastNodeID2,
6642 CreatePolygons, CreatePolyedrs):
6647 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6650 This operation can create gaps in numeration of nodes or elements.
6651 Call :meth:`RenumberElements` to remove the gaps.
6654 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6655 FirstNodeID2, SecondNodeID2, LastNodeID2,
6656 CreatePolygons, CreatePolyedrs)
6658 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6659 FirstNodeID2, SecondNodeID2):
6661 Sew conform free borders
6664 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6667 This operation can create gaps in numeration of elements.
6668 Call :meth:`RenumberElements` to remove the gaps.
6671 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6672 FirstNodeID2, SecondNodeID2)
6674 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6675 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6680 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6683 This operation can create gaps in numeration of elements.
6684 Call :meth:`RenumberElements` to remove the gaps.
6687 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6688 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6690 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6691 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6692 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6694 Sew two sides of a mesh. The nodes belonging to Side1 are
6695 merged with the nodes of elements of Side2.
6696 The number of elements in theSide1 and in theSide2 must be
6697 equal and they should have similar nodal connectivity.
6698 The nodes to merge should belong to side borders and
6699 the first node should be linked to the second.
6702 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6705 This operation can create gaps in numeration of nodes.
6706 Call :meth:`RenumberElements` to remove the gaps.
6709 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6710 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6711 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6713 def ChangeElemNodes(self, ide, newIDs):
6715 Set new nodes for the given element. Number of nodes should be kept.
6722 False if the number of nodes does not correspond to the type of element
6725 return self.editor.ChangeElemNodes(ide, newIDs)
6727 def GetLastCreatedNodes(self):
6729 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6730 created, this method return the list of their IDs.
6731 If new nodes were not created - return empty list
6734 the list of integer values (can be empty)
6737 return self.editor.GetLastCreatedNodes()
6739 def GetLastCreatedElems(self):
6741 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6742 created this method return the list of their IDs.
6743 If new elements were not created - return empty list
6746 the list of integer values (can be empty)
6749 return self.editor.GetLastCreatedElems()
6751 def ClearLastCreated(self):
6753 Forget what nodes and elements were created by the last mesh edition operation
6756 self.editor.ClearLastCreated()
6758 def DoubleElements(self, theElements, theGroupName=""):
6760 Create duplicates of given elements, i.e. create new elements based on the
6761 same nodes as the given ones.
6764 theElements: container of elements to duplicate. It can be a
6765 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6766 or a list of element IDs. If *theElements* is
6767 a :class:`Mesh`, elements of highest dimension are duplicated
6768 theGroupName: a name of group to contain the generated elements.
6769 If a group with such a name already exists, the new elements
6770 are added to the existing group, else a new group is created.
6771 If *theGroupName* is empty, new elements are not added
6775 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6776 None if *theGroupName* == "".
6779 unRegister = genObjUnRegister()
6780 if isinstance( theElements, Mesh ):
6781 theElements = theElements.mesh
6782 elif isinstance( theElements, list ):
6783 theElements = self.GetIDSource( theElements, SMESH.ALL )
6784 unRegister.set( theElements )
6785 return self.editor.DoubleElements(theElements, theGroupName)
6787 def DoubleNodes(self, theNodes, theModifiedElems):
6789 Create a hole in a mesh by doubling the nodes of some particular elements
6792 theNodes: IDs of nodes to be doubled
6793 theModifiedElems: IDs of elements to be updated by the new (doubled)
6794 nodes. If list of element identifiers is empty then nodes are doubled but
6795 they not assigned to elements
6798 True if operation has been completed successfully, False otherwise
6801 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6803 def DoubleNode(self, theNodeId, theModifiedElems):
6805 Create a hole in a mesh by doubling the nodes of some particular elements.
6806 This method provided for convenience works as :meth:`DoubleNodes`.
6809 theNodeId: IDs of node to double
6810 theModifiedElems: IDs of elements to update
6813 True if operation has been completed successfully, False otherwise
6816 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6818 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6820 Create a hole in a mesh by doubling the nodes of some particular elements.
6821 This method provided for convenience works as :meth:`DoubleNodes`.
6824 theNodes: group of nodes to double.
6825 theModifiedElems: group of elements to update.
6826 theMakeGroup: forces the generation of a group containing new nodes.
6829 True or a created group if operation has been completed successfully,
6830 False or None otherwise
6834 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6835 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6837 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6839 Create a hole in a mesh by doubling the nodes of some particular elements.
6840 This method provided for convenience works as :meth:`DoubleNodes`.
6843 theNodes: list of groups of nodes to double.
6844 theModifiedElems: list of groups of elements to update.
6845 theMakeGroup: forces the generation of a group containing new nodes.
6848 True if operation has been completed successfully, False otherwise
6852 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6853 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6855 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6857 Create a hole in a mesh by doubling the nodes of some particular elements
6860 theElems: the list of elements (edges or faces) to replicate.
6861 The nodes for duplication could be found from these elements
6862 theNodesNot: list of nodes NOT to replicate
6863 theAffectedElems: the list of elements (cells and edges) to which the
6864 replicated nodes should be associated to
6867 True if operation has been completed successfully, False otherwise
6870 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6872 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6874 Create a hole in a mesh by doubling the nodes of some particular elements
6877 theElems: the list of elements (edges or faces) to replicate.
6878 The nodes for duplication could be found from these elements
6879 theNodesNot: list of nodes NOT to replicate
6880 theShape: shape to detect affected elements (element which geometric center
6881 located on or inside shape).
6882 The replicated nodes should be associated to affected elements.
6885 True if operation has been completed successfully, False otherwise
6888 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6890 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6891 theMakeGroup=False, theMakeNodeGroup=False):
6893 Create a hole in a mesh by doubling the nodes of some particular elements.
6894 This method provided for convenience works as :meth:`DoubleNodes`.
6897 theElems: group of of elements (edges or faces) to replicate.
6898 theNodesNot: group of nodes NOT to replicate.
6899 theAffectedElems: group of elements to which the replicated nodes
6900 should be associated to.
6901 theMakeGroup: forces the generation of a group containing new elements.
6902 theMakeNodeGroup: forces the generation of a group containing new nodes.
6905 True or created groups (one or two) if operation has been completed successfully,
6906 False or None otherwise
6909 if theMakeGroup or theMakeNodeGroup:
6910 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6912 theMakeGroup, theMakeNodeGroup)
6913 if theMakeGroup and theMakeNodeGroup:
6916 return twoGroups[ int(theMakeNodeGroup) ]
6917 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6919 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6921 Create a hole in a mesh by doubling the nodes of some particular elements.
6922 This method provided for convenience works as :meth:`DoubleNodes`.
6925 theElems: group of of elements (edges or faces) to replicate
6926 theNodesNot: group of nodes not to replicate
6927 theShape: shape to detect affected elements (element which geometric center
6928 located on or inside shape).
6929 The replicated nodes should be associated to affected elements
6932 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6934 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6935 theMakeGroup=False, theMakeNodeGroup=False):
6937 Create a hole in a mesh by doubling the nodes of some particular elements.
6938 This method provided for convenience works as :meth:`DoubleNodes`.
6941 theElems: list of groups of elements (edges or faces) to replicate
6942 theNodesNot: list of groups of nodes NOT to replicate
6943 theAffectedElems: group of elements to which the replicated nodes
6944 should be associated to
6945 theMakeGroup: forces generation of a group containing new elements.
6946 theMakeNodeGroup: forces generation of a group containing new nodes
6949 True or created groups (one or two) if operation has been completed successfully,
6950 False or None otherwise
6953 if theMakeGroup or theMakeNodeGroup:
6954 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6956 theMakeGroup, theMakeNodeGroup)
6957 if theMakeGroup and theMakeNodeGroup:
6960 return twoGroups[ int(theMakeNodeGroup) ]
6961 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6963 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6965 Create a hole in a mesh by doubling the nodes of some particular elements.
6966 This method provided for convenience works as :meth:`DoubleNodes`.
6969 theElems: list of groups of elements (edges or faces) to replicate
6970 theNodesNot: list of groups of nodes NOT to replicate
6971 theShape: shape to detect affected elements (element which geometric center
6972 located on or inside shape).
6973 The replicated nodes should be associated to affected elements
6976 True if operation has been completed successfully, False otherwise
6979 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6981 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6983 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6984 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6987 theElems: list of groups of nodes or elements (edges or faces) to replicate
6988 theNodesNot: list of groups of nodes NOT to replicate
6989 theShape: shape to detect affected elements (element which geometric center
6990 located on or inside shape).
6991 The replicated nodes should be associated to affected elements
6994 groups of affected elements in order: volumes, faces, edges
6997 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6999 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7002 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7003 The list of groups must describe a partition of the mesh volumes.
7004 The nodes of the internal faces at the boundaries of the groups are doubled.
7005 In option, the internal faces are replaced by flat elements.
7006 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7009 theDomains: list of groups of volumes
7010 createJointElems: if True, create the elements
7011 onAllBoundaries: if True, the nodes and elements are also created on
7012 the boundary between *theDomains* and the rest mesh
7015 True if operation has been completed successfully, False otherwise
7018 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7020 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7022 Double nodes on some external faces and create flat elements.
7023 Flat elements are mainly used by some types of mechanic calculations.
7025 Each group of the list must be constituted of faces.
7026 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7029 theGroupsOfFaces: list of groups of faces
7032 True if operation has been completed successfully, False otherwise
7035 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7037 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7039 Identify all the elements around a geom shape, get the faces delimiting the hole
7041 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7043 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7045 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7046 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7047 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7048 If there are several paths connecting a pair of points, the shortest path is
7049 selected by the module. Position of the cutting plane is defined by the two
7050 points and an optional vector lying on the plane specified by a PolySegment.
7051 By default the vector is defined by Mesh module as following. A middle point
7052 of the two given points is computed. The middle point is projected to the mesh.
7053 The vector goes from the middle point to the projection point. In case of planar
7054 mesh, the vector is normal to the mesh.
7056 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7059 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7060 groupName: optional name of a group where created mesh segments will be added.
7063 editor = self.editor
7065 editor = self.mesh.GetMeshEditPreviewer()
7066 segmentsRes = editor.MakePolyLine( segments, groupName )
7067 for i, seg in enumerate( segmentsRes ):
7068 segments[i].vector = seg.vector
7070 return editor.GetPreviewData()
7073 def MakeSlot(self, segmentGroup, width ):
7075 Create a slot of given width around given 1D elements lying on a triangle mesh.
7076 The slot is constructed by cutting faces by cylindrical surfaces made
7077 around each segment. Segments are expected to be created by MakePolyLine().
7080 FaceEdge's located at the slot boundary
7082 return self.editor.MakeSlot( segmentGroup, width )
7084 def GetFunctor(self, funcType ):
7086 Return a cached numerical functor by its type.
7089 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7090 Note that not all items correspond to numerical functors.
7093 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7096 fn = self.functors[ funcType._v ]
7098 fn = self.smeshpyD.GetFunctor(funcType)
7099 fn.SetMesh(self.mesh)
7100 self.functors[ funcType._v ] = fn
7103 def FunctorValue(self, funcType, elemId, isElem=True):
7105 Return value of a functor for a given element
7108 funcType: an item of :class:`SMESH.FunctorType` enum.
7109 elemId: element or node ID
7110 isElem: *elemId* is ID of element or node
7113 the functor value or zero in case of invalid arguments
7116 fn = self.GetFunctor( funcType )
7117 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7118 val = fn.GetValue(elemId)
7123 def GetLength(self, elemId=None):
7125 Get length of given 1D elements or of all 1D mesh elements
7128 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.
7131 Sum of lengths of given elements
7136 length = self.smeshpyD.GetLength(self)
7137 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7138 length = self.smeshpyD.GetLength(elemId)
7141 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7143 length += self.smeshpyD.GetLength(obj)
7144 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7145 unRegister = genObjUnRegister()
7146 obj = self.GetIDSource( elemId )
7147 unRegister.set( obj )
7148 length = self.smeshpyD.GetLength( obj )
7150 length = self.FunctorValue(SMESH.FT_Length, elemId)
7153 def GetArea(self, elemId=None):
7155 Get area of given 2D elements or of all 2D mesh elements
7158 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.
7161 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7166 area = self.smeshpyD.GetArea(self)
7167 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7168 area = self.smeshpyD.GetArea(elemId)
7171 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7173 area += self.smeshpyD.GetArea(obj)
7174 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7175 unRegister = genObjUnRegister()
7176 obj = self.GetIDSource( elemId )
7177 unRegister.set( obj )
7178 area = self.smeshpyD.GetArea( obj )
7180 area = self.FunctorValue(SMESH.FT_Area, elemId)
7183 def GetVolume(self, elemId=None):
7185 Get volume of given 3D elements or of all 3D mesh elements
7188 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.
7191 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7196 volume= self.smeshpyD.GetVolume(self)
7197 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7198 volume= self.smeshpyD.GetVolume(elemId)
7201 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7203 volume+= self.smeshpyD.GetVolume(obj)
7204 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7205 unRegister = genObjUnRegister()
7206 obj = self.GetIDSource( elemId )
7207 unRegister.set( obj )
7208 volume= self.smeshpyD.GetVolume( obj )
7210 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7213 def GetAngle(self, node1, node2, node3 ):
7215 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7218 node1,node2,node3: IDs of the three nodes
7221 Angle in radians [0,PI]. -1 if failure case.
7223 p1 = self.GetNodeXYZ( node1 )
7224 p2 = self.GetNodeXYZ( node2 )
7225 p3 = self.GetNodeXYZ( node3 )
7226 if p1 and p2 and p3:
7227 return self.smeshpyD.GetAngle( p1,p2,p3 )
7231 def GetMaxElementLength(self, elemId):
7233 Get maximum element length.
7236 elemId: mesh element ID
7239 element's maximum length value
7242 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7243 ftype = SMESH.FT_MaxElementLength3D
7245 ftype = SMESH.FT_MaxElementLength2D
7246 return self.FunctorValue(ftype, elemId)
7248 def GetAspectRatio(self, elemId):
7250 Get aspect ratio of 2D or 3D element.
7253 elemId: mesh element ID
7256 element's aspect ratio value
7259 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7260 ftype = SMESH.FT_AspectRatio3D
7262 ftype = SMESH.FT_AspectRatio
7263 return self.FunctorValue(ftype, elemId)
7265 def GetWarping(self, elemId):
7267 Get warping angle of 2D element.
7270 elemId: mesh element ID
7273 element's warping angle value
7276 return self.FunctorValue(SMESH.FT_Warping, elemId)
7278 def GetMinimumAngle(self, elemId):
7280 Get minimum angle of 2D element.
7283 elemId: mesh element ID
7286 element's minimum angle value
7289 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7291 def GetTaper(self, elemId):
7293 Get taper of 2D element.
7296 elemId: mesh element ID
7299 element's taper value
7302 return self.FunctorValue(SMESH.FT_Taper, elemId)
7304 def GetSkew(self, elemId):
7306 Get skew of 2D element.
7309 elemId: mesh element ID
7312 element's skew value
7315 return self.FunctorValue(SMESH.FT_Skew, elemId)
7317 def GetMinMax(self, funType, meshPart=None):
7319 Return minimal and maximal value of a given functor.
7322 funType (SMESH.FunctorType): a functor type.
7323 Note that not all items of :class:`SMESH.FunctorType` corresponds
7324 to numerical functors.
7325 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7331 unRegister = genObjUnRegister()
7332 if isinstance( meshPart, list ):
7333 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7334 unRegister.set( meshPart )
7335 if isinstance( meshPart, Mesh ):
7336 meshPart = meshPart.mesh
7337 fun = self.GetFunctor( funType )
7340 if hasattr( meshPart, "SetMesh" ):
7341 meshPart.SetMesh( self.mesh ) # set mesh to filter
7342 hist = fun.GetLocalHistogram( 1, False, meshPart )
7344 hist = fun.GetHistogram( 1, False )
7346 return hist[0].min, hist[0].max
7349 pass # end of Mesh class
7352 class meshProxy(SMESH._objref_SMESH_Mesh):
7354 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7355 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7357 def __init__(self,*args):
7358 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7359 def __deepcopy__(self, memo=None):
7360 new = self.__class__(self)
7362 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7363 if len( args ) == 3:
7364 args += SMESH.ALL_NODES, True
7365 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7366 def ExportToMEDX(self, *args): # function removed
7367 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7368 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7369 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7370 def ExportToMED(self, *args): # function removed
7371 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7372 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7374 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7376 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7377 def ExportPartToMED(self, *args): # 'version' parameter removed
7378 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7379 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7380 def ExportMED(self, *args): # signature of method changed
7381 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7383 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7385 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7387 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7390 class submeshProxy(SMESH._objref_SMESH_subMesh):
7393 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7395 def __init__(self,*args):
7396 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7398 def __deepcopy__(self, memo=None):
7399 new = self.__class__(self)
7402 def Compute(self,refresh=False):
7404 Compute the sub-mesh and return the status of the computation
7407 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7412 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7413 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7417 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7419 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7421 if salome.sg.hasDesktop():
7422 if refresh: salome.sg.updateObjBrowser()
7427 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7430 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7432 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7433 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7436 def __init__(self,*args):
7437 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7439 def __getattr__(self, name ): # method called if an attribute not found
7440 if not self.mesh: # look for name() method in Mesh class
7441 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7442 if hasattr( self.mesh, name ):
7443 return getattr( self.mesh, name )
7444 if name == "ExtrusionAlongPathObjX":
7445 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7446 print("meshEditor: attribute '%s' NOT FOUND" % name)
7448 def __deepcopy__(self, memo=None):
7449 new = self.__class__(self)
7451 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7452 if len( args ) == 1: args += False,
7453 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7454 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7455 if len( args ) == 2: args += False,
7456 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7457 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7458 if len( args ) == 1:
7459 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7460 NodesToKeep = args[1]
7461 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7462 unRegister = genObjUnRegister()
7464 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7465 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7466 if not isinstance( NodesToKeep, list ):
7467 NodesToKeep = [ NodesToKeep ]
7468 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7470 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7472 class Pattern(SMESH._objref_SMESH_Pattern):
7474 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7475 variables in some methods
7478 def LoadFromFile(self, patternTextOrFile ):
7479 text = patternTextOrFile
7480 if os.path.exists( text ):
7481 text = open( patternTextOrFile ).read()
7483 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7485 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7486 decrFun = lambda i: i-1
7487 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7488 theMesh.SetParameters(Parameters)
7489 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7491 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7492 decrFun = lambda i: i-1
7493 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7494 theMesh.SetParameters(Parameters)
7495 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7497 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7498 if isinstance( mesh, Mesh ):
7499 mesh = mesh.GetMesh()
7500 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7502 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7504 Registering the new proxy for Pattern
7509 Private class used to bind methods creating algorithms to the class Mesh
7512 def __init__(self, method):
7514 self.defaultAlgoType = ""
7515 self.algoTypeToClass = {}
7516 self.method = method
7518 def add(self, algoClass):
7520 Store a python class of algorithm
7522 if inspect.isclass(algoClass) and \
7523 hasattr( algoClass, "algoType"):
7524 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7525 if not self.defaultAlgoType and \
7526 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7527 self.defaultAlgoType = algoClass.algoType
7528 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7530 def copy(self, mesh):
7532 Create a copy of self and assign mesh to the copy
7535 other = algoCreator( self.method )
7536 other.defaultAlgoType = self.defaultAlgoType
7537 other.algoTypeToClass = self.algoTypeToClass
7541 def __call__(self,algo="",geom=0,*args):
7543 Create an instance of algorithm
7547 if isinstance( algo, str ):
7549 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7550 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7555 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7557 elif not algoType and isinstance( geom, str ):
7562 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7564 elif isinstance( arg, str ) and not algoType:
7567 import traceback, sys
7568 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7569 sys.stderr.write( msg + '\n' )
7570 tb = traceback.extract_stack(None,2)
7571 traceback.print_list( [tb[0]] )
7573 algoType = self.defaultAlgoType
7574 if not algoType and self.algoTypeToClass:
7575 algoType = sorted( self.algoTypeToClass.keys() )[0]
7576 if algoType in self.algoTypeToClass:
7577 #print("Create algo",algoType)
7578 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7579 raise RuntimeError( "No class found for algo type %s" % algoType)
7582 class hypMethodWrapper:
7584 Private class used to substitute and store variable parameters of hypotheses.
7587 def __init__(self, hyp, method):
7589 self.method = method
7590 #print("REBIND:", method.__name__)
7593 def __call__(self,*args):
7595 call a method of hypothesis with calling SetVarParameter() before
7599 return self.method( self.hyp, *args ) # hypothesis method with no args
7601 #print("MethWrapper.__call__", self.method.__name__, args)
7603 parsed = ParseParameters(*args) # replace variables with their values
7604 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7605 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7606 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7607 # maybe there is a replaced string arg which is not variable
7608 result = self.method( self.hyp, *args )
7609 except ValueError as detail: # raised by ParseParameters()
7611 result = self.method( self.hyp, *args )
7612 except omniORB.CORBA.BAD_PARAM:
7613 raise ValueError(detail) # wrong variable name
7618 class genObjUnRegister:
7620 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7623 def __init__(self, genObj=None):
7624 self.genObjList = []
7628 def set(self, genObj):
7629 "Store one or a list of of SALOME.GenericObj'es"
7630 if isinstance( genObj, list ):
7631 self.genObjList.extend( genObj )
7633 self.genObjList.append( genObj )
7637 for genObj in self.genObjList:
7638 if genObj and hasattr( genObj, "UnRegister" ):
7641 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7643 Bind methods creating mesher plug-ins to the Mesh class
7646 # print("pluginName: ", pluginName)
7647 pluginBuilderName = pluginName + "Builder"
7649 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7650 except Exception as e:
7651 from salome_utils import verbose
7652 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7654 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7655 plugin = eval( pluginBuilderName )
7656 # print(" plugin:" , str(plugin))
7658 # add methods creating algorithms to Mesh
7659 for k in dir( plugin ):
7660 if k[0] == '_': continue
7661 algo = getattr( plugin, k )
7662 #print(" algo:", str(algo))
7663 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7664 #print(" meshMethod:" , str(algo.meshMethod))
7665 if not hasattr( Mesh, algo.meshMethod ):
7666 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7668 _mmethod = getattr( Mesh, algo.meshMethod )
7669 if hasattr( _mmethod, "add" ):