1 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
308 if not geom.GetStudyEntry():
310 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
311 # for all groups SubShapeName() return "Compound_-1"
312 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
314 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
316 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
319 def FirstVertexOnCurve(mesh, edge):
322 the first vertex of a geometrical edge by ignoring orientation
324 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
326 raise TypeError("Given object has no vertices")
327 if len( vv ) == 1: return vv[0]
328 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
329 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
330 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
331 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
334 dist1 += abs( xyz[i] - xyz1[i] )
335 dist2 += abs( xyz[i] - xyz2[i] )
344 smeshInst is a singleton
350 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
352 This class allows to create, load or manipulate meshes.
353 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
354 It also has methods to get infos and measure meshes.
357 # MirrorType enumeration
358 POINT = SMESH_MeshEditor.POINT
359 AXIS = SMESH_MeshEditor.AXIS
360 PLANE = SMESH_MeshEditor.PLANE
362 # Smooth_Method enumeration
363 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
364 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
366 PrecisionConfusion = smeshPrecisionConfusion
368 # TopAbs_State enumeration
369 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
371 # Methods of splitting a hexahedron into tetrahedra
372 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
374 def __new__(cls, *args):
378 #print("==== __new__", engine, smeshInst, doLcc)
380 if smeshInst is None:
381 # smesh engine is either retrieved from engine, or created
383 # Following test avoids a recursive loop
385 if smeshInst is not None:
386 # smesh engine not created: existing engine found
390 # FindOrLoadComponent called:
391 # 1. CORBA resolution of server
392 # 2. the __new__ method is called again
393 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
394 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
396 # FindOrLoadComponent not called
397 if smeshInst is None:
398 # smeshBuilder instance is created from lcc.FindOrLoadComponent
399 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
400 smeshInst = super(smeshBuilder,cls).__new__(cls)
402 # smesh engine not created: existing engine found
403 #print("==== existing ", engine, smeshInst, doLcc)
405 #print("====1 ", smeshInst)
408 #print("====2 ", smeshInst)
411 def __init__(self, *args):
413 #print("--------------- smeshbuilder __init__ ---", created)
416 SMESH._objref_SMESH_Gen.__init__(self, *args)
419 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
421 Dump component to the Python script.
422 This method overrides IDL function to allow default values for the parameters.
425 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
427 def SetDumpPythonHistorical(self, isHistorical):
429 Set mode of DumpPython(), *historical* or *snapshot*.
430 In the *historical* mode, the Python Dump script includes all commands
431 performed by SMESH engine. In the *snapshot* mode, commands
432 relating to objects removed from the Study are excluded from the script
433 as well as commands not influencing the current state of meshes
436 if isHistorical: val = "true"
438 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
440 def init_smesh(self,geompyD = None):
442 Set Geometry component
445 self.UpdateStudy(geompyD)
446 notebook.myStudy = salome.myStudy
448 def Mesh(self, obj=0, name=0):
450 Create a mesh. This mesh can be either
452 * an empty mesh not bound to geometry, if *obj* == 0
453 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
454 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
459 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
462 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
464 2. a geometrical object for meshing
466 name: the name for the new mesh.
469 an instance of class :class:`Mesh`.
472 if isinstance(obj,str):
474 return Mesh(self, self.geompyD, obj, name)
476 def EnumToLong(self,theItem):
478 Return a long value from enumeration
483 def ColorToString(self,c):
485 Convert SALOMEDS.Color to string.
486 To be used with filters.
489 c: color value (SALOMEDS.Color)
492 a string representation of the color.
496 if isinstance(c, SALOMEDS.Color):
497 val = "%s;%s;%s" % (c.R, c.G, c.B)
498 elif isinstance(c, str):
501 raise ValueError("Color value should be of string or SALOMEDS.Color type")
504 def GetPointStruct(self,theVertex):
506 Get :class:`SMESH.PointStruct` from vertex
509 theVertex (GEOM.GEOM_Object): vertex
512 :class:`SMESH.PointStruct`
515 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
516 return PointStruct(x,y,z)
518 def GetDirStruct(self,theVector):
520 Get :class:`SMESH.DirStruct` from vector
523 theVector (GEOM.GEOM_Object): vector
526 :class:`SMESH.DirStruct`
529 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
530 if(len(vertices) != 2):
531 print("Error: vector object is incorrect.")
533 p1 = self.geompyD.PointCoordinates(vertices[0])
534 p2 = self.geompyD.PointCoordinates(vertices[1])
535 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
536 dirst = DirStruct(pnt)
539 def MakeDirStruct(self,x,y,z):
541 Make :class:`SMESH.DirStruct` from a triplet of floats
544 x,y,z (float): vector components
547 :class:`SMESH.DirStruct`
550 pnt = PointStruct(x,y,z)
551 return DirStruct(pnt)
553 def GetAxisStruct(self,theObj):
555 Get :class:`SMESH.AxisStruct` from a geometrical object
558 theObj (GEOM.GEOM_Object): line or plane
561 :class:`SMESH.AxisStruct`
564 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
567 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
568 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
569 vertex1 = self.geompyD.PointCoordinates(vertex1)
570 vertex2 = self.geompyD.PointCoordinates(vertex2)
571 vertex3 = self.geompyD.PointCoordinates(vertex3)
572 vertex4 = self.geompyD.PointCoordinates(vertex4)
573 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
574 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
575 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] ]
576 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
577 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
578 elif len(edges) == 1:
579 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
580 p1 = self.geompyD.PointCoordinates( vertex1 )
581 p2 = self.geompyD.PointCoordinates( vertex2 )
582 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
583 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
584 elif theObj.GetShapeType() == GEOM.VERTEX:
585 x,y,z = self.geompyD.PointCoordinates( theObj )
586 axis = AxisStruct( x,y,z, 1,0,0,)
587 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
590 # From SMESH_Gen interface:
591 # ------------------------
593 def SetName(self, obj, name):
595 Set the given name to an object
598 obj: the object to rename
599 name: a new object name
602 if isinstance( obj, Mesh ):
604 elif isinstance( obj, Mesh_Algorithm ):
605 obj = obj.GetAlgorithm()
606 ior = salome.orb.object_to_string(obj)
607 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
609 def SetEmbeddedMode( self,theMode ):
614 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
616 def IsEmbeddedMode(self):
621 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
623 def UpdateStudy( self, geompyD = None ):
625 Update the current study. Calling UpdateStudy() allows to
626 update meshes at switching GEOM->SMESH
630 from salome.geom import geomBuilder
631 geompyD = geomBuilder.geom
633 geompyD = geomBuilder.New()
636 self.SetGeomEngine(geompyD)
637 SMESH._objref_SMESH_Gen.UpdateStudy(self)
638 sb = salome.myStudy.NewBuilder()
639 sc = salome.myStudy.FindComponent("SMESH")
641 sb.LoadWith(sc, self)
644 def SetEnablePublish( self, theIsEnablePublish ):
646 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
647 switch **off** publishing in the Study of mesh objects.
649 #self.SetEnablePublish(theIsEnablePublish)
650 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
652 notebook = salome_notebook.NoteBook( theIsEnablePublish )
655 def CreateMeshesFromUNV( self,theFileName ):
657 Create a Mesh object importing data from the given UNV file
660 an instance of class :class:`Mesh`
663 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
664 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
667 def CreateMeshesFromMED( self,theFileName ):
669 Create a Mesh object(s) importing data from the given MED file
672 a tuple ( list of class :class:`Mesh` instances,
673 :class:`SMESH.DriverMED_ReadStatus` )
676 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
677 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
678 return aMeshes, aStatus
680 def CreateMeshesFromSAUV( self,theFileName ):
682 Create a Mesh object(s) importing data from the given SAUV file
685 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
688 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
689 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
690 return aMeshes, aStatus
692 def CreateMeshesFromSTL( self, theFileName ):
694 Create a Mesh object importing data from the given STL file
697 an instance of class :class:`Mesh`
700 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
701 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
704 def CreateMeshesFromCGNS( self, theFileName ):
706 Create Mesh objects importing data from the given CGNS file
709 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
712 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
713 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
714 return aMeshes, aStatus
716 def CreateMeshesFromGMF( self, theFileName ):
718 Create a Mesh object importing data from the given GMF file.
719 GMF files must have .mesh extension for the ASCII format and .meshb for
723 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
726 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
729 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
730 return Mesh(self, self.geompyD, aSmeshMesh), error
732 def Concatenate( self, meshes, uniteIdenticalGroups,
733 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736 Concatenate the given meshes into one mesh. All groups of input meshes will be
737 present in the new mesh.
740 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
741 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
742 mergeNodesAndElements: if True, equal nodes and elements are merged
743 mergeTolerance: tolerance for merging nodes
744 allGroups: forces creation of groups corresponding to every input mesh
745 name: name of a new mesh
748 an instance of class :class:`Mesh`
751 if not meshes: return None
752 for i,m in enumerate(meshes):
753 if isinstance(m, Mesh):
754 meshes[i] = m.GetMesh()
755 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
756 meshes[0].SetParameters(Parameters)
758 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
759 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
761 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
762 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
763 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
766 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
768 Create a mesh by copying a part of another mesh.
771 meshPart: a part of mesh to copy, either
772 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
773 To copy nodes or elements not forming any mesh object,
774 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
775 meshName: a name of the new mesh
776 toCopyGroups: to create in the new mesh groups the copied elements belongs to
777 toKeepIDs: to preserve order of the copied elements or not
780 an instance of class :class:`Mesh`
783 if (isinstance( meshPart, Mesh )):
784 meshPart = meshPart.GetMesh()
785 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
786 return Mesh(self, self.geompyD, mesh)
788 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
790 Return IDs of sub-shapes
793 theMainObject (GEOM.GEOM_Object): a shape
794 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
796 the list of integer values
799 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
801 def GetPattern(self):
803 Create a pattern mapper.
806 an instance of :class:`SMESH.SMESH_Pattern`
808 :ref:`Example of Patterns usage <tui_pattern_mapping>`
811 return SMESH._objref_SMESH_Gen.GetPattern(self)
813 def SetBoundaryBoxSegmentation(self, nbSegments):
815 Set number of segments per diagonal of boundary box of geometry, by which
816 default segment length of appropriate 1D hypotheses is defined in GUI.
820 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
822 # Filtering. Auxiliary functions:
823 # ------------------------------
825 def GetEmptyCriterion(self):
827 Create an empty criterion
830 :class:`SMESH.Filter.Criterion`
833 Type = self.EnumToLong(FT_Undefined)
834 Compare = self.EnumToLong(FT_Undefined)
838 UnaryOp = self.EnumToLong(FT_Undefined)
839 BinaryOp = self.EnumToLong(FT_Undefined)
842 Precision = -1 ##@1e-07
843 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
844 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
846 def GetCriterion(self,elementType,
848 Compare = FT_EqualTo,
850 UnaryOp=FT_Undefined,
851 BinaryOp=FT_Undefined,
854 Create a criterion by the given parameters
855 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
858 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
859 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
860 Note that the items starting from FT_LessThan are not suitable for *CritType*.
861 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
862 Threshold: the threshold value (range of ids as string, shape, numeric)
863 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
864 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
866 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
867 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
870 :class:`SMESH.Filter.Criterion`
872 Example: :ref:`combining_filters`
875 if not CritType in SMESH.FunctorType._items:
876 raise TypeError("CritType should be of SMESH.FunctorType")
877 aCriterion = self.GetEmptyCriterion()
878 aCriterion.TypeOfElement = elementType
879 aCriterion.Type = self.EnumToLong(CritType)
880 aCriterion.Tolerance = Tolerance
882 aThreshold = Threshold
884 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
885 aCriterion.Compare = self.EnumToLong(Compare)
886 elif Compare == "=" or Compare == "==":
887 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
889 aCriterion.Compare = self.EnumToLong(FT_LessThan)
891 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
892 elif Compare != FT_Undefined:
893 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
896 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
897 FT_BelongToCylinder, FT_LyingOnGeom]:
898 # Check that Threshold is GEOM object
899 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
900 aCriterion.ThresholdStr = GetName(aThreshold)
901 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
902 if not aCriterion.ThresholdID:
903 name = aCriterion.ThresholdStr
905 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
906 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
907 # or a name of GEOM object
908 elif isinstance( aThreshold, str ):
909 aCriterion.ThresholdStr = aThreshold
911 raise TypeError("The Threshold should be a shape.")
912 if isinstance(UnaryOp,float):
913 aCriterion.Tolerance = UnaryOp
914 UnaryOp = FT_Undefined
916 elif CritType == FT_BelongToMeshGroup:
917 # Check that Threshold is a group
918 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
919 if aThreshold.GetType() != elementType:
920 raise ValueError("Group type mismatches Element type")
921 aCriterion.ThresholdStr = aThreshold.GetName()
922 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
923 study = salome.myStudy
925 so = study.FindObjectIOR( aCriterion.ThresholdID )
929 aCriterion.ThresholdID = entry
931 raise TypeError("The Threshold should be a Mesh Group")
932 elif CritType == FT_RangeOfIds:
933 # Check that Threshold is string
934 if isinstance(aThreshold, str):
935 aCriterion.ThresholdStr = aThreshold
937 raise TypeError("The Threshold should be a string.")
938 elif CritType == FT_CoplanarFaces:
939 # Check the Threshold
940 if isinstance(aThreshold, int):
941 aCriterion.ThresholdID = str(aThreshold)
942 elif isinstance(aThreshold, str):
945 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
946 aCriterion.ThresholdID = aThreshold
948 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
949 elif CritType == FT_ConnectedElements:
950 # Check the Threshold
951 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
952 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
953 if not aCriterion.ThresholdID:
954 name = aThreshold.GetName()
956 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
957 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
958 elif isinstance(aThreshold, int): # node id
959 aCriterion.Threshold = aThreshold
960 elif isinstance(aThreshold, list): # 3 point coordinates
961 if len( aThreshold ) < 3:
962 raise ValueError("too few point coordinates, must be 3")
963 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
964 elif isinstance(aThreshold, str):
965 if aThreshold.isdigit():
966 aCriterion.Threshold = aThreshold # node id
968 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
970 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
971 "or a list of point coordinates and not '%s'"%aThreshold)
972 elif CritType == FT_ElemGeomType:
973 # Check the Threshold
975 aCriterion.Threshold = self.EnumToLong(aThreshold)
976 assert( aThreshold in SMESH.GeometryType._items )
978 if isinstance(aThreshold, int):
979 aCriterion.Threshold = aThreshold
981 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
984 elif CritType == FT_EntityType:
985 # Check the Threshold
987 aCriterion.Threshold = self.EnumToLong(aThreshold)
988 assert( aThreshold in SMESH.EntityType._items )
990 if isinstance(aThreshold, int):
991 aCriterion.Threshold = aThreshold
993 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
997 elif CritType == FT_GroupColor:
998 # Check the Threshold
1000 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1002 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1004 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1005 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1006 FT_BareBorderFace, FT_BareBorderVolume,
1007 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1008 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1009 # At this point the Threshold is unnecessary
1010 if aThreshold == FT_LogicalNOT:
1011 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1012 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1013 aCriterion.BinaryOp = aThreshold
1017 aThreshold = float(aThreshold)
1018 aCriterion.Threshold = aThreshold
1020 raise TypeError("The Threshold should be a number.")
1023 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1024 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1026 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1027 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1029 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1030 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1032 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1033 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1037 def GetFilter(self,elementType,
1038 CritType=FT_Undefined,
1041 UnaryOp=FT_Undefined,
1045 Create a filter with the given parameters
1048 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1049 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1050 Note that the items starting from FT_LessThan are not suitable for CritType.
1051 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1052 Threshold: the threshold value (range of ids as string, shape, numeric)
1053 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1054 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1055 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1056 mesh: the mesh to initialize the filter with
1059 :class:`SMESH.Filter`
1062 See :doc:`Filters usage examples <tui_filters>`
1065 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1066 aFilterMgr = self.CreateFilterManager()
1067 aFilter = aFilterMgr.CreateFilter()
1069 aCriteria.append(aCriterion)
1070 aFilter.SetCriteria(aCriteria)
1072 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1073 else : aFilter.SetMesh( mesh )
1074 aFilterMgr.UnRegister()
1077 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1079 Create a filter from criteria
1082 criteria: a list of :class:`SMESH.Filter.Criterion`
1083 binOp: binary operator used when binary operator of criteria is undefined
1086 :class:`SMESH.Filter`
1089 See :doc:`Filters usage examples <tui_filters>`
1092 for i in range( len( criteria ) - 1 ):
1093 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1094 criteria[i].BinaryOp = self.EnumToLong( binOp )
1095 aFilterMgr = self.CreateFilterManager()
1096 aFilter = aFilterMgr.CreateFilter()
1097 aFilter.SetCriteria(criteria)
1098 aFilterMgr.UnRegister()
1101 def GetFunctor(self,theCriterion):
1103 Create a numerical functor by its type
1106 theCriterion (SMESH.FunctorType): functor type.
1107 Note that not all items correspond to numerical functors.
1110 :class:`SMESH.NumericalFunctor`
1113 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1115 aFilterMgr = self.CreateFilterManager()
1117 if theCriterion == FT_AspectRatio:
1118 functor = aFilterMgr.CreateAspectRatio()
1119 elif theCriterion == FT_AspectRatio3D:
1120 functor = aFilterMgr.CreateAspectRatio3D()
1121 elif theCriterion == FT_Warping:
1122 functor = aFilterMgr.CreateWarping()
1123 elif theCriterion == FT_MinimumAngle:
1124 functor = aFilterMgr.CreateMinimumAngle()
1125 elif theCriterion == FT_Taper:
1126 functor = aFilterMgr.CreateTaper()
1127 elif theCriterion == FT_Skew:
1128 functor = aFilterMgr.CreateSkew()
1129 elif theCriterion == FT_Area:
1130 functor = aFilterMgr.CreateArea()
1131 elif theCriterion == FT_Volume3D:
1132 functor = aFilterMgr.CreateVolume3D()
1133 elif theCriterion == FT_MaxElementLength2D:
1134 functor = aFilterMgr.CreateMaxElementLength2D()
1135 elif theCriterion == FT_MaxElementLength3D:
1136 functor = aFilterMgr.CreateMaxElementLength3D()
1137 elif theCriterion == FT_MultiConnection:
1138 functor = aFilterMgr.CreateMultiConnection()
1139 elif theCriterion == FT_MultiConnection2D:
1140 functor = aFilterMgr.CreateMultiConnection2D()
1141 elif theCriterion == FT_Length:
1142 functor = aFilterMgr.CreateLength()
1143 elif theCriterion == FT_Length2D:
1144 functor = aFilterMgr.CreateLength2D()
1145 elif theCriterion == FT_Deflection2D:
1146 functor = aFilterMgr.CreateDeflection2D()
1147 elif theCriterion == FT_NodeConnectivityNumber:
1148 functor = aFilterMgr.CreateNodeConnectivityNumber()
1149 elif theCriterion == FT_BallDiameter:
1150 functor = aFilterMgr.CreateBallDiameter()
1152 print("Error: given parameter is not numerical functor type.")
1153 aFilterMgr.UnRegister()
1156 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1161 theHType (string): mesh hypothesis type
1162 theLibName (string): mesh plug-in library name
1165 created hypothesis instance
1167 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1169 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1172 # wrap hypothesis methods
1173 for meth_name in dir( hyp.__class__ ):
1174 if not meth_name.startswith("Get") and \
1175 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1176 method = getattr ( hyp.__class__, meth_name )
1177 if callable(method):
1178 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1182 def GetMeshInfo(self, obj):
1184 Get the mesh statistic.
1185 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1186 an item of :class:`SMESH.EntityType`.
1189 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1192 if isinstance( obj, Mesh ):
1195 if hasattr(obj, "GetMeshInfo"):
1196 values = obj.GetMeshInfo()
1197 for i in range(SMESH.Entity_Last._v):
1198 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1202 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1204 Get minimum distance between two objects
1206 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1207 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1210 src1 (SMESH.SMESH_IDSource): first source object
1211 src2 (SMESH.SMESH_IDSource): second source object
1212 id1 (int): node/element id from the first source
1213 id2 (int): node/element id from the second (or first) source
1214 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1215 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1218 minimum distance value
1221 :meth:`GetMinDistance`
1224 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1228 result = result.value
1231 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1233 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1235 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1236 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1239 src1 (SMESH.SMESH_IDSource): first source object
1240 src2 (SMESH.SMESH_IDSource): second source object
1241 id1 (int): node/element id from the first source
1242 id2 (int): node/element id from the second (or first) source
1243 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1244 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1247 :class:`SMESH.Measure` structure or None if input data is invalid
1252 if isinstance(src1, Mesh): src1 = src1.mesh
1253 if isinstance(src2, Mesh): src2 = src2.mesh
1254 if src2 is None and id2 != 0: src2 = src1
1255 if not hasattr(src1, "_narrow"): return None
1256 src1 = src1._narrow(SMESH.SMESH_IDSource)
1257 if not src1: return None
1258 unRegister = genObjUnRegister()
1261 e = m.GetMeshEditor()
1263 src1 = e.MakeIDSource([id1], SMESH.FACE)
1265 src1 = e.MakeIDSource([id1], SMESH.NODE)
1266 unRegister.set( src1 )
1268 if hasattr(src2, "_narrow"):
1269 src2 = src2._narrow(SMESH.SMESH_IDSource)
1270 if src2 and id2 != 0:
1272 e = m.GetMeshEditor()
1274 src2 = e.MakeIDSource([id2], SMESH.FACE)
1276 src2 = e.MakeIDSource([id2], SMESH.NODE)
1277 unRegister.set( src2 )
1280 aMeasurements = self.CreateMeasurements()
1281 unRegister.set( aMeasurements )
1282 result = aMeasurements.MinDistance(src1, src2)
1285 def BoundingBox(self, objects):
1287 Get bounding box of the specified object(s)
1290 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1293 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1296 :meth:`GetBoundingBox`
1299 result = self.GetBoundingBox(objects)
1303 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1306 def GetBoundingBox(self, objects):
1308 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1311 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1314 :class:`SMESH.Measure` structure
1320 if isinstance(objects, tuple):
1321 objects = list(objects)
1322 if not isinstance(objects, list):
1326 if isinstance(o, Mesh):
1327 srclist.append(o.mesh)
1328 elif hasattr(o, "_narrow"):
1329 src = o._narrow(SMESH.SMESH_IDSource)
1330 if src: srclist.append(src)
1333 aMeasurements = self.CreateMeasurements()
1334 result = aMeasurements.BoundingBox(srclist)
1335 aMeasurements.UnRegister()
1338 def GetLength(self, obj):
1340 Get sum of lengths of all 1D elements in the mesh object.
1343 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1346 sum of lengths of all 1D elements
1349 if isinstance(obj, Mesh): obj = obj.mesh
1350 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1351 aMeasurements = self.CreateMeasurements()
1352 value = aMeasurements.Length(obj)
1353 aMeasurements.UnRegister()
1356 def GetArea(self, obj):
1358 Get sum of areas of all 2D elements in the mesh object.
1361 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1364 sum of areas of all 2D elements
1367 if isinstance(obj, Mesh): obj = obj.mesh
1368 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1369 aMeasurements = self.CreateMeasurements()
1370 value = aMeasurements.Area(obj)
1371 aMeasurements.UnRegister()
1374 def GetVolume(self, obj):
1376 Get sum of volumes of all 3D elements in the mesh object.
1379 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1382 sum of volumes of all 3D elements
1385 if isinstance(obj, Mesh): obj = obj.mesh
1386 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1387 aMeasurements = self.CreateMeasurements()
1388 value = aMeasurements.Volume(obj)
1389 aMeasurements.UnRegister()
1392 def GetGravityCenter(self, obj):
1394 Get gravity center of all nodes of the mesh object.
1397 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1400 Three components of the gravity center (x,y,z)
1402 if isinstance(obj, Mesh): obj = obj.mesh
1403 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1404 aMeasurements = self.CreateMeasurements()
1405 pointStruct = aMeasurements.GravityCenter(obj)
1406 aMeasurements.UnRegister()
1407 return pointStruct.x, pointStruct.y, pointStruct.z
1409 pass # end of class smeshBuilder
1412 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1413 """Registering the new proxy for SMESH.SMESH_Gen"""
1416 def New( instance=None, instanceGeom=None):
1418 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1419 interface to create or load meshes.
1424 salome.salome_init()
1425 from salome.smesh import smeshBuilder
1426 smesh = smeshBuilder.New()
1429 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1430 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1432 :class:`smeshBuilder` instance
1437 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1439 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1444 smeshInst = smeshBuilder()
1445 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1446 smeshInst.init_smesh(instanceGeom)
1450 # Public class: Mesh
1451 # ==================
1454 class Mesh(metaclass = MeshMeta):
1456 This class allows defining and managing a mesh.
1457 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1458 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1459 new nodes and elements and by changing the existing entities), to get information
1460 about a mesh and to export a mesh in different formats.
1467 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1472 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1473 sets the GUI name of this mesh to *name*.
1476 smeshpyD: an instance of smeshBuilder class
1477 geompyD: an instance of geomBuilder class
1478 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1479 name: Study name of the mesh
1482 self.smeshpyD = smeshpyD
1483 self.geompyD = geompyD
1488 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1491 # publish geom of mesh (issue 0021122)
1492 if not self.geom.GetStudyEntry():
1496 geo_name = name + " shape"
1498 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1499 geompyD.addToStudy( self.geom, geo_name )
1500 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1502 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1505 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1507 self.smeshpyD.SetName(self.mesh, name)
1509 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1512 self.geom = self.mesh.GetShapeToMesh()
1514 self.editor = self.mesh.GetMeshEditor()
1515 self.functors = [None] * SMESH.FT_Undefined._v
1517 # set self to algoCreator's
1518 for attrName in dir(self):
1519 attr = getattr( self, attrName )
1520 if isinstance( attr, algoCreator ):
1521 setattr( self, attrName, attr.copy( self ))
1528 Destructor. Clean-up resources
1531 #self.mesh.UnRegister()
1535 def SetMesh(self, theMesh):
1537 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1540 theMesh: a :class:`SMESH.SMESH_Mesh` object
1544 # do not call Register() as this prevents mesh servant deletion at closing study
1545 #if self.mesh: self.mesh.UnRegister()
1548 #self.mesh.Register()
1549 self.geom = self.mesh.GetShapeToMesh()
1554 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1557 a :class:`SMESH.SMESH_Mesh` object
1564 Get the name of the mesh
1567 the name of the mesh as a string
1570 name = GetName(self.GetMesh())
1573 def SetName(self, name):
1575 Set a name to the mesh
1578 name: a new name of the mesh
1581 self.smeshpyD.SetName(self.GetMesh(), name)
1583 def GetSubMesh(self, geom, name):
1585 Get a sub-mesh object associated to a *geom* geometrical object.
1588 geom: a geometrical object (shape)
1589 name: a name for the sub-mesh in the Object Browser
1592 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1593 which lies on the given shape
1596 A sub-mesh is implicitly created when a sub-shape is specified at
1597 creating an algorithm, for example::
1599 algo1D = mesh.Segment(geom=Edge_1)
1601 creates a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1602 The created sub-mesh can be retrieved from the algorithm::
1604 submesh = algo1D.GetSubMesh()
1607 AssureGeomPublished( self, geom, name )
1608 submesh = self.mesh.GetSubMesh( geom, name )
1613 Return the shape associated to the mesh
1621 def SetShape(self, geom):
1623 Associate the given shape to the mesh (entails the recreation of the mesh)
1626 geom: the shape to be meshed (GEOM_Object)
1629 self.mesh = self.smeshpyD.CreateMesh(geom)
1633 Load mesh from the study after opening the study
1637 def IsReadyToCompute(self, theSubObject):
1639 Return true if the hypotheses are defined well
1642 theSubObject: a sub-shape of a mesh shape
1648 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1650 def GetAlgoState(self, theSubObject):
1652 Return errors of hypotheses definition.
1653 The list of errors is empty if everything is OK.
1656 theSubObject: a sub-shape of a mesh shape
1662 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1664 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1666 Return a geometrical object on which the given element was built.
1667 The returned geometrical object, if not nil, is either found in the
1668 study or published by this method with the given name
1671 theElementID: the id of the mesh element
1672 theGeomName: the user-defined name of the geometrical object
1675 GEOM.GEOM_Object instance
1678 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1680 def MeshDimension(self):
1682 Return the mesh dimension depending on the dimension of the underlying shape
1683 or, if the mesh is not based on any shape, basing on deimension of elements
1686 mesh dimension as an integer value [0,3]
1689 if self.mesh.HasShapeToMesh():
1690 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1691 if len( shells ) > 0 :
1693 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1695 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1700 if self.NbVolumes() > 0: return 3
1701 if self.NbFaces() > 0: return 2
1702 if self.NbEdges() > 0: return 1
1705 def Evaluate(self, geom=0):
1707 Evaluate size of prospective mesh on a shape
1710 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1711 To know predicted number of e.g. edges, inquire it this way::
1713 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1716 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1718 geom = self.mesh.GetShapeToMesh()
1721 return self.smeshpyD.Evaluate(self.mesh, geom)
1724 def Compute(self, geom=0, discardModifs=False, refresh=False):
1726 Compute the mesh and return the status of the computation
1729 geom: geomtrical shape on which mesh data should be computed
1730 discardModifs: if True and the mesh has been edited since
1731 a last total re-compute and that may prevent successful partial re-compute,
1732 then the mesh is cleaned before Compute()
1733 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1739 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1741 geom = self.mesh.GetShapeToMesh()
1746 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1748 ok = self.smeshpyD.Compute(self.mesh, geom)
1749 except SALOME.SALOME_Exception as ex:
1750 print("Mesh computation failed, exception caught:")
1751 print(" ", ex.details.text)
1754 print("Mesh computation failed, exception caught:")
1755 traceback.print_exc()
1759 # Treat compute errors
1760 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1762 for err in computeErrors:
1763 if self.mesh.HasShapeToMesh():
1764 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1766 stdErrors = ["OK", #COMPERR_OK
1767 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1768 "std::exception", #COMPERR_STD_EXCEPTION
1769 "OCC exception", #COMPERR_OCC_EXCEPTION
1770 "..", #COMPERR_SLM_EXCEPTION
1771 "Unknown exception", #COMPERR_EXCEPTION
1772 "Memory allocation problem", #COMPERR_MEMORY_PB
1773 "Algorithm failed", #COMPERR_ALGO_FAILED
1774 "Unexpected geometry", #COMPERR_BAD_SHAPE
1775 "Warning", #COMPERR_WARNING
1776 "Computation cancelled",#COMPERR_CANCELED
1777 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1779 if err.code < len(stdErrors): errText = stdErrors[err.code]
1781 errText = "code %s" % -err.code
1782 if errText: errText += ". "
1783 errText += err.comment
1784 if allReasons: allReasons += "\n"
1786 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1788 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1792 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1794 if err.isGlobalAlgo:
1802 reason = '%s %sD algorithm is missing' % (glob, dim)
1803 elif err.state == HYP_MISSING:
1804 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1805 % (glob, dim, name, dim))
1806 elif err.state == HYP_NOTCONFORM:
1807 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1808 elif err.state == HYP_BAD_PARAMETER:
1809 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1810 % ( glob, dim, name ))
1811 elif err.state == HYP_BAD_GEOMETRY:
1812 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1813 'geometry' % ( glob, dim, name ))
1814 elif err.state == HYP_HIDDEN_ALGO:
1815 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1816 'algorithm of upper dimension generating %sD mesh'
1817 % ( glob, dim, name, glob, dim ))
1819 reason = ("For unknown reason. "
1820 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1822 if allReasons: allReasons += "\n"
1823 allReasons += "- " + reason
1825 if not ok or allReasons != "":
1826 msg = '"' + GetName(self.mesh) + '"'
1827 if ok: msg += " has been computed with warnings"
1828 else: msg += " has not been computed"
1829 if allReasons != "": msg += ":"
1834 if salome.sg.hasDesktop():
1835 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1836 if refresh: salome.sg.updateObjBrowser()
1840 def GetComputeErrors(self, shape=0 ):
1842 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1846 shape = self.mesh.GetShapeToMesh()
1847 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1849 def GetSubShapeName(self, subShapeID ):
1851 Return a name of a sub-shape by its ID.
1852 Possible variants (for *subShapeID* == 3):
1854 - **"Face_12"** - published sub-shape
1855 - **FACE #3** - not published sub-shape
1856 - **sub-shape #3** - invalid sub-shape ID
1857 - **#3** - error in this function
1860 subShapeID: a unique ID of a sub-shape
1863 a string describing the sub-shape
1867 if not self.mesh.HasShapeToMesh():
1871 mainIOR = salome.orb.object_to_string( self.GetShape() )
1873 mainSO = s.FindObjectIOR(mainIOR)
1876 shapeText = '"%s"' % mainSO.GetName()
1877 subIt = s.NewChildIterator(mainSO)
1879 subSO = subIt.Value()
1881 obj = subSO.GetObject()
1882 if not obj: continue
1883 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1886 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1889 if ids == subShapeID:
1890 shapeText = '"%s"' % subSO.GetName()
1893 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1895 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1897 shapeText = 'sub-shape #%s' % (subShapeID)
1899 shapeText = "#%s" % (subShapeID)
1902 def GetFailedShapes(self, publish=False):
1904 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1905 error of an algorithm
1908 publish: if *True*, the returned groups will be published in the study
1911 a list of GEOM groups each named after a failed algorithm
1916 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1917 for err in computeErrors:
1918 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1919 if not shape: continue
1920 if err.algoName in algo2shapes:
1921 algo2shapes[ err.algoName ].append( shape )
1923 algo2shapes[ err.algoName ] = [ shape ]
1927 for algoName, shapes in list(algo2shapes.items()):
1929 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1930 otherTypeShapes = []
1932 group = self.geompyD.CreateGroup( self.geom, groupType )
1933 for shape in shapes:
1934 if shape.GetShapeType() == shapes[0].GetShapeType():
1935 sameTypeShapes.append( shape )
1937 otherTypeShapes.append( shape )
1938 self.geompyD.UnionList( group, sameTypeShapes )
1940 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1942 group.SetName( algoName )
1943 groups.append( group )
1944 shapes = otherTypeShapes
1947 for group in groups:
1948 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1951 def GetMeshOrder(self):
1953 Return sub-mesh objects list in meshing order
1956 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1959 return self.mesh.GetMeshOrder()
1961 def SetMeshOrder(self, submeshes):
1963 Set order in which concurrent sub-meshes should be meshed
1966 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1969 return self.mesh.SetMeshOrder(submeshes)
1971 def Clear(self, refresh=False):
1973 Remove all nodes and elements generated on geometry. Imported elements remain.
1976 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1980 if ( salome.sg.hasDesktop() ):
1981 if refresh: salome.sg.updateObjBrowser()
1983 def ClearSubMesh(self, geomId, refresh=False):
1985 Remove all nodes and elements of indicated shape
1988 geomId: the ID of a sub-shape to remove elements on
1989 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1992 self.mesh.ClearSubMesh(geomId)
1993 if salome.sg.hasDesktop():
1994 if refresh: salome.sg.updateObjBrowser()
1996 def AutomaticTetrahedralization(self, fineness=0):
1998 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2001 fineness: [0.0,1.0] defines mesh fineness
2007 dim = self.MeshDimension()
2009 self.RemoveGlobalHypotheses()
2010 self.Segment().AutomaticLength(fineness)
2012 self.Triangle().LengthFromEdges()
2017 return self.Compute()
2019 def AutomaticHexahedralization(self, fineness=0):
2021 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2024 fineness: [0.0, 1.0] defines mesh fineness
2030 dim = self.MeshDimension()
2031 # assign the hypotheses
2032 self.RemoveGlobalHypotheses()
2033 self.Segment().AutomaticLength(fineness)
2040 return self.Compute()
2042 def AddHypothesis(self, hyp, geom=0):
2047 hyp: a hypothesis to assign
2048 geom: a subhape of mesh geometry
2051 :class:`SMESH.Hypothesis_Status`
2054 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2055 hyp, geom = geom, hyp
2056 if isinstance( hyp, Mesh_Algorithm ):
2057 hyp = hyp.GetAlgorithm()
2062 geom = self.mesh.GetShapeToMesh()
2065 if self.mesh.HasShapeToMesh():
2066 hyp_type = hyp.GetName()
2067 lib_name = hyp.GetLibName()
2068 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2069 # if checkAll and geom:
2070 # checkAll = geom.GetType() == 37
2072 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2074 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2075 status = self.mesh.AddHypothesis(geom, hyp)
2077 status = HYP_BAD_GEOMETRY, ""
2078 hyp_name = GetName( hyp )
2081 geom_name = geom.GetName()
2082 isAlgo = hyp._narrow( SMESH_Algo )
2083 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2086 def IsUsedHypothesis(self, hyp, geom):
2088 Return True if an algorithm or hypothesis is assigned to a given shape
2091 hyp: an algorithm or hypothesis to check
2092 geom: a subhape of mesh geometry
2098 if not hyp: # or not geom
2100 if isinstance( hyp, Mesh_Algorithm ):
2101 hyp = hyp.GetAlgorithm()
2103 hyps = self.GetHypothesisList(geom)
2105 if h.GetId() == hyp.GetId():
2109 def RemoveHypothesis(self, hyp, geom=0):
2111 Unassign a hypothesis
2114 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2115 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2118 :class:`SMESH.Hypothesis_Status`
2123 if isinstance( hyp, Mesh_Algorithm ):
2124 hyp = hyp.GetAlgorithm()
2130 if self.IsUsedHypothesis( hyp, shape ):
2131 return self.mesh.RemoveHypothesis( shape, hyp )
2132 hypName = GetName( hyp )
2133 geoName = GetName( shape )
2134 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2137 def GetHypothesisList(self, geom):
2139 Get the list of hypotheses added on a geometry
2142 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2145 the sequence of :class:`SMESH.SMESH_Hypothesis`
2148 return self.mesh.GetHypothesisList( geom )
2150 def RemoveGlobalHypotheses(self):
2152 Remove all global hypotheses
2155 current_hyps = self.mesh.GetHypothesisList( self.geom )
2156 for hyp in current_hyps:
2157 self.mesh.RemoveHypothesis( self.geom, hyp )
2160 def ExportMED(self, *args, **kwargs):
2162 Export the mesh in a file in MED format
2163 allowing to overwrite the file if it exists or add the exported data to its contents
2166 fileName: is the file name
2167 auto_groups (boolean): parameter for creating/not creating
2168 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2169 the typical use is auto_groups=False.
2170 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2171 The minor must be between 0 and the current minor version of MED file library.
2172 If minor is equal to -1, the minor version is not changed (default).
2173 The major version (x, where version is x.y.z) cannot be changed.
2174 overwrite (boolean): parameter for overwriting/not overwriting the file
2175 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2176 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2178 - 1D if all mesh nodes lie on OX coordinate axis, or
2179 - 2D if all mesh nodes lie on XOY coordinate plane, or
2180 - 3D in the rest cases.
2182 If *autoDimension* is *False*, the space dimension is always 3.
2183 fields: list of GEOM fields defined on the shape to mesh.
2184 geomAssocFields: each character of this string means a need to export a
2185 corresponding field; correspondence between fields and characters is following:
2186 - 'v' stands for "_vertices _" field;
2187 - 'e' stands for "_edges _" field;
2188 - 'f' stands for "_faces _" field;
2189 - 's' stands for "_solids _" field.
2191 # process positional arguments
2192 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2194 auto_groups = args[1] if len(args) > 1 else False
2195 minor = args[2] if len(args) > 2 else -1
2196 overwrite = args[3] if len(args) > 3 else True
2197 meshPart = args[4] if len(args) > 4 else None
2198 autoDimension = args[5] if len(args) > 5 else True
2199 fields = args[6] if len(args) > 6 else []
2200 geomAssocFields = args[7] if len(args) > 7 else ''
2201 # process keywords arguments
2202 auto_groups = kwargs.get("auto_groups", auto_groups)
2203 minor = kwargs.get("minor", minor)
2204 overwrite = kwargs.get("overwrite", overwrite)
2205 meshPart = kwargs.get("meshPart", meshPart)
2206 autoDimension = kwargs.get("autoDimension", autoDimension)
2207 fields = kwargs.get("fields", fields)
2208 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2209 # invoke engine's function
2210 if meshPart or fields or geomAssocFields:
2211 unRegister = genObjUnRegister()
2212 if isinstance( meshPart, list ):
2213 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2214 unRegister.set( meshPart )
2215 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2216 fields, geomAssocFields)
2218 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2220 def ExportSAUV(self, f, auto_groups=0):
2222 Export the mesh in a file in SAUV format
2227 auto_groups: boolean parameter for creating/not creating
2228 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2229 the typical use is auto_groups=False.
2232 self.mesh.ExportSAUV(f, auto_groups)
2234 def ExportDAT(self, f, meshPart=None):
2236 Export the mesh in a file in DAT format
2240 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2244 unRegister = genObjUnRegister()
2245 if isinstance( meshPart, list ):
2246 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2247 unRegister.set( meshPart )
2248 self.mesh.ExportPartToDAT( meshPart, f )
2250 self.mesh.ExportDAT(f)
2252 def ExportUNV(self, f, meshPart=None):
2254 Export the mesh in a file in UNV format
2258 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2262 unRegister = genObjUnRegister()
2263 if isinstance( meshPart, list ):
2264 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2265 unRegister.set( meshPart )
2266 self.mesh.ExportPartToUNV( meshPart, f )
2268 self.mesh.ExportUNV(f)
2270 def ExportSTL(self, f, ascii=1, meshPart=None):
2272 Export the mesh in a file in STL format
2276 ascii: defines the file encoding
2277 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2281 unRegister = genObjUnRegister()
2282 if isinstance( meshPart, list ):
2283 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2284 unRegister.set( meshPart )
2285 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2287 self.mesh.ExportSTL(f, ascii)
2289 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2291 Export the mesh in a file in CGNS format
2295 overwrite: boolean parameter for overwriting/not overwriting the file
2296 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2297 groupElemsByType: if True all elements of same entity type are exported at ones,
2298 else elements are exported in order of their IDs which can cause creation
2299 of multiple cgns sections
2302 unRegister = genObjUnRegister()
2303 if isinstance( meshPart, list ):
2304 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2305 unRegister.set( meshPart )
2306 if isinstance( meshPart, Mesh ):
2307 meshPart = meshPart.mesh
2309 meshPart = self.mesh
2310 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2312 def ExportGMF(self, f, meshPart=None):
2314 Export the mesh in a file in GMF format.
2315 GMF files must have .mesh extension for the ASCII format and .meshb for
2316 the bynary format. Other extensions are not allowed.
2320 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2323 unRegister = genObjUnRegister()
2324 if isinstance( meshPart, list ):
2325 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2326 unRegister.set( meshPart )
2327 if isinstance( meshPart, Mesh ):
2328 meshPart = meshPart.mesh
2330 meshPart = self.mesh
2331 self.mesh.ExportGMF(meshPart, f, True)
2333 def ExportToMED(self, *args, **kwargs):
2335 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2336 Export the mesh in a file in MED format
2337 allowing to overwrite the file if it exists or add the exported data to its contents
2340 fileName: the file name
2341 opt (boolean): parameter for creating/not creating
2342 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2343 overwrite: boolean parameter for overwriting/not overwriting the file
2344 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2346 - 1D if all mesh nodes lie on OX coordinate axis, or
2347 - 2D if all mesh nodes lie on XOY coordinate plane, or
2348 - 3D in the rest cases.
2350 If **autoDimension** is *False*, the space dimension is always 3.
2353 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2354 # process positional arguments
2355 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2357 auto_groups = args[1] if len(args) > 1 else False
2358 overwrite = args[2] if len(args) > 2 else True
2359 autoDimension = args[3] if len(args) > 3 else True
2360 # process keywords arguments
2361 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2362 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2363 overwrite = kwargs.get("overwrite", overwrite)
2364 autoDimension = kwargs.get("autoDimension", autoDimension)
2366 # invoke engine's function
2367 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2369 def ExportToMEDX(self, *args, **kwargs):
2371 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2372 Export the mesh in a file in MED format
2375 fileName: the file name
2376 opt (boolean): parameter for creating/not creating
2377 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2378 overwrite: boolean parameter for overwriting/not overwriting the file
2379 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2381 - 1D if all mesh nodes lie on OX coordinate axis, or
2382 - 2D if all mesh nodes lie on XOY coordinate plane, or
2383 - 3D in the rest cases.
2385 If **autoDimension** is *False*, the space dimension is always 3.
2388 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2389 # process positional arguments
2390 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2392 auto_groups = args[1] if len(args) > 1 else False
2393 overwrite = args[2] if len(args) > 2 else True
2394 autoDimension = args[3] if len(args) > 3 else True
2395 # process keywords arguments
2396 auto_groups = kwargs.get("auto_groups", auto_groups)
2397 overwrite = kwargs.get("overwrite", overwrite)
2398 autoDimension = kwargs.get("autoDimension", autoDimension)
2400 # invoke engine's function
2401 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2403 # Operations with groups:
2404 # ----------------------
2405 def CreateEmptyGroup(self, elementType, name):
2407 Create an empty mesh group
2410 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2411 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2412 name: the name of the mesh group
2415 :class:`SMESH.SMESH_Group`
2418 return self.mesh.CreateGroup(elementType, name)
2420 def Group(self, grp, name=""):
2422 Create a mesh group based on the geometric object *grp*
2423 and give it a *name*.
2424 If *name* is not defined the name of the geometric group is used
2427 Works like :meth:`GroupOnGeom`.
2430 grp: a geometric group, a vertex, an edge, a face or a solid
2431 name: the name of the mesh group
2434 :class:`SMESH.SMESH_GroupOnGeom`
2437 return self.GroupOnGeom(grp, name)
2439 def GroupOnGeom(self, grp, name="", typ=None):
2441 Create a mesh group based on the geometrical object *grp*
2443 if *name* is not defined the name of the geometric group is used
2446 grp: a geometrical group, a vertex, an edge, a face or a solid
2447 name: the name of the mesh group
2448 typ: the type of elements in the group; either of
2449 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2450 automatically detected by the type of the geometry
2453 :class:`SMESH.SMESH_GroupOnGeom`
2456 AssureGeomPublished( self, grp, name )
2458 name = grp.GetName()
2460 typ = self._groupTypeFromShape( grp )
2461 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2463 def _groupTypeFromShape( self, shape ):
2465 Pivate method to get a type of group on geometry
2467 tgeo = str(shape.GetShapeType())
2468 if tgeo == "VERTEX":
2470 elif tgeo == "EDGE":
2472 elif tgeo == "FACE" or tgeo == "SHELL":
2474 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2476 elif tgeo == "COMPOUND":
2477 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2479 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2480 return self._groupTypeFromShape( sub[0] )
2482 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2485 def GroupOnFilter(self, typ, name, filter):
2487 Create a mesh group with given *name* based on the *filter* which
2488 is a special type of group dynamically updating it's contents during
2492 typ: the type of elements in the group; either of
2493 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2494 name: the name of the mesh group
2495 filter (SMESH.Filter): the filter defining group contents
2498 :class:`SMESH.SMESH_GroupOnFilter`
2501 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2503 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2505 Create a mesh group by the given ids of elements
2508 groupName: the name of the mesh group
2509 elementType: the type of elements in the group; either of
2510 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2511 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2514 :class:`SMESH.SMESH_Group`
2517 group = self.mesh.CreateGroup(elementType, groupName)
2518 if isinstance( elemIDs, Mesh ):
2519 elemIDs = elemIDs.GetMesh()
2520 if hasattr( elemIDs, "GetIDs" ):
2521 if hasattr( elemIDs, "SetMesh" ):
2522 elemIDs.SetMesh( self.GetMesh() )
2523 group.AddFrom( elemIDs )
2531 CritType=FT_Undefined,
2534 UnaryOp=FT_Undefined,
2537 Create a mesh group by the given conditions
2540 groupName: the name of the mesh group
2541 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2542 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2543 Note that the items starting from FT_LessThan are not suitable for CritType.
2544 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2545 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2546 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2547 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2548 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2551 :class:`SMESH.SMESH_GroupOnFilter`
2554 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2555 group = self.MakeGroupByCriterion(groupName, aCriterion)
2558 def MakeGroupByCriterion(self, groupName, Criterion):
2560 Create a mesh group by the given criterion
2563 groupName: the name of the mesh group
2564 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2567 :class:`SMESH.SMESH_GroupOnFilter`
2570 :meth:`smeshBuilder.GetCriterion`
2573 return self.MakeGroupByCriteria( groupName, [Criterion] )
2575 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2577 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2580 groupName: the name of the mesh group
2581 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2582 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2585 :class:`SMESH.SMESH_GroupOnFilter`
2588 :meth:`smeshBuilder.GetCriterion`
2591 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2592 group = self.MakeGroupByFilter(groupName, aFilter)
2595 def MakeGroupByFilter(self, groupName, theFilter):
2597 Create a mesh group by the given filter
2600 groupName (string): the name of the mesh group
2601 theFilter (SMESH.Filter): the filter
2604 :class:`SMESH.SMESH_GroupOnFilter`
2607 :meth:`smeshBuilder.GetFilter`
2610 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2611 #theFilter.SetMesh( self.mesh )
2612 #group.AddFrom( theFilter )
2613 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2616 def RemoveGroup(self, group):
2621 group (SMESH.SMESH_GroupBase): group to remove
2624 self.mesh.RemoveGroup(group)
2626 def RemoveGroupWithContents(self, group):
2628 Remove a group with its contents
2631 group (SMESH.SMESH_GroupBase): group to remove
2634 self.mesh.RemoveGroupWithContents(group)
2636 def GetGroups(self, elemType = SMESH.ALL):
2638 Get the list of groups existing in the mesh in the order
2639 of creation (starting from the oldest one)
2642 elemType (SMESH.ElementType): type of elements the groups contain;
2643 by default groups of elements of all types are returned
2646 a sequence of :class:`SMESH.SMESH_GroupBase`
2649 groups = self.mesh.GetGroups()
2650 if elemType == SMESH.ALL:
2654 if g.GetType() == elemType:
2655 typedGroups.append( g )
2662 Get the number of groups existing in the mesh
2665 the quantity of groups as an integer value
2668 return self.mesh.NbGroups()
2670 def GetGroupNames(self):
2672 Get the list of names of groups existing in the mesh
2678 groups = self.GetGroups()
2680 for group in groups:
2681 names.append(group.GetName())
2684 def GetGroupByName(self, name, elemType = None):
2686 Find groups by name and type
2689 name (string): name of the group of interest
2690 elemType (SMESH.ElementType): type of elements the groups contain;
2691 by default one group of any type is returned;
2692 if elemType == SMESH.ALL then all groups of any type are returned
2695 a list of :class:`SMESH.SMESH_GroupBase`
2699 for group in self.GetGroups():
2700 if group.GetName() == name:
2701 if elemType is None:
2703 if ( elemType == SMESH.ALL or
2704 group.GetType() == elemType ):
2705 groups.append( group )
2708 def UnionGroups(self, group1, group2, name):
2710 Produce a union of two groups.
2711 A new group is created. All mesh elements that are
2712 present in the initial groups are added to the new one
2715 group1 (SMESH.SMESH_GroupBase): a group
2716 group2 (SMESH.SMESH_GroupBase): another group
2719 instance of :class:`SMESH.SMESH_Group`
2722 return self.mesh.UnionGroups(group1, group2, name)
2724 def UnionListOfGroups(self, groups, name):
2726 Produce a union list of groups.
2727 New group is created. All mesh elements that are present in
2728 initial groups are added to the new one
2731 groups: list of :class:`SMESH.SMESH_GroupBase`
2734 instance of :class:`SMESH.SMESH_Group`
2736 return self.mesh.UnionListOfGroups(groups, name)
2738 def IntersectGroups(self, group1, group2, name):
2740 Prodice an intersection of two groups.
2741 A new group is created. All mesh elements that are common
2742 for the two initial groups are added to the new one.
2745 group1 (SMESH.SMESH_GroupBase): a group
2746 group2 (SMESH.SMESH_GroupBase): another group
2749 instance of :class:`SMESH.SMESH_Group`
2752 return self.mesh.IntersectGroups(group1, group2, name)
2754 def IntersectListOfGroups(self, groups, name):
2756 Produce an intersection of groups.
2757 New group is created. All mesh elements that are present in all
2758 initial groups simultaneously are added to the new one
2761 groups: a list of :class:`SMESH.SMESH_GroupBase`
2764 instance of :class:`SMESH.SMESH_Group`
2766 return self.mesh.IntersectListOfGroups(groups, name)
2768 def CutGroups(self, main_group, tool_group, name):
2770 Produce a cut of two groups.
2771 A new group is created. All mesh elements that are present in
2772 the main group but are not present in the tool group are added to the new one
2775 main_group (SMESH.SMESH_GroupBase): a group to cut from
2776 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2779 an instance of :class:`SMESH.SMESH_Group`
2782 return self.mesh.CutGroups(main_group, tool_group, name)
2784 def CutListOfGroups(self, main_groups, tool_groups, name):
2786 Produce a cut of groups.
2787 A new group is created. All mesh elements that are present in main groups
2788 but do not present in tool groups are added to the new one
2791 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2792 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2795 an instance of :class:`SMESH.SMESH_Group`
2798 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2800 def CreateDimGroup(self, groups, elemType, name,
2801 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2803 Create a standalone group of entities basing on nodes of other groups.
2806 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2807 elemType: a type of elements to include to the new group; either of
2808 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2809 name: a name of the new group.
2810 nbCommonNodes: a criterion of inclusion of an element to the new group
2811 basing on number of element nodes common with reference *groups*.
2812 Meaning of possible values are:
2814 - SMESH.ALL_NODES - include if all nodes are common,
2815 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2816 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2817 - SMEHS.MAJORITY - include if half of nodes or more are common.
2818 underlyingOnly: if *True* (default), an element is included to the
2819 new group provided that it is based on nodes of an element of *groups*;
2820 in this case the reference *groups* are supposed to be of higher dimension
2821 than *elemType*, which can be useful for example to get all faces lying on
2822 volumes of the reference *groups*.
2825 an instance of :class:`SMESH.SMESH_Group`
2828 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2830 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2833 def ConvertToStandalone(self, group):
2835 Convert group on geom into standalone group
2838 return self.mesh.ConvertToStandalone(group)
2840 # Get some info about mesh:
2841 # ------------------------
2843 def GetLog(self, clearAfterGet):
2845 Return the log of nodes and elements added or removed
2846 since the previous clear of the log.
2849 clearAfterGet: log is emptied after Get (safe if concurrents access)
2852 list of SMESH.log_block structures { commandType, number, coords, indexes }
2855 return self.mesh.GetLog(clearAfterGet)
2859 Clear the log of nodes and elements added or removed since the previous
2860 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2863 self.mesh.ClearLog()
2865 def SetAutoColor(self, theAutoColor):
2867 Toggle auto color mode on the object.
2868 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2871 theAutoColor (boolean): the flag which toggles auto color mode.
2874 self.mesh.SetAutoColor(theAutoColor)
2876 def GetAutoColor(self):
2878 Get flag of object auto color mode.
2884 return self.mesh.GetAutoColor()
2891 integer value, which is the internal Id of the mesh
2894 return self.mesh.GetId()
2896 def HasDuplicatedGroupNamesMED(self):
2898 Check the group names for duplications.
2899 Consider the maximum group name length stored in MED file.
2905 return self.mesh.HasDuplicatedGroupNamesMED()
2907 def GetMeshEditor(self):
2909 Obtain the mesh editor tool
2912 an instance of :class:`SMESH.SMESH_MeshEditor`
2917 def GetIDSource(self, ids, elemType = SMESH.ALL):
2919 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2920 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2924 elemType: type of elements; this parameter is used to distinguish
2925 IDs of nodes from IDs of elements; by default ids are treated as
2926 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2929 an instance of :class:`SMESH.SMESH_IDSource`
2932 call UnRegister() for the returned object as soon as it is no more useful::
2934 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2935 mesh.DoSomething( idSrc )
2939 if isinstance( ids, int ):
2941 return self.editor.MakeIDSource(ids, elemType)
2944 # Get information about mesh contents:
2945 # ------------------------------------
2947 def GetMeshInfo(self, obj = None):
2949 Get the mesh statistic.
2950 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2951 an item of :class:`SMESH.EntityType`.
2954 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2957 if not obj: obj = self.mesh
2958 return self.smeshpyD.GetMeshInfo(obj)
2962 Return the number of nodes in the mesh
2968 return self.mesh.NbNodes()
2970 def NbElements(self):
2972 Return the number of elements in the mesh
2978 return self.mesh.NbElements()
2980 def Nb0DElements(self):
2982 Return the number of 0d elements in the mesh
2988 return self.mesh.Nb0DElements()
2992 Return the number of ball discrete elements in the mesh
2998 return self.mesh.NbBalls()
3002 Return the number of edges in the mesh
3008 return self.mesh.NbEdges()
3010 def NbEdgesOfOrder(self, elementOrder):
3012 Return the number of edges with the given order in the mesh
3015 elementOrder: the order of elements
3016 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3022 return self.mesh.NbEdgesOfOrder(elementOrder)
3026 Return the number of faces in the mesh
3032 return self.mesh.NbFaces()
3034 def NbFacesOfOrder(self, elementOrder):
3036 Return the number of faces with the given order in the mesh
3039 elementOrder: the order of elements
3040 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3046 return self.mesh.NbFacesOfOrder(elementOrder)
3048 def NbTriangles(self):
3050 Return the number of triangles in the mesh
3056 return self.mesh.NbTriangles()
3058 def NbTrianglesOfOrder(self, elementOrder):
3060 Return the number of triangles with the given order in the mesh
3063 elementOrder: is the order of elements
3064 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3070 return self.mesh.NbTrianglesOfOrder(elementOrder)
3072 def NbBiQuadTriangles(self):
3074 Return the number of biquadratic triangles in the mesh
3080 return self.mesh.NbBiQuadTriangles()
3082 def NbQuadrangles(self):
3084 Return the number of quadrangles in the mesh
3090 return self.mesh.NbQuadrangles()
3092 def NbQuadranglesOfOrder(self, elementOrder):
3094 Return the number of quadrangles with the given order in the mesh
3097 elementOrder: the order of elements
3098 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3104 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3106 def NbBiQuadQuadrangles(self):
3108 Return the number of biquadratic quadrangles in the mesh
3114 return self.mesh.NbBiQuadQuadrangles()
3116 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3118 Return the number of polygons of given order in the mesh
3121 elementOrder: the order of elements
3122 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3128 return self.mesh.NbPolygonsOfOrder(elementOrder)
3130 def NbVolumes(self):
3132 Return the number of volumes in the mesh
3138 return self.mesh.NbVolumes()
3141 def NbVolumesOfOrder(self, elementOrder):
3143 Return the number of volumes with the given order in the mesh
3146 elementOrder: the order of elements
3147 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3153 return self.mesh.NbVolumesOfOrder(elementOrder)
3157 Return the number of tetrahedrons in the mesh
3163 return self.mesh.NbTetras()
3165 def NbTetrasOfOrder(self, elementOrder):
3167 Return the number of tetrahedrons with the given order in the mesh
3170 elementOrder: the order of elements
3171 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3177 return self.mesh.NbTetrasOfOrder(elementOrder)
3181 Return the number of hexahedrons in the mesh
3187 return self.mesh.NbHexas()
3189 def NbHexasOfOrder(self, elementOrder):
3191 Return the number of hexahedrons with the given order in the mesh
3194 elementOrder: the order of elements
3195 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3201 return self.mesh.NbHexasOfOrder(elementOrder)
3203 def NbTriQuadraticHexas(self):
3205 Return the number of triquadratic hexahedrons in the mesh
3211 return self.mesh.NbTriQuadraticHexas()
3213 def NbPyramids(self):
3215 Return the number of pyramids in the mesh
3221 return self.mesh.NbPyramids()
3223 def NbPyramidsOfOrder(self, elementOrder):
3225 Return the number of pyramids with the given order in the mesh
3228 elementOrder: the order of elements
3229 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3235 return self.mesh.NbPyramidsOfOrder(elementOrder)
3239 Return the number of prisms in the mesh
3245 return self.mesh.NbPrisms()
3247 def NbPrismsOfOrder(self, elementOrder):
3249 Return the number of prisms with the given order in the mesh
3252 elementOrder: the order of elements
3253 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3259 return self.mesh.NbPrismsOfOrder(elementOrder)
3261 def NbHexagonalPrisms(self):
3263 Return the number of hexagonal prisms in the mesh
3269 return self.mesh.NbHexagonalPrisms()
3271 def NbPolyhedrons(self):
3273 Return the number of polyhedrons in the mesh
3279 return self.mesh.NbPolyhedrons()
3281 def NbSubMesh(self):
3283 Return the number of submeshes in the mesh
3289 return self.mesh.NbSubMesh()
3291 def GetElementsId(self):
3293 Return the list of all mesh elements IDs
3296 the list of integer values
3299 :meth:`GetElementsByType`
3302 return self.mesh.GetElementsId()
3304 def GetElementsByType(self, elementType):
3306 Return the list of IDs of mesh elements with the given type
3309 elementType (SMESH.ElementType): the required type of elements
3312 list of integer values
3315 return self.mesh.GetElementsByType(elementType)
3317 def GetNodesId(self):
3319 Return the list of mesh nodes IDs
3322 the list of integer values
3325 return self.mesh.GetNodesId()
3327 # Get the information about mesh elements:
3328 # ------------------------------------
3330 def GetElementType(self, id, iselem=True):
3332 Return the type of mesh element or node
3335 the value from :class:`SMESH.ElementType` enumeration.
3336 Return SMESH.ALL if element or node with the given ID does not exist
3339 return self.mesh.GetElementType(id, iselem)
3341 def GetElementGeomType(self, id):
3343 Return the geometric type of mesh element
3346 the value from :class:`SMESH.EntityType` enumeration.
3349 return self.mesh.GetElementGeomType(id)
3351 def GetElementShape(self, id):
3353 Return the shape type of mesh element
3356 the value from :class:`SMESH.GeometryType` enumeration.
3359 return self.mesh.GetElementShape(id)
3361 def GetSubMeshElementsId(self, Shape):
3363 Return the list of sub-mesh elements IDs
3366 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3367 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3370 list of integer values
3373 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3374 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3377 return self.mesh.GetSubMeshElementsId(ShapeID)
3379 def GetSubMeshNodesId(self, Shape, all):
3381 Return the list of sub-mesh nodes IDs
3384 Shape: a geom object (sub-shape).
3385 *Shape* must be the sub-shape of a :meth:`GetShape`
3386 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3389 list of integer values
3392 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3393 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3396 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3398 def GetSubMeshElementType(self, Shape):
3400 Return type of elements on given shape
3403 Shape: a geom object (sub-shape).
3404 *Shape* must be a sub-shape of a ShapeToMesh()
3407 :class:`SMESH.ElementType`
3410 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3411 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3414 return self.mesh.GetSubMeshElementType(ShapeID)
3418 Get the mesh description
3424 return self.mesh.Dump()
3427 # Get the information about nodes and elements of a mesh by its IDs:
3428 # -----------------------------------------------------------
3430 def GetNodeXYZ(self, id):
3432 Get XYZ coordinates of a node.
3433 If there is no node for the given ID - return an empty list
3436 list of float values
3439 return self.mesh.GetNodeXYZ(id)
3441 def GetNodeInverseElements(self, id):
3443 Return list of IDs of inverse elements for the given node.
3444 If there is no node for the given ID - return an empty list
3447 list of integer values
3450 return self.mesh.GetNodeInverseElements(id)
3452 def GetNodePosition(self,NodeID):
3454 Return the position of a node on the shape
3457 :class:`SMESH.NodePosition`
3460 return self.mesh.GetNodePosition(NodeID)
3462 def GetElementPosition(self,ElemID):
3464 Return the position of an element on the shape
3467 :class:`SMESH.ElementPosition`
3470 return self.mesh.GetElementPosition(ElemID)
3472 def GetShapeID(self, id):
3474 Return the ID of the shape, on which the given node was generated.
3477 an integer value > 0 or -1 if there is no node for the given
3478 ID or the node is not assigned to any geometry
3481 return self.mesh.GetShapeID(id)
3483 def GetShapeIDForElem(self,id):
3485 Return the ID of the shape, on which the given element was generated.
3488 an integer value > 0 or -1 if there is no element for the given
3489 ID or the element is not assigned to any geometry
3492 return self.mesh.GetShapeIDForElem(id)
3494 def GetElemNbNodes(self, id):
3496 Return the number of nodes of the given element
3499 an integer value > 0 or -1 if there is no element for the given ID
3502 return self.mesh.GetElemNbNodes(id)
3504 def GetElemNode(self, id, index):
3506 Return the node ID the given (zero based) index for the given element.
3508 * If there is no element for the given ID - return -1.
3509 * If there is no node for the given index - return -2.
3512 id (int): element ID
3513 index (int): node index within the element
3516 an integer value (ID)
3519 :meth:`GetElemNodes`
3522 return self.mesh.GetElemNode(id, index)
3524 def GetElemNodes(self, id):
3526 Return the IDs of nodes of the given element
3529 a list of integer values
3532 return self.mesh.GetElemNodes(id)
3534 def IsMediumNode(self, elementID, nodeID):
3536 Return true if the given node is the medium node in the given quadratic element
3539 return self.mesh.IsMediumNode(elementID, nodeID)
3541 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3543 Return true if the given node is the medium node in one of quadratic elements
3546 nodeID: ID of the node
3547 elementType: the type of elements to check a state of the node, either of
3548 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3551 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3553 def ElemNbEdges(self, id):
3555 Return the number of edges for the given element
3558 return self.mesh.ElemNbEdges(id)
3560 def ElemNbFaces(self, id):
3562 Return the number of faces for the given element
3565 return self.mesh.ElemNbFaces(id)
3567 def GetElemFaceNodes(self,elemId, faceIndex):
3569 Return nodes of given face (counted from zero) for given volumic element.
3572 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3574 def GetFaceNormal(self, faceId, normalized=False):
3576 Return three components of normal of given mesh face
3577 (or an empty array in KO case)
3580 return self.mesh.GetFaceNormal(faceId,normalized)
3582 def FindElementByNodes(self, nodes):
3584 Return an element based on all given nodes.
3587 return self.mesh.FindElementByNodes(nodes)
3589 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3591 Return elements including all given nodes.
3594 return self.mesh.GetElementsByNodes( nodes, elemType )
3596 def IsPoly(self, id):
3598 Return true if the given element is a polygon
3601 return self.mesh.IsPoly(id)
3603 def IsQuadratic(self, id):
3605 Return true if the given element is quadratic
3608 return self.mesh.IsQuadratic(id)
3610 def GetBallDiameter(self, id):
3612 Return diameter of a ball discrete element or zero in case of an invalid *id*
3615 return self.mesh.GetBallDiameter(id)
3617 def BaryCenter(self, id):
3619 Return XYZ coordinates of the barycenter of the given element.
3620 If there is no element for the given ID - return an empty list
3623 a list of three double values
3626 return self.mesh.BaryCenter(id)
3628 def GetIdsFromFilter(self, theFilter):
3630 Pass mesh elements through the given filter and return IDs of fitting elements
3633 theFilter: :class:`SMESH.Filter`
3639 :meth:`SMESH.Filter.GetIDs`
3642 theFilter.SetMesh( self.mesh )
3643 return theFilter.GetIDs()
3645 # Get mesh measurements information:
3646 # ------------------------------------
3648 def GetFreeBorders(self):
3650 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3651 Return a list of special structures (borders).
3654 a list of :class:`SMESH.FreeEdges.Border`
3657 aFilterMgr = self.smeshpyD.CreateFilterManager()
3658 aPredicate = aFilterMgr.CreateFreeEdges()
3659 aPredicate.SetMesh(self.mesh)
3660 aBorders = aPredicate.GetBorders()
3661 aFilterMgr.UnRegister()
3664 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3666 Get minimum distance between two nodes, elements or distance to the origin
3669 id1: first node/element id
3670 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3671 isElem1: *True* if *id1* is element id, *False* if it is node id
3672 isElem2: *True* if *id2* is element id, *False* if it is node id
3675 minimum distance value **GetMinDistance()**
3678 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3679 return aMeasure.value
3681 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3683 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3686 id1: first node/element id
3687 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3688 isElem1: *True* if *id1* is element id, *False* if it is node id
3689 isElem2: *True* if *id2* is element id, *False* if it is node id
3692 :class:`SMESH.Measure` structure
3698 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3700 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3703 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3705 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3710 aMeasurements = self.smeshpyD.CreateMeasurements()
3711 aMeasure = aMeasurements.MinDistance(id1, id2)
3712 genObjUnRegister([aMeasurements,id1, id2])
3715 def BoundingBox(self, objects=None, isElem=False):
3717 Get bounding box of the specified object(s)
3720 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3721 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3722 *False* specifies that *objects* are nodes
3725 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3728 :meth:`GetBoundingBox()`
3731 result = self.GetBoundingBox(objects, isElem)
3735 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3738 def GetBoundingBox(self, objects=None, isElem=False):
3740 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3743 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3744 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3745 False means that *objects* are nodes
3748 :class:`SMESH.Measure` structure
3751 :meth:`BoundingBox()`
3755 objects = [self.mesh]
3756 elif isinstance(objects, tuple):
3757 objects = list(objects)
3758 if not isinstance(objects, list):
3760 if len(objects) > 0 and isinstance(objects[0], int):
3763 unRegister = genObjUnRegister()
3765 if isinstance(o, Mesh):
3766 srclist.append(o.mesh)
3767 elif hasattr(o, "_narrow"):
3768 src = o._narrow(SMESH.SMESH_IDSource)
3769 if src: srclist.append(src)
3771 elif isinstance(o, list):
3773 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3775 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3776 unRegister.set( srclist[-1] )
3779 aMeasurements = self.smeshpyD.CreateMeasurements()
3780 unRegister.set( aMeasurements )
3781 aMeasure = aMeasurements.BoundingBox(srclist)
3784 # Mesh edition (SMESH_MeshEditor functionality):
3785 # ---------------------------------------------
3787 def RemoveElements(self, IDsOfElements):
3789 Remove the elements from the mesh by ids
3792 IDsOfElements: is a list of ids of elements to remove
3798 return self.editor.RemoveElements(IDsOfElements)
3800 def RemoveNodes(self, IDsOfNodes):
3802 Remove nodes from mesh by ids
3805 IDsOfNodes: is a list of ids of nodes to remove
3811 return self.editor.RemoveNodes(IDsOfNodes)
3813 def RemoveOrphanNodes(self):
3815 Remove all orphan (free) nodes from mesh
3818 number of the removed nodes
3821 return self.editor.RemoveOrphanNodes()
3823 def AddNode(self, x, y, z):
3825 Add a node to the mesh by coordinates
3831 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3832 if hasVars: self.mesh.SetParameters(Parameters)
3833 return self.editor.AddNode( x, y, z)
3835 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3837 Create a 0D element on a node with given number.
3840 IDOfNode: the ID of node for creation of the element.
3841 DuplicateElements: to add one more 0D element to a node or not
3844 ID of the new 0D element
3847 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3849 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3851 Create 0D elements on all nodes of the given elements except those
3852 nodes on which a 0D element already exists.
3855 theObject: an object on whose nodes 0D elements will be created.
3856 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3857 theGroupName: optional name of a group to add 0D elements created
3858 and/or found on nodes of *theObject*.
3859 DuplicateElements: to add one more 0D element to a node or not
3862 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3863 IDs of new and/or found 0D elements. IDs of 0D elements
3864 can be retrieved from the returned object by
3865 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3868 unRegister = genObjUnRegister()
3869 if isinstance( theObject, Mesh ):
3870 theObject = theObject.GetMesh()
3871 elif isinstance( theObject, list ):
3872 theObject = self.GetIDSource( theObject, SMESH.ALL )
3873 unRegister.set( theObject )
3874 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3876 def AddBall(self, IDOfNode, diameter):
3878 Create a ball element on a node with given ID.
3881 IDOfNode: the ID of node for creation of the element.
3882 diameter: the bal diameter.
3885 ID of the new ball element
3888 return self.editor.AddBall( IDOfNode, diameter )
3890 def AddEdge(self, IDsOfNodes):
3892 Create a linear or quadratic edge (this is determined
3893 by the number of given nodes).
3896 IDsOfNodes: list of node IDs for creation of the element.
3897 The order of nodes in this list should correspond to
3898 the :ref:`connectivity convention <connectivity_page>`.
3904 return self.editor.AddEdge(IDsOfNodes)
3906 def AddFace(self, IDsOfNodes):
3908 Create a linear or quadratic face (this is determined
3909 by the number of given nodes).
3912 IDsOfNodes: list of node IDs for creation of the element.
3913 The order of nodes in this list should correspond to
3914 the :ref:`connectivity convention <connectivity_page>`.
3920 return self.editor.AddFace(IDsOfNodes)
3922 def AddPolygonalFace(self, IdsOfNodes):
3924 Add a polygonal face defined by a list of node IDs
3927 IdsOfNodes: the list of node IDs for creation of the element.
3933 return self.editor.AddPolygonalFace(IdsOfNodes)
3935 def AddQuadPolygonalFace(self, IdsOfNodes):
3937 Add a quadratic polygonal face defined by a list of node IDs
3940 IdsOfNodes: the list of node IDs for creation of the element;
3941 corner nodes follow first.
3947 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3949 def AddVolume(self, IDsOfNodes):
3951 Create both simple and quadratic volume (this is determined
3952 by the number of given nodes).
3955 IDsOfNodes: list of node IDs for creation of the element.
3956 The order of nodes in this list should correspond to
3957 the :ref:`connectivity convention <connectivity_page>`.
3960 ID of the new volumic element
3963 return self.editor.AddVolume(IDsOfNodes)
3965 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3967 Create a volume of many faces, giving nodes for each face.
3970 IdsOfNodes: list of node IDs for volume creation, face by face.
3971 Quantities: list of integer values, Quantities[i]
3972 gives the quantity of nodes in face number i.
3975 ID of the new volumic element
3978 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3980 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3982 Create a volume of many faces, giving the IDs of the existing faces.
3985 The created volume will refer only to the nodes
3986 of the given faces, not to the faces themselves.
3989 IdsOfFaces: the list of face IDs for volume creation.
3992 ID of the new volumic element
3995 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
3998 def SetNodeOnVertex(self, NodeID, Vertex):
4000 Binds a node to a vertex
4004 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4007 True if succeed else raises an exception
4010 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4011 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4015 self.editor.SetNodeOnVertex(NodeID, VertexID)
4016 except SALOME.SALOME_Exception as inst:
4017 raise ValueError(inst.details.text)
4021 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4023 Stores the node position on an edge
4027 Edge: an edge (GEOM.GEOM_Object) or edge ID
4028 paramOnEdge: a parameter on the edge where the node is located
4031 True if succeed else raises an exception
4034 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4035 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4039 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4040 except SALOME.SALOME_Exception as inst:
4041 raise ValueError(inst.details.text)
4044 def SetNodeOnFace(self, NodeID, Face, u, v):
4046 Stores node position on a face
4050 Face: a face (GEOM.GEOM_Object) or face ID
4051 u: U parameter on the face where the node is located
4052 v: V parameter on the face where the node is located
4055 True if succeed else raises an exception
4058 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4059 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4063 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4064 except SALOME.SALOME_Exception as inst:
4065 raise ValueError(inst.details.text)
4068 def SetNodeInVolume(self, NodeID, Solid):
4070 Binds a node to a solid
4074 Solid: a solid (GEOM.GEOM_Object) or solid ID
4077 True if succeed else raises an exception
4080 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4081 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4085 self.editor.SetNodeInVolume(NodeID, SolidID)
4086 except SALOME.SALOME_Exception as inst:
4087 raise ValueError(inst.details.text)
4090 def SetMeshElementOnShape(self, ElementID, Shape):
4092 Bind an element to a shape
4095 ElementID: an element ID
4096 Shape: a shape (GEOM.GEOM_Object) or shape ID
4099 True if succeed else raises an exception
4102 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4103 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4107 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4108 except SALOME.SALOME_Exception as inst:
4109 raise ValueError(inst.details.text)
4113 def MoveNode(self, NodeID, x, y, z):
4115 Move the node with the given id
4118 NodeID: the id of the node
4119 x: a new X coordinate
4120 y: a new Y coordinate
4121 z: a new Z coordinate
4124 True if succeed else False
4127 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4128 if hasVars: self.mesh.SetParameters(Parameters)
4129 return self.editor.MoveNode(NodeID, x, y, z)
4131 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4133 Find the node closest to a point and moves it to a point location
4136 x: the X coordinate of a point
4137 y: the Y coordinate of a point
4138 z: the Z coordinate of a point
4139 NodeID: if specified (>0), the node with this ID is moved,
4140 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4143 the ID of a moved node
4146 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4147 if hasVars: self.mesh.SetParameters(Parameters)
4148 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4150 def FindNodeClosestTo(self, x, y, z):
4152 Find the node closest to a point
4155 x: the X coordinate of a point
4156 y: the Y coordinate of a point
4157 z: the Z coordinate of a point
4163 #preview = self.mesh.GetMeshEditPreviewer()
4164 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4165 return self.editor.FindNodeClosestTo(x, y, z)
4167 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4169 Find the elements where a point lays IN or ON
4172 x,y,z (float): coordinates of the point
4173 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4174 means elements of any type excluding nodes, discrete and 0D elements.
4175 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4178 list of IDs of found elements
4181 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4183 return self.editor.FindElementsByPoint(x, y, z, elementType)
4185 def GetPointState(self, x, y, z):
4187 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4188 0-IN, 1-OUT, 2-ON, 3-UNKNOWN.
4189 UNKNOWN state means that either mesh is wrong or the analysis fails.
4192 return self.editor.GetPointState(x, y, z)
4194 def IsManifold(self):
4196 Check if a 2D mesh is manifold
4199 return self.editor.IsManifold()
4201 def IsCoherentOrientation2D(self):
4203 Check if orientation of 2D elements is coherent
4206 return self.editor.IsCoherentOrientation2D()
4208 def MeshToPassThroughAPoint(self, x, y, z):
4210 Find the node closest to a point and moves it to a point location
4213 x: the X coordinate of a point
4214 y: the Y coordinate of a point
4215 z: the Z coordinate of a point
4218 the ID of a moved node
4221 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4223 def InverseDiag(self, NodeID1, NodeID2):
4225 Replace two neighbour triangles sharing Node1-Node2 link
4226 with the triangles built on the same 4 nodes but having other common link.
4229 NodeID1: the ID of the first node
4230 NodeID2: the ID of the second node
4233 False if proper faces were not found
4235 return self.editor.InverseDiag(NodeID1, NodeID2)
4237 def DeleteDiag(self, NodeID1, NodeID2):
4239 Replace two neighbour triangles sharing *Node1-Node2* link
4240 with a quadrangle built on the same 4 nodes.
4243 NodeID1: ID of the first node
4244 NodeID2: ID of the second node
4247 False if proper faces were not found
4250 return self.editor.DeleteDiag(NodeID1, NodeID2)
4252 def Reorient(self, IDsOfElements=None):
4254 Reorient elements by ids
4257 IDsOfElements: if undefined reorients all mesh elements
4260 True if succeed else False
4263 if IDsOfElements == None:
4264 IDsOfElements = self.GetElementsId()
4265 return self.editor.Reorient(IDsOfElements)
4267 def ReorientObject(self, theObject):
4269 Reorient all elements of the object
4272 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4275 True if succeed else False
4278 if ( isinstance( theObject, Mesh )):
4279 theObject = theObject.GetMesh()
4280 return self.editor.ReorientObject(theObject)
4282 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4284 Reorient faces contained in *the2DObject*.
4287 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4288 theDirection: is a desired direction of normal of *theFace*.
4289 It can be either a GEOM vector or a list of coordinates [x,y,z].
4290 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4291 compared with theDirection. It can be either ID of face or a point
4292 by which the face will be found. The point can be given as either
4293 a GEOM vertex or a list of point coordinates.
4296 number of reoriented faces
4299 unRegister = genObjUnRegister()
4301 if isinstance( the2DObject, Mesh ):
4302 the2DObject = the2DObject.GetMesh()
4303 if isinstance( the2DObject, list ):
4304 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4305 unRegister.set( the2DObject )
4306 # check theDirection
4307 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4308 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4309 if isinstance( theDirection, list ):
4310 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4311 # prepare theFace and thePoint
4312 theFace = theFaceOrPoint
4313 thePoint = PointStruct(0,0,0)
4314 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4315 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4317 if isinstance( theFaceOrPoint, list ):
4318 thePoint = PointStruct( *theFaceOrPoint )
4320 if isinstance( theFaceOrPoint, PointStruct ):
4321 thePoint = theFaceOrPoint
4323 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4325 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4327 Reorient faces according to adjacent volumes.
4330 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4331 either IDs of faces or face groups.
4332 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4333 theOutsideNormal: to orient faces to have their normals
4334 pointing either *outside* or *inside* the adjacent volumes.
4337 number of reoriented faces.
4340 unRegister = genObjUnRegister()
4342 if not isinstance( the2DObject, list ):
4343 the2DObject = [ the2DObject ]
4344 elif the2DObject and isinstance( the2DObject[0], int ):
4345 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4346 unRegister.set( the2DObject )
4347 the2DObject = [ the2DObject ]
4348 for i,obj2D in enumerate( the2DObject ):
4349 if isinstance( obj2D, Mesh ):
4350 the2DObject[i] = obj2D.GetMesh()
4351 if isinstance( obj2D, list ):
4352 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4353 unRegister.set( the2DObject[i] )
4355 if isinstance( the3DObject, Mesh ):
4356 the3DObject = the3DObject.GetMesh()
4357 if isinstance( the3DObject, list ):
4358 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4359 unRegister.set( the3DObject )
4360 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4362 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4364 Fuse the neighbouring triangles into quadrangles.
4367 IDsOfElements: The triangles to be fused.
4368 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4369 applied to possible quadrangles to choose a neighbour to fuse with.
4370 Note that not all items of :class:`SMESH.FunctorType` corresponds
4371 to numerical functors.
4372 MaxAngle: is the maximum angle between element normals at which the fusion
4373 is still performed; theMaxAngle is measured in radians.
4374 Also it could be a name of variable which defines angle in degrees.
4377 True in case of success, False otherwise.
4380 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4381 self.mesh.SetParameters(Parameters)
4382 if not IDsOfElements:
4383 IDsOfElements = self.GetElementsId()
4384 Functor = self.smeshpyD.GetFunctor(theCriterion)
4385 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4387 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4389 Fuse the neighbouring triangles of the object into quadrangles
4392 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4393 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4394 applied to possible quadrangles to choose a neighbour to fuse with.
4395 Note that not all items of :class:`SMESH.FunctorType` corresponds
4396 to numerical functors.
4397 MaxAngle: a max angle between element normals at which the fusion
4398 is still performed; theMaxAngle is measured in radians.
4401 True in case of success, False otherwise.
4404 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4405 self.mesh.SetParameters(Parameters)
4406 if isinstance( theObject, Mesh ):
4407 theObject = theObject.GetMesh()
4408 Functor = self.smeshpyD.GetFunctor(theCriterion)
4409 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4411 def QuadToTri (self, IDsOfElements, theCriterion = None):
4413 Split quadrangles into triangles.
4416 IDsOfElements: the faces to be splitted.
4417 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4418 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4419 value, then quadrangles will be split by the smallest diagonal.
4420 Note that not all items of :class:`SMESH.FunctorType` corresponds
4421 to numerical functors.
4424 True in case of success, False otherwise.
4426 if IDsOfElements == []:
4427 IDsOfElements = self.GetElementsId()
4428 if theCriterion is None:
4429 theCriterion = FT_MaxElementLength2D
4430 Functor = self.smeshpyD.GetFunctor(theCriterion)
4431 return self.editor.QuadToTri(IDsOfElements, Functor)
4433 def QuadToTriObject (self, theObject, theCriterion = None):
4435 Split quadrangles into triangles.
4438 theObject: the object from which the list of elements is taken,
4439 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4440 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4441 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4442 value, then quadrangles will be split by the smallest diagonal.
4443 Note that not all items of :class:`SMESH.FunctorType` corresponds
4444 to numerical functors.
4447 True in case of success, False otherwise.
4449 if ( isinstance( theObject, Mesh )):
4450 theObject = theObject.GetMesh()
4451 if theCriterion is None:
4452 theCriterion = FT_MaxElementLength2D
4453 Functor = self.smeshpyD.GetFunctor(theCriterion)
4454 return self.editor.QuadToTriObject(theObject, Functor)
4456 def QuadTo4Tri (self, theElements=[]):
4458 Split each of given quadrangles into 4 triangles. A node is added at the center of
4462 theElements: the faces to be splitted. This can be either
4463 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4464 or a list of face IDs. By default all quadrangles are split
4466 unRegister = genObjUnRegister()
4467 if isinstance( theElements, Mesh ):
4468 theElements = theElements.mesh
4469 elif not theElements:
4470 theElements = self.mesh
4471 elif isinstance( theElements, list ):
4472 theElements = self.GetIDSource( theElements, SMESH.FACE )
4473 unRegister.set( theElements )
4474 return self.editor.QuadTo4Tri( theElements )
4476 def SplitQuad (self, IDsOfElements, Diag13):
4478 Split quadrangles into triangles.
4481 IDsOfElements: the faces to be splitted
4482 Diag13: is used to choose a diagonal for splitting.
4485 True in case of success, False otherwise.
4487 if IDsOfElements == []:
4488 IDsOfElements = self.GetElementsId()
4489 return self.editor.SplitQuad(IDsOfElements, Diag13)
4491 def SplitQuadObject (self, theObject, Diag13):
4493 Split quadrangles into triangles.
4496 theObject: the object from which the list of elements is taken,
4497 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4498 Diag13: is used to choose a diagonal for splitting.
4501 True in case of success, False otherwise.
4503 if ( isinstance( theObject, Mesh )):
4504 theObject = theObject.GetMesh()
4505 return self.editor.SplitQuadObject(theObject, Diag13)
4507 def BestSplit (self, IDOfQuad, theCriterion):
4509 Find a better splitting of the given quadrangle.
4512 IDOfQuad: the ID of the quadrangle to be splitted.
4513 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4514 choose a diagonal for splitting.
4515 Note that not all items of :class:`SMESH.FunctorType` corresponds
4516 to numerical functors.
4519 * 1 if 1-3 diagonal is better,
4520 * 2 if 2-4 diagonal is better,
4521 * 0 if error occurs.
4523 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4525 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4527 Split volumic elements into tetrahedrons
4530 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4531 method: flags passing splitting method:
4532 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4533 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4535 unRegister = genObjUnRegister()
4536 if isinstance( elems, Mesh ):
4537 elems = elems.GetMesh()
4538 if ( isinstance( elems, list )):
4539 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4540 unRegister.set( elems )
4541 self.editor.SplitVolumesIntoTetra(elems, method)
4544 def SplitBiQuadraticIntoLinear(self, elems=None):
4546 Split bi-quadratic elements into linear ones without creation of additional nodes:
4548 - bi-quadratic triangle will be split into 3 linear quadrangles;
4549 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4550 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4552 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4553 will be split in order to keep the mesh conformal.
4556 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4557 if None (default), all bi-quadratic elements will be split
4559 unRegister = genObjUnRegister()
4560 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4561 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4562 unRegister.set( elems )
4564 elems = [ self.GetMesh() ]
4565 if isinstance( elems, Mesh ):
4566 elems = [ elems.GetMesh() ]
4567 if not isinstance( elems, list ):
4569 self.editor.SplitBiQuadraticIntoLinear( elems )
4571 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4572 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4574 Split hexahedra into prisms
4577 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4578 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4579 gives a normal vector defining facets to split into triangles.
4580 *startHexPoint* can be either a triple of coordinates or a vertex.
4581 facetNormal: a normal to a facet to split into triangles of a
4582 hexahedron found by *startHexPoint*.
4583 *facetNormal* can be either a triple of coordinates or an edge.
4584 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4585 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4586 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4587 to *startHexPoint* are split, else *startHexPoint*
4588 is used to find the facet to split in all domains present in *elems*.
4591 unRegister = genObjUnRegister()
4592 if isinstance( elems, Mesh ):
4593 elems = elems.GetMesh()
4594 if ( isinstance( elems, list )):
4595 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4596 unRegister.set( elems )
4599 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4600 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4601 elif isinstance( startHexPoint, list ):
4602 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4605 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4606 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4607 elif isinstance( facetNormal, list ):
4608 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4611 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4613 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4615 def SplitQuadsNearTriangularFacets(self):
4617 Split quadrangle faces near triangular facets of volumes
4619 faces_array = self.GetElementsByType(SMESH.FACE)
4620 for face_id in faces_array:
4621 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4622 quad_nodes = self.mesh.GetElemNodes(face_id)
4623 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4624 isVolumeFound = False
4625 for node1_elem in node1_elems:
4626 if not isVolumeFound:
4627 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4628 nb_nodes = self.GetElemNbNodes(node1_elem)
4629 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4630 volume_elem = node1_elem
4631 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4632 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4633 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4634 isVolumeFound = True
4635 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4636 self.SplitQuad([face_id], False) # diagonal 2-4
4637 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4638 isVolumeFound = True
4639 self.SplitQuad([face_id], True) # diagonal 1-3
4640 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4641 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4642 isVolumeFound = True
4643 self.SplitQuad([face_id], True) # diagonal 1-3
4645 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4647 Split hexahedrons into tetrahedrons.
4649 This operation uses :doc:`pattern_mapping` functionality for splitting.
4652 theObject: the object from which the list of hexahedrons is taken;
4653 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4654 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4655 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4656 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4657 key-point will be mapped into *theNode001*-th node of each volume.
4658 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4661 True in case of success, False otherwise.
4669 # (0,0,1) 4.---------.7 * |
4676 # (0,0,0) 0.---------.3
4677 pattern_tetra = "!!! Nb of points: \n 8 \n\
4687 !!! Indices of points of 6 tetras: \n\
4695 pattern = self.smeshpyD.GetPattern()
4696 isDone = pattern.LoadFromFile(pattern_tetra)
4698 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4701 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4702 isDone = pattern.MakeMesh(self.mesh, False, False)
4703 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4705 # split quafrangle faces near triangular facets of volumes
4706 self.SplitQuadsNearTriangularFacets()
4710 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4712 Split hexahedrons into prisms.
4714 Uses the :doc:`pattern_mapping` functionality for splitting.
4717 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4718 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4719 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4720 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4721 will be mapped into the *theNode001* -th node of each volume.
4722 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4725 True in case of success, False otherwise.
4727 # Pattern: 5.---------.6
4732 # (0,0,1) 4.---------.7 |
4739 # (0,0,0) 0.---------.3
4740 pattern_prism = "!!! Nb of points: \n 8 \n\
4750 !!! Indices of points of 2 prisms: \n\
4754 pattern = self.smeshpyD.GetPattern()
4755 isDone = pattern.LoadFromFile(pattern_prism)
4757 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4760 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4761 isDone = pattern.MakeMesh(self.mesh, False, False)
4762 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4764 # Split quafrangle faces near triangular facets of volumes
4765 self.SplitQuadsNearTriangularFacets()
4769 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4770 MaxNbOfIterations, MaxAspectRatio, Method):
4775 IDsOfElements: the list if ids of elements to smooth
4776 IDsOfFixedNodes: the list of ids of fixed nodes.
4777 Note that nodes built on edges and boundary nodes are always fixed.
4778 MaxNbOfIterations: the maximum number of iterations
4779 MaxAspectRatio: varies in range [1.0, inf]
4780 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4781 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4784 True in case of success, False otherwise.
4787 if IDsOfElements == []:
4788 IDsOfElements = self.GetElementsId()
4789 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4790 self.mesh.SetParameters(Parameters)
4791 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4792 MaxNbOfIterations, MaxAspectRatio, Method)
4794 def SmoothObject(self, theObject, IDsOfFixedNodes,
4795 MaxNbOfIterations, MaxAspectRatio, Method):
4797 Smooth elements which belong to the given object
4800 theObject: the object to smooth
4801 IDsOfFixedNodes: the list of ids of fixed nodes.
4802 Note that nodes built on edges and boundary nodes are always fixed.
4803 MaxNbOfIterations: the maximum number of iterations
4804 MaxAspectRatio: varies in range [1.0, inf]
4805 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4806 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4809 True in case of success, False otherwise.
4812 if ( isinstance( theObject, Mesh )):
4813 theObject = theObject.GetMesh()
4814 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4815 MaxNbOfIterations, MaxAspectRatio, Method)
4817 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4818 MaxNbOfIterations, MaxAspectRatio, Method):
4820 Parametrically smooth the given elements
4823 IDsOfElements: the list if ids of elements to smooth
4824 IDsOfFixedNodes: the list of ids of fixed nodes.
4825 Note that nodes built on edges and boundary nodes are always fixed.
4826 MaxNbOfIterations: the maximum number of iterations
4827 MaxAspectRatio: varies in range [1.0, inf]
4828 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4829 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4832 True in case of success, False otherwise.
4835 if IDsOfElements == []:
4836 IDsOfElements = self.GetElementsId()
4837 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4838 self.mesh.SetParameters(Parameters)
4839 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4840 MaxNbOfIterations, MaxAspectRatio, Method)
4842 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4843 MaxNbOfIterations, MaxAspectRatio, Method):
4845 Parametrically smooth the elements which belong to the given object
4848 theObject: the object to smooth
4849 IDsOfFixedNodes: the list of ids of fixed nodes.
4850 Note that nodes built on edges and boundary nodes are always fixed.
4851 MaxNbOfIterations: the maximum number of iterations
4852 MaxAspectRatio: varies in range [1.0, inf]
4853 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4854 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4857 True in case of success, False otherwise.
4860 if ( isinstance( theObject, Mesh )):
4861 theObject = theObject.GetMesh()
4862 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4863 MaxNbOfIterations, MaxAspectRatio, Method)
4865 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4867 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4868 them with quadratic with the same id.
4871 theForce3d: method of new node creation:
4873 * False - the medium node lies at the geometrical entity from which the mesh element is built
4874 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4875 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4876 theToBiQuad: If True, converts the mesh to bi-quadratic
4879 :class:`SMESH.ComputeError` which can hold a warning
4882 If *theSubMesh* is provided, the mesh can become non-conformal
4885 if isinstance( theSubMesh, Mesh ):
4886 theSubMesh = theSubMesh.mesh
4888 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4891 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4893 self.editor.ConvertToQuadratic(theForce3d)
4894 error = self.editor.GetLastError()
4895 if error and error.comment:
4896 print(error.comment)
4899 def ConvertFromQuadratic(self, theSubMesh=None):
4901 Convert the mesh from quadratic to ordinary,
4902 deletes old quadratic elements,
4903 replacing them with ordinary mesh elements with the same id.
4906 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4909 If *theSubMesh* is provided, the mesh can become non-conformal
4913 self.editor.ConvertFromQuadraticObject(theSubMesh)
4915 return self.editor.ConvertFromQuadratic()
4917 def Make2DMeshFrom3D(self):
4919 Create 2D mesh as skin on boundary faces of a 3D mesh
4922 True if operation has been completed successfully, False otherwise
4925 return self.editor.Make2DMeshFrom3D()
4927 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4928 toCopyElements=False, toCopyExistingBondary=False):
4930 Create missing boundary elements
4933 elements: elements whose boundary is to be checked:
4934 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4935 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4936 dimension: defines type of boundary elements to create, either of
4937 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4938 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4939 groupName: a name of group to store created boundary elements in,
4940 "" means not to create the group
4941 meshName: a name of new mesh to store created boundary elements in,
4942 "" means not to create the new mesh
4943 toCopyElements: if True, the checked elements will be copied into
4944 the new mesh else only boundary elements will be copied into the new mesh
4945 toCopyExistingBondary: if True, not only new but also pre-existing
4946 boundary elements will be copied into the new mesh
4949 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4952 unRegister = genObjUnRegister()
4953 if isinstance( elements, Mesh ):
4954 elements = elements.GetMesh()
4955 if ( isinstance( elements, list )):
4956 elemType = SMESH.ALL
4957 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4958 elements = self.editor.MakeIDSource(elements, elemType)
4959 unRegister.set( elements )
4960 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4961 toCopyElements,toCopyExistingBondary)
4962 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4965 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4966 toCopyAll=False, groups=[]):
4968 Create missing boundary elements around either the whole mesh or
4972 dimension: defines type of boundary elements to create, either of
4973 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4974 groupName: a name of group to store all boundary elements in,
4975 "" means not to create the group
4976 meshName: a name of a new mesh, which is a copy of the initial
4977 mesh + created boundary elements; "" means not to create the new mesh
4978 toCopyAll: if True, the whole initial mesh will be copied into
4979 the new mesh else only boundary elements will be copied into the new mesh
4980 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4983 tuple( long, mesh, groups )
4984 - long - number of added boundary elements
4985 - mesh - the :class:`Mesh` where elements were added to
4986 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4989 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4991 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4992 return nb, mesh, group
4994 def RenumberNodes(self):
4996 Renumber mesh nodes to remove unused node IDs
4998 self.editor.RenumberNodes()
5000 def RenumberElements(self):
5002 Renumber mesh elements to remove unused element IDs
5004 self.editor.RenumberElements()
5006 def _getIdSourceList(self, arg, idType, unRegister):
5008 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5010 if arg and isinstance( arg, list ):
5011 if isinstance( arg[0], int ):
5012 arg = self.GetIDSource( arg, idType )
5013 unRegister.set( arg )
5014 elif isinstance( arg[0], Mesh ):
5015 arg[0] = arg[0].GetMesh()
5016 elif isinstance( arg, Mesh ):
5018 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5022 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5023 MakeGroups=False, TotalAngle=False):
5025 Generate new elements by rotation of the given elements and nodes around the axis
5028 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5029 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5030 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5031 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5032 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5033 which defines angle in degrees
5034 NbOfSteps: the number of steps
5035 Tolerance: tolerance
5036 MakeGroups: forces the generation of new groups from existing ones
5037 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5038 of all steps, else - size of each step
5041 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5044 unRegister = genObjUnRegister()
5045 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5046 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5047 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5049 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5050 Axis = self.smeshpyD.GetAxisStruct( Axis )
5051 if isinstance( Axis, list ):
5052 Axis = SMESH.AxisStruct( *Axis )
5054 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5055 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5056 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5057 self.mesh.SetParameters(Parameters)
5058 if TotalAngle and NbOfSteps:
5059 AngleInRadians /= NbOfSteps
5060 return self.editor.RotationSweepObjects( nodes, edges, faces,
5061 Axis, AngleInRadians,
5062 NbOfSteps, Tolerance, MakeGroups)
5064 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5065 MakeGroups=False, TotalAngle=False):
5067 Generate new elements by rotation of the elements around the axis
5070 IDsOfElements: the list of ids of elements to sweep
5071 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5072 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5073 NbOfSteps: the number of steps
5074 Tolerance: tolerance
5075 MakeGroups: forces the generation of new groups from existing ones
5076 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5077 of all steps, else - size of each step
5080 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5083 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5084 AngleInRadians, NbOfSteps, Tolerance,
5085 MakeGroups, TotalAngle)
5087 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5088 MakeGroups=False, TotalAngle=False):
5090 Generate new elements by rotation of the elements of object around the axis
5091 theObject object which elements should be sweeped.
5092 It can be a mesh, a sub mesh or a group.
5095 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5096 AngleInRadians: the angle of Rotation
5097 NbOfSteps: number of steps
5098 Tolerance: tolerance
5099 MakeGroups: forces the generation of new groups from existing ones
5100 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5101 of all steps, else - size of each step
5104 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5107 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5108 AngleInRadians, NbOfSteps, Tolerance,
5109 MakeGroups, TotalAngle )
5111 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5112 MakeGroups=False, TotalAngle=False):
5114 Generate new elements by rotation of the elements of object around the axis
5115 theObject object which elements should be sweeped.
5116 It can be a mesh, a sub mesh or a group.
5119 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5120 AngleInRadians: the angle of Rotation
5121 NbOfSteps: number of steps
5122 Tolerance: tolerance
5123 MakeGroups: forces the generation of new groups from existing ones
5124 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5125 of all steps, else - size of each step
5128 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5129 empty list otherwise
5132 return self.RotationSweepObjects([],theObject,[], Axis,
5133 AngleInRadians, NbOfSteps, Tolerance,
5134 MakeGroups, TotalAngle)
5136 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5137 MakeGroups=False, TotalAngle=False):
5139 Generate new elements by rotation of the elements of object around the axis
5140 theObject object which elements should be sweeped.
5141 It can be a mesh, a sub mesh or a group.
5144 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5145 AngleInRadians: the angle of Rotation
5146 NbOfSteps: number of steps
5147 Tolerance: tolerance
5148 MakeGroups: forces the generation of new groups from existing ones
5149 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5150 of all steps, else - size of each step
5153 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5156 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5157 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5159 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5160 scaleFactors=[], linearVariation=False, basePoint=[] ):
5162 Generate new elements by extrusion of the given elements and nodes
5165 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5166 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5167 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5168 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5169 the direction and value of extrusion for one step (the total extrusion
5170 length will be NbOfSteps * ||StepVector||)
5171 NbOfSteps: the number of steps
5172 MakeGroups: forces the generation of new groups from existing ones
5173 scaleFactors: optional scale factors to apply during extrusion
5174 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5175 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5176 basePoint: optional scaling center; if not provided, a gravity center of
5177 nodes and elements being extruded is used as the scaling center.
5180 - a list of tree components of the point or
5184 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5186 Example: :ref:`tui_extrusion`
5188 unRegister = genObjUnRegister()
5189 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5190 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5191 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5193 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5194 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5195 if isinstance( StepVector, list ):
5196 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5198 if isinstance( basePoint, int):
5199 xyz = self.GetNodeXYZ( basePoint )
5201 raise RuntimeError("Invalid node ID: %s" % basePoint)
5203 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5204 basePoint = self.geompyD.PointCoordinates( basePoint )
5206 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5207 Parameters = StepVector.PS.parameters + var_separator + Parameters
5208 self.mesh.SetParameters(Parameters)
5210 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5211 StepVector, NbOfSteps,
5212 scaleFactors, linearVariation, basePoint,
5216 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5218 Generate new elements by extrusion of the elements with given ids
5221 IDsOfElements: the list of ids of elements or nodes for extrusion
5222 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5223 the direction and value of extrusion for one step (the total extrusion
5224 length will be NbOfSteps * ||StepVector||)
5225 NbOfSteps: the number of steps
5226 MakeGroups: forces the generation of new groups from existing ones
5227 IsNodes: is True if elements with given ids are nodes
5230 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5232 Example: :ref:`tui_extrusion`
5235 if IsNodes: n = IDsOfElements
5236 else : e,f, = IDsOfElements,IDsOfElements
5237 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5239 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5240 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5242 Generate new elements by extrusion along the normal to a discretized surface or wire
5245 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5246 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5247 StepSize: length of one extrusion step (the total extrusion
5248 length will be *NbOfSteps* *StepSize*).
5249 NbOfSteps: number of extrusion steps.
5250 ByAverageNormal: if True each node is translated by *StepSize*
5251 along the average of the normal vectors to the faces sharing the node;
5252 else each node is translated along the same average normal till
5253 intersection with the plane got by translation of the face sharing
5254 the node along its own normal by *StepSize*.
5255 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5256 for every node of *Elements*.
5257 MakeGroups: forces generation of new groups from existing ones.
5258 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5259 is not yet implemented. This parameter is used if *Elements* contains
5260 both faces and edges, i.e. *Elements* is a Mesh.
5263 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5264 empty list otherwise.
5265 Example: :ref:`tui_extrusion`
5268 unRegister = genObjUnRegister()
5269 if isinstance( Elements, Mesh ):
5270 Elements = [ Elements.GetMesh() ]
5271 if isinstance( Elements, list ):
5273 raise RuntimeError("Elements empty!")
5274 if isinstance( Elements[0], int ):
5275 Elements = self.GetIDSource( Elements, SMESH.ALL )
5276 unRegister.set( Elements )
5277 if not isinstance( Elements, list ):
5278 Elements = [ Elements ]
5279 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5280 self.mesh.SetParameters(Parameters)
5281 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5282 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5284 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5286 Generate new elements by extrusion of the elements or nodes which belong to the object
5289 theObject: the object whose elements or nodes should be processed.
5290 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5291 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5292 the direction and value of extrusion for one step (the total extrusion
5293 length will be NbOfSteps * ||StepVector||)
5294 NbOfSteps: the number of steps
5295 MakeGroups: forces the generation of new groups from existing ones
5296 IsNodes: is True if elements to extrude are nodes
5299 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5300 Example: :ref:`tui_extrusion`
5304 if IsNodes: n = theObject
5305 else : e,f, = theObject,theObject
5306 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5308 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5310 Generate new elements by extrusion of edges which belong to the object
5313 theObject: object whose 1D elements should be processed.
5314 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5315 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5316 the direction and value of extrusion for one step (the total extrusion
5317 length will be NbOfSteps * ||StepVector||)
5318 NbOfSteps: the number of steps
5319 MakeGroups: to generate new groups from existing ones
5322 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5323 Example: :ref:`tui_extrusion`
5326 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5328 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5330 Generate new elements by extrusion of faces which belong to the object
5333 theObject: object whose 2D elements should be processed.
5334 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5335 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5336 the direction and value of extrusion for one step (the total extrusion
5337 length will be NbOfSteps * ||StepVector||)
5338 NbOfSteps: the number of steps
5339 MakeGroups: forces the generation of new groups from existing ones
5342 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5343 Example: :ref:`tui_extrusion`
5346 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5348 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5349 ExtrFlags, SewTolerance, MakeGroups=False):
5351 Generate new elements by extrusion of the elements with given ids
5354 IDsOfElements: is ids of elements
5355 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5356 the direction and value of extrusion for one step (the total extrusion
5357 length will be NbOfSteps * ||StepVector||)
5358 NbOfSteps: the number of steps
5359 ExtrFlags: sets flags for extrusion
5360 SewTolerance: uses for comparing locations of nodes if flag
5361 EXTRUSION_FLAG_SEW is set
5362 MakeGroups: forces the generation of new groups from existing ones
5365 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5368 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5369 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5370 if isinstance( StepVector, list ):
5371 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5372 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5373 ExtrFlags, SewTolerance, MakeGroups)
5375 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5376 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5377 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5379 Generate new elements by extrusion of the given elements and nodes along the path.
5380 The path of extrusion must be a meshed edge.
5383 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5384 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5385 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5386 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5387 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5388 contains not only path segments, else it can be None
5389 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5390 HasAngles: allows the shape to be rotated around the path
5391 to get the resulting mesh in a helical fashion
5392 Angles: list of angles
5393 LinearVariation: forces the computation of rotation angles as linear
5394 variation of the given Angles along path steps
5395 HasRefPoint: allows using the reference point
5396 RefPoint: the reference point around which the shape is rotated (the mass center of the
5397 shape by default). The User can specify any point as the Reference Point.
5398 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5399 MakeGroups: forces the generation of new groups from existing ones
5402 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5403 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5404 Example: :ref:`tui_extrusion_along_path`
5407 unRegister = genObjUnRegister()
5408 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5409 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5410 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5412 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5413 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5414 if isinstance( RefPoint, list ):
5415 if not RefPoint: RefPoint = [0,0,0]
5416 RefPoint = SMESH.PointStruct( *RefPoint )
5417 if isinstance( PathMesh, Mesh ):
5418 PathMesh = PathMesh.GetMesh()
5419 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5420 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5421 self.mesh.SetParameters(Parameters)
5422 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5423 PathMesh, PathShape, NodeStart,
5424 HasAngles, Angles, LinearVariation,
5425 HasRefPoint, RefPoint, MakeGroups)
5427 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5428 HasAngles=False, Angles=[], LinearVariation=False,
5429 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5430 ElemType=SMESH.FACE):
5432 Generate new elements by extrusion of the given elements.
5433 The path of extrusion must be a meshed edge.
5436 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5437 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5438 NodeStart: the start node from Path. Defines the direction of extrusion
5439 HasAngles: allows the shape to be rotated around the path
5440 to get the resulting mesh in a helical fashion
5441 Angles: list of angles in radians
5442 LinearVariation: forces the computation of rotation angles as linear
5443 variation of the given Angles along path steps
5444 HasRefPoint: allows using the reference point
5445 RefPoint: the reference point around which the elements are rotated (the mass
5446 center of the elements by default).
5447 The User can specify any point as the Reference Point.
5448 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5449 MakeGroups: forces the generation of new groups from existing ones
5450 ElemType: type of elements for extrusion (if param Base is a mesh)
5453 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5454 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5455 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5457 Example: :ref:`tui_extrusion_along_path`
5461 if ElemType == SMESH.NODE: n = Base
5462 if ElemType == SMESH.EDGE: e = Base
5463 if ElemType == SMESH.FACE: f = Base
5464 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5465 HasAngles, Angles, LinearVariation,
5466 HasRefPoint, RefPoint, MakeGroups)
5467 if MakeGroups: return gr,er
5470 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5471 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5472 MakeGroups=False, LinearVariation=False):
5474 Generate new elements by extrusion of the given elements.
5475 The path of extrusion must be a meshed edge.
5478 IDsOfElements: ids of elements
5479 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5480 PathShape: shape (edge) defines the sub-mesh for the path
5481 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5482 HasAngles: allows the shape to be rotated around the path
5483 to get the resulting mesh in a helical fashion
5484 Angles: list of angles in radians
5485 HasRefPoint: allows using the reference point
5486 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5487 The User can specify any point as the Reference Point.
5488 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5489 MakeGroups: forces the generation of new groups from existing ones
5490 LinearVariation: forces the computation of rotation angles as linear
5491 variation of the given Angles along path steps
5494 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5495 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5496 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5497 Example: :ref:`tui_extrusion_along_path`
5500 n,e,f = [],IDsOfElements,IDsOfElements
5501 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5502 NodeStart, HasAngles, Angles,
5504 HasRefPoint, RefPoint, MakeGroups)
5505 if MakeGroups: return gr,er
5508 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5509 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5510 MakeGroups=False, LinearVariation=False):
5512 Generate new elements by extrusion of the elements which belong to the object.
5513 The path of extrusion must be a meshed edge.
5516 theObject: the object whose elements should be processed.
5517 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5518 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5519 PathShape: shape (edge) defines the sub-mesh for the path
5520 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5521 HasAngles: allows the shape to be rotated around the path
5522 to get the resulting mesh in a helical fashion
5523 Angles: list of angles
5524 HasRefPoint: allows using the reference point
5525 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5526 The User can specify any point as the Reference Point.
5527 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5528 MakeGroups: forces the generation of new groups from existing ones
5529 LinearVariation: forces the computation of rotation angles as linear
5530 variation of the given Angles along path steps
5533 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5534 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5535 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5536 Example: :ref:`tui_extrusion_along_path`
5539 n,e,f = [],theObject,theObject
5540 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5541 HasAngles, Angles, LinearVariation,
5542 HasRefPoint, RefPoint, MakeGroups)
5543 if MakeGroups: return gr,er
5546 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5547 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5548 MakeGroups=False, LinearVariation=False):
5550 Generate new elements by extrusion of mesh segments which belong to the object.
5551 The path of extrusion must be a meshed edge.
5554 theObject: the object whose 1D elements should be processed.
5555 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5556 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5557 PathShape: shape (edge) defines the sub-mesh for the path
5558 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5559 HasAngles: allows the shape to be rotated around the path
5560 to get the resulting mesh in a helical fashion
5561 Angles: list of angles
5562 HasRefPoint: allows using the reference point
5563 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5564 The User can specify any point as the Reference Point.
5565 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5566 MakeGroups: forces the generation of new groups from existing ones
5567 LinearVariation: forces the computation of rotation angles as linear
5568 variation of the given Angles along path steps
5571 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5572 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5573 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5574 Example: :ref:`tui_extrusion_along_path`
5577 n,e,f = [],theObject,[]
5578 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5579 HasAngles, Angles, LinearVariation,
5580 HasRefPoint, RefPoint, MakeGroups)
5581 if MakeGroups: return gr,er
5584 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5585 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5586 MakeGroups=False, LinearVariation=False):
5588 Generate new elements by extrusion of faces which belong to the object.
5589 The path of extrusion must be a meshed edge.
5592 theObject: the object whose 2D elements should be processed.
5593 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5594 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5595 PathShape: shape (edge) defines the sub-mesh for the path
5596 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5597 HasAngles: allows the shape to be rotated around the path
5598 to get the resulting mesh in a helical fashion
5599 Angles: list of angles
5600 HasRefPoint: allows using the reference point
5601 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5602 The User can specify any point as the Reference Point.
5603 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5604 MakeGroups: forces the generation of new groups from existing ones
5605 LinearVariation: forces the computation of rotation angles as linear
5606 variation of the given Angles along path steps
5609 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5610 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5611 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5612 Example: :ref:`tui_extrusion_along_path`
5615 n,e,f = [],[],theObject
5616 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5617 HasAngles, Angles, LinearVariation,
5618 HasRefPoint, RefPoint, MakeGroups)
5619 if MakeGroups: return gr,er
5622 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5624 Create a symmetrical copy of mesh elements
5627 IDsOfElements: list of elements ids
5628 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5629 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5630 If the *Mirror* is a geom object this parameter is unnecessary
5631 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5632 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5635 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5638 if IDsOfElements == []:
5639 IDsOfElements = self.GetElementsId()
5640 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5641 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5642 theMirrorType = Mirror._mirrorType
5644 self.mesh.SetParameters(Mirror.parameters)
5645 if Copy and MakeGroups:
5646 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5647 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5650 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5652 Create a new mesh by a symmetrical copy of mesh elements
5655 IDsOfElements: the list of elements ids
5656 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5657 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5658 If the *Mirror* is a geom object this parameter is unnecessary
5659 MakeGroups: to generate new groups from existing ones
5660 NewMeshName: a name of the new mesh to create
5663 instance of class :class:`Mesh`
5666 if IDsOfElements == []:
5667 IDsOfElements = self.GetElementsId()
5668 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5669 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5670 theMirrorType = Mirror._mirrorType
5672 self.mesh.SetParameters(Mirror.parameters)
5673 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5674 MakeGroups, NewMeshName)
5675 return Mesh(self.smeshpyD,self.geompyD,mesh)
5677 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5679 Create a symmetrical copy of the object
5682 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5683 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5684 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5685 If the *Mirror* is a geom object this parameter is unnecessary
5686 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5687 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5690 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5693 if ( isinstance( theObject, Mesh )):
5694 theObject = theObject.GetMesh()
5695 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5696 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5697 theMirrorType = Mirror._mirrorType
5699 self.mesh.SetParameters(Mirror.parameters)
5700 if Copy and MakeGroups:
5701 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5702 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5705 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5707 Create a new mesh by a symmetrical copy of the object
5710 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5711 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5712 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5713 If the *Mirror* is a geom object this parameter is unnecessary
5714 MakeGroups: forces the generation of new groups from existing ones
5715 NewMeshName: the name of the new mesh to create
5718 instance of class :class:`Mesh`
5721 if ( isinstance( theObject, Mesh )):
5722 theObject = theObject.GetMesh()
5723 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5724 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5725 theMirrorType = Mirror._mirrorType
5727 self.mesh.SetParameters(Mirror.parameters)
5728 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5729 MakeGroups, NewMeshName)
5730 return Mesh( self.smeshpyD,self.geompyD,mesh )
5732 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5734 Translate the elements
5737 IDsOfElements: list of elements ids
5738 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5739 Copy: allows copying the translated elements
5740 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5743 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5746 if IDsOfElements == []:
5747 IDsOfElements = self.GetElementsId()
5748 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5749 Vector = self.smeshpyD.GetDirStruct(Vector)
5750 if isinstance( Vector, list ):
5751 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5752 self.mesh.SetParameters(Vector.PS.parameters)
5753 if Copy and MakeGroups:
5754 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5755 self.editor.Translate(IDsOfElements, Vector, Copy)
5758 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5760 Create a new mesh of translated elements
5763 IDsOfElements: list of elements ids
5764 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5765 MakeGroups: forces the generation of new groups from existing ones
5766 NewMeshName: the name of the newly created mesh
5769 instance of class :class:`Mesh`
5772 if IDsOfElements == []:
5773 IDsOfElements = self.GetElementsId()
5774 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5775 Vector = self.smeshpyD.GetDirStruct(Vector)
5776 if isinstance( Vector, list ):
5777 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5778 self.mesh.SetParameters(Vector.PS.parameters)
5779 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5780 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5782 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5784 Translate the object
5787 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5788 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5789 Copy: allows copying the translated elements
5790 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5793 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5796 if ( isinstance( theObject, Mesh )):
5797 theObject = theObject.GetMesh()
5798 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5799 Vector = self.smeshpyD.GetDirStruct(Vector)
5800 if isinstance( Vector, list ):
5801 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5802 self.mesh.SetParameters(Vector.PS.parameters)
5803 if Copy and MakeGroups:
5804 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5805 self.editor.TranslateObject(theObject, Vector, Copy)
5808 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5810 Create a new mesh from the translated object
5813 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5814 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5815 MakeGroups: forces the generation of new groups from existing ones
5816 NewMeshName: the name of the newly created mesh
5819 instance of class :class:`Mesh`
5822 if isinstance( theObject, Mesh ):
5823 theObject = theObject.GetMesh()
5824 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5825 Vector = self.smeshpyD.GetDirStruct(Vector)
5826 if isinstance( Vector, list ):
5827 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5828 self.mesh.SetParameters(Vector.PS.parameters)
5829 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5830 return Mesh( self.smeshpyD, self.geompyD, mesh )
5834 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5839 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5840 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5841 theScaleFact: list of 1-3 scale factors for axises
5842 Copy: allows copying the translated elements
5843 MakeGroups: forces the generation of new groups from existing
5847 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5848 empty list otherwise
5850 unRegister = genObjUnRegister()
5851 if ( isinstance( theObject, Mesh )):
5852 theObject = theObject.GetMesh()
5853 if ( isinstance( theObject, list )):
5854 theObject = self.GetIDSource(theObject, SMESH.ALL)
5855 unRegister.set( theObject )
5856 if ( isinstance( thePoint, list )):
5857 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5858 if ( isinstance( theScaleFact, float )):
5859 theScaleFact = [theScaleFact]
5860 if ( isinstance( theScaleFact, int )):
5861 theScaleFact = [ float(theScaleFact)]
5863 self.mesh.SetParameters(thePoint.parameters)
5865 if Copy and MakeGroups:
5866 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5867 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5870 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5872 Create a new mesh from the translated object
5875 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5876 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5877 theScaleFact: list of 1-3 scale factors for axises
5878 MakeGroups: forces the generation of new groups from existing ones
5879 NewMeshName: the name of the newly created mesh
5882 instance of class :class:`Mesh`
5884 unRegister = genObjUnRegister()
5885 if (isinstance(theObject, Mesh)):
5886 theObject = theObject.GetMesh()
5887 if ( isinstance( theObject, list )):
5888 theObject = self.GetIDSource(theObject,SMESH.ALL)
5889 unRegister.set( theObject )
5890 if ( isinstance( thePoint, list )):
5891 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5892 if ( isinstance( theScaleFact, float )):
5893 theScaleFact = [theScaleFact]
5894 if ( isinstance( theScaleFact, int )):
5895 theScaleFact = [ float(theScaleFact)]
5897 self.mesh.SetParameters(thePoint.parameters)
5898 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5899 MakeGroups, NewMeshName)
5900 return Mesh( self.smeshpyD, self.geompyD, mesh )
5904 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5909 IDsOfElements: list of elements ids
5910 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5911 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5912 Copy: allows copying the rotated elements
5913 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5916 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5920 if IDsOfElements == []:
5921 IDsOfElements = self.GetElementsId()
5922 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5923 Axis = self.smeshpyD.GetAxisStruct(Axis)
5924 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5925 Parameters = Axis.parameters + var_separator + Parameters
5926 self.mesh.SetParameters(Parameters)
5927 if Copy and MakeGroups:
5928 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5929 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5932 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5934 Create a new mesh of rotated elements
5937 IDsOfElements: list of element ids
5938 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5939 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5940 MakeGroups: forces the generation of new groups from existing ones
5941 NewMeshName: the name of the newly created mesh
5944 instance of class :class:`Mesh`
5947 if IDsOfElements == []:
5948 IDsOfElements = self.GetElementsId()
5949 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5950 Axis = self.smeshpyD.GetAxisStruct(Axis)
5951 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5952 Parameters = Axis.parameters + var_separator + Parameters
5953 self.mesh.SetParameters(Parameters)
5954 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5955 MakeGroups, NewMeshName)
5956 return Mesh( self.smeshpyD, self.geompyD, mesh )
5958 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5963 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5964 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5965 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5966 Copy: allows copying the rotated elements
5967 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5970 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5973 if (isinstance(theObject, Mesh)):
5974 theObject = theObject.GetMesh()
5975 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5976 Axis = self.smeshpyD.GetAxisStruct(Axis)
5977 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5978 Parameters = Axis.parameters + ":" + Parameters
5979 self.mesh.SetParameters(Parameters)
5980 if Copy and MakeGroups:
5981 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5982 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5985 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5987 Create a new mesh from the rotated object
5990 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5991 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5992 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5993 MakeGroups: forces the generation of new groups from existing ones
5994 NewMeshName: the name of the newly created mesh
5997 instance of class :class:`Mesh`
6000 if (isinstance( theObject, Mesh )):
6001 theObject = theObject.GetMesh()
6002 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6003 Axis = self.smeshpyD.GetAxisStruct(Axis)
6004 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6005 Parameters = Axis.parameters + ":" + Parameters
6006 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6007 MakeGroups, NewMeshName)
6008 self.mesh.SetParameters(Parameters)
6009 return Mesh( self.smeshpyD, self.geompyD, mesh )
6011 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6013 Create an offset mesh from the given 2D object
6016 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6017 theValue (float): signed offset size
6018 MakeGroups (boolean): forces the generation of new groups from existing ones
6019 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6020 False means to remove original elements.
6021 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6024 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6027 if isinstance( theObject, Mesh ):
6028 theObject = theObject.GetMesh()
6029 theValue,Parameters,hasVars = ParseParameters(Value)
6030 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6031 self.mesh.SetParameters(Parameters)
6032 # if mesh_groups[0]:
6033 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6036 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6038 Find groups of adjacent nodes within Tolerance.
6041 Tolerance (float): the value of tolerance
6042 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6043 corner and medium nodes in separate groups thus preventing
6044 their further merge.
6047 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6050 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6052 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6053 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6055 Find groups of adjacent nodes within Tolerance.
6058 Tolerance: the value of tolerance
6059 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6060 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6061 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6062 corner and medium nodes in separate groups thus preventing
6063 their further merge.
6066 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6069 unRegister = genObjUnRegister()
6070 if (isinstance( SubMeshOrGroup, Mesh )):
6071 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6072 if not isinstance( exceptNodes, list ):
6073 exceptNodes = [ exceptNodes ]
6074 if exceptNodes and isinstance( exceptNodes[0], int ):
6075 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6076 unRegister.set( exceptNodes )
6077 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6078 exceptNodes, SeparateCornerAndMediumNodes)
6080 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6085 GroupsOfNodes: a list of groups of nodes IDs for merging.
6086 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6087 in all elements and groups by nodes 1 and 25 correspondingly
6088 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6089 If *NodesToKeep* does not include a node to keep for some group to merge,
6090 then the first node in the group is kept.
6091 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6094 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6095 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6097 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6099 Find the elements built on the same nodes.
6102 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6105 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6108 if not MeshOrSubMeshOrGroup:
6109 MeshOrSubMeshOrGroup=self.mesh
6110 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6111 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6112 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6114 def MergeElements(self, GroupsOfElementsID):
6116 Merge elements in each given group.
6119 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6120 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6121 replaced in all groups by elements 1 and 25)
6124 self.editor.MergeElements(GroupsOfElementsID)
6126 def MergeEqualElements(self):
6128 Leave one element and remove all other elements built on the same nodes.
6131 self.editor.MergeEqualElements()
6133 def FindFreeBorders(self, ClosedOnly=True):
6135 Returns all or only closed free borders
6138 list of SMESH.FreeBorder's
6141 return self.editor.FindFreeBorders( ClosedOnly )
6143 def FillHole(self, holeNodes):
6145 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6148 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6149 must describe all sequential nodes of the hole border. The first and the last
6150 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6154 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6155 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6156 if not isinstance( holeNodes, SMESH.FreeBorder ):
6157 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6158 self.editor.FillHole( holeNodes )
6160 def FindCoincidentFreeBorders (self, tolerance=0.):
6162 Return groups of FreeBorder's coincident within the given tolerance.
6165 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6166 size of elements adjacent to free borders being compared is used.
6169 SMESH.CoincidentFreeBorders structure
6172 return self.editor.FindCoincidentFreeBorders( tolerance )
6174 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6176 Sew FreeBorder's of each group
6179 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6180 where each enclosed list contains node IDs of a group of coincident free
6181 borders such that each consequent triple of IDs within a group describes
6182 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6183 last node of a border.
6184 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6185 groups of coincident free borders, each group including two borders.
6186 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6187 polygons if a node of opposite border falls on a face edge, else such
6188 faces are split into several ones.
6189 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6190 polyhedra if a node of opposite border falls on a volume edge, else such
6191 volumes, if any, remain intact and the mesh becomes non-conformal.
6194 a number of successfully sewed groups
6197 if freeBorders and isinstance( freeBorders, list ):
6198 # construct SMESH.CoincidentFreeBorders
6199 if isinstance( freeBorders[0], int ):
6200 freeBorders = [freeBorders]
6202 coincidentGroups = []
6203 for nodeList in freeBorders:
6204 if not nodeList or len( nodeList ) % 3:
6205 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6208 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6209 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6210 nodeList = nodeList[3:]
6212 coincidentGroups.append( group )
6214 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6216 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6218 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6219 FirstNodeID2, SecondNodeID2, LastNodeID2,
6220 CreatePolygons, CreatePolyedrs):
6225 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6228 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6229 FirstNodeID2, SecondNodeID2, LastNodeID2,
6230 CreatePolygons, CreatePolyedrs)
6232 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6233 FirstNodeID2, SecondNodeID2):
6235 Sew conform free borders
6238 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6241 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6242 FirstNodeID2, SecondNodeID2)
6244 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6245 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6250 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6253 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6254 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6256 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6257 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6258 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6260 Sew two sides of a mesh. The nodes belonging to Side1 are
6261 merged with the nodes of elements of Side2.
6262 The number of elements in theSide1 and in theSide2 must be
6263 equal and they should have similar nodal connectivity.
6264 The nodes to merge should belong to side borders and
6265 the first node should be linked to the second.
6268 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6271 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6272 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6273 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6275 def ChangeElemNodes(self, ide, newIDs):
6277 Set new nodes for the given element.
6284 False if the number of nodes does not correspond to the type of element
6287 return self.editor.ChangeElemNodes(ide, newIDs)
6289 def GetLastCreatedNodes(self):
6291 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6292 created, this method return the list of their IDs.
6293 If new nodes were not created - return empty list
6296 the list of integer values (can be empty)
6299 return self.editor.GetLastCreatedNodes()
6301 def GetLastCreatedElems(self):
6303 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6304 created this method return the list of their IDs.
6305 If new elements were not created - return empty list
6308 the list of integer values (can be empty)
6311 return self.editor.GetLastCreatedElems()
6313 def ClearLastCreated(self):
6315 Forget what nodes and elements were created by the last mesh edition operation
6318 self.editor.ClearLastCreated()
6320 def DoubleElements(self, theElements, theGroupName=""):
6322 Create duplicates of given elements, i.e. create new elements based on the
6323 same nodes as the given ones.
6326 theElements: container of elements to duplicate. It can be a
6327 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6328 or a list of element IDs. If *theElements* is
6329 a :class:`Mesh`, elements of highest dimension are duplicated
6330 theGroupName: a name of group to contain the generated elements.
6331 If a group with such a name already exists, the new elements
6332 are added to the existing group, else a new group is created.
6333 If *theGroupName* is empty, new elements are not added
6337 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6338 None if *theGroupName* == "".
6341 unRegister = genObjUnRegister()
6342 if isinstance( theElements, Mesh ):
6343 theElements = theElements.mesh
6344 elif isinstance( theElements, list ):
6345 theElements = self.GetIDSource( theElements, SMESH.ALL )
6346 unRegister.set( theElements )
6347 return self.editor.DoubleElements(theElements, theGroupName)
6349 def DoubleNodes(self, theNodes, theModifiedElems):
6351 Create a hole in a mesh by doubling the nodes of some particular elements
6354 theNodes: IDs of nodes to be doubled
6355 theModifiedElems: IDs of elements to be updated by the new (doubled)
6356 nodes. If list of element identifiers is empty then nodes are doubled but
6357 they not assigned to elements
6360 True if operation has been completed successfully, False otherwise
6363 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6365 def DoubleNode(self, theNodeId, theModifiedElems):
6367 Create a hole in a mesh by doubling the nodes of some particular elements.
6368 This method provided for convenience works as :meth:`DoubleNodes`.
6371 theNodeId: IDs of node to double
6372 theModifiedElems: IDs of elements to update
6375 True if operation has been completed successfully, False otherwise
6378 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6380 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6382 Create a hole in a mesh by doubling the nodes of some particular elements.
6383 This method provided for convenience works as :meth:`DoubleNodes`.
6386 theNodes: group of nodes to double.
6387 theModifiedElems: group of elements to update.
6388 theMakeGroup: forces the generation of a group containing new nodes.
6391 True or a created group if operation has been completed successfully,
6392 False or None otherwise
6396 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6397 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6399 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6401 Create a hole in a mesh by doubling the nodes of some particular elements.
6402 This method provided for convenience works as :meth:`DoubleNodes`.
6405 theNodes: list of groups of nodes to double.
6406 theModifiedElems: list of groups of elements to update.
6407 theMakeGroup: forces the generation of a group containing new nodes.
6410 True if operation has been completed successfully, False otherwise
6414 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6415 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6417 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6419 Create a hole in a mesh by doubling the nodes of some particular elements
6422 theElems: the list of elements (edges or faces) to replicate.
6423 The nodes for duplication could be found from these elements
6424 theNodesNot: list of nodes NOT to replicate
6425 theAffectedElems: the list of elements (cells and edges) to which the
6426 replicated nodes should be associated to
6429 True if operation has been completed successfully, False otherwise
6432 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6434 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6436 Create a hole in a mesh by doubling the nodes of some particular elements
6439 theElems: the list of elements (edges or faces) to replicate.
6440 The nodes for duplication could be found from these elements
6441 theNodesNot: list of nodes NOT to replicate
6442 theShape: shape to detect affected elements (element which geometric center
6443 located on or inside shape).
6444 The replicated nodes should be associated to affected elements.
6447 True if operation has been completed successfully, False otherwise
6450 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6452 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6453 theMakeGroup=False, theMakeNodeGroup=False):
6455 Create a hole in a mesh by doubling the nodes of some particular elements.
6456 This method provided for convenience works as :meth:`DoubleNodes`.
6459 theElems: group of of elements (edges or faces) to replicate.
6460 theNodesNot: group of nodes NOT to replicate.
6461 theAffectedElems: group of elements to which the replicated nodes
6462 should be associated to.
6463 theMakeGroup: forces the generation of a group containing new elements.
6464 theMakeNodeGroup: forces the generation of a group containing new nodes.
6467 True or created groups (one or two) if operation has been completed successfully,
6468 False or None otherwise
6471 if theMakeGroup or theMakeNodeGroup:
6472 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6474 theMakeGroup, theMakeNodeGroup)
6475 if theMakeGroup and theMakeNodeGroup:
6478 return twoGroups[ int(theMakeNodeGroup) ]
6479 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6481 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6483 Create a hole in a mesh by doubling the nodes of some particular elements.
6484 This method provided for convenience works as :meth:`DoubleNodes`.
6487 theElems: group of of elements (edges or faces) to replicate
6488 theNodesNot: group of nodes not to replicate
6489 theShape: shape to detect affected elements (element which geometric center
6490 located on or inside shape).
6491 The replicated nodes should be associated to affected elements
6494 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6496 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6497 theMakeGroup=False, theMakeNodeGroup=False):
6499 Create a hole in a mesh by doubling the nodes of some particular elements.
6500 This method provided for convenience works as :meth:`DoubleNodes`.
6503 theElems: list of groups of elements (edges or faces) to replicate
6504 theNodesNot: list of groups of nodes NOT to replicate
6505 theAffectedElems: group of elements to which the replicated nodes
6506 should be associated to
6507 theMakeGroup: forces generation of a group containing new elements.
6508 theMakeNodeGroup: forces generation of a group containing new nodes
6511 True or created groups (one or two) if operation has been completed successfully,
6512 False or None otherwise
6515 if theMakeGroup or theMakeNodeGroup:
6516 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6518 theMakeGroup, theMakeNodeGroup)
6519 if theMakeGroup and theMakeNodeGroup:
6522 return twoGroups[ int(theMakeNodeGroup) ]
6523 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6525 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6527 Create a hole in a mesh by doubling the nodes of some particular elements.
6528 This method provided for convenience works as :meth:`DoubleNodes`.
6531 theElems: list of groups of elements (edges or faces) to replicate
6532 theNodesNot: list of groups of nodes NOT to replicate
6533 theShape: shape to detect affected elements (element which geometric center
6534 located on or inside shape).
6535 The replicated nodes should be associated to affected elements
6538 True if operation has been completed successfully, False otherwise
6541 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6543 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6545 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6546 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6549 theElems: list of groups of nodes or elements (edges or faces) to replicate
6550 theNodesNot: list of groups of nodes NOT to replicate
6551 theShape: shape to detect affected elements (element which geometric center
6552 located on or inside shape).
6553 The replicated nodes should be associated to affected elements
6556 groups of affected elements in order: volumes, faces, edges
6559 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6561 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6564 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6565 The list of groups must describe a partition of the mesh volumes.
6566 The nodes of the internal faces at the boundaries of the groups are doubled.
6567 In option, the internal faces are replaced by flat elements.
6568 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6571 theDomains: list of groups of volumes
6572 createJointElems: if True, create the elements
6573 onAllBoundaries: if True, the nodes and elements are also created on
6574 the boundary between *theDomains* and the rest mesh
6577 True if operation has been completed successfully, False otherwise
6580 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6582 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6584 Double nodes on some external faces and create flat elements.
6585 Flat elements are mainly used by some types of mechanic calculations.
6587 Each group of the list must be constituted of faces.
6588 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6591 theGroupsOfFaces: list of groups of faces
6594 True if operation has been completed successfully, False otherwise
6597 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6599 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6601 Identify all the elements around a geom shape, get the faces delimiting the hole
6603 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6605 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6607 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6608 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6609 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6610 If there are several paths connecting a pair of points, the shortest path is
6611 selected by the module. Position of the cutting plane is defined by the two
6612 points and an optional vector lying on the plane specified by a PolySegment.
6613 By default the vector is defined by Mesh module as following. A middle point
6614 of the two given points is computed. The middle point is projected to the mesh.
6615 The vector goes from the middle point to the projection point. In case of planar
6616 mesh, the vector is normal to the mesh.
6618 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6621 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6622 groupName: optional name of a group where created mesh segments will be added.
6625 editor = self.editor
6627 editor = self.mesh.GetMeshEditPreviewer()
6628 segmentsRes = editor.MakePolyLine( segments, groupName )
6629 for i, seg in enumerate( segmentsRes ):
6630 segments[i].vector = seg.vector
6632 return editor.GetPreviewData()
6635 def GetFunctor(self, funcType ):
6637 Return a cached numerical functor by its type.
6640 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6641 Note that not all items correspond to numerical functors.
6644 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6647 fn = self.functors[ funcType._v ]
6649 fn = self.smeshpyD.GetFunctor(funcType)
6650 fn.SetMesh(self.mesh)
6651 self.functors[ funcType._v ] = fn
6654 def FunctorValue(self, funcType, elemId, isElem=True):
6656 Return value of a functor for a given element
6659 funcType: an item of :class:`SMESH.FunctorType` enum.
6660 elemId: element or node ID
6661 isElem: *elemId* is ID of element or node
6664 the functor value or zero in case of invalid arguments
6667 fn = self.GetFunctor( funcType )
6668 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6669 val = fn.GetValue(elemId)
6674 def GetLength(self, elemId=None):
6676 Get length of 1D element or sum of lengths of all 1D mesh elements
6679 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6682 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6687 length = self.smeshpyD.GetLength(self)
6689 length = self.FunctorValue(SMESH.FT_Length, elemId)
6692 def GetArea(self, elemId=None):
6694 Get area of 2D element or sum of areas of all 2D mesh elements
6695 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6698 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6703 area = self.smeshpyD.GetArea(self)
6705 area = self.FunctorValue(SMESH.FT_Area, elemId)
6708 def GetVolume(self, elemId=None):
6710 Get volume of 3D element or sum of volumes of all 3D mesh elements
6713 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6716 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6721 volume = self.smeshpyD.GetVolume(self)
6723 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6726 def GetMaxElementLength(self, elemId):
6728 Get maximum element length.
6731 elemId: mesh element ID
6734 element's maximum length value
6737 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6738 ftype = SMESH.FT_MaxElementLength3D
6740 ftype = SMESH.FT_MaxElementLength2D
6741 return self.FunctorValue(ftype, elemId)
6743 def GetAspectRatio(self, elemId):
6745 Get aspect ratio of 2D or 3D element.
6748 elemId: mesh element ID
6751 element's aspect ratio value
6754 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6755 ftype = SMESH.FT_AspectRatio3D
6757 ftype = SMESH.FT_AspectRatio
6758 return self.FunctorValue(ftype, elemId)
6760 def GetWarping(self, elemId):
6762 Get warping angle of 2D element.
6765 elemId: mesh element ID
6768 element's warping angle value
6771 return self.FunctorValue(SMESH.FT_Warping, elemId)
6773 def GetMinimumAngle(self, elemId):
6775 Get minimum angle of 2D element.
6778 elemId: mesh element ID
6781 element's minimum angle value
6784 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6786 def GetTaper(self, elemId):
6788 Get taper of 2D element.
6791 elemId: mesh element ID
6794 element's taper value
6797 return self.FunctorValue(SMESH.FT_Taper, elemId)
6799 def GetSkew(self, elemId):
6801 Get skew of 2D element.
6804 elemId: mesh element ID
6807 element's skew value
6810 return self.FunctorValue(SMESH.FT_Skew, elemId)
6812 def GetMinMax(self, funType, meshPart=None):
6814 Return minimal and maximal value of a given functor.
6817 funType (SMESH.FunctorType): a functor type.
6818 Note that not all items of :class:`SMESH.FunctorType` corresponds
6819 to numerical functors.
6820 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6826 unRegister = genObjUnRegister()
6827 if isinstance( meshPart, list ):
6828 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6829 unRegister.set( meshPart )
6830 if isinstance( meshPart, Mesh ):
6831 meshPart = meshPart.mesh
6832 fun = self.GetFunctor( funType )
6835 if hasattr( meshPart, "SetMesh" ):
6836 meshPart.SetMesh( self.mesh ) # set mesh to filter
6837 hist = fun.GetLocalHistogram( 1, False, meshPart )
6839 hist = fun.GetHistogram( 1, False )
6841 return hist[0].min, hist[0].max
6844 pass # end of Mesh class
6847 class meshProxy(SMESH._objref_SMESH_Mesh):
6849 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6850 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6852 def __init__(self,*args):
6853 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6854 def __deepcopy__(self, memo=None):
6855 new = self.__class__(self)
6857 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6858 if len( args ) == 3:
6859 args += SMESH.ALL_NODES, True
6860 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6861 def ExportToMEDX(self, *args): # function removed
6862 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6863 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6864 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6865 def ExportToMED(self, *args): # function removed
6866 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6867 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6868 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6870 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6871 def ExportPartToMED(self, *args): # 'version' parameter removed
6872 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6873 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6874 def ExportMED(self, *args): # signature of method changed
6875 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6876 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6878 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6880 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6883 class submeshProxy(SMESH._objref_SMESH_subMesh):
6886 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6888 def __init__(self,*args):
6889 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6891 def __deepcopy__(self, memo=None):
6892 new = self.__class__(self)
6895 def Compute(self,refresh=False):
6897 Compute the sub-mesh and return the status of the computation
6900 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6905 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6906 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6910 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6912 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6914 if salome.sg.hasDesktop():
6915 if refresh: salome.sg.updateObjBrowser()
6920 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6923 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6925 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6926 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6929 def __init__(self,*args):
6930 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6932 def __getattr__(self, name ): # method called if an attribute not found
6933 if not self.mesh: # look for name() method in Mesh class
6934 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6935 if hasattr( self.mesh, name ):
6936 return getattr( self.mesh, name )
6937 if name == "ExtrusionAlongPathObjX":
6938 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6939 print("meshEditor: attribute '%s' NOT FOUND" % name)
6941 def __deepcopy__(self, memo=None):
6942 new = self.__class__(self)
6944 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6945 if len( args ) == 1: args += False,
6946 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6947 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6948 if len( args ) == 2: args += False,
6949 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6950 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6951 if len( args ) == 1:
6952 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6953 NodesToKeep = args[1]
6954 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6955 unRegister = genObjUnRegister()
6957 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6958 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6959 if not isinstance( NodesToKeep, list ):
6960 NodesToKeep = [ NodesToKeep ]
6961 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6963 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6965 class Pattern(SMESH._objref_SMESH_Pattern):
6967 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6968 variables in some methods
6971 def LoadFromFile(self, patternTextOrFile ):
6972 text = patternTextOrFile
6973 if os.path.exists( text ):
6974 text = open( patternTextOrFile ).read()
6976 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6978 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6979 decrFun = lambda i: i-1
6980 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6981 theMesh.SetParameters(Parameters)
6982 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6984 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6985 decrFun = lambda i: i-1
6986 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6987 theMesh.SetParameters(Parameters)
6988 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
6990 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
6991 if isinstance( mesh, Mesh ):
6992 mesh = mesh.GetMesh()
6993 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
6995 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
6997 Registering the new proxy for Pattern
7002 Private class used to bind methods creating algorithms to the class Mesh
7005 def __init__(self, method):
7007 self.defaultAlgoType = ""
7008 self.algoTypeToClass = {}
7009 self.method = method
7011 def add(self, algoClass):
7013 Store a python class of algorithm
7015 if inspect.isclass(algoClass) and \
7016 hasattr( algoClass, "algoType"):
7017 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7018 if not self.defaultAlgoType and \
7019 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7020 self.defaultAlgoType = algoClass.algoType
7021 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7023 def copy(self, mesh):
7025 Create a copy of self and assign mesh to the copy
7028 other = algoCreator( self.method )
7029 other.defaultAlgoType = self.defaultAlgoType
7030 other.algoTypeToClass = self.algoTypeToClass
7034 def __call__(self,algo="",geom=0,*args):
7036 Create an instance of algorithm
7040 if isinstance( algo, str ):
7042 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7043 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7048 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7050 elif not algoType and isinstance( geom, str ):
7055 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7057 elif isinstance( arg, str ) and not algoType:
7060 import traceback, sys
7061 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7062 sys.stderr.write( msg + '\n' )
7063 tb = traceback.extract_stack(None,2)
7064 traceback.print_list( [tb[0]] )
7066 algoType = self.defaultAlgoType
7067 if not algoType and self.algoTypeToClass:
7068 algoType = sorted( self.algoTypeToClass.keys() )[0]
7069 if algoType in self.algoTypeToClass:
7070 #print("Create algo",algoType)
7071 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7072 raise RuntimeError( "No class found for algo type %s" % algoType)
7075 class hypMethodWrapper:
7077 Private class used to substitute and store variable parameters of hypotheses.
7080 def __init__(self, hyp, method):
7082 self.method = method
7083 #print("REBIND:", method.__name__)
7086 def __call__(self,*args):
7088 call a method of hypothesis with calling SetVarParameter() before
7092 return self.method( self.hyp, *args ) # hypothesis method with no args
7094 #print("MethWrapper.__call__", self.method.__name__, args)
7096 parsed = ParseParameters(*args) # replace variables with their values
7097 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7098 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7099 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7100 # maybe there is a replaced string arg which is not variable
7101 result = self.method( self.hyp, *args )
7102 except ValueError as detail: # raised by ParseParameters()
7104 result = self.method( self.hyp, *args )
7105 except omniORB.CORBA.BAD_PARAM:
7106 raise ValueError(detail) # wrong variable name
7111 class genObjUnRegister:
7113 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7116 def __init__(self, genObj=None):
7117 self.genObjList = []
7121 def set(self, genObj):
7122 "Store one or a list of of SALOME.GenericObj'es"
7123 if isinstance( genObj, list ):
7124 self.genObjList.extend( genObj )
7126 self.genObjList.append( genObj )
7130 for genObj in self.genObjList:
7131 if genObj and hasattr( genObj, "UnRegister" ):
7134 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7136 Bind methods creating mesher plug-ins to the Mesh class
7139 # print("pluginName: ", pluginName)
7140 pluginBuilderName = pluginName + "Builder"
7142 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7143 except Exception as e:
7144 from salome_utils import verbose
7145 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7147 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7148 plugin = eval( pluginBuilderName )
7149 # print(" plugin:" , str(plugin))
7151 # add methods creating algorithms to Mesh
7152 for k in dir( plugin ):
7153 if k[0] == '_': continue
7154 algo = getattr( plugin, k )
7155 #print(" algo:", str(algo))
7156 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7157 #print(" meshMethod:" , str(algo.meshMethod))
7158 if not hasattr( Mesh, algo.meshMethod ):
7159 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7161 _mmethod = getattr( Mesh, algo.meshMethod )
7162 if hasattr( _mmethod, "add" ):