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 create 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)
1631 def HasShapeToMesh(self):
1633 Return ``True`` if this mesh is based on geometry
1635 return self.mesh.HasShapeToMesh()
1639 Load mesh from the study after opening the study
1643 def IsReadyToCompute(self, theSubObject):
1645 Return true if the hypotheses are defined well
1648 theSubObject: a sub-shape of a mesh shape
1654 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1656 def GetAlgoState(self, theSubObject):
1658 Return errors of hypotheses definition.
1659 The list of errors is empty if everything is OK.
1662 theSubObject: a sub-shape of a mesh shape
1668 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1670 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1672 Return a geometrical object on which the given element was built.
1673 The returned geometrical object, if not nil, is either found in the
1674 study or published by this method with the given name
1677 theElementID: the id of the mesh element
1678 theGeomName: the user-defined name of the geometrical object
1681 GEOM.GEOM_Object instance
1684 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1686 def MeshDimension(self):
1688 Return the mesh dimension depending on the dimension of the underlying shape
1689 or, if the mesh is not based on any shape, basing on deimension of elements
1692 mesh dimension as an integer value [0,3]
1695 if self.mesh.HasShapeToMesh():
1696 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1697 if len( shells ) > 0 :
1699 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1701 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1706 if self.NbVolumes() > 0: return 3
1707 if self.NbFaces() > 0: return 2
1708 if self.NbEdges() > 0: return 1
1711 def Evaluate(self, geom=0):
1713 Evaluate size of prospective mesh on a shape
1716 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1717 To know predicted number of e.g. edges, inquire it this way::
1719 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1722 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1724 geom = self.mesh.GetShapeToMesh()
1727 return self.smeshpyD.Evaluate(self.mesh, geom)
1730 def Compute(self, geom=0, discardModifs=False, refresh=False):
1732 Compute the mesh and return the status of the computation
1735 geom: geomtrical shape on which mesh data should be computed
1736 discardModifs: if True and the mesh has been edited since
1737 a last total re-compute and that may prevent successful partial re-compute,
1738 then the mesh is cleaned before Compute()
1739 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1745 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1747 geom = self.mesh.GetShapeToMesh()
1752 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1754 ok = self.smeshpyD.Compute(self.mesh, geom)
1755 except SALOME.SALOME_Exception as ex:
1756 print("Mesh computation failed, exception caught:")
1757 print(" ", ex.details.text)
1760 print("Mesh computation failed, exception caught:")
1761 traceback.print_exc()
1765 # Treat compute errors
1766 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1768 for err in computeErrors:
1769 if self.mesh.HasShapeToMesh():
1770 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1772 stdErrors = ["OK", #COMPERR_OK
1773 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1774 "std::exception", #COMPERR_STD_EXCEPTION
1775 "OCC exception", #COMPERR_OCC_EXCEPTION
1776 "..", #COMPERR_SLM_EXCEPTION
1777 "Unknown exception", #COMPERR_EXCEPTION
1778 "Memory allocation problem", #COMPERR_MEMORY_PB
1779 "Algorithm failed", #COMPERR_ALGO_FAILED
1780 "Unexpected geometry", #COMPERR_BAD_SHAPE
1781 "Warning", #COMPERR_WARNING
1782 "Computation cancelled",#COMPERR_CANCELED
1783 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1785 if err.code < len(stdErrors): errText = stdErrors[err.code]
1787 errText = "code %s" % -err.code
1788 if errText: errText += ". "
1789 errText += err.comment
1790 if allReasons: allReasons += "\n"
1792 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1794 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1798 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1800 if err.isGlobalAlgo:
1808 reason = '%s %sD algorithm is missing' % (glob, dim)
1809 elif err.state == HYP_MISSING:
1810 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1811 % (glob, dim, name, dim))
1812 elif err.state == HYP_NOTCONFORM:
1813 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1814 elif err.state == HYP_BAD_PARAMETER:
1815 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1816 % ( glob, dim, name ))
1817 elif err.state == HYP_BAD_GEOMETRY:
1818 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1819 'geometry' % ( glob, dim, name ))
1820 elif err.state == HYP_HIDDEN_ALGO:
1821 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1822 'algorithm of upper dimension generating %sD mesh'
1823 % ( glob, dim, name, glob, dim ))
1825 reason = ("For unknown reason. "
1826 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1828 if allReasons: allReasons += "\n"
1829 allReasons += "- " + reason
1831 if not ok or allReasons != "":
1832 msg = '"' + GetName(self.mesh) + '"'
1833 if ok: msg += " has been computed with warnings"
1834 else: msg += " has not been computed"
1835 if allReasons != "": msg += ":"
1840 if salome.sg.hasDesktop():
1841 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1842 if refresh: salome.sg.updateObjBrowser()
1846 def GetComputeErrors(self, shape=0 ):
1848 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1852 shape = self.mesh.GetShapeToMesh()
1853 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1855 def GetSubShapeName(self, subShapeID ):
1857 Return a name of a sub-shape by its ID.
1858 Possible variants (for *subShapeID* == 3):
1860 - **"Face_12"** - published sub-shape
1861 - **FACE #3** - not published sub-shape
1862 - **sub-shape #3** - invalid sub-shape ID
1863 - **#3** - error in this function
1866 subShapeID: a unique ID of a sub-shape
1869 a string describing the sub-shape
1873 if not self.mesh.HasShapeToMesh():
1877 mainIOR = salome.orb.object_to_string( self.GetShape() )
1879 mainSO = s.FindObjectIOR(mainIOR)
1882 shapeText = '"%s"' % mainSO.GetName()
1883 subIt = s.NewChildIterator(mainSO)
1885 subSO = subIt.Value()
1887 obj = subSO.GetObject()
1888 if not obj: continue
1889 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1892 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1895 if ids == subShapeID:
1896 shapeText = '"%s"' % subSO.GetName()
1899 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1901 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1903 shapeText = 'sub-shape #%s' % (subShapeID)
1905 shapeText = "#%s" % (subShapeID)
1908 def GetFailedShapes(self, publish=False):
1910 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1911 error of an algorithm
1914 publish: if *True*, the returned groups will be published in the study
1917 a list of GEOM groups each named after a failed algorithm
1922 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1923 for err in computeErrors:
1924 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1925 if not shape: continue
1926 if err.algoName in algo2shapes:
1927 algo2shapes[ err.algoName ].append( shape )
1929 algo2shapes[ err.algoName ] = [ shape ]
1933 for algoName, shapes in list(algo2shapes.items()):
1935 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1936 otherTypeShapes = []
1938 group = self.geompyD.CreateGroup( self.geom, groupType )
1939 for shape in shapes:
1940 if shape.GetShapeType() == shapes[0].GetShapeType():
1941 sameTypeShapes.append( shape )
1943 otherTypeShapes.append( shape )
1944 self.geompyD.UnionList( group, sameTypeShapes )
1946 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1948 group.SetName( algoName )
1949 groups.append( group )
1950 shapes = otherTypeShapes
1953 for group in groups:
1954 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1957 def GetMeshOrder(self):
1959 Return sub-mesh objects list in meshing order
1962 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1965 return self.mesh.GetMeshOrder()
1967 def SetMeshOrder(self, submeshes):
1969 Set order in which concurrent sub-meshes should be meshed
1972 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1975 return self.mesh.SetMeshOrder(submeshes)
1977 def Clear(self, refresh=False):
1979 Remove all nodes and elements generated on geometry. Imported elements remain.
1982 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1986 if ( salome.sg.hasDesktop() ):
1987 if refresh: salome.sg.updateObjBrowser()
1989 def ClearSubMesh(self, geomId, refresh=False):
1991 Remove all nodes and elements of indicated shape
1994 geomId: the ID of a sub-shape to remove elements on
1995 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1998 self.mesh.ClearSubMesh(geomId)
1999 if salome.sg.hasDesktop():
2000 if refresh: salome.sg.updateObjBrowser()
2002 def AutomaticTetrahedralization(self, fineness=0):
2004 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2007 fineness: [0.0,1.0] defines mesh fineness
2013 dim = self.MeshDimension()
2015 self.RemoveGlobalHypotheses()
2016 self.Segment().AutomaticLength(fineness)
2018 self.Triangle().LengthFromEdges()
2023 return self.Compute()
2025 def AutomaticHexahedralization(self, fineness=0):
2027 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2030 fineness: [0.0, 1.0] defines mesh fineness
2036 dim = self.MeshDimension()
2037 # assign the hypotheses
2038 self.RemoveGlobalHypotheses()
2039 self.Segment().AutomaticLength(fineness)
2046 return self.Compute()
2048 def AddHypothesis(self, hyp, geom=0):
2053 hyp: a hypothesis to assign
2054 geom: a subhape of mesh geometry
2057 :class:`SMESH.Hypothesis_Status`
2060 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2061 hyp, geom = geom, hyp
2062 if isinstance( hyp, Mesh_Algorithm ):
2063 hyp = hyp.GetAlgorithm()
2068 geom = self.mesh.GetShapeToMesh()
2071 if self.mesh.HasShapeToMesh():
2072 hyp_type = hyp.GetName()
2073 lib_name = hyp.GetLibName()
2074 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2075 # if checkAll and geom:
2076 # checkAll = geom.GetType() == 37
2078 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2080 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2081 status = self.mesh.AddHypothesis(geom, hyp)
2083 status = HYP_BAD_GEOMETRY, ""
2084 hyp_name = GetName( hyp )
2087 geom_name = geom.GetName()
2088 isAlgo = hyp._narrow( SMESH_Algo )
2089 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2092 def IsUsedHypothesis(self, hyp, geom):
2094 Return True if an algorithm or hypothesis is assigned to a given shape
2097 hyp: an algorithm or hypothesis to check
2098 geom: a subhape of mesh geometry
2104 if not hyp: # or not geom
2106 if isinstance( hyp, Mesh_Algorithm ):
2107 hyp = hyp.GetAlgorithm()
2109 hyps = self.GetHypothesisList(geom)
2111 if h.GetId() == hyp.GetId():
2115 def RemoveHypothesis(self, hyp, geom=0):
2117 Unassign a hypothesis
2120 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2121 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2124 :class:`SMESH.Hypothesis_Status`
2129 if isinstance( hyp, Mesh_Algorithm ):
2130 hyp = hyp.GetAlgorithm()
2136 if self.IsUsedHypothesis( hyp, shape ):
2137 return self.mesh.RemoveHypothesis( shape, hyp )
2138 hypName = GetName( hyp )
2139 geoName = GetName( shape )
2140 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2143 def GetHypothesisList(self, geom):
2145 Get the list of hypotheses added on a geometry
2148 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2151 the sequence of :class:`SMESH.SMESH_Hypothesis`
2154 return self.mesh.GetHypothesisList( geom )
2156 def RemoveGlobalHypotheses(self):
2158 Remove all global hypotheses
2161 current_hyps = self.mesh.GetHypothesisList( self.geom )
2162 for hyp in current_hyps:
2163 self.mesh.RemoveHypothesis( self.geom, hyp )
2166 def ExportMED(self, *args, **kwargs):
2168 Export the mesh in a file in MED format
2169 allowing to overwrite the file if it exists or add the exported data to its contents
2172 fileName: is the file name
2173 auto_groups (boolean): parameter for creating/not creating
2174 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2175 the typical use is auto_groups=False.
2176 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2177 The minor must be between 0 and the current minor version of MED file library.
2178 If minor is equal to -1, the minor version is not changed (default).
2179 The major version (x, where version is x.y.z) cannot be changed.
2180 overwrite (boolean): parameter for overwriting/not overwriting the file
2181 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2182 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2184 - 1D if all mesh nodes lie on OX coordinate axis, or
2185 - 2D if all mesh nodes lie on XOY coordinate plane, or
2186 - 3D in the rest cases.
2188 If *autoDimension* is *False*, the space dimension is always 3.
2189 fields: list of GEOM fields defined on the shape to mesh.
2190 geomAssocFields: each character of this string means a need to export a
2191 corresponding field; correspondence between fields and characters is following:
2192 - 'v' stands for "_vertices _" field;
2193 - 'e' stands for "_edges _" field;
2194 - 'f' stands for "_faces _" field;
2195 - 's' stands for "_solids _" field.
2197 # process positional arguments
2198 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2200 auto_groups = args[1] if len(args) > 1 else False
2201 minor = args[2] if len(args) > 2 else -1
2202 overwrite = args[3] if len(args) > 3 else True
2203 meshPart = args[4] if len(args) > 4 else None
2204 autoDimension = args[5] if len(args) > 5 else True
2205 fields = args[6] if len(args) > 6 else []
2206 geomAssocFields = args[7] if len(args) > 7 else ''
2207 # process keywords arguments
2208 auto_groups = kwargs.get("auto_groups", auto_groups)
2209 minor = kwargs.get("minor", minor)
2210 overwrite = kwargs.get("overwrite", overwrite)
2211 meshPart = kwargs.get("meshPart", meshPart)
2212 autoDimension = kwargs.get("autoDimension", autoDimension)
2213 fields = kwargs.get("fields", fields)
2214 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2215 # invoke engine's function
2216 if meshPart or fields or geomAssocFields:
2217 unRegister = genObjUnRegister()
2218 if isinstance( meshPart, list ):
2219 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2220 unRegister.set( meshPart )
2221 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2222 fields, geomAssocFields)
2224 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2226 def ExportSAUV(self, f, auto_groups=0):
2228 Export the mesh in a file in SAUV format
2233 auto_groups: boolean parameter for creating/not creating
2234 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2235 the typical use is auto_groups=False.
2238 self.mesh.ExportSAUV(f, auto_groups)
2240 def ExportDAT(self, f, meshPart=None):
2242 Export the mesh in a file in DAT format
2246 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2250 unRegister = genObjUnRegister()
2251 if isinstance( meshPart, list ):
2252 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2253 unRegister.set( meshPart )
2254 self.mesh.ExportPartToDAT( meshPart, f )
2256 self.mesh.ExportDAT(f)
2258 def ExportUNV(self, f, meshPart=None):
2260 Export the mesh in a file in UNV format
2264 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2268 unRegister = genObjUnRegister()
2269 if isinstance( meshPart, list ):
2270 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2271 unRegister.set( meshPart )
2272 self.mesh.ExportPartToUNV( meshPart, f )
2274 self.mesh.ExportUNV(f)
2276 def ExportSTL(self, f, ascii=1, meshPart=None):
2278 Export the mesh in a file in STL format
2282 ascii: defines the file encoding
2283 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2287 unRegister = genObjUnRegister()
2288 if isinstance( meshPart, list ):
2289 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2290 unRegister.set( meshPart )
2291 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2293 self.mesh.ExportSTL(f, ascii)
2295 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2297 Export the mesh in a file in CGNS format
2301 overwrite: boolean parameter for overwriting/not overwriting the file
2302 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2303 groupElemsByType: if True all elements of same entity type are exported at ones,
2304 else elements are exported in order of their IDs which can cause creation
2305 of multiple cgns sections
2308 unRegister = genObjUnRegister()
2309 if isinstance( meshPart, list ):
2310 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2311 unRegister.set( meshPart )
2312 if isinstance( meshPart, Mesh ):
2313 meshPart = meshPart.mesh
2315 meshPart = self.mesh
2316 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2318 def ExportGMF(self, f, meshPart=None):
2320 Export the mesh in a file in GMF format.
2321 GMF files must have .mesh extension for the ASCII format and .meshb for
2322 the bynary format. Other extensions are not allowed.
2326 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2329 unRegister = genObjUnRegister()
2330 if isinstance( meshPart, list ):
2331 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2332 unRegister.set( meshPart )
2333 if isinstance( meshPart, Mesh ):
2334 meshPart = meshPart.mesh
2336 meshPart = self.mesh
2337 self.mesh.ExportGMF(meshPart, f, True)
2339 def ExportToMED(self, *args, **kwargs):
2341 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2342 Export the mesh in a file in MED format
2343 allowing to overwrite the file if it exists or add the exported data to its contents
2346 fileName: the file name
2347 opt (boolean): parameter for creating/not creating
2348 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2349 overwrite: boolean parameter for overwriting/not overwriting the file
2350 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2352 - 1D if all mesh nodes lie on OX coordinate axis, or
2353 - 2D if all mesh nodes lie on XOY coordinate plane, or
2354 - 3D in the rest cases.
2356 If **autoDimension** is *False*, the space dimension is always 3.
2359 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2360 # process positional arguments
2361 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2363 auto_groups = args[1] if len(args) > 1 else False
2364 overwrite = args[2] if len(args) > 2 else True
2365 autoDimension = args[3] if len(args) > 3 else True
2366 # process keywords arguments
2367 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2368 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2369 overwrite = kwargs.get("overwrite", overwrite)
2370 autoDimension = kwargs.get("autoDimension", autoDimension)
2372 # invoke engine's function
2373 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2375 def ExportToMEDX(self, *args, **kwargs):
2377 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2378 Export the mesh in a file in MED format
2381 fileName: the file name
2382 opt (boolean): parameter for creating/not creating
2383 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2384 overwrite: boolean parameter for overwriting/not overwriting the file
2385 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2387 - 1D if all mesh nodes lie on OX coordinate axis, or
2388 - 2D if all mesh nodes lie on XOY coordinate plane, or
2389 - 3D in the rest cases.
2391 If **autoDimension** is *False*, the space dimension is always 3.
2394 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2395 # process positional arguments
2396 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2398 auto_groups = args[1] if len(args) > 1 else False
2399 overwrite = args[2] if len(args) > 2 else True
2400 autoDimension = args[3] if len(args) > 3 else True
2401 # process keywords arguments
2402 auto_groups = kwargs.get("auto_groups", auto_groups)
2403 overwrite = kwargs.get("overwrite", overwrite)
2404 autoDimension = kwargs.get("autoDimension", autoDimension)
2406 # invoke engine's function
2407 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2409 # Operations with groups:
2410 # ----------------------
2411 def CreateEmptyGroup(self, elementType, name):
2413 Create an empty standalone mesh group
2416 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2417 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2418 name: the name of the mesh group
2421 :class:`SMESH.SMESH_Group`
2424 return self.mesh.CreateGroup(elementType, name)
2426 def Group(self, grp, name=""):
2428 Create a mesh group based on the geometric object *grp*
2429 and give it a *name*.
2430 If *name* is not defined the name of the geometric group is used
2433 Works like :meth:`GroupOnGeom`.
2436 grp: a geometric group, a vertex, an edge, a face or a solid
2437 name: the name of the mesh group
2440 :class:`SMESH.SMESH_GroupOnGeom`
2443 return self.GroupOnGeom(grp, name)
2445 def GroupOnGeom(self, grp, name="", typ=None):
2447 Create a mesh group based on the geometrical object *grp*
2448 and give it a *name*.
2449 if *name* is not defined the name of the geometric group is used
2452 grp: a geometrical group, a vertex, an edge, a face or a solid
2453 name: the name of the mesh group
2454 typ: the type of elements in the group; either of
2455 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2456 automatically detected by the type of the geometry
2459 :class:`SMESH.SMESH_GroupOnGeom`
2462 AssureGeomPublished( self, grp, name )
2464 name = grp.GetName()
2466 typ = self._groupTypeFromShape( grp )
2467 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2469 def _groupTypeFromShape( self, shape ):
2471 Pivate method to get a type of group on geometry
2473 tgeo = str(shape.GetShapeType())
2474 if tgeo == "VERTEX":
2476 elif tgeo == "EDGE":
2478 elif tgeo == "FACE" or tgeo == "SHELL":
2480 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2482 elif tgeo == "COMPOUND":
2483 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2485 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2486 return self._groupTypeFromShape( sub[0] )
2488 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2491 def GroupOnFilter(self, typ, name, filter):
2493 Create a mesh group with given *name* based on the *filter*.
2494 It is a special type of group dynamically updating it's contents during
2498 typ: the type of elements in the group; either of
2499 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2500 name: the name of the mesh group
2501 filter (SMESH.Filter): the filter defining group contents
2504 :class:`SMESH.SMESH_GroupOnFilter`
2507 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2509 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2511 Create a mesh group by the given ids of elements
2514 groupName: the name of the mesh group
2515 elementType: the type of elements in the group; either of
2516 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2517 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2520 :class:`SMESH.SMESH_Group`
2523 group = self.mesh.CreateGroup(elementType, groupName)
2524 if isinstance( elemIDs, Mesh ):
2525 elemIDs = elemIDs.GetMesh()
2526 if hasattr( elemIDs, "GetIDs" ):
2527 if hasattr( elemIDs, "SetMesh" ):
2528 elemIDs.SetMesh( self.GetMesh() )
2529 group.AddFrom( elemIDs )
2537 CritType=FT_Undefined,
2540 UnaryOp=FT_Undefined,
2543 Create a mesh group by the given conditions
2546 groupName: the name of the mesh group
2547 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2548 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2549 Note that the items starting from FT_LessThan are not suitable for CritType.
2550 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2551 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2552 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2553 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2554 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2557 :class:`SMESH.SMESH_GroupOnFilter`
2560 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2561 group = self.MakeGroupByCriterion(groupName, aCriterion)
2564 def MakeGroupByCriterion(self, groupName, Criterion):
2566 Create a mesh group by the given criterion
2569 groupName: the name of the mesh group
2570 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2573 :class:`SMESH.SMESH_GroupOnFilter`
2576 :meth:`smeshBuilder.GetCriterion`
2579 return self.MakeGroupByCriteria( groupName, [Criterion] )
2581 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2583 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2586 groupName: the name of the mesh group
2587 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2588 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2591 :class:`SMESH.SMESH_GroupOnFilter`
2594 :meth:`smeshBuilder.GetCriterion`
2597 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2598 group = self.MakeGroupByFilter(groupName, aFilter)
2601 def MakeGroupByFilter(self, groupName, theFilter):
2603 Create a mesh group by the given filter
2606 groupName (string): the name of the mesh group
2607 theFilter (SMESH.Filter): the filter
2610 :class:`SMESH.SMESH_GroupOnFilter`
2613 :meth:`smeshBuilder.GetFilter`
2616 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2617 #theFilter.SetMesh( self.mesh )
2618 #group.AddFrom( theFilter )
2619 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2622 def RemoveGroup(self, group):
2627 group (SMESH.SMESH_GroupBase): group to remove
2630 self.mesh.RemoveGroup(group)
2632 def RemoveGroupWithContents(self, group):
2634 Remove a group with its contents
2637 group (SMESH.SMESH_GroupBase): group to remove
2640 self.mesh.RemoveGroupWithContents(group)
2642 def GetGroups(self, elemType = SMESH.ALL):
2644 Get the list of groups existing in the mesh in the order of creation
2645 (starting from the oldest one)
2648 elemType (SMESH.ElementType): type of elements the groups contain;
2649 by default groups of elements of all types are returned
2652 a list of :class:`SMESH.SMESH_GroupBase`
2655 groups = self.mesh.GetGroups()
2656 if elemType == SMESH.ALL:
2660 if g.GetType() == elemType:
2661 typedGroups.append( g )
2668 Get the number of groups existing in the mesh
2671 the quantity of groups as an integer value
2674 return self.mesh.NbGroups()
2676 def GetGroupNames(self):
2678 Get the list of names of groups existing in the mesh
2684 groups = self.GetGroups()
2686 for group in groups:
2687 names.append(group.GetName())
2690 def GetGroupByName(self, name, elemType = None):
2692 Find groups by name and type
2695 name (string): name of the group of interest
2696 elemType (SMESH.ElementType): type of elements the groups contain;
2697 by default one group of any type is returned;
2698 if elemType == SMESH.ALL then all groups of any type are returned
2701 a list of :class:`SMESH.SMESH_GroupBase`
2705 for group in self.GetGroups():
2706 if group.GetName() == name:
2707 if elemType is None:
2709 if ( elemType == SMESH.ALL or
2710 group.GetType() == elemType ):
2711 groups.append( group )
2714 def UnionGroups(self, group1, group2, name):
2716 Produce a union of two groups.
2717 A new group is created. All mesh elements that are
2718 present in the initial groups are added to the new one
2721 group1 (SMESH.SMESH_GroupBase): a group
2722 group2 (SMESH.SMESH_GroupBase): another group
2725 instance of :class:`SMESH.SMESH_Group`
2728 return self.mesh.UnionGroups(group1, group2, name)
2730 def UnionListOfGroups(self, groups, name):
2732 Produce a union list of groups.
2733 New group is created. All mesh elements that are present in
2734 initial groups are added to the new one
2737 groups: list of :class:`SMESH.SMESH_GroupBase`
2740 instance of :class:`SMESH.SMESH_Group`
2742 return self.mesh.UnionListOfGroups(groups, name)
2744 def IntersectGroups(self, group1, group2, name):
2746 Prodice an intersection of two groups.
2747 A new group is created. All mesh elements that are common
2748 for the two initial groups are added to the new one.
2751 group1 (SMESH.SMESH_GroupBase): a group
2752 group2 (SMESH.SMESH_GroupBase): another group
2755 instance of :class:`SMESH.SMESH_Group`
2758 return self.mesh.IntersectGroups(group1, group2, name)
2760 def IntersectListOfGroups(self, groups, name):
2762 Produce an intersection of groups.
2763 New group is created. All mesh elements that are present in all
2764 initial groups simultaneously are added to the new one
2767 groups: a list of :class:`SMESH.SMESH_GroupBase`
2770 instance of :class:`SMESH.SMESH_Group`
2772 return self.mesh.IntersectListOfGroups(groups, name)
2774 def CutGroups(self, main_group, tool_group, name):
2776 Produce a cut of two groups.
2777 A new group is created. All mesh elements that are present in
2778 the main group but are not present in the tool group are added to the new one
2781 main_group (SMESH.SMESH_GroupBase): a group to cut from
2782 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2785 an instance of :class:`SMESH.SMESH_Group`
2788 return self.mesh.CutGroups(main_group, tool_group, name)
2790 def CutListOfGroups(self, main_groups, tool_groups, name):
2792 Produce a cut of groups.
2793 A new group is created. All mesh elements that are present in main groups
2794 but do not present in tool groups are added to the new one
2797 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2798 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2801 an instance of :class:`SMESH.SMESH_Group`
2804 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2806 def CreateDimGroup(self, groups, elemType, name,
2807 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2809 Create a standalone group of entities basing on nodes of other groups.
2812 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2813 elemType: a type of elements to include to the new group; either of
2814 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2815 name: a name of the new group.
2816 nbCommonNodes: a criterion of inclusion of an element to the new group
2817 basing on number of element nodes common with reference *groups*.
2818 Meaning of possible values are:
2820 - SMESH.ALL_NODES - include if all nodes are common,
2821 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2822 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2823 - SMEHS.MAJORITY - include if half of nodes or more are common.
2824 underlyingOnly: if *True* (default), an element is included to the
2825 new group provided that it is based on nodes of an element of *groups*;
2826 in this case the reference *groups* are supposed to be of higher dimension
2827 than *elemType*, which can be useful for example to get all faces lying on
2828 volumes of the reference *groups*.
2831 an instance of :class:`SMESH.SMESH_Group`
2834 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2836 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2839 def ConvertToStandalone(self, group):
2841 Convert group on geom into standalone group
2844 return self.mesh.ConvertToStandalone(group)
2846 # Get some info about mesh:
2847 # ------------------------
2849 def GetLog(self, clearAfterGet):
2851 Return the log of nodes and elements added or removed
2852 since the previous clear of the log.
2855 clearAfterGet: log is emptied after Get (safe if concurrents access)
2858 list of SMESH.log_block structures { commandType, number, coords, indexes }
2861 return self.mesh.GetLog(clearAfterGet)
2865 Clear the log of nodes and elements added or removed since the previous
2866 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2869 self.mesh.ClearLog()
2871 def SetAutoColor(self, theAutoColor):
2873 Toggle auto color mode on the object.
2874 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2877 theAutoColor (boolean): the flag which toggles auto color mode.
2880 self.mesh.SetAutoColor(theAutoColor)
2882 def GetAutoColor(self):
2884 Get flag of object auto color mode.
2890 return self.mesh.GetAutoColor()
2897 integer value, which is the internal Id of the mesh
2900 return self.mesh.GetId()
2902 def HasDuplicatedGroupNamesMED(self):
2904 Check the group names for duplications.
2905 Consider the maximum group name length stored in MED file.
2911 return self.mesh.HasDuplicatedGroupNamesMED()
2913 def GetMeshEditor(self):
2915 Obtain the mesh editor tool
2918 an instance of :class:`SMESH.SMESH_MeshEditor`
2923 def GetIDSource(self, ids, elemType = SMESH.ALL):
2925 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2926 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2930 elemType: type of elements; this parameter is used to distinguish
2931 IDs of nodes from IDs of elements; by default ids are treated as
2932 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2935 an instance of :class:`SMESH.SMESH_IDSource`
2938 call UnRegister() for the returned object as soon as it is no more useful::
2940 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2941 mesh.DoSomething( idSrc )
2945 if isinstance( ids, int ):
2947 return self.editor.MakeIDSource(ids, elemType)
2950 # Get information about mesh contents:
2951 # ------------------------------------
2953 def GetMeshInfo(self, obj = None):
2955 Get the mesh statistic.
2956 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2957 an item of :class:`SMESH.EntityType`.
2960 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2963 if not obj: obj = self.mesh
2964 return self.smeshpyD.GetMeshInfo(obj)
2968 Return the number of nodes in the mesh
2974 return self.mesh.NbNodes()
2976 def NbElements(self):
2978 Return the number of elements in the mesh
2984 return self.mesh.NbElements()
2986 def Nb0DElements(self):
2988 Return the number of 0d elements in the mesh
2994 return self.mesh.Nb0DElements()
2998 Return the number of ball discrete elements in the mesh
3004 return self.mesh.NbBalls()
3008 Return the number of edges in the mesh
3014 return self.mesh.NbEdges()
3016 def NbEdgesOfOrder(self, elementOrder):
3018 Return the number of edges with the given order in the mesh
3021 elementOrder: the order of elements
3022 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3028 return self.mesh.NbEdgesOfOrder(elementOrder)
3032 Return the number of faces in the mesh
3038 return self.mesh.NbFaces()
3040 def NbFacesOfOrder(self, elementOrder):
3042 Return the number of faces with the given order in the mesh
3045 elementOrder: the order of elements
3046 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3052 return self.mesh.NbFacesOfOrder(elementOrder)
3054 def NbTriangles(self):
3056 Return the number of triangles in the mesh
3062 return self.mesh.NbTriangles()
3064 def NbTrianglesOfOrder(self, elementOrder):
3066 Return the number of triangles with the given order in the mesh
3069 elementOrder: is the order of elements
3070 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3076 return self.mesh.NbTrianglesOfOrder(elementOrder)
3078 def NbBiQuadTriangles(self):
3080 Return the number of biquadratic triangles in the mesh
3086 return self.mesh.NbBiQuadTriangles()
3088 def NbQuadrangles(self):
3090 Return the number of quadrangles in the mesh
3096 return self.mesh.NbQuadrangles()
3098 def NbQuadranglesOfOrder(self, elementOrder):
3100 Return the number of quadrangles with the given order in the mesh
3103 elementOrder: the order of elements
3104 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3110 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3112 def NbBiQuadQuadrangles(self):
3114 Return the number of biquadratic quadrangles in the mesh
3120 return self.mesh.NbBiQuadQuadrangles()
3122 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3124 Return the number of polygons of given order in the mesh
3127 elementOrder: the order of elements
3128 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3134 return self.mesh.NbPolygonsOfOrder(elementOrder)
3136 def NbVolumes(self):
3138 Return the number of volumes in the mesh
3144 return self.mesh.NbVolumes()
3147 def NbVolumesOfOrder(self, elementOrder):
3149 Return the number of volumes with the given order in the mesh
3152 elementOrder: the order of elements
3153 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3159 return self.mesh.NbVolumesOfOrder(elementOrder)
3163 Return the number of tetrahedrons in the mesh
3169 return self.mesh.NbTetras()
3171 def NbTetrasOfOrder(self, elementOrder):
3173 Return the number of tetrahedrons with the given order in the mesh
3176 elementOrder: the order of elements
3177 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3183 return self.mesh.NbTetrasOfOrder(elementOrder)
3187 Return the number of hexahedrons in the mesh
3193 return self.mesh.NbHexas()
3195 def NbHexasOfOrder(self, elementOrder):
3197 Return the number of hexahedrons with the given order in the mesh
3200 elementOrder: the order of elements
3201 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3207 return self.mesh.NbHexasOfOrder(elementOrder)
3209 def NbTriQuadraticHexas(self):
3211 Return the number of triquadratic hexahedrons in the mesh
3217 return self.mesh.NbTriQuadraticHexas()
3219 def NbPyramids(self):
3221 Return the number of pyramids in the mesh
3227 return self.mesh.NbPyramids()
3229 def NbPyramidsOfOrder(self, elementOrder):
3231 Return the number of pyramids with the given order in the mesh
3234 elementOrder: the order of elements
3235 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3241 return self.mesh.NbPyramidsOfOrder(elementOrder)
3245 Return the number of prisms in the mesh
3251 return self.mesh.NbPrisms()
3253 def NbPrismsOfOrder(self, elementOrder):
3255 Return the number of prisms with the given order in the mesh
3258 elementOrder: the order of elements
3259 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3265 return self.mesh.NbPrismsOfOrder(elementOrder)
3267 def NbHexagonalPrisms(self):
3269 Return the number of hexagonal prisms in the mesh
3275 return self.mesh.NbHexagonalPrisms()
3277 def NbPolyhedrons(self):
3279 Return the number of polyhedrons in the mesh
3285 return self.mesh.NbPolyhedrons()
3287 def NbSubMesh(self):
3289 Return the number of submeshes in the mesh
3295 return self.mesh.NbSubMesh()
3297 def GetElementsId(self):
3299 Return the list of all mesh elements IDs
3302 the list of integer values
3305 :meth:`GetElementsByType`
3308 return self.mesh.GetElementsId()
3310 def GetElementsByType(self, elementType):
3312 Return the list of IDs of mesh elements with the given type
3315 elementType (SMESH.ElementType): the required type of elements
3318 list of integer values
3321 return self.mesh.GetElementsByType(elementType)
3323 def GetNodesId(self):
3325 Return the list of mesh nodes IDs
3328 the list of integer values
3331 return self.mesh.GetNodesId()
3333 # Get the information about mesh elements:
3334 # ------------------------------------
3336 def GetElementType(self, id, iselem=True):
3338 Return the type of mesh element or node
3341 the value from :class:`SMESH.ElementType` enumeration.
3342 Return SMESH.ALL if element or node with the given ID does not exist
3345 return self.mesh.GetElementType(id, iselem)
3347 def GetElementGeomType(self, id):
3349 Return the geometric type of mesh element
3352 the value from :class:`SMESH.EntityType` enumeration.
3355 return self.mesh.GetElementGeomType(id)
3357 def GetElementShape(self, id):
3359 Return the shape type of mesh element
3362 the value from :class:`SMESH.GeometryType` enumeration.
3365 return self.mesh.GetElementShape(id)
3367 def GetSubMeshElementsId(self, Shape):
3369 Return the list of sub-mesh elements IDs
3372 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3373 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3376 list of integer values
3379 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3380 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3383 return self.mesh.GetSubMeshElementsId(ShapeID)
3385 def GetSubMeshNodesId(self, Shape, all):
3387 Return the list of sub-mesh nodes IDs
3390 Shape: a geom object (sub-shape).
3391 *Shape* must be the sub-shape of a :meth:`GetShape`
3392 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3395 list of integer values
3398 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3399 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3402 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3404 def GetSubMeshElementType(self, Shape):
3406 Return type of elements on given shape
3409 Shape: a geom object (sub-shape).
3410 *Shape* must be a sub-shape of a ShapeToMesh()
3413 :class:`SMESH.ElementType`
3416 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3417 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3420 return self.mesh.GetSubMeshElementType(ShapeID)
3424 Get the mesh description
3430 return self.mesh.Dump()
3433 # Get the information about nodes and elements of a mesh by its IDs:
3434 # -----------------------------------------------------------
3436 def GetNodeXYZ(self, id):
3438 Get XYZ coordinates of a node.
3439 If there is no node for the given ID - return an empty list
3442 list of float values
3445 return self.mesh.GetNodeXYZ(id)
3447 def GetNodeInverseElements(self, id):
3449 Return list of IDs of inverse elements for the given node.
3450 If there is no node for the given ID - return an empty list
3453 list of integer values
3456 return self.mesh.GetNodeInverseElements(id)
3458 def GetNodePosition(self,NodeID):
3460 Return the position of a node on the shape
3463 :class:`SMESH.NodePosition`
3466 return self.mesh.GetNodePosition(NodeID)
3468 def GetElementPosition(self,ElemID):
3470 Return the position of an element on the shape
3473 :class:`SMESH.ElementPosition`
3476 return self.mesh.GetElementPosition(ElemID)
3478 def GetShapeID(self, id):
3480 Return the ID of the shape, on which the given node was generated.
3483 an integer value > 0 or -1 if there is no node for the given
3484 ID or the node is not assigned to any geometry
3487 return self.mesh.GetShapeID(id)
3489 def GetShapeIDForElem(self,id):
3491 Return the ID of the shape, on which the given element was generated.
3494 an integer value > 0 or -1 if there is no element for the given
3495 ID or the element is not assigned to any geometry
3498 return self.mesh.GetShapeIDForElem(id)
3500 def GetElemNbNodes(self, id):
3502 Return the number of nodes of the given element
3505 an integer value > 0 or -1 if there is no element for the given ID
3508 return self.mesh.GetElemNbNodes(id)
3510 def GetElemNode(self, id, index):
3512 Return the node ID the given (zero based) index for the given element.
3514 * If there is no element for the given ID - return -1.
3515 * If there is no node for the given index - return -2.
3518 id (int): element ID
3519 index (int): node index within the element
3522 an integer value (ID)
3525 :meth:`GetElemNodes`
3528 return self.mesh.GetElemNode(id, index)
3530 def GetElemNodes(self, id):
3532 Return the IDs of nodes of the given element
3535 a list of integer values
3538 return self.mesh.GetElemNodes(id)
3540 def IsMediumNode(self, elementID, nodeID):
3542 Return true if the given node is the medium node in the given quadratic element
3545 return self.mesh.IsMediumNode(elementID, nodeID)
3547 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3549 Return true if the given node is the medium node in one of quadratic elements
3552 nodeID: ID of the node
3553 elementType: the type of elements to check a state of the node, either of
3554 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3557 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3559 def ElemNbEdges(self, id):
3561 Return the number of edges for the given element
3564 return self.mesh.ElemNbEdges(id)
3566 def ElemNbFaces(self, id):
3568 Return the number of faces for the given element
3571 return self.mesh.ElemNbFaces(id)
3573 def GetElemFaceNodes(self,elemId, faceIndex):
3575 Return nodes of given face (counted from zero) for given volumic element.
3578 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3580 def GetFaceNormal(self, faceId, normalized=False):
3582 Return three components of normal of given mesh face
3583 (or an empty array in KO case)
3586 return self.mesh.GetFaceNormal(faceId,normalized)
3588 def FindElementByNodes(self, nodes):
3590 Return an element based on all given nodes.
3593 return self.mesh.FindElementByNodes(nodes)
3595 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3597 Return elements including all given nodes.
3600 return self.mesh.GetElementsByNodes( nodes, elemType )
3602 def IsPoly(self, id):
3604 Return true if the given element is a polygon
3607 return self.mesh.IsPoly(id)
3609 def IsQuadratic(self, id):
3611 Return true if the given element is quadratic
3614 return self.mesh.IsQuadratic(id)
3616 def GetBallDiameter(self, id):
3618 Return diameter of a ball discrete element or zero in case of an invalid *id*
3621 return self.mesh.GetBallDiameter(id)
3623 def BaryCenter(self, id):
3625 Return XYZ coordinates of the barycenter of the given element.
3626 If there is no element for the given ID - return an empty list
3629 a list of three double values
3632 return self.mesh.BaryCenter(id)
3634 def GetIdsFromFilter(self, theFilter):
3636 Pass mesh elements through the given filter and return IDs of fitting elements
3639 theFilter: :class:`SMESH.Filter`
3645 :meth:`SMESH.Filter.GetIDs`
3648 theFilter.SetMesh( self.mesh )
3649 return theFilter.GetIDs()
3651 # Get mesh measurements information:
3652 # ------------------------------------
3654 def GetFreeBorders(self):
3656 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3657 Return a list of special structures (borders).
3660 a list of :class:`SMESH.FreeEdges.Border`
3663 aFilterMgr = self.smeshpyD.CreateFilterManager()
3664 aPredicate = aFilterMgr.CreateFreeEdges()
3665 aPredicate.SetMesh(self.mesh)
3666 aBorders = aPredicate.GetBorders()
3667 aFilterMgr.UnRegister()
3670 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3672 Get minimum distance between two nodes, elements or distance to the origin
3675 id1: first node/element id
3676 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3677 isElem1: *True* if *id1* is element id, *False* if it is node id
3678 isElem2: *True* if *id2* is element id, *False* if it is node id
3681 minimum distance value **GetMinDistance()**
3684 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3685 return aMeasure.value
3687 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3689 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3692 id1: first node/element id
3693 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3694 isElem1: *True* if *id1* is element id, *False* if it is node id
3695 isElem2: *True* if *id2* is element id, *False* if it is node id
3698 :class:`SMESH.Measure` structure
3704 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3706 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3709 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3711 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3716 aMeasurements = self.smeshpyD.CreateMeasurements()
3717 aMeasure = aMeasurements.MinDistance(id1, id2)
3718 genObjUnRegister([aMeasurements,id1, id2])
3721 def BoundingBox(self, objects=None, isElem=False):
3723 Get bounding box of the specified object(s)
3726 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3727 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3728 *False* specifies that *objects* are nodes
3731 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3734 :meth:`GetBoundingBox()`
3737 result = self.GetBoundingBox(objects, isElem)
3741 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3744 def GetBoundingBox(self, objects=None, isElem=False):
3746 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3749 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3750 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3751 False means that *objects* are nodes
3754 :class:`SMESH.Measure` structure
3757 :meth:`BoundingBox()`
3761 objects = [self.mesh]
3762 elif isinstance(objects, tuple):
3763 objects = list(objects)
3764 if not isinstance(objects, list):
3766 if len(objects) > 0 and isinstance(objects[0], int):
3769 unRegister = genObjUnRegister()
3771 if isinstance(o, Mesh):
3772 srclist.append(o.mesh)
3773 elif hasattr(o, "_narrow"):
3774 src = o._narrow(SMESH.SMESH_IDSource)
3775 if src: srclist.append(src)
3777 elif isinstance(o, list):
3779 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3781 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3782 unRegister.set( srclist[-1] )
3785 aMeasurements = self.smeshpyD.CreateMeasurements()
3786 unRegister.set( aMeasurements )
3787 aMeasure = aMeasurements.BoundingBox(srclist)
3790 # Mesh edition (SMESH_MeshEditor functionality):
3791 # ---------------------------------------------
3793 def RemoveElements(self, IDsOfElements):
3795 Remove the elements from the mesh by ids
3798 IDsOfElements: is a list of ids of elements to remove
3804 return self.editor.RemoveElements(IDsOfElements)
3806 def RemoveNodes(self, IDsOfNodes):
3808 Remove nodes from mesh by ids
3811 IDsOfNodes: is a list of ids of nodes to remove
3817 return self.editor.RemoveNodes(IDsOfNodes)
3819 def RemoveOrphanNodes(self):
3821 Remove all orphan (free) nodes from mesh
3824 number of the removed nodes
3827 return self.editor.RemoveOrphanNodes()
3829 def AddNode(self, x, y, z):
3831 Add a node to the mesh by coordinates
3837 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3838 if hasVars: self.mesh.SetParameters(Parameters)
3839 return self.editor.AddNode( x, y, z)
3841 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3843 Create a 0D element on a node with given number.
3846 IDOfNode: the ID of node for creation of the element.
3847 DuplicateElements: to add one more 0D element to a node or not
3850 ID of the new 0D element
3853 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3855 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3857 Create 0D elements on all nodes of the given elements except those
3858 nodes on which a 0D element already exists.
3861 theObject: an object on whose nodes 0D elements will be created.
3862 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3863 theGroupName: optional name of a group to add 0D elements created
3864 and/or found on nodes of *theObject*.
3865 DuplicateElements: to add one more 0D element to a node or not
3868 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3869 IDs of new and/or found 0D elements. IDs of 0D elements
3870 can be retrieved from the returned object by
3871 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3874 unRegister = genObjUnRegister()
3875 if isinstance( theObject, Mesh ):
3876 theObject = theObject.GetMesh()
3877 elif isinstance( theObject, list ):
3878 theObject = self.GetIDSource( theObject, SMESH.ALL )
3879 unRegister.set( theObject )
3880 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3882 def AddBall(self, IDOfNode, diameter):
3884 Create a ball element on a node with given ID.
3887 IDOfNode: the ID of node for creation of the element.
3888 diameter: the bal diameter.
3891 ID of the new ball element
3894 return self.editor.AddBall( IDOfNode, diameter )
3896 def AddEdge(self, IDsOfNodes):
3898 Create a linear or quadratic edge (this is determined
3899 by the number of given nodes).
3902 IDsOfNodes: list of node IDs for creation of the element.
3903 The order of nodes in this list should correspond to
3904 the :ref:`connectivity convention <connectivity_page>`.
3910 return self.editor.AddEdge(IDsOfNodes)
3912 def AddFace(self, IDsOfNodes):
3914 Create a linear or quadratic face (this is determined
3915 by the number of given nodes).
3918 IDsOfNodes: list of node IDs for creation of the element.
3919 The order of nodes in this list should correspond to
3920 the :ref:`connectivity convention <connectivity_page>`.
3926 return self.editor.AddFace(IDsOfNodes)
3928 def AddPolygonalFace(self, IdsOfNodes):
3930 Add a polygonal face defined by a list of node IDs
3933 IdsOfNodes: the list of node IDs for creation of the element.
3939 return self.editor.AddPolygonalFace(IdsOfNodes)
3941 def AddQuadPolygonalFace(self, IdsOfNodes):
3943 Add a quadratic polygonal face defined by a list of node IDs
3946 IdsOfNodes: the list of node IDs for creation of the element;
3947 corner nodes follow first.
3953 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3955 def AddVolume(self, IDsOfNodes):
3957 Create both simple and quadratic volume (this is determined
3958 by the number of given nodes).
3961 IDsOfNodes: list of node IDs for creation of the element.
3962 The order of nodes in this list should correspond to
3963 the :ref:`connectivity convention <connectivity_page>`.
3966 ID of the new volumic element
3969 return self.editor.AddVolume(IDsOfNodes)
3971 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3973 Create a volume of many faces, giving nodes for each face.
3976 IdsOfNodes: list of node IDs for volume creation, face by face.
3977 Quantities: list of integer values, Quantities[i]
3978 gives the quantity of nodes in face number i.
3981 ID of the new volumic element
3984 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3986 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3988 Create a volume of many faces, giving the IDs of the existing faces.
3991 The created volume will refer only to the nodes
3992 of the given faces, not to the faces themselves.
3995 IdsOfFaces: the list of face IDs for volume creation.
3998 ID of the new volumic element
4001 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4004 def SetNodeOnVertex(self, NodeID, Vertex):
4006 Bind a node to a vertex
4010 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4013 True if succeed else raises an exception
4016 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4017 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4021 self.editor.SetNodeOnVertex(NodeID, VertexID)
4022 except SALOME.SALOME_Exception as inst:
4023 raise ValueError(inst.details.text)
4027 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4029 Store the node position on an edge
4033 Edge: an edge (GEOM.GEOM_Object) or edge ID
4034 paramOnEdge: a parameter on the edge where the node is located
4037 True if succeed else raises an exception
4040 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4041 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4045 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4046 except SALOME.SALOME_Exception as inst:
4047 raise ValueError(inst.details.text)
4050 def SetNodeOnFace(self, NodeID, Face, u, v):
4052 Store node position on a face
4056 Face: a face (GEOM.GEOM_Object) or face ID
4057 u: U parameter on the face where the node is located
4058 v: V parameter on the face where the node is located
4061 True if succeed else raises an exception
4064 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4065 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4069 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4070 except SALOME.SALOME_Exception as inst:
4071 raise ValueError(inst.details.text)
4074 def SetNodeInVolume(self, NodeID, Solid):
4076 Bind a node to a solid
4080 Solid: a solid (GEOM.GEOM_Object) or solid ID
4083 True if succeed else raises an exception
4086 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4087 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4091 self.editor.SetNodeInVolume(NodeID, SolidID)
4092 except SALOME.SALOME_Exception as inst:
4093 raise ValueError(inst.details.text)
4096 def SetMeshElementOnShape(self, ElementID, Shape):
4098 Bind an element to a shape
4101 ElementID: an element ID
4102 Shape: a shape (GEOM.GEOM_Object) or shape ID
4105 True if succeed else raises an exception
4108 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4109 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4113 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4114 except SALOME.SALOME_Exception as inst:
4115 raise ValueError(inst.details.text)
4119 def MoveNode(self, NodeID, x, y, z):
4121 Move the node with the given id
4124 NodeID: the id of the node
4125 x: a new X coordinate
4126 y: a new Y coordinate
4127 z: a new Z coordinate
4130 True if succeed else False
4133 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4134 if hasVars: self.mesh.SetParameters(Parameters)
4135 return self.editor.MoveNode(NodeID, x, y, z)
4137 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4139 Find the node closest to a point and moves it to a point location
4142 x: the X coordinate of a point
4143 y: the Y coordinate of a point
4144 z: the Z coordinate of a point
4145 NodeID: if specified (>0), the node with this ID is moved,
4146 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4149 the ID of a moved node
4152 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4153 if hasVars: self.mesh.SetParameters(Parameters)
4154 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4156 def FindNodeClosestTo(self, x, y, z):
4158 Find the node closest to a point
4161 x: the X coordinate of a point
4162 y: the Y coordinate of a point
4163 z: the Z coordinate of a point
4169 #preview = self.mesh.GetMeshEditPreviewer()
4170 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4171 return self.editor.FindNodeClosestTo(x, y, z)
4173 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4175 Find the elements where a point lays IN or ON
4178 x,y,z (float): coordinates of the point
4179 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4180 means elements of any type excluding nodes, discrete and 0D elements.
4181 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4184 list of IDs of found elements
4187 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4189 return self.editor.FindElementsByPoint(x, y, z, elementType)
4191 def GetPointState(self, x, y, z):
4193 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4194 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4195 UNKNOWN state means that either mesh is wrong or the analysis fails.
4198 return self.editor.GetPointState(x, y, z)
4200 def IsManifold(self):
4202 Check if a 2D mesh is manifold
4205 return self.editor.IsManifold()
4207 def IsCoherentOrientation2D(self):
4209 Check if orientation of 2D elements is coherent
4212 return self.editor.IsCoherentOrientation2D()
4214 def MeshToPassThroughAPoint(self, x, y, z):
4216 Find the node closest to a point and moves it to a point location
4219 x: the X coordinate of a point
4220 y: the Y coordinate of a point
4221 z: the Z coordinate of a point
4224 the ID of a moved node
4227 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4229 def InverseDiag(self, NodeID1, NodeID2):
4231 Replace two neighbour triangles sharing Node1-Node2 link
4232 with the triangles built on the same 4 nodes but having other common link.
4235 NodeID1: the ID of the first node
4236 NodeID2: the ID of the second node
4239 False if proper faces were not found
4241 return self.editor.InverseDiag(NodeID1, NodeID2)
4243 def DeleteDiag(self, NodeID1, NodeID2):
4245 Replace two neighbour triangles sharing *Node1-Node2* link
4246 with a quadrangle built on the same 4 nodes.
4249 NodeID1: ID of the first node
4250 NodeID2: ID of the second node
4253 False if proper faces were not found
4256 return self.editor.DeleteDiag(NodeID1, NodeID2)
4258 def Reorient(self, IDsOfElements=None):
4260 Reorient elements by ids
4263 IDsOfElements: if undefined reorients all mesh elements
4266 True if succeed else False
4269 if IDsOfElements == None:
4270 IDsOfElements = self.GetElementsId()
4271 return self.editor.Reorient(IDsOfElements)
4273 def ReorientObject(self, theObject):
4275 Reorient all elements of the object
4278 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4281 True if succeed else False
4284 if ( isinstance( theObject, Mesh )):
4285 theObject = theObject.GetMesh()
4286 return self.editor.ReorientObject(theObject)
4288 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4290 Reorient faces contained in *the2DObject*.
4293 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4294 theDirection: is a desired direction of normal of *theFace*.
4295 It can be either a GEOM vector or a list of coordinates [x,y,z].
4296 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4297 compared with theDirection. It can be either ID of face or a point
4298 by which the face will be found. The point can be given as either
4299 a GEOM vertex or a list of point coordinates.
4302 number of reoriented faces
4305 unRegister = genObjUnRegister()
4307 if isinstance( the2DObject, Mesh ):
4308 the2DObject = the2DObject.GetMesh()
4309 if isinstance( the2DObject, list ):
4310 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4311 unRegister.set( the2DObject )
4312 # check theDirection
4313 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4314 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4315 if isinstance( theDirection, list ):
4316 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4317 # prepare theFace and thePoint
4318 theFace = theFaceOrPoint
4319 thePoint = PointStruct(0,0,0)
4320 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4321 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4323 if isinstance( theFaceOrPoint, list ):
4324 thePoint = PointStruct( *theFaceOrPoint )
4326 if isinstance( theFaceOrPoint, PointStruct ):
4327 thePoint = theFaceOrPoint
4329 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4331 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4333 Reorient faces according to adjacent volumes.
4336 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4337 either IDs of faces or face groups.
4338 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4339 theOutsideNormal: to orient faces to have their normals
4340 pointing either *outside* or *inside* the adjacent volumes.
4343 number of reoriented faces.
4346 unRegister = genObjUnRegister()
4348 if not isinstance( the2DObject, list ):
4349 the2DObject = [ the2DObject ]
4350 elif the2DObject and isinstance( the2DObject[0], int ):
4351 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4352 unRegister.set( the2DObject )
4353 the2DObject = [ the2DObject ]
4354 for i,obj2D in enumerate( the2DObject ):
4355 if isinstance( obj2D, Mesh ):
4356 the2DObject[i] = obj2D.GetMesh()
4357 if isinstance( obj2D, list ):
4358 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4359 unRegister.set( the2DObject[i] )
4361 if isinstance( the3DObject, Mesh ):
4362 the3DObject = the3DObject.GetMesh()
4363 if isinstance( the3DObject, list ):
4364 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4365 unRegister.set( the3DObject )
4366 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4368 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4370 Fuse the neighbouring triangles into quadrangles.
4373 IDsOfElements: The triangles to be fused.
4374 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4375 applied to possible quadrangles to choose a neighbour to fuse with.
4376 Note that not all items of :class:`SMESH.FunctorType` corresponds
4377 to numerical functors.
4378 MaxAngle: is the maximum angle between element normals at which the fusion
4379 is still performed; theMaxAngle is measured in radians.
4380 Also it could be a name of variable which defines angle in degrees.
4383 True in case of success, False otherwise.
4386 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4387 self.mesh.SetParameters(Parameters)
4388 if not IDsOfElements:
4389 IDsOfElements = self.GetElementsId()
4390 Functor = self.smeshpyD.GetFunctor(theCriterion)
4391 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4393 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4395 Fuse the neighbouring triangles of the object into quadrangles
4398 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4399 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4400 applied to possible quadrangles to choose a neighbour to fuse with.
4401 Note that not all items of :class:`SMESH.FunctorType` corresponds
4402 to numerical functors.
4403 MaxAngle: a max angle between element normals at which the fusion
4404 is still performed; theMaxAngle is measured in radians.
4407 True in case of success, False otherwise.
4410 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4411 self.mesh.SetParameters(Parameters)
4412 if isinstance( theObject, Mesh ):
4413 theObject = theObject.GetMesh()
4414 Functor = self.smeshpyD.GetFunctor(theCriterion)
4415 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4417 def QuadToTri (self, IDsOfElements, theCriterion = None):
4419 Split quadrangles into triangles.
4422 IDsOfElements: the faces to be splitted.
4423 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4424 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4425 value, then quadrangles will be split by the smallest diagonal.
4426 Note that not all items of :class:`SMESH.FunctorType` corresponds
4427 to numerical functors.
4430 True in case of success, False otherwise.
4432 if IDsOfElements == []:
4433 IDsOfElements = self.GetElementsId()
4434 if theCriterion is None:
4435 theCriterion = FT_MaxElementLength2D
4436 Functor = self.smeshpyD.GetFunctor(theCriterion)
4437 return self.editor.QuadToTri(IDsOfElements, Functor)
4439 def QuadToTriObject (self, theObject, theCriterion = None):
4441 Split quadrangles into triangles.
4444 theObject: the object from which the list of elements is taken,
4445 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4446 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4447 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4448 value, then quadrangles will be split by the smallest diagonal.
4449 Note that not all items of :class:`SMESH.FunctorType` corresponds
4450 to numerical functors.
4453 True in case of success, False otherwise.
4455 if ( isinstance( theObject, Mesh )):
4456 theObject = theObject.GetMesh()
4457 if theCriterion is None:
4458 theCriterion = FT_MaxElementLength2D
4459 Functor = self.smeshpyD.GetFunctor(theCriterion)
4460 return self.editor.QuadToTriObject(theObject, Functor)
4462 def QuadTo4Tri (self, theElements=[]):
4464 Split each of given quadrangles into 4 triangles. A node is added at the center of
4468 theElements: the faces to be splitted. This can be either
4469 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4470 or a list of face IDs. By default all quadrangles are split
4472 unRegister = genObjUnRegister()
4473 if isinstance( theElements, Mesh ):
4474 theElements = theElements.mesh
4475 elif not theElements:
4476 theElements = self.mesh
4477 elif isinstance( theElements, list ):
4478 theElements = self.GetIDSource( theElements, SMESH.FACE )
4479 unRegister.set( theElements )
4480 return self.editor.QuadTo4Tri( theElements )
4482 def SplitQuad (self, IDsOfElements, Diag13):
4484 Split quadrangles into triangles.
4487 IDsOfElements: the faces to be splitted
4488 Diag13: is used to choose a diagonal for splitting.
4491 True in case of success, False otherwise.
4493 if IDsOfElements == []:
4494 IDsOfElements = self.GetElementsId()
4495 return self.editor.SplitQuad(IDsOfElements, Diag13)
4497 def SplitQuadObject (self, theObject, Diag13):
4499 Split quadrangles into triangles.
4502 theObject: the object from which the list of elements is taken,
4503 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4504 Diag13: is used to choose a diagonal for splitting.
4507 True in case of success, False otherwise.
4509 if ( isinstance( theObject, Mesh )):
4510 theObject = theObject.GetMesh()
4511 return self.editor.SplitQuadObject(theObject, Diag13)
4513 def BestSplit (self, IDOfQuad, theCriterion):
4515 Find a better splitting of the given quadrangle.
4518 IDOfQuad: the ID of the quadrangle to be splitted.
4519 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4520 choose a diagonal for splitting.
4521 Note that not all items of :class:`SMESH.FunctorType` corresponds
4522 to numerical functors.
4525 * 1 if 1-3 diagonal is better,
4526 * 2 if 2-4 diagonal is better,
4527 * 0 if error occurs.
4529 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4531 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4533 Split volumic elements into tetrahedrons
4536 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4537 method: flags passing splitting method:
4538 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4539 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4541 unRegister = genObjUnRegister()
4542 if isinstance( elems, Mesh ):
4543 elems = elems.GetMesh()
4544 if ( isinstance( elems, list )):
4545 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4546 unRegister.set( elems )
4547 self.editor.SplitVolumesIntoTetra(elems, method)
4550 def SplitBiQuadraticIntoLinear(self, elems=None):
4552 Split bi-quadratic elements into linear ones without creation of additional nodes:
4554 - bi-quadratic triangle will be split into 3 linear quadrangles;
4555 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4556 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4558 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4559 will be split in order to keep the mesh conformal.
4562 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4563 if None (default), all bi-quadratic elements will be split
4565 unRegister = genObjUnRegister()
4566 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4567 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4568 unRegister.set( elems )
4570 elems = [ self.GetMesh() ]
4571 if isinstance( elems, Mesh ):
4572 elems = [ elems.GetMesh() ]
4573 if not isinstance( elems, list ):
4575 self.editor.SplitBiQuadraticIntoLinear( elems )
4577 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4578 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4580 Split hexahedra into prisms
4583 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4584 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4585 gives a normal vector defining facets to split into triangles.
4586 *startHexPoint* can be either a triple of coordinates or a vertex.
4587 facetNormal: a normal to a facet to split into triangles of a
4588 hexahedron found by *startHexPoint*.
4589 *facetNormal* can be either a triple of coordinates or an edge.
4590 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4591 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4592 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4593 to *startHexPoint* are split, else *startHexPoint*
4594 is used to find the facet to split in all domains present in *elems*.
4597 unRegister = genObjUnRegister()
4598 if isinstance( elems, Mesh ):
4599 elems = elems.GetMesh()
4600 if ( isinstance( elems, list )):
4601 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4602 unRegister.set( elems )
4605 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4606 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4607 elif isinstance( startHexPoint, list ):
4608 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4611 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4612 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4613 elif isinstance( facetNormal, list ):
4614 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4617 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4619 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4621 def SplitQuadsNearTriangularFacets(self):
4623 Split quadrangle faces near triangular facets of volumes
4625 faces_array = self.GetElementsByType(SMESH.FACE)
4626 for face_id in faces_array:
4627 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4628 quad_nodes = self.mesh.GetElemNodes(face_id)
4629 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4630 isVolumeFound = False
4631 for node1_elem in node1_elems:
4632 if not isVolumeFound:
4633 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4634 nb_nodes = self.GetElemNbNodes(node1_elem)
4635 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4636 volume_elem = node1_elem
4637 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4638 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4639 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4640 isVolumeFound = True
4641 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4642 self.SplitQuad([face_id], False) # diagonal 2-4
4643 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4644 isVolumeFound = True
4645 self.SplitQuad([face_id], True) # diagonal 1-3
4646 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4647 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4648 isVolumeFound = True
4649 self.SplitQuad([face_id], True) # diagonal 1-3
4651 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4653 Split hexahedrons into tetrahedrons.
4655 This operation uses :doc:`pattern_mapping` functionality for splitting.
4658 theObject: the object from which the list of hexahedrons is taken;
4659 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4660 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4661 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4662 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4663 key-point will be mapped into *theNode001*-th node of each volume.
4664 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4667 True in case of success, False otherwise.
4675 # (0,0,1) 4.---------.7 * |
4682 # (0,0,0) 0.---------.3
4683 pattern_tetra = "!!! Nb of points: \n 8 \n\
4693 !!! Indices of points of 6 tetras: \n\
4701 pattern = self.smeshpyD.GetPattern()
4702 isDone = pattern.LoadFromFile(pattern_tetra)
4704 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4707 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4708 isDone = pattern.MakeMesh(self.mesh, False, False)
4709 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4711 # split quafrangle faces near triangular facets of volumes
4712 self.SplitQuadsNearTriangularFacets()
4716 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4718 Split hexahedrons into prisms.
4720 Uses the :doc:`pattern_mapping` functionality for splitting.
4723 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4724 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4725 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4726 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4727 will be mapped into the *theNode001* -th node of each volume.
4728 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4731 True in case of success, False otherwise.
4733 # Pattern: 5.---------.6
4738 # (0,0,1) 4.---------.7 |
4745 # (0,0,0) 0.---------.3
4746 pattern_prism = "!!! Nb of points: \n 8 \n\
4756 !!! Indices of points of 2 prisms: \n\
4760 pattern = self.smeshpyD.GetPattern()
4761 isDone = pattern.LoadFromFile(pattern_prism)
4763 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4766 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4767 isDone = pattern.MakeMesh(self.mesh, False, False)
4768 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4770 # Split quafrangle faces near triangular facets of volumes
4771 self.SplitQuadsNearTriangularFacets()
4775 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4776 MaxNbOfIterations, MaxAspectRatio, Method):
4781 IDsOfElements: the list if ids of elements to smooth
4782 IDsOfFixedNodes: the list of ids of fixed nodes.
4783 Note that nodes built on edges and boundary nodes are always fixed.
4784 MaxNbOfIterations: the maximum number of iterations
4785 MaxAspectRatio: varies in range [1.0, inf]
4786 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4787 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4790 True in case of success, False otherwise.
4793 if IDsOfElements == []:
4794 IDsOfElements = self.GetElementsId()
4795 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4796 self.mesh.SetParameters(Parameters)
4797 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4798 MaxNbOfIterations, MaxAspectRatio, Method)
4800 def SmoothObject(self, theObject, IDsOfFixedNodes,
4801 MaxNbOfIterations, MaxAspectRatio, Method):
4803 Smooth elements which belong to the given object
4806 theObject: the object to smooth
4807 IDsOfFixedNodes: the list of ids of fixed nodes.
4808 Note that nodes built on edges and boundary nodes are always fixed.
4809 MaxNbOfIterations: the maximum number of iterations
4810 MaxAspectRatio: varies in range [1.0, inf]
4811 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4812 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4815 True in case of success, False otherwise.
4818 if ( isinstance( theObject, Mesh )):
4819 theObject = theObject.GetMesh()
4820 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4821 MaxNbOfIterations, MaxAspectRatio, Method)
4823 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4824 MaxNbOfIterations, MaxAspectRatio, Method):
4826 Parametrically smooth the given elements
4829 IDsOfElements: the list if ids of elements to smooth
4830 IDsOfFixedNodes: the list of ids of fixed nodes.
4831 Note that nodes built on edges and boundary nodes are always fixed.
4832 MaxNbOfIterations: the maximum number of iterations
4833 MaxAspectRatio: varies in range [1.0, inf]
4834 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4835 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4838 True in case of success, False otherwise.
4841 if IDsOfElements == []:
4842 IDsOfElements = self.GetElementsId()
4843 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4844 self.mesh.SetParameters(Parameters)
4845 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4846 MaxNbOfIterations, MaxAspectRatio, Method)
4848 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4849 MaxNbOfIterations, MaxAspectRatio, Method):
4851 Parametrically smooth the elements which belong to the given object
4854 theObject: the object to smooth
4855 IDsOfFixedNodes: the list of ids of fixed nodes.
4856 Note that nodes built on edges and boundary nodes are always fixed.
4857 MaxNbOfIterations: the maximum number of iterations
4858 MaxAspectRatio: varies in range [1.0, inf]
4859 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4860 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4863 True in case of success, False otherwise.
4866 if ( isinstance( theObject, Mesh )):
4867 theObject = theObject.GetMesh()
4868 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4869 MaxNbOfIterations, MaxAspectRatio, Method)
4871 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4873 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4874 them with quadratic with the same id.
4877 theForce3d: method of new node creation:
4879 * False - the medium node lies at the geometrical entity from which the mesh element is built
4880 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4881 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4882 theToBiQuad: If True, converts the mesh to bi-quadratic
4885 :class:`SMESH.ComputeError` which can hold a warning
4888 If *theSubMesh* is provided, the mesh can become non-conformal
4891 if isinstance( theSubMesh, Mesh ):
4892 theSubMesh = theSubMesh.mesh
4894 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4897 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4899 self.editor.ConvertToQuadratic(theForce3d)
4900 error = self.editor.GetLastError()
4901 if error and error.comment:
4902 print(error.comment)
4905 def ConvertFromQuadratic(self, theSubMesh=None):
4907 Convert the mesh from quadratic to ordinary,
4908 deletes old quadratic elements,
4909 replacing them with ordinary mesh elements with the same id.
4912 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4915 If *theSubMesh* is provided, the mesh can become non-conformal
4919 self.editor.ConvertFromQuadraticObject(theSubMesh)
4921 return self.editor.ConvertFromQuadratic()
4923 def Make2DMeshFrom3D(self):
4925 Create 2D mesh as skin on boundary faces of a 3D mesh
4928 True if operation has been completed successfully, False otherwise
4931 return self.editor.Make2DMeshFrom3D()
4933 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4934 toCopyElements=False, toCopyExistingBondary=False):
4936 Create missing boundary elements
4939 elements: elements whose boundary is to be checked:
4940 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4941 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4942 dimension: defines type of boundary elements to create, either of
4943 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4944 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4945 groupName: a name of group to store created boundary elements in,
4946 "" means not to create the group
4947 meshName: a name of new mesh to store created boundary elements in,
4948 "" means not to create the new mesh
4949 toCopyElements: if True, the checked elements will be copied into
4950 the new mesh else only boundary elements will be copied into the new mesh
4951 toCopyExistingBondary: if True, not only new but also pre-existing
4952 boundary elements will be copied into the new mesh
4955 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4958 unRegister = genObjUnRegister()
4959 if isinstance( elements, Mesh ):
4960 elements = elements.GetMesh()
4961 if ( isinstance( elements, list )):
4962 elemType = SMESH.ALL
4963 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4964 elements = self.editor.MakeIDSource(elements, elemType)
4965 unRegister.set( elements )
4966 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4967 toCopyElements,toCopyExistingBondary)
4968 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4971 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4972 toCopyAll=False, groups=[]):
4974 Create missing boundary elements around either the whole mesh or
4978 dimension: defines type of boundary elements to create, either of
4979 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4980 groupName: a name of group to store all boundary elements in,
4981 "" means not to create the group
4982 meshName: a name of a new mesh, which is a copy of the initial
4983 mesh + created boundary elements; "" means not to create the new mesh
4984 toCopyAll: if True, the whole initial mesh will be copied into
4985 the new mesh else only boundary elements will be copied into the new mesh
4986 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4989 tuple( long, mesh, groups )
4990 - long - number of added boundary elements
4991 - mesh - the :class:`Mesh` where elements were added to
4992 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4995 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4997 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4998 return nb, mesh, group
5000 def RenumberNodes(self):
5002 Renumber mesh nodes to remove unused node IDs
5004 self.editor.RenumberNodes()
5006 def RenumberElements(self):
5008 Renumber mesh elements to remove unused element IDs
5010 self.editor.RenumberElements()
5012 def _getIdSourceList(self, arg, idType, unRegister):
5014 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5016 if arg and isinstance( arg, list ):
5017 if isinstance( arg[0], int ):
5018 arg = self.GetIDSource( arg, idType )
5019 unRegister.set( arg )
5020 elif isinstance( arg[0], Mesh ):
5021 arg[0] = arg[0].GetMesh()
5022 elif isinstance( arg, Mesh ):
5024 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5028 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5029 MakeGroups=False, TotalAngle=False):
5031 Generate new elements by rotation of the given elements and nodes around the axis
5034 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5035 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5036 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5037 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5038 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5039 which defines angle in degrees
5040 NbOfSteps: the number of steps
5041 Tolerance: tolerance
5042 MakeGroups: forces the generation of new groups from existing ones
5043 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5044 of all steps, else - size of each step
5047 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5050 unRegister = genObjUnRegister()
5051 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5052 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5053 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5055 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5056 Axis = self.smeshpyD.GetAxisStruct( Axis )
5057 if isinstance( Axis, list ):
5058 Axis = SMESH.AxisStruct( *Axis )
5060 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5061 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5062 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5063 self.mesh.SetParameters(Parameters)
5064 if TotalAngle and NbOfSteps:
5065 AngleInRadians /= NbOfSteps
5066 return self.editor.RotationSweepObjects( nodes, edges, faces,
5067 Axis, AngleInRadians,
5068 NbOfSteps, Tolerance, MakeGroups)
5070 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5071 MakeGroups=False, TotalAngle=False):
5073 Generate new elements by rotation of the elements around the axis
5076 IDsOfElements: the list of ids of elements to sweep
5077 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5078 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5079 NbOfSteps: the number of steps
5080 Tolerance: tolerance
5081 MakeGroups: forces the generation of new groups from existing ones
5082 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5083 of all steps, else - size of each step
5086 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5089 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5090 AngleInRadians, NbOfSteps, Tolerance,
5091 MakeGroups, TotalAngle)
5093 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5094 MakeGroups=False, TotalAngle=False):
5096 Generate new elements by rotation of the elements of object around the axis
5097 theObject object which elements should be sweeped.
5098 It can be a mesh, a sub mesh or a group.
5101 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5102 AngleInRadians: the angle of Rotation
5103 NbOfSteps: number of steps
5104 Tolerance: tolerance
5105 MakeGroups: forces the generation of new groups from existing ones
5106 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5107 of all steps, else - size of each step
5110 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5113 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5114 AngleInRadians, NbOfSteps, Tolerance,
5115 MakeGroups, TotalAngle )
5117 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5118 MakeGroups=False, TotalAngle=False):
5120 Generate new elements by rotation of the elements of object around the axis
5121 theObject object which elements should be sweeped.
5122 It can be a mesh, a sub mesh or a group.
5125 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5126 AngleInRadians: the angle of Rotation
5127 NbOfSteps: number of steps
5128 Tolerance: tolerance
5129 MakeGroups: forces the generation of new groups from existing ones
5130 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5131 of all steps, else - size of each step
5134 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5135 empty list otherwise
5138 return self.RotationSweepObjects([],theObject,[], Axis,
5139 AngleInRadians, NbOfSteps, Tolerance,
5140 MakeGroups, TotalAngle)
5142 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5143 MakeGroups=False, TotalAngle=False):
5145 Generate new elements by rotation of the elements of object around the axis
5146 theObject object which elements should be sweeped.
5147 It can be a mesh, a sub mesh or a group.
5150 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5151 AngleInRadians: the angle of Rotation
5152 NbOfSteps: number of steps
5153 Tolerance: tolerance
5154 MakeGroups: forces the generation of new groups from existing ones
5155 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5156 of all steps, else - size of each step
5159 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5162 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5163 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5165 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5166 scaleFactors=[], linearVariation=False, basePoint=[] ):
5168 Generate new elements by extrusion of the given elements and nodes
5171 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5172 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5173 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5174 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5175 the direction and value of extrusion for one step (the total extrusion
5176 length will be NbOfSteps * ||StepVector||)
5177 NbOfSteps: the number of steps
5178 MakeGroups: forces the generation of new groups from existing ones
5179 scaleFactors: optional scale factors to apply during extrusion
5180 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5181 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5182 basePoint: optional scaling center; if not provided, a gravity center of
5183 nodes and elements being extruded is used as the scaling center.
5186 - a list of tree components of the point or
5190 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5192 Example: :ref:`tui_extrusion`
5194 unRegister = genObjUnRegister()
5195 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5196 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5197 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5199 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5200 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5201 if isinstance( StepVector, list ):
5202 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5204 if isinstance( basePoint, int):
5205 xyz = self.GetNodeXYZ( basePoint )
5207 raise RuntimeError("Invalid node ID: %s" % basePoint)
5209 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5210 basePoint = self.geompyD.PointCoordinates( basePoint )
5212 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5213 Parameters = StepVector.PS.parameters + var_separator + Parameters
5214 self.mesh.SetParameters(Parameters)
5216 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5217 StepVector, NbOfSteps,
5218 scaleFactors, linearVariation, basePoint,
5222 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5224 Generate new elements by extrusion of the elements with given ids
5227 IDsOfElements: the list of ids of elements or nodes for extrusion
5228 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5229 the direction and value of extrusion for one step (the total extrusion
5230 length will be NbOfSteps * ||StepVector||)
5231 NbOfSteps: the number of steps
5232 MakeGroups: forces the generation of new groups from existing ones
5233 IsNodes: is True if elements with given ids are nodes
5236 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5238 Example: :ref:`tui_extrusion`
5241 if IsNodes: n = IDsOfElements
5242 else : e,f, = IDsOfElements,IDsOfElements
5243 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5245 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5246 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5248 Generate new elements by extrusion along the normal to a discretized surface or wire
5251 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5252 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5253 StepSize: length of one extrusion step (the total extrusion
5254 length will be *NbOfSteps* *StepSize*).
5255 NbOfSteps: number of extrusion steps.
5256 ByAverageNormal: if True each node is translated by *StepSize*
5257 along the average of the normal vectors to the faces sharing the node;
5258 else each node is translated along the same average normal till
5259 intersection with the plane got by translation of the face sharing
5260 the node along its own normal by *StepSize*.
5261 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5262 for every node of *Elements*.
5263 MakeGroups: forces generation of new groups from existing ones.
5264 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5265 is not yet implemented. This parameter is used if *Elements* contains
5266 both faces and edges, i.e. *Elements* is a Mesh.
5269 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5270 empty list otherwise.
5271 Example: :ref:`tui_extrusion`
5274 unRegister = genObjUnRegister()
5275 if isinstance( Elements, Mesh ):
5276 Elements = [ Elements.GetMesh() ]
5277 if isinstance( Elements, list ):
5279 raise RuntimeError("Elements empty!")
5280 if isinstance( Elements[0], int ):
5281 Elements = self.GetIDSource( Elements, SMESH.ALL )
5282 unRegister.set( Elements )
5283 if not isinstance( Elements, list ):
5284 Elements = [ Elements ]
5285 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5286 self.mesh.SetParameters(Parameters)
5287 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5288 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5290 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5292 Generate new elements by extrusion of the elements or nodes which belong to the object
5295 theObject: the object whose elements or nodes should be processed.
5296 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5297 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5298 the direction and value of extrusion for one step (the total extrusion
5299 length will be NbOfSteps * ||StepVector||)
5300 NbOfSteps: the number of steps
5301 MakeGroups: forces the generation of new groups from existing ones
5302 IsNodes: is True if elements to extrude are nodes
5305 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5306 Example: :ref:`tui_extrusion`
5310 if IsNodes: n = theObject
5311 else : e,f, = theObject,theObject
5312 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5314 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5316 Generate new elements by extrusion of edges which belong to the object
5319 theObject: object whose 1D elements should be processed.
5320 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5321 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5322 the direction and value of extrusion for one step (the total extrusion
5323 length will be NbOfSteps * ||StepVector||)
5324 NbOfSteps: the number of steps
5325 MakeGroups: to generate new groups from existing ones
5328 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5329 Example: :ref:`tui_extrusion`
5332 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5334 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5336 Generate new elements by extrusion of faces which belong to the object
5339 theObject: object whose 2D elements should be processed.
5340 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5341 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5342 the direction and value of extrusion for one step (the total extrusion
5343 length will be NbOfSteps * ||StepVector||)
5344 NbOfSteps: the number of steps
5345 MakeGroups: forces the generation of new groups from existing ones
5348 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5349 Example: :ref:`tui_extrusion`
5352 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5354 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5355 ExtrFlags, SewTolerance, MakeGroups=False):
5357 Generate new elements by extrusion of the elements with given ids
5360 IDsOfElements: is ids of elements
5361 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5362 the direction and value of extrusion for one step (the total extrusion
5363 length will be NbOfSteps * ||StepVector||)
5364 NbOfSteps: the number of steps
5365 ExtrFlags: sets flags for extrusion
5366 SewTolerance: uses for comparing locations of nodes if flag
5367 EXTRUSION_FLAG_SEW is set
5368 MakeGroups: forces the generation of new groups from existing ones
5371 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5374 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5375 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5376 if isinstance( StepVector, list ):
5377 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5378 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5379 ExtrFlags, SewTolerance, MakeGroups)
5381 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5382 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5383 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5385 Generate new elements by extrusion of the given elements and nodes along the path.
5386 The path of extrusion must be a meshed edge.
5389 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5390 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5391 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5392 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5393 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5394 contains not only path segments, else it can be None
5395 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5396 HasAngles: allows the shape to be rotated around the path
5397 to get the resulting mesh in a helical fashion
5398 Angles: list of angles
5399 LinearVariation: forces the computation of rotation angles as linear
5400 variation of the given Angles along path steps
5401 HasRefPoint: allows using the reference point
5402 RefPoint: the reference point around which the shape is rotated (the mass center of the
5403 shape by default). The User can specify any point as the Reference Point.
5404 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5405 MakeGroups: forces the generation of new groups from existing ones
5408 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5409 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5410 Example: :ref:`tui_extrusion_along_path`
5413 unRegister = genObjUnRegister()
5414 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5415 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5416 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5418 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5419 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5420 if isinstance( RefPoint, list ):
5421 if not RefPoint: RefPoint = [0,0,0]
5422 RefPoint = SMESH.PointStruct( *RefPoint )
5423 if isinstance( PathMesh, Mesh ):
5424 PathMesh = PathMesh.GetMesh()
5425 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5426 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5427 self.mesh.SetParameters(Parameters)
5428 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5429 PathMesh, PathShape, NodeStart,
5430 HasAngles, Angles, LinearVariation,
5431 HasRefPoint, RefPoint, MakeGroups)
5433 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5434 HasAngles=False, Angles=[], LinearVariation=False,
5435 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5436 ElemType=SMESH.FACE):
5438 Generate new elements by extrusion of the given elements.
5439 The path of extrusion must be a meshed edge.
5442 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5443 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5444 NodeStart: the start node from Path. Defines the direction of extrusion
5445 HasAngles: allows the shape to be rotated around the path
5446 to get the resulting mesh in a helical fashion
5447 Angles: list of angles in radians
5448 LinearVariation: forces the computation of rotation angles as linear
5449 variation of the given Angles along path steps
5450 HasRefPoint: allows using the reference point
5451 RefPoint: the reference point around which the elements are rotated (the mass
5452 center of the elements by default).
5453 The User can specify any point as the Reference Point.
5454 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5455 MakeGroups: forces the generation of new groups from existing ones
5456 ElemType: type of elements for extrusion (if param Base is a mesh)
5459 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5460 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5461 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5463 Example: :ref:`tui_extrusion_along_path`
5467 if ElemType == SMESH.NODE: n = Base
5468 if ElemType == SMESH.EDGE: e = Base
5469 if ElemType == SMESH.FACE: f = Base
5470 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5471 HasAngles, Angles, LinearVariation,
5472 HasRefPoint, RefPoint, MakeGroups)
5473 if MakeGroups: return gr,er
5476 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5477 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5478 MakeGroups=False, LinearVariation=False):
5480 Generate new elements by extrusion of the given elements.
5481 The path of extrusion must be a meshed edge.
5484 IDsOfElements: ids of elements
5485 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5486 PathShape: shape (edge) defines the sub-mesh for the path
5487 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5488 HasAngles: allows the shape to be rotated around the path
5489 to get the resulting mesh in a helical fashion
5490 Angles: list of angles in radians
5491 HasRefPoint: allows using the reference point
5492 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5493 The User can specify any point as the Reference Point.
5494 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5495 MakeGroups: forces the generation of new groups from existing ones
5496 LinearVariation: forces the computation of rotation angles as linear
5497 variation of the given Angles along path steps
5500 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5501 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5502 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5503 Example: :ref:`tui_extrusion_along_path`
5506 n,e,f = [],IDsOfElements,IDsOfElements
5507 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5508 NodeStart, HasAngles, Angles,
5510 HasRefPoint, RefPoint, MakeGroups)
5511 if MakeGroups: return gr,er
5514 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5515 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5516 MakeGroups=False, LinearVariation=False):
5518 Generate new elements by extrusion of the elements which belong to the object.
5519 The path of extrusion must be a meshed edge.
5522 theObject: the object whose elements should be processed.
5523 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5524 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5525 PathShape: shape (edge) defines the sub-mesh for the path
5526 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5527 HasAngles: allows the shape to be rotated around the path
5528 to get the resulting mesh in a helical fashion
5529 Angles: list of angles
5530 HasRefPoint: allows using the reference point
5531 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5532 The User can specify any point as the Reference Point.
5533 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5534 MakeGroups: forces the generation of new groups from existing ones
5535 LinearVariation: forces the computation of rotation angles as linear
5536 variation of the given Angles along path steps
5539 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5540 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5541 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5542 Example: :ref:`tui_extrusion_along_path`
5545 n,e,f = [],theObject,theObject
5546 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5547 HasAngles, Angles, LinearVariation,
5548 HasRefPoint, RefPoint, MakeGroups)
5549 if MakeGroups: return gr,er
5552 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5553 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5554 MakeGroups=False, LinearVariation=False):
5556 Generate new elements by extrusion of mesh segments which belong to the object.
5557 The path of extrusion must be a meshed edge.
5560 theObject: the object whose 1D elements should be processed.
5561 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5562 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5563 PathShape: shape (edge) defines the sub-mesh for the path
5564 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5565 HasAngles: allows the shape to be rotated around the path
5566 to get the resulting mesh in a helical fashion
5567 Angles: list of angles
5568 HasRefPoint: allows using the reference point
5569 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5570 The User can specify any point as the Reference Point.
5571 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5572 MakeGroups: forces the generation of new groups from existing ones
5573 LinearVariation: forces the computation of rotation angles as linear
5574 variation of the given Angles along path steps
5577 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5578 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5579 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5580 Example: :ref:`tui_extrusion_along_path`
5583 n,e,f = [],theObject,[]
5584 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5585 HasAngles, Angles, LinearVariation,
5586 HasRefPoint, RefPoint, MakeGroups)
5587 if MakeGroups: return gr,er
5590 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5591 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5592 MakeGroups=False, LinearVariation=False):
5594 Generate new elements by extrusion of faces which belong to the object.
5595 The path of extrusion must be a meshed edge.
5598 theObject: the object whose 2D elements should be processed.
5599 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5600 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5601 PathShape: shape (edge) defines the sub-mesh for the path
5602 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5603 HasAngles: allows the shape to be rotated around the path
5604 to get the resulting mesh in a helical fashion
5605 Angles: list of angles
5606 HasRefPoint: allows using the reference point
5607 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5608 The User can specify any point as the Reference Point.
5609 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5610 MakeGroups: forces the generation of new groups from existing ones
5611 LinearVariation: forces the computation of rotation angles as linear
5612 variation of the given Angles along path steps
5615 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5616 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5617 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5618 Example: :ref:`tui_extrusion_along_path`
5621 n,e,f = [],[],theObject
5622 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5623 HasAngles, Angles, LinearVariation,
5624 HasRefPoint, RefPoint, MakeGroups)
5625 if MakeGroups: return gr,er
5628 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5630 Create a symmetrical copy of mesh elements
5633 IDsOfElements: list of elements ids
5634 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5635 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5636 If the *Mirror* is a geom object this parameter is unnecessary
5637 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5638 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5641 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5644 if IDsOfElements == []:
5645 IDsOfElements = self.GetElementsId()
5646 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5647 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5648 theMirrorType = Mirror._mirrorType
5650 self.mesh.SetParameters(Mirror.parameters)
5651 if Copy and MakeGroups:
5652 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5653 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5656 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5658 Create a new mesh by a symmetrical copy of mesh elements
5661 IDsOfElements: the list of elements ids
5662 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5663 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5664 If the *Mirror* is a geom object this parameter is unnecessary
5665 MakeGroups: to generate new groups from existing ones
5666 NewMeshName: a name of the new mesh to create
5669 instance of class :class:`Mesh`
5672 if IDsOfElements == []:
5673 IDsOfElements = self.GetElementsId()
5674 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5675 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5676 theMirrorType = Mirror._mirrorType
5678 self.mesh.SetParameters(Mirror.parameters)
5679 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5680 MakeGroups, NewMeshName)
5681 return Mesh(self.smeshpyD,self.geompyD,mesh)
5683 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5685 Create a symmetrical copy of the object
5688 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5689 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5690 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5691 If the *Mirror* is a geom object this parameter is unnecessary
5692 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5693 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5696 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5699 if ( isinstance( theObject, Mesh )):
5700 theObject = theObject.GetMesh()
5701 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5702 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5703 theMirrorType = Mirror._mirrorType
5705 self.mesh.SetParameters(Mirror.parameters)
5706 if Copy and MakeGroups:
5707 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5708 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5711 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5713 Create a new mesh by a symmetrical copy of the object
5716 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5717 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5718 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5719 If the *Mirror* is a geom object this parameter is unnecessary
5720 MakeGroups: forces the generation of new groups from existing ones
5721 NewMeshName: the name of the new mesh to create
5724 instance of class :class:`Mesh`
5727 if ( isinstance( theObject, Mesh )):
5728 theObject = theObject.GetMesh()
5729 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5730 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5731 theMirrorType = Mirror._mirrorType
5733 self.mesh.SetParameters(Mirror.parameters)
5734 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5735 MakeGroups, NewMeshName)
5736 return Mesh( self.smeshpyD,self.geompyD,mesh )
5738 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5740 Translate the elements
5743 IDsOfElements: list of elements ids
5744 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5745 Copy: allows copying the translated elements
5746 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5749 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5752 if IDsOfElements == []:
5753 IDsOfElements = self.GetElementsId()
5754 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5755 Vector = self.smeshpyD.GetDirStruct(Vector)
5756 if isinstance( Vector, list ):
5757 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5758 self.mesh.SetParameters(Vector.PS.parameters)
5759 if Copy and MakeGroups:
5760 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5761 self.editor.Translate(IDsOfElements, Vector, Copy)
5764 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5766 Create a new mesh of translated elements
5769 IDsOfElements: list of elements ids
5770 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5771 MakeGroups: forces the generation of new groups from existing ones
5772 NewMeshName: the name of the newly created mesh
5775 instance of class :class:`Mesh`
5778 if IDsOfElements == []:
5779 IDsOfElements = self.GetElementsId()
5780 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5781 Vector = self.smeshpyD.GetDirStruct(Vector)
5782 if isinstance( Vector, list ):
5783 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5784 self.mesh.SetParameters(Vector.PS.parameters)
5785 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5786 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5788 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5790 Translate the object
5793 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5794 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5795 Copy: allows copying the translated elements
5796 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5799 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5802 if ( isinstance( theObject, Mesh )):
5803 theObject = theObject.GetMesh()
5804 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5805 Vector = self.smeshpyD.GetDirStruct(Vector)
5806 if isinstance( Vector, list ):
5807 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5808 self.mesh.SetParameters(Vector.PS.parameters)
5809 if Copy and MakeGroups:
5810 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5811 self.editor.TranslateObject(theObject, Vector, Copy)
5814 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5816 Create a new mesh from the translated object
5819 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5820 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5821 MakeGroups: forces the generation of new groups from existing ones
5822 NewMeshName: the name of the newly created mesh
5825 instance of class :class:`Mesh`
5828 if isinstance( theObject, Mesh ):
5829 theObject = theObject.GetMesh()
5830 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5831 Vector = self.smeshpyD.GetDirStruct(Vector)
5832 if isinstance( Vector, list ):
5833 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5834 self.mesh.SetParameters(Vector.PS.parameters)
5835 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5836 return Mesh( self.smeshpyD, self.geompyD, mesh )
5840 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5845 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5846 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5847 theScaleFact: list of 1-3 scale factors for axises
5848 Copy: allows copying the translated elements
5849 MakeGroups: forces the generation of new groups from existing
5853 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5854 empty list otherwise
5856 unRegister = genObjUnRegister()
5857 if ( isinstance( theObject, Mesh )):
5858 theObject = theObject.GetMesh()
5859 if ( isinstance( theObject, list )):
5860 theObject = self.GetIDSource(theObject, SMESH.ALL)
5861 unRegister.set( theObject )
5862 if ( isinstance( thePoint, list )):
5863 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5864 if ( isinstance( theScaleFact, float )):
5865 theScaleFact = [theScaleFact]
5866 if ( isinstance( theScaleFact, int )):
5867 theScaleFact = [ float(theScaleFact)]
5869 self.mesh.SetParameters(thePoint.parameters)
5871 if Copy and MakeGroups:
5872 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5873 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5876 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5878 Create a new mesh from the translated object
5881 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5882 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5883 theScaleFact: list of 1-3 scale factors for axises
5884 MakeGroups: forces the generation of new groups from existing ones
5885 NewMeshName: the name of the newly created mesh
5888 instance of class :class:`Mesh`
5890 unRegister = genObjUnRegister()
5891 if (isinstance(theObject, Mesh)):
5892 theObject = theObject.GetMesh()
5893 if ( isinstance( theObject, list )):
5894 theObject = self.GetIDSource(theObject,SMESH.ALL)
5895 unRegister.set( theObject )
5896 if ( isinstance( thePoint, list )):
5897 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5898 if ( isinstance( theScaleFact, float )):
5899 theScaleFact = [theScaleFact]
5900 if ( isinstance( theScaleFact, int )):
5901 theScaleFact = [ float(theScaleFact)]
5903 self.mesh.SetParameters(thePoint.parameters)
5904 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5905 MakeGroups, NewMeshName)
5906 return Mesh( self.smeshpyD, self.geompyD, mesh )
5910 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5915 IDsOfElements: list of elements ids
5916 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5917 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5918 Copy: allows copying the rotated elements
5919 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5922 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5926 if IDsOfElements == []:
5927 IDsOfElements = self.GetElementsId()
5928 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5929 Axis = self.smeshpyD.GetAxisStruct(Axis)
5930 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5931 Parameters = Axis.parameters + var_separator + Parameters
5932 self.mesh.SetParameters(Parameters)
5933 if Copy and MakeGroups:
5934 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5935 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5938 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5940 Create a new mesh of rotated elements
5943 IDsOfElements: list of element ids
5944 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5945 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5946 MakeGroups: forces the generation of new groups from existing ones
5947 NewMeshName: the name of the newly created mesh
5950 instance of class :class:`Mesh`
5953 if IDsOfElements == []:
5954 IDsOfElements = self.GetElementsId()
5955 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5956 Axis = self.smeshpyD.GetAxisStruct(Axis)
5957 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5958 Parameters = Axis.parameters + var_separator + Parameters
5959 self.mesh.SetParameters(Parameters)
5960 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5961 MakeGroups, NewMeshName)
5962 return Mesh( self.smeshpyD, self.geompyD, mesh )
5964 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5969 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5970 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5971 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5972 Copy: allows copying the rotated elements
5973 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5976 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5979 if (isinstance(theObject, Mesh)):
5980 theObject = theObject.GetMesh()
5981 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5982 Axis = self.smeshpyD.GetAxisStruct(Axis)
5983 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5984 Parameters = Axis.parameters + ":" + Parameters
5985 self.mesh.SetParameters(Parameters)
5986 if Copy and MakeGroups:
5987 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5988 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5991 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5993 Create a new mesh from the rotated object
5996 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5997 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5998 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5999 MakeGroups: forces the generation of new groups from existing ones
6000 NewMeshName: the name of the newly created mesh
6003 instance of class :class:`Mesh`
6006 if (isinstance( theObject, Mesh )):
6007 theObject = theObject.GetMesh()
6008 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6009 Axis = self.smeshpyD.GetAxisStruct(Axis)
6010 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6011 Parameters = Axis.parameters + ":" + Parameters
6012 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6013 MakeGroups, NewMeshName)
6014 self.mesh.SetParameters(Parameters)
6015 return Mesh( self.smeshpyD, self.geompyD, mesh )
6017 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6019 Create an offset mesh from the given 2D object
6022 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6023 theValue (float): signed offset size
6024 MakeGroups (boolean): forces the generation of new groups from existing ones
6025 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6026 False means to remove original elements.
6027 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6030 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6033 if isinstance( theObject, Mesh ):
6034 theObject = theObject.GetMesh()
6035 theValue,Parameters,hasVars = ParseParameters(Value)
6036 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6037 self.mesh.SetParameters(Parameters)
6038 # if mesh_groups[0]:
6039 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6042 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6044 Find groups of adjacent nodes within Tolerance.
6047 Tolerance (float): the value of tolerance
6048 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6049 corner and medium nodes in separate groups thus preventing
6050 their further merge.
6053 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6056 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6058 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6059 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6061 Find groups of adjacent nodes within Tolerance.
6064 Tolerance: the value of tolerance
6065 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6066 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6067 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6068 corner and medium nodes in separate groups thus preventing
6069 their further merge.
6072 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6075 unRegister = genObjUnRegister()
6076 if (isinstance( SubMeshOrGroup, Mesh )):
6077 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6078 if not isinstance( exceptNodes, list ):
6079 exceptNodes = [ exceptNodes ]
6080 if exceptNodes and isinstance( exceptNodes[0], int ):
6081 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6082 unRegister.set( exceptNodes )
6083 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6084 exceptNodes, SeparateCornerAndMediumNodes)
6086 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6091 GroupsOfNodes: a list of groups of nodes IDs for merging.
6092 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6093 in all elements and groups by nodes 1 and 25 correspondingly
6094 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6095 If *NodesToKeep* does not include a node to keep for some group to merge,
6096 then the first node in the group is kept.
6097 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6100 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6101 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6103 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6105 Find the elements built on the same nodes.
6108 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6111 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6114 if not MeshOrSubMeshOrGroup:
6115 MeshOrSubMeshOrGroup=self.mesh
6116 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6117 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6118 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6120 def MergeElements(self, GroupsOfElementsID):
6122 Merge elements in each given group.
6125 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6126 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6127 replaced in all groups by elements 1 and 25)
6130 self.editor.MergeElements(GroupsOfElementsID)
6132 def MergeEqualElements(self):
6134 Leave one element and remove all other elements built on the same nodes.
6137 self.editor.MergeEqualElements()
6139 def FindFreeBorders(self, ClosedOnly=True):
6141 Returns all or only closed free borders
6144 list of SMESH.FreeBorder's
6147 return self.editor.FindFreeBorders( ClosedOnly )
6149 def FillHole(self, holeNodes, groupName=""):
6151 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6154 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6155 must describe all sequential nodes of the hole border. The first and the last
6156 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6157 groupName (string): name of a group to add new faces
6159 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if :option:`groupName` == ""
6163 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6164 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6165 if not isinstance( holeNodes, SMESH.FreeBorder ):
6166 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6167 self.editor.FillHole( holeNodes, groupName )
6169 def FindCoincidentFreeBorders (self, tolerance=0.):
6171 Return groups of FreeBorder's coincident within the given tolerance.
6174 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6175 size of elements adjacent to free borders being compared is used.
6178 SMESH.CoincidentFreeBorders structure
6181 return self.editor.FindCoincidentFreeBorders( tolerance )
6183 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6185 Sew FreeBorder's of each group
6188 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6189 where each enclosed list contains node IDs of a group of coincident free
6190 borders such that each consequent triple of IDs within a group describes
6191 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6192 last node of a border.
6193 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6194 groups of coincident free borders, each group including two borders.
6195 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6196 polygons if a node of opposite border falls on a face edge, else such
6197 faces are split into several ones.
6198 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6199 polyhedra if a node of opposite border falls on a volume edge, else such
6200 volumes, if any, remain intact and the mesh becomes non-conformal.
6203 a number of successfully sewed groups
6206 if freeBorders and isinstance( freeBorders, list ):
6207 # construct SMESH.CoincidentFreeBorders
6208 if isinstance( freeBorders[0], int ):
6209 freeBorders = [freeBorders]
6211 coincidentGroups = []
6212 for nodeList in freeBorders:
6213 if not nodeList or len( nodeList ) % 3:
6214 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6217 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6218 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6219 nodeList = nodeList[3:]
6221 coincidentGroups.append( group )
6223 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6225 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6227 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6228 FirstNodeID2, SecondNodeID2, LastNodeID2,
6229 CreatePolygons, CreatePolyedrs):
6234 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6237 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6238 FirstNodeID2, SecondNodeID2, LastNodeID2,
6239 CreatePolygons, CreatePolyedrs)
6241 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6242 FirstNodeID2, SecondNodeID2):
6244 Sew conform free borders
6247 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6250 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6251 FirstNodeID2, SecondNodeID2)
6253 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6254 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6259 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6262 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6263 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6265 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6266 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6267 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6269 Sew two sides of a mesh. The nodes belonging to Side1 are
6270 merged with the nodes of elements of Side2.
6271 The number of elements in theSide1 and in theSide2 must be
6272 equal and they should have similar nodal connectivity.
6273 The nodes to merge should belong to side borders and
6274 the first node should be linked to the second.
6277 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6280 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6281 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6282 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6284 def ChangeElemNodes(self, ide, newIDs):
6286 Set new nodes for the given element.
6293 False if the number of nodes does not correspond to the type of element
6296 return self.editor.ChangeElemNodes(ide, newIDs)
6298 def GetLastCreatedNodes(self):
6300 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6301 created, this method return the list of their IDs.
6302 If new nodes were not created - return empty list
6305 the list of integer values (can be empty)
6308 return self.editor.GetLastCreatedNodes()
6310 def GetLastCreatedElems(self):
6312 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6313 created this method return the list of their IDs.
6314 If new elements were not created - return empty list
6317 the list of integer values (can be empty)
6320 return self.editor.GetLastCreatedElems()
6322 def ClearLastCreated(self):
6324 Forget what nodes and elements were created by the last mesh edition operation
6327 self.editor.ClearLastCreated()
6329 def DoubleElements(self, theElements, theGroupName=""):
6331 Create duplicates of given elements, i.e. create new elements based on the
6332 same nodes as the given ones.
6335 theElements: container of elements to duplicate. It can be a
6336 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6337 or a list of element IDs. If *theElements* is
6338 a :class:`Mesh`, elements of highest dimension are duplicated
6339 theGroupName: a name of group to contain the generated elements.
6340 If a group with such a name already exists, the new elements
6341 are added to the existing group, else a new group is created.
6342 If *theGroupName* is empty, new elements are not added
6346 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6347 None if *theGroupName* == "".
6350 unRegister = genObjUnRegister()
6351 if isinstance( theElements, Mesh ):
6352 theElements = theElements.mesh
6353 elif isinstance( theElements, list ):
6354 theElements = self.GetIDSource( theElements, SMESH.ALL )
6355 unRegister.set( theElements )
6356 return self.editor.DoubleElements(theElements, theGroupName)
6358 def DoubleNodes(self, theNodes, theModifiedElems):
6360 Create a hole in a mesh by doubling the nodes of some particular elements
6363 theNodes: IDs of nodes to be doubled
6364 theModifiedElems: IDs of elements to be updated by the new (doubled)
6365 nodes. If list of element identifiers is empty then nodes are doubled but
6366 they not assigned to elements
6369 True if operation has been completed successfully, False otherwise
6372 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6374 def DoubleNode(self, theNodeId, theModifiedElems):
6376 Create a hole in a mesh by doubling the nodes of some particular elements.
6377 This method provided for convenience works as :meth:`DoubleNodes`.
6380 theNodeId: IDs of node to double
6381 theModifiedElems: IDs of elements to update
6384 True if operation has been completed successfully, False otherwise
6387 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6389 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6391 Create a hole in a mesh by doubling the nodes of some particular elements.
6392 This method provided for convenience works as :meth:`DoubleNodes`.
6395 theNodes: group of nodes to double.
6396 theModifiedElems: group of elements to update.
6397 theMakeGroup: forces the generation of a group containing new nodes.
6400 True or a created group if operation has been completed successfully,
6401 False or None otherwise
6405 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6406 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6408 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6410 Create a hole in a mesh by doubling the nodes of some particular elements.
6411 This method provided for convenience works as :meth:`DoubleNodes`.
6414 theNodes: list of groups of nodes to double.
6415 theModifiedElems: list of groups of elements to update.
6416 theMakeGroup: forces the generation of a group containing new nodes.
6419 True if operation has been completed successfully, False otherwise
6423 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6424 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6426 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6428 Create a hole in a mesh by doubling the nodes of some particular elements
6431 theElems: the list of elements (edges or faces) to replicate.
6432 The nodes for duplication could be found from these elements
6433 theNodesNot: list of nodes NOT to replicate
6434 theAffectedElems: the list of elements (cells and edges) to which the
6435 replicated nodes should be associated to
6438 True if operation has been completed successfully, False otherwise
6441 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6443 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6445 Create a hole in a mesh by doubling the nodes of some particular elements
6448 theElems: the list of elements (edges or faces) to replicate.
6449 The nodes for duplication could be found from these elements
6450 theNodesNot: list of nodes NOT to replicate
6451 theShape: shape to detect affected elements (element which geometric center
6452 located on or inside shape).
6453 The replicated nodes should be associated to affected elements.
6456 True if operation has been completed successfully, False otherwise
6459 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6461 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6462 theMakeGroup=False, theMakeNodeGroup=False):
6464 Create a hole in a mesh by doubling the nodes of some particular elements.
6465 This method provided for convenience works as :meth:`DoubleNodes`.
6468 theElems: group of of elements (edges or faces) to replicate.
6469 theNodesNot: group of nodes NOT to replicate.
6470 theAffectedElems: group of elements to which the replicated nodes
6471 should be associated to.
6472 theMakeGroup: forces the generation of a group containing new elements.
6473 theMakeNodeGroup: forces the generation of a group containing new nodes.
6476 True or created groups (one or two) if operation has been completed successfully,
6477 False or None otherwise
6480 if theMakeGroup or theMakeNodeGroup:
6481 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6483 theMakeGroup, theMakeNodeGroup)
6484 if theMakeGroup and theMakeNodeGroup:
6487 return twoGroups[ int(theMakeNodeGroup) ]
6488 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6490 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6492 Create a hole in a mesh by doubling the nodes of some particular elements.
6493 This method provided for convenience works as :meth:`DoubleNodes`.
6496 theElems: group of of elements (edges or faces) to replicate
6497 theNodesNot: group of nodes not to replicate
6498 theShape: shape to detect affected elements (element which geometric center
6499 located on or inside shape).
6500 The replicated nodes should be associated to affected elements
6503 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6505 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6506 theMakeGroup=False, theMakeNodeGroup=False):
6508 Create a hole in a mesh by doubling the nodes of some particular elements.
6509 This method provided for convenience works as :meth:`DoubleNodes`.
6512 theElems: list of groups of elements (edges or faces) to replicate
6513 theNodesNot: list of groups of nodes NOT to replicate
6514 theAffectedElems: group of elements to which the replicated nodes
6515 should be associated to
6516 theMakeGroup: forces generation of a group containing new elements.
6517 theMakeNodeGroup: forces generation of a group containing new nodes
6520 True or created groups (one or two) if operation has been completed successfully,
6521 False or None otherwise
6524 if theMakeGroup or theMakeNodeGroup:
6525 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6527 theMakeGroup, theMakeNodeGroup)
6528 if theMakeGroup and theMakeNodeGroup:
6531 return twoGroups[ int(theMakeNodeGroup) ]
6532 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6534 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6536 Create a hole in a mesh by doubling the nodes of some particular elements.
6537 This method provided for convenience works as :meth:`DoubleNodes`.
6540 theElems: list of groups of elements (edges or faces) to replicate
6541 theNodesNot: list of groups of nodes NOT to replicate
6542 theShape: shape to detect affected elements (element which geometric center
6543 located on or inside shape).
6544 The replicated nodes should be associated to affected elements
6547 True if operation has been completed successfully, False otherwise
6550 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6552 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6554 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6555 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6558 theElems: list of groups of nodes or elements (edges or faces) to replicate
6559 theNodesNot: list of groups of nodes NOT to replicate
6560 theShape: shape to detect affected elements (element which geometric center
6561 located on or inside shape).
6562 The replicated nodes should be associated to affected elements
6565 groups of affected elements in order: volumes, faces, edges
6568 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6570 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6573 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6574 The list of groups must describe a partition of the mesh volumes.
6575 The nodes of the internal faces at the boundaries of the groups are doubled.
6576 In option, the internal faces are replaced by flat elements.
6577 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6580 theDomains: list of groups of volumes
6581 createJointElems: if True, create the elements
6582 onAllBoundaries: if True, the nodes and elements are also created on
6583 the boundary between *theDomains* and the rest mesh
6586 True if operation has been completed successfully, False otherwise
6589 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6591 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6593 Double nodes on some external faces and create flat elements.
6594 Flat elements are mainly used by some types of mechanic calculations.
6596 Each group of the list must be constituted of faces.
6597 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6600 theGroupsOfFaces: list of groups of faces
6603 True if operation has been completed successfully, False otherwise
6606 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6608 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6610 Identify all the elements around a geom shape, get the faces delimiting the hole
6612 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6614 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6616 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6617 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6618 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6619 If there are several paths connecting a pair of points, the shortest path is
6620 selected by the module. Position of the cutting plane is defined by the two
6621 points and an optional vector lying on the plane specified by a PolySegment.
6622 By default the vector is defined by Mesh module as following. A middle point
6623 of the two given points is computed. The middle point is projected to the mesh.
6624 The vector goes from the middle point to the projection point. In case of planar
6625 mesh, the vector is normal to the mesh.
6627 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6630 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6631 groupName: optional name of a group where created mesh segments will be added.
6634 editor = self.editor
6636 editor = self.mesh.GetMeshEditPreviewer()
6637 segmentsRes = editor.MakePolyLine( segments, groupName )
6638 for i, seg in enumerate( segmentsRes ):
6639 segments[i].vector = seg.vector
6641 return editor.GetPreviewData()
6644 def GetFunctor(self, funcType ):
6646 Return a cached numerical functor by its type.
6649 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6650 Note that not all items correspond to numerical functors.
6653 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6656 fn = self.functors[ funcType._v ]
6658 fn = self.smeshpyD.GetFunctor(funcType)
6659 fn.SetMesh(self.mesh)
6660 self.functors[ funcType._v ] = fn
6663 def FunctorValue(self, funcType, elemId, isElem=True):
6665 Return value of a functor for a given element
6668 funcType: an item of :class:`SMESH.FunctorType` enum.
6669 elemId: element or node ID
6670 isElem: *elemId* is ID of element or node
6673 the functor value or zero in case of invalid arguments
6676 fn = self.GetFunctor( funcType )
6677 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6678 val = fn.GetValue(elemId)
6683 def GetLength(self, elemId=None):
6685 Get length of 1D element or sum of lengths of all 1D mesh elements
6688 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6691 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6696 length = self.smeshpyD.GetLength(self)
6698 length = self.FunctorValue(SMESH.FT_Length, elemId)
6701 def GetArea(self, elemId=None):
6703 Get area of 2D element or sum of areas of all 2D mesh elements
6704 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6707 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6712 area = self.smeshpyD.GetArea(self)
6714 area = self.FunctorValue(SMESH.FT_Area, elemId)
6717 def GetVolume(self, elemId=None):
6719 Get volume of 3D element or sum of volumes of all 3D mesh elements
6722 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6725 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6730 volume = self.smeshpyD.GetVolume(self)
6732 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6735 def GetMaxElementLength(self, elemId):
6737 Get maximum element length.
6740 elemId: mesh element ID
6743 element's maximum length value
6746 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6747 ftype = SMESH.FT_MaxElementLength3D
6749 ftype = SMESH.FT_MaxElementLength2D
6750 return self.FunctorValue(ftype, elemId)
6752 def GetAspectRatio(self, elemId):
6754 Get aspect ratio of 2D or 3D element.
6757 elemId: mesh element ID
6760 element's aspect ratio value
6763 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6764 ftype = SMESH.FT_AspectRatio3D
6766 ftype = SMESH.FT_AspectRatio
6767 return self.FunctorValue(ftype, elemId)
6769 def GetWarping(self, elemId):
6771 Get warping angle of 2D element.
6774 elemId: mesh element ID
6777 element's warping angle value
6780 return self.FunctorValue(SMESH.FT_Warping, elemId)
6782 def GetMinimumAngle(self, elemId):
6784 Get minimum angle of 2D element.
6787 elemId: mesh element ID
6790 element's minimum angle value
6793 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6795 def GetTaper(self, elemId):
6797 Get taper of 2D element.
6800 elemId: mesh element ID
6803 element's taper value
6806 return self.FunctorValue(SMESH.FT_Taper, elemId)
6808 def GetSkew(self, elemId):
6810 Get skew of 2D element.
6813 elemId: mesh element ID
6816 element's skew value
6819 return self.FunctorValue(SMESH.FT_Skew, elemId)
6821 def GetMinMax(self, funType, meshPart=None):
6823 Return minimal and maximal value of a given functor.
6826 funType (SMESH.FunctorType): a functor type.
6827 Note that not all items of :class:`SMESH.FunctorType` corresponds
6828 to numerical functors.
6829 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6835 unRegister = genObjUnRegister()
6836 if isinstance( meshPart, list ):
6837 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6838 unRegister.set( meshPart )
6839 if isinstance( meshPart, Mesh ):
6840 meshPart = meshPart.mesh
6841 fun = self.GetFunctor( funType )
6844 if hasattr( meshPart, "SetMesh" ):
6845 meshPart.SetMesh( self.mesh ) # set mesh to filter
6846 hist = fun.GetLocalHistogram( 1, False, meshPart )
6848 hist = fun.GetHistogram( 1, False )
6850 return hist[0].min, hist[0].max
6853 pass # end of Mesh class
6856 class meshProxy(SMESH._objref_SMESH_Mesh):
6858 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6859 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6861 def __init__(self,*args):
6862 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6863 def __deepcopy__(self, memo=None):
6864 new = self.__class__(self)
6866 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6867 if len( args ) == 3:
6868 args += SMESH.ALL_NODES, True
6869 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6870 def ExportToMEDX(self, *args): # function removed
6871 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6872 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6873 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6874 def ExportToMED(self, *args): # function removed
6875 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6876 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6877 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6879 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6880 def ExportPartToMED(self, *args): # 'version' parameter removed
6881 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6882 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6883 def ExportMED(self, *args): # signature of method changed
6884 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6885 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6887 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6889 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6892 class submeshProxy(SMESH._objref_SMESH_subMesh):
6895 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6897 def __init__(self,*args):
6898 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6900 def __deepcopy__(self, memo=None):
6901 new = self.__class__(self)
6904 def Compute(self,refresh=False):
6906 Compute the sub-mesh and return the status of the computation
6909 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6914 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6915 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6919 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6921 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6923 if salome.sg.hasDesktop():
6924 if refresh: salome.sg.updateObjBrowser()
6929 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6932 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6934 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6935 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6938 def __init__(self,*args):
6939 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6941 def __getattr__(self, name ): # method called if an attribute not found
6942 if not self.mesh: # look for name() method in Mesh class
6943 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6944 if hasattr( self.mesh, name ):
6945 return getattr( self.mesh, name )
6946 if name == "ExtrusionAlongPathObjX":
6947 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6948 print("meshEditor: attribute '%s' NOT FOUND" % name)
6950 def __deepcopy__(self, memo=None):
6951 new = self.__class__(self)
6953 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6954 if len( args ) == 1: args += False,
6955 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6956 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6957 if len( args ) == 2: args += False,
6958 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6959 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6960 if len( args ) == 1:
6961 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6962 NodesToKeep = args[1]
6963 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6964 unRegister = genObjUnRegister()
6966 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6967 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6968 if not isinstance( NodesToKeep, list ):
6969 NodesToKeep = [ NodesToKeep ]
6970 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6972 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6974 class Pattern(SMESH._objref_SMESH_Pattern):
6976 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6977 variables in some methods
6980 def LoadFromFile(self, patternTextOrFile ):
6981 text = patternTextOrFile
6982 if os.path.exists( text ):
6983 text = open( patternTextOrFile ).read()
6985 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6987 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6988 decrFun = lambda i: i-1
6989 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6990 theMesh.SetParameters(Parameters)
6991 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6993 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6994 decrFun = lambda i: i-1
6995 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6996 theMesh.SetParameters(Parameters)
6997 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
6999 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7000 if isinstance( mesh, Mesh ):
7001 mesh = mesh.GetMesh()
7002 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7004 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7006 Registering the new proxy for Pattern
7011 Private class used to bind methods creating algorithms to the class Mesh
7014 def __init__(self, method):
7016 self.defaultAlgoType = ""
7017 self.algoTypeToClass = {}
7018 self.method = method
7020 def add(self, algoClass):
7022 Store a python class of algorithm
7024 if inspect.isclass(algoClass) and \
7025 hasattr( algoClass, "algoType"):
7026 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7027 if not self.defaultAlgoType and \
7028 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7029 self.defaultAlgoType = algoClass.algoType
7030 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7032 def copy(self, mesh):
7034 Create a copy of self and assign mesh to the copy
7037 other = algoCreator( self.method )
7038 other.defaultAlgoType = self.defaultAlgoType
7039 other.algoTypeToClass = self.algoTypeToClass
7043 def __call__(self,algo="",geom=0,*args):
7045 Create an instance of algorithm
7049 if isinstance( algo, str ):
7051 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7052 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7057 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7059 elif not algoType and isinstance( geom, str ):
7064 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7066 elif isinstance( arg, str ) and not algoType:
7069 import traceback, sys
7070 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7071 sys.stderr.write( msg + '\n' )
7072 tb = traceback.extract_stack(None,2)
7073 traceback.print_list( [tb[0]] )
7075 algoType = self.defaultAlgoType
7076 if not algoType and self.algoTypeToClass:
7077 algoType = sorted( self.algoTypeToClass.keys() )[0]
7078 if algoType in self.algoTypeToClass:
7079 #print("Create algo",algoType)
7080 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7081 raise RuntimeError( "No class found for algo type %s" % algoType)
7084 class hypMethodWrapper:
7086 Private class used to substitute and store variable parameters of hypotheses.
7089 def __init__(self, hyp, method):
7091 self.method = method
7092 #print("REBIND:", method.__name__)
7095 def __call__(self,*args):
7097 call a method of hypothesis with calling SetVarParameter() before
7101 return self.method( self.hyp, *args ) # hypothesis method with no args
7103 #print("MethWrapper.__call__", self.method.__name__, args)
7105 parsed = ParseParameters(*args) # replace variables with their values
7106 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7107 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7108 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7109 # maybe there is a replaced string arg which is not variable
7110 result = self.method( self.hyp, *args )
7111 except ValueError as detail: # raised by ParseParameters()
7113 result = self.method( self.hyp, *args )
7114 except omniORB.CORBA.BAD_PARAM:
7115 raise ValueError(detail) # wrong variable name
7120 class genObjUnRegister:
7122 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7125 def __init__(self, genObj=None):
7126 self.genObjList = []
7130 def set(self, genObj):
7131 "Store one or a list of of SALOME.GenericObj'es"
7132 if isinstance( genObj, list ):
7133 self.genObjList.extend( genObj )
7135 self.genObjList.append( genObj )
7139 for genObj in self.genObjList:
7140 if genObj and hasattr( genObj, "UnRegister" ):
7143 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7145 Bind methods creating mesher plug-ins to the Mesh class
7148 # print("pluginName: ", pluginName)
7149 pluginBuilderName = pluginName + "Builder"
7151 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7152 except Exception as e:
7153 from salome_utils import verbose
7154 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7156 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7157 plugin = eval( pluginBuilderName )
7158 # print(" plugin:" , str(plugin))
7160 # add methods creating algorithms to Mesh
7161 for k in dir( plugin ):
7162 if k[0] == '_': continue
7163 algo = getattr( plugin, k )
7164 #print(" algo:", str(algo))
7165 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7166 #print(" meshMethod:" , str(algo.meshMethod))
7167 if not hasattr( Mesh, algo.meshMethod ):
7168 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7170 _mmethod = getattr( Mesh, algo.meshMethod )
7171 if hasattr( _mmethod, "add" ):