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:
2193 - 'v' stands for "_vertices_" field;
2194 - 'e' stands for "_edges_" field;
2195 - 'f' stands for "_faces_" field;
2196 - 's' stands for "_solids_" field.
2198 # process positional arguments
2199 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2201 auto_groups = args[1] if len(args) > 1 else False
2202 minor = args[2] if len(args) > 2 else -1
2203 overwrite = args[3] if len(args) > 3 else True
2204 meshPart = args[4] if len(args) > 4 else None
2205 autoDimension = args[5] if len(args) > 5 else True
2206 fields = args[6] if len(args) > 6 else []
2207 geomAssocFields = args[7] if len(args) > 7 else ''
2208 # process keywords arguments
2209 auto_groups = kwargs.get("auto_groups", auto_groups)
2210 minor = kwargs.get("minor", minor)
2211 overwrite = kwargs.get("overwrite", overwrite)
2212 meshPart = kwargs.get("meshPart", meshPart)
2213 autoDimension = kwargs.get("autoDimension", autoDimension)
2214 fields = kwargs.get("fields", fields)
2215 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2216 # invoke engine's function
2217 if meshPart or fields or geomAssocFields:
2218 unRegister = genObjUnRegister()
2219 if isinstance( meshPart, list ):
2220 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2221 unRegister.set( meshPart )
2222 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2223 fields, geomAssocFields)
2225 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2227 def ExportSAUV(self, f, auto_groups=0):
2229 Export the mesh in a file in SAUV format
2234 auto_groups: boolean parameter for creating/not creating
2235 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2236 the typical use is auto_groups=False.
2239 self.mesh.ExportSAUV(f, auto_groups)
2241 def ExportDAT(self, f, meshPart=None):
2243 Export the mesh in a file in DAT format
2247 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2251 unRegister = genObjUnRegister()
2252 if isinstance( meshPart, list ):
2253 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2254 unRegister.set( meshPart )
2255 self.mesh.ExportPartToDAT( meshPart, f )
2257 self.mesh.ExportDAT(f)
2259 def ExportUNV(self, f, meshPart=None):
2261 Export the mesh in a file in UNV format
2265 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2269 unRegister = genObjUnRegister()
2270 if isinstance( meshPart, list ):
2271 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2272 unRegister.set( meshPart )
2273 self.mesh.ExportPartToUNV( meshPart, f )
2275 self.mesh.ExportUNV(f)
2277 def ExportSTL(self, f, ascii=1, meshPart=None):
2279 Export the mesh in a file in STL format
2283 ascii: defines the file encoding
2284 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2288 unRegister = genObjUnRegister()
2289 if isinstance( meshPart, list ):
2290 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2291 unRegister.set( meshPart )
2292 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2294 self.mesh.ExportSTL(f, ascii)
2296 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2298 Export the mesh in a file in CGNS format
2302 overwrite: boolean parameter for overwriting/not overwriting the file
2303 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2304 groupElemsByType: if True all elements of same entity type are exported at ones,
2305 else elements are exported in order of their IDs which can cause creation
2306 of multiple cgns sections
2309 unRegister = genObjUnRegister()
2310 if isinstance( meshPart, list ):
2311 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2312 unRegister.set( meshPart )
2313 if isinstance( meshPart, Mesh ):
2314 meshPart = meshPart.mesh
2316 meshPart = self.mesh
2317 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2319 def ExportGMF(self, f, meshPart=None):
2321 Export the mesh in a file in GMF format.
2322 GMF files must have .mesh extension for the ASCII format and .meshb for
2323 the bynary format. Other extensions are not allowed.
2327 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2330 unRegister = genObjUnRegister()
2331 if isinstance( meshPart, list ):
2332 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2333 unRegister.set( meshPart )
2334 if isinstance( meshPart, Mesh ):
2335 meshPart = meshPart.mesh
2337 meshPart = self.mesh
2338 self.mesh.ExportGMF(meshPart, f, True)
2340 def ExportToMED(self, *args, **kwargs):
2342 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2343 Export the mesh in a file in MED format
2344 allowing to overwrite the file if it exists or add the exported data to its contents
2347 fileName: the file name
2348 opt (boolean): parameter for creating/not creating
2349 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2350 overwrite: boolean parameter for overwriting/not overwriting the file
2351 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2353 - 1D if all mesh nodes lie on OX coordinate axis, or
2354 - 2D if all mesh nodes lie on XOY coordinate plane, or
2355 - 3D in the rest cases.
2357 If **autoDimension** is *False*, the space dimension is always 3.
2360 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2361 # process positional arguments
2362 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2364 auto_groups = args[1] if len(args) > 1 else False
2365 overwrite = args[2] if len(args) > 2 else True
2366 autoDimension = args[3] if len(args) > 3 else True
2367 # process keywords arguments
2368 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2369 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2370 overwrite = kwargs.get("overwrite", overwrite)
2371 autoDimension = kwargs.get("autoDimension", autoDimension)
2373 # invoke engine's function
2374 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2376 def ExportToMEDX(self, *args, **kwargs):
2378 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2379 Export the mesh in a file in MED format
2382 fileName: the file name
2383 opt (boolean): parameter for creating/not creating
2384 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2385 overwrite: boolean parameter for overwriting/not overwriting the file
2386 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2388 - 1D if all mesh nodes lie on OX coordinate axis, or
2389 - 2D if all mesh nodes lie on XOY coordinate plane, or
2390 - 3D in the rest cases.
2392 If **autoDimension** is *False*, the space dimension is always 3.
2395 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2396 # process positional arguments
2397 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2399 auto_groups = args[1] if len(args) > 1 else False
2400 overwrite = args[2] if len(args) > 2 else True
2401 autoDimension = args[3] if len(args) > 3 else True
2402 # process keywords arguments
2403 auto_groups = kwargs.get("auto_groups", auto_groups)
2404 overwrite = kwargs.get("overwrite", overwrite)
2405 autoDimension = kwargs.get("autoDimension", autoDimension)
2407 # invoke engine's function
2408 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2410 # Operations with groups:
2411 # ----------------------
2412 def CreateEmptyGroup(self, elementType, name):
2414 Create an empty standalone mesh group
2417 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2418 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2419 name: the name of the mesh group
2422 :class:`SMESH.SMESH_Group`
2425 return self.mesh.CreateGroup(elementType, name)
2427 def Group(self, grp, name=""):
2429 Create a mesh group based on the geometric object *grp*
2430 and give it a *name*.
2431 If *name* is not defined the name of the geometric group is used
2434 Works like :meth:`GroupOnGeom`.
2437 grp: a geometric group, a vertex, an edge, a face or a solid
2438 name: the name of the mesh group
2441 :class:`SMESH.SMESH_GroupOnGeom`
2444 return self.GroupOnGeom(grp, name)
2446 def GroupOnGeom(self, grp, name="", typ=None):
2448 Create a mesh group based on the geometrical object *grp*
2449 and give it a *name*.
2450 if *name* is not defined the name of the geometric group is used
2453 grp: a geometrical group, a vertex, an edge, a face or a solid
2454 name: the name of the mesh group
2455 typ: the type of elements in the group; either of
2456 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2457 automatically detected by the type of the geometry
2460 :class:`SMESH.SMESH_GroupOnGeom`
2463 AssureGeomPublished( self, grp, name )
2465 name = grp.GetName()
2467 typ = self._groupTypeFromShape( grp )
2468 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2470 def _groupTypeFromShape( self, shape ):
2472 Pivate method to get a type of group on geometry
2474 tgeo = str(shape.GetShapeType())
2475 if tgeo == "VERTEX":
2477 elif tgeo == "EDGE":
2479 elif tgeo == "FACE" or tgeo == "SHELL":
2481 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2483 elif tgeo == "COMPOUND":
2484 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2486 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2487 return self._groupTypeFromShape( sub[0] )
2489 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2492 def GroupOnFilter(self, typ, name, filter):
2494 Create a mesh group with given *name* based on the *filter*.
2495 It is a special type of group dynamically updating it's contents during
2499 typ: the type of elements in the group; either of
2500 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2501 name: the name of the mesh group
2502 filter (SMESH.Filter): the filter defining group contents
2505 :class:`SMESH.SMESH_GroupOnFilter`
2508 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2510 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2512 Create a mesh group by the given ids of elements
2515 groupName: the name of the mesh group
2516 elementType: the type of elements in the group; either of
2517 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2518 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2521 :class:`SMESH.SMESH_Group`
2524 group = self.mesh.CreateGroup(elementType, groupName)
2525 if isinstance( elemIDs, Mesh ):
2526 elemIDs = elemIDs.GetMesh()
2527 if hasattr( elemIDs, "GetIDs" ):
2528 if hasattr( elemIDs, "SetMesh" ):
2529 elemIDs.SetMesh( self.GetMesh() )
2530 group.AddFrom( elemIDs )
2538 CritType=FT_Undefined,
2541 UnaryOp=FT_Undefined,
2544 Create a mesh group by the given conditions
2547 groupName: the name of the mesh group
2548 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2549 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2550 Note that the items starting from FT_LessThan are not suitable for CritType.
2551 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2552 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2553 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2554 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2555 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2558 :class:`SMESH.SMESH_GroupOnFilter`
2561 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2562 group = self.MakeGroupByCriterion(groupName, aCriterion)
2565 def MakeGroupByCriterion(self, groupName, Criterion):
2567 Create a mesh group by the given criterion
2570 groupName: the name of the mesh group
2571 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2574 :class:`SMESH.SMESH_GroupOnFilter`
2577 :meth:`smeshBuilder.GetCriterion`
2580 return self.MakeGroupByCriteria( groupName, [Criterion] )
2582 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2584 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2587 groupName: the name of the mesh group
2588 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2589 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2592 :class:`SMESH.SMESH_GroupOnFilter`
2595 :meth:`smeshBuilder.GetCriterion`
2598 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2599 group = self.MakeGroupByFilter(groupName, aFilter)
2602 def MakeGroupByFilter(self, groupName, theFilter):
2604 Create a mesh group by the given filter
2607 groupName (string): the name of the mesh group
2608 theFilter (SMESH.Filter): the filter
2611 :class:`SMESH.SMESH_GroupOnFilter`
2614 :meth:`smeshBuilder.GetFilter`
2617 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2618 #theFilter.SetMesh( self.mesh )
2619 #group.AddFrom( theFilter )
2620 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2623 def RemoveGroup(self, group):
2628 group (SMESH.SMESH_GroupBase): group to remove
2631 self.mesh.RemoveGroup(group)
2633 def RemoveGroupWithContents(self, group):
2635 Remove a group with its contents
2638 group (SMESH.SMESH_GroupBase): group to remove
2641 self.mesh.RemoveGroupWithContents(group)
2643 def GetGroups(self, elemType = SMESH.ALL):
2645 Get the list of groups existing in the mesh in the order of creation
2646 (starting from the oldest one)
2649 elemType (SMESH.ElementType): type of elements the groups contain;
2650 by default groups of elements of all types are returned
2653 a list of :class:`SMESH.SMESH_GroupBase`
2656 groups = self.mesh.GetGroups()
2657 if elemType == SMESH.ALL:
2661 if g.GetType() == elemType:
2662 typedGroups.append( g )
2669 Get the number of groups existing in the mesh
2672 the quantity of groups as an integer value
2675 return self.mesh.NbGroups()
2677 def GetGroupNames(self):
2679 Get the list of names of groups existing in the mesh
2685 groups = self.GetGroups()
2687 for group in groups:
2688 names.append(group.GetName())
2691 def GetGroupByName(self, name, elemType = None):
2693 Find groups by name and type
2696 name (string): name of the group of interest
2697 elemType (SMESH.ElementType): type of elements the groups contain;
2698 by default one group of any type is returned;
2699 if elemType == SMESH.ALL then all groups of any type are returned
2702 a list of :class:`SMESH.SMESH_GroupBase`
2706 for group in self.GetGroups():
2707 if group.GetName() == name:
2708 if elemType is None:
2710 if ( elemType == SMESH.ALL or
2711 group.GetType() == elemType ):
2712 groups.append( group )
2715 def UnionGroups(self, group1, group2, name):
2717 Produce a union of two groups.
2718 A new group is created. All mesh elements that are
2719 present in the initial groups are added to the new one
2722 group1 (SMESH.SMESH_GroupBase): a group
2723 group2 (SMESH.SMESH_GroupBase): another group
2726 instance of :class:`SMESH.SMESH_Group`
2729 return self.mesh.UnionGroups(group1, group2, name)
2731 def UnionListOfGroups(self, groups, name):
2733 Produce a union list of groups.
2734 New group is created. All mesh elements that are present in
2735 initial groups are added to the new one
2738 groups: list of :class:`SMESH.SMESH_GroupBase`
2741 instance of :class:`SMESH.SMESH_Group`
2743 return self.mesh.UnionListOfGroups(groups, name)
2745 def IntersectGroups(self, group1, group2, name):
2747 Prodice an intersection of two groups.
2748 A new group is created. All mesh elements that are common
2749 for the two initial groups are added to the new one.
2752 group1 (SMESH.SMESH_GroupBase): a group
2753 group2 (SMESH.SMESH_GroupBase): another group
2756 instance of :class:`SMESH.SMESH_Group`
2759 return self.mesh.IntersectGroups(group1, group2, name)
2761 def IntersectListOfGroups(self, groups, name):
2763 Produce an intersection of groups.
2764 New group is created. All mesh elements that are present in all
2765 initial groups simultaneously are added to the new one
2768 groups: a list of :class:`SMESH.SMESH_GroupBase`
2771 instance of :class:`SMESH.SMESH_Group`
2773 return self.mesh.IntersectListOfGroups(groups, name)
2775 def CutGroups(self, main_group, tool_group, name):
2777 Produce a cut of two groups.
2778 A new group is created. All mesh elements that are present in
2779 the main group but are not present in the tool group are added to the new one
2782 main_group (SMESH.SMESH_GroupBase): a group to cut from
2783 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2786 an instance of :class:`SMESH.SMESH_Group`
2789 return self.mesh.CutGroups(main_group, tool_group, name)
2791 def CutListOfGroups(self, main_groups, tool_groups, name):
2793 Produce a cut of groups.
2794 A new group is created. All mesh elements that are present in main groups
2795 but do not present in tool groups are added to the new one
2798 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2799 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2802 an instance of :class:`SMESH.SMESH_Group`
2805 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2807 def CreateDimGroup(self, groups, elemType, name,
2808 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2810 Create a standalone group of entities basing on nodes of other groups.
2813 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2814 elemType: a type of elements to include to the new group; either of
2815 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2816 name: a name of the new group.
2817 nbCommonNodes: a criterion of inclusion of an element to the new group
2818 basing on number of element nodes common with reference *groups*.
2819 Meaning of possible values are:
2821 - SMESH.ALL_NODES - include if all nodes are common,
2822 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2823 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2824 - SMEHS.MAJORITY - include if half of nodes or more are common.
2825 underlyingOnly: if *True* (default), an element is included to the
2826 new group provided that it is based on nodes of an element of *groups*;
2827 in this case the reference *groups* are supposed to be of higher dimension
2828 than *elemType*, which can be useful for example to get all faces lying on
2829 volumes of the reference *groups*.
2832 an instance of :class:`SMESH.SMESH_Group`
2835 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2837 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2840 def ConvertToStandalone(self, group):
2842 Convert group on geom into standalone group
2845 return self.mesh.ConvertToStandalone(group)
2847 # Get some info about mesh:
2848 # ------------------------
2850 def GetLog(self, clearAfterGet):
2852 Return the log of nodes and elements added or removed
2853 since the previous clear of the log.
2856 clearAfterGet: log is emptied after Get (safe if concurrents access)
2859 list of SMESH.log_block structures { commandType, number, coords, indexes }
2862 return self.mesh.GetLog(clearAfterGet)
2866 Clear the log of nodes and elements added or removed since the previous
2867 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2870 self.mesh.ClearLog()
2872 def SetAutoColor(self, theAutoColor):
2874 Toggle auto color mode on the object.
2875 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2878 theAutoColor (boolean): the flag which toggles auto color mode.
2881 self.mesh.SetAutoColor(theAutoColor)
2883 def GetAutoColor(self):
2885 Get flag of object auto color mode.
2891 return self.mesh.GetAutoColor()
2898 integer value, which is the internal Id of the mesh
2901 return self.mesh.GetId()
2903 def HasDuplicatedGroupNamesMED(self):
2905 Check the group names for duplications.
2906 Consider the maximum group name length stored in MED file.
2912 return self.mesh.HasDuplicatedGroupNamesMED()
2914 def GetMeshEditor(self):
2916 Obtain the mesh editor tool
2919 an instance of :class:`SMESH.SMESH_MeshEditor`
2924 def GetIDSource(self, ids, elemType = SMESH.ALL):
2926 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2927 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2931 elemType: type of elements; this parameter is used to distinguish
2932 IDs of nodes from IDs of elements; by default ids are treated as
2933 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2936 an instance of :class:`SMESH.SMESH_IDSource`
2939 call UnRegister() for the returned object as soon as it is no more useful::
2941 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2942 mesh.DoSomething( idSrc )
2946 if isinstance( ids, int ):
2948 return self.editor.MakeIDSource(ids, elemType)
2951 # Get information about mesh contents:
2952 # ------------------------------------
2954 def GetMeshInfo(self, obj = None):
2956 Get the mesh statistic.
2957 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2958 an item of :class:`SMESH.EntityType`.
2961 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2964 if not obj: obj = self.mesh
2965 return self.smeshpyD.GetMeshInfo(obj)
2969 Return the number of nodes in the mesh
2975 return self.mesh.NbNodes()
2977 def NbElements(self):
2979 Return the number of elements in the mesh
2985 return self.mesh.NbElements()
2987 def Nb0DElements(self):
2989 Return the number of 0d elements in the mesh
2995 return self.mesh.Nb0DElements()
2999 Return the number of ball discrete elements in the mesh
3005 return self.mesh.NbBalls()
3009 Return the number of edges in the mesh
3015 return self.mesh.NbEdges()
3017 def NbEdgesOfOrder(self, elementOrder):
3019 Return the number of edges with the given order in the mesh
3022 elementOrder: the order of elements
3023 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3029 return self.mesh.NbEdgesOfOrder(elementOrder)
3033 Return the number of faces in the mesh
3039 return self.mesh.NbFaces()
3041 def NbFacesOfOrder(self, elementOrder):
3043 Return the number of faces with the given order in the mesh
3046 elementOrder: the order of elements
3047 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3053 return self.mesh.NbFacesOfOrder(elementOrder)
3055 def NbTriangles(self):
3057 Return the number of triangles in the mesh
3063 return self.mesh.NbTriangles()
3065 def NbTrianglesOfOrder(self, elementOrder):
3067 Return the number of triangles with the given order in the mesh
3070 elementOrder: is the order of elements
3071 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3077 return self.mesh.NbTrianglesOfOrder(elementOrder)
3079 def NbBiQuadTriangles(self):
3081 Return the number of biquadratic triangles in the mesh
3087 return self.mesh.NbBiQuadTriangles()
3089 def NbQuadrangles(self):
3091 Return the number of quadrangles in the mesh
3097 return self.mesh.NbQuadrangles()
3099 def NbQuadranglesOfOrder(self, elementOrder):
3101 Return the number of quadrangles with the given order in the mesh
3104 elementOrder: the order of elements
3105 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3111 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3113 def NbBiQuadQuadrangles(self):
3115 Return the number of biquadratic quadrangles in the mesh
3121 return self.mesh.NbBiQuadQuadrangles()
3123 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3125 Return the number of polygons of given order in the mesh
3128 elementOrder: the order of elements
3129 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3135 return self.mesh.NbPolygonsOfOrder(elementOrder)
3137 def NbVolumes(self):
3139 Return the number of volumes in the mesh
3145 return self.mesh.NbVolumes()
3148 def NbVolumesOfOrder(self, elementOrder):
3150 Return the number of volumes with the given order in the mesh
3153 elementOrder: the order of elements
3154 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3160 return self.mesh.NbVolumesOfOrder(elementOrder)
3164 Return the number of tetrahedrons in the mesh
3170 return self.mesh.NbTetras()
3172 def NbTetrasOfOrder(self, elementOrder):
3174 Return the number of tetrahedrons with the given order in the mesh
3177 elementOrder: the order of elements
3178 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3184 return self.mesh.NbTetrasOfOrder(elementOrder)
3188 Return the number of hexahedrons in the mesh
3194 return self.mesh.NbHexas()
3196 def NbHexasOfOrder(self, elementOrder):
3198 Return the number of hexahedrons with the given order in the mesh
3201 elementOrder: the order of elements
3202 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3208 return self.mesh.NbHexasOfOrder(elementOrder)
3210 def NbTriQuadraticHexas(self):
3212 Return the number of triquadratic hexahedrons in the mesh
3218 return self.mesh.NbTriQuadraticHexas()
3220 def NbPyramids(self):
3222 Return the number of pyramids in the mesh
3228 return self.mesh.NbPyramids()
3230 def NbPyramidsOfOrder(self, elementOrder):
3232 Return the number of pyramids with the given order in the mesh
3235 elementOrder: the order of elements
3236 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3242 return self.mesh.NbPyramidsOfOrder(elementOrder)
3246 Return the number of prisms in the mesh
3252 return self.mesh.NbPrisms()
3254 def NbPrismsOfOrder(self, elementOrder):
3256 Return the number of prisms with the given order in the mesh
3259 elementOrder: the order of elements
3260 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3266 return self.mesh.NbPrismsOfOrder(elementOrder)
3268 def NbHexagonalPrisms(self):
3270 Return the number of hexagonal prisms in the mesh
3276 return self.mesh.NbHexagonalPrisms()
3278 def NbPolyhedrons(self):
3280 Return the number of polyhedrons in the mesh
3286 return self.mesh.NbPolyhedrons()
3288 def NbSubMesh(self):
3290 Return the number of submeshes in the mesh
3296 return self.mesh.NbSubMesh()
3298 def GetElementsId(self):
3300 Return the list of all mesh elements IDs
3303 the list of integer values
3306 :meth:`GetElementsByType`
3309 return self.mesh.GetElementsId()
3311 def GetElementsByType(self, elementType):
3313 Return the list of IDs of mesh elements with the given type
3316 elementType (SMESH.ElementType): the required type of elements
3319 list of integer values
3322 return self.mesh.GetElementsByType(elementType)
3324 def GetNodesId(self):
3326 Return the list of mesh nodes IDs
3329 the list of integer values
3332 return self.mesh.GetNodesId()
3334 # Get the information about mesh elements:
3335 # ------------------------------------
3337 def GetElementType(self, id, iselem=True):
3339 Return the type of mesh element or node
3342 the value from :class:`SMESH.ElementType` enumeration.
3343 Return SMESH.ALL if element or node with the given ID does not exist
3346 return self.mesh.GetElementType(id, iselem)
3348 def GetElementGeomType(self, id):
3350 Return the geometric type of mesh element
3353 the value from :class:`SMESH.EntityType` enumeration.
3356 return self.mesh.GetElementGeomType(id)
3358 def GetElementShape(self, id):
3360 Return the shape type of mesh element
3363 the value from :class:`SMESH.GeometryType` enumeration.
3366 return self.mesh.GetElementShape(id)
3368 def GetSubMeshElementsId(self, Shape):
3370 Return the list of sub-mesh elements IDs
3373 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3374 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3377 list of integer values
3380 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3381 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3384 return self.mesh.GetSubMeshElementsId(ShapeID)
3386 def GetSubMeshNodesId(self, Shape, all):
3388 Return the list of sub-mesh nodes IDs
3391 Shape: a geom object (sub-shape).
3392 *Shape* must be the sub-shape of a :meth:`GetShape`
3393 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3396 list of integer values
3399 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3400 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3403 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3405 def GetSubMeshElementType(self, Shape):
3407 Return type of elements on given shape
3410 Shape: a geom object (sub-shape).
3411 *Shape* must be a sub-shape of a ShapeToMesh()
3414 :class:`SMESH.ElementType`
3417 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3418 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3421 return self.mesh.GetSubMeshElementType(ShapeID)
3425 Get the mesh description
3431 return self.mesh.Dump()
3434 # Get the information about nodes and elements of a mesh by its IDs:
3435 # -----------------------------------------------------------
3437 def GetNodeXYZ(self, id):
3439 Get XYZ coordinates of a node.
3440 If there is no node for the given ID - return an empty list
3443 list of float values
3446 return self.mesh.GetNodeXYZ(id)
3448 def GetNodeInverseElements(self, id):
3450 Return list of IDs of inverse elements for the given node.
3451 If there is no node for the given ID - return an empty list
3454 list of integer values
3457 return self.mesh.GetNodeInverseElements(id)
3459 def GetNodePosition(self,NodeID):
3461 Return the position of a node on the shape
3464 :class:`SMESH.NodePosition`
3467 return self.mesh.GetNodePosition(NodeID)
3469 def GetElementPosition(self,ElemID):
3471 Return the position of an element on the shape
3474 :class:`SMESH.ElementPosition`
3477 return self.mesh.GetElementPosition(ElemID)
3479 def GetShapeID(self, id):
3481 Return the ID of the shape, on which the given node was generated.
3484 an integer value > 0 or -1 if there is no node for the given
3485 ID or the node is not assigned to any geometry
3488 return self.mesh.GetShapeID(id)
3490 def GetShapeIDForElem(self,id):
3492 Return the ID of the shape, on which the given element was generated.
3495 an integer value > 0 or -1 if there is no element for the given
3496 ID or the element is not assigned to any geometry
3499 return self.mesh.GetShapeIDForElem(id)
3501 def GetElemNbNodes(self, id):
3503 Return the number of nodes of the given element
3506 an integer value > 0 or -1 if there is no element for the given ID
3509 return self.mesh.GetElemNbNodes(id)
3511 def GetElemNode(self, id, index):
3513 Return the node ID the given (zero based) index for the given element.
3515 * If there is no element for the given ID - return -1.
3516 * If there is no node for the given index - return -2.
3519 id (int): element ID
3520 index (int): node index within the element
3523 an integer value (ID)
3526 :meth:`GetElemNodes`
3529 return self.mesh.GetElemNode(id, index)
3531 def GetElemNodes(self, id):
3533 Return the IDs of nodes of the given element
3536 a list of integer values
3539 return self.mesh.GetElemNodes(id)
3541 def IsMediumNode(self, elementID, nodeID):
3543 Return true if the given node is the medium node in the given quadratic element
3546 return self.mesh.IsMediumNode(elementID, nodeID)
3548 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3550 Return true if the given node is the medium node in one of quadratic elements
3553 nodeID: ID of the node
3554 elementType: the type of elements to check a state of the node, either of
3555 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3558 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3560 def ElemNbEdges(self, id):
3562 Return the number of edges for the given element
3565 return self.mesh.ElemNbEdges(id)
3567 def ElemNbFaces(self, id):
3569 Return the number of faces for the given element
3572 return self.mesh.ElemNbFaces(id)
3574 def GetElemFaceNodes(self,elemId, faceIndex):
3576 Return nodes of given face (counted from zero) for given volumic element.
3579 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3581 def GetFaceNormal(self, faceId, normalized=False):
3583 Return three components of normal of given mesh face
3584 (or an empty array in KO case)
3587 return self.mesh.GetFaceNormal(faceId,normalized)
3589 def FindElementByNodes(self, nodes):
3591 Return an element based on all given nodes.
3594 return self.mesh.FindElementByNodes(nodes)
3596 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3598 Return elements including all given nodes.
3601 return self.mesh.GetElementsByNodes( nodes, elemType )
3603 def IsPoly(self, id):
3605 Return true if the given element is a polygon
3608 return self.mesh.IsPoly(id)
3610 def IsQuadratic(self, id):
3612 Return true if the given element is quadratic
3615 return self.mesh.IsQuadratic(id)
3617 def GetBallDiameter(self, id):
3619 Return diameter of a ball discrete element or zero in case of an invalid *id*
3622 return self.mesh.GetBallDiameter(id)
3624 def BaryCenter(self, id):
3626 Return XYZ coordinates of the barycenter of the given element.
3627 If there is no element for the given ID - return an empty list
3630 a list of three double values
3633 return self.mesh.BaryCenter(id)
3635 def GetIdsFromFilter(self, theFilter):
3637 Pass mesh elements through the given filter and return IDs of fitting elements
3640 theFilter: :class:`SMESH.Filter`
3646 :meth:`SMESH.Filter.GetIDs`
3649 theFilter.SetMesh( self.mesh )
3650 return theFilter.GetIDs()
3652 # Get mesh measurements information:
3653 # ------------------------------------
3655 def GetFreeBorders(self):
3657 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3658 Return a list of special structures (borders).
3661 a list of :class:`SMESH.FreeEdges.Border`
3664 aFilterMgr = self.smeshpyD.CreateFilterManager()
3665 aPredicate = aFilterMgr.CreateFreeEdges()
3666 aPredicate.SetMesh(self.mesh)
3667 aBorders = aPredicate.GetBorders()
3668 aFilterMgr.UnRegister()
3671 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3673 Get minimum distance between two nodes, elements or distance to the origin
3676 id1: first node/element id
3677 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3678 isElem1: *True* if *id1* is element id, *False* if it is node id
3679 isElem2: *True* if *id2* is element id, *False* if it is node id
3682 minimum distance value **GetMinDistance()**
3685 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3686 return aMeasure.value
3688 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3690 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3693 id1: first node/element id
3694 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3695 isElem1: *True* if *id1* is element id, *False* if it is node id
3696 isElem2: *True* if *id2* is element id, *False* if it is node id
3699 :class:`SMESH.Measure` structure
3705 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3707 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3710 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3712 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3717 aMeasurements = self.smeshpyD.CreateMeasurements()
3718 aMeasure = aMeasurements.MinDistance(id1, id2)
3719 genObjUnRegister([aMeasurements,id1, id2])
3722 def BoundingBox(self, objects=None, isElem=False):
3724 Get bounding box of the specified object(s)
3727 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3728 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3729 *False* specifies that *objects* are nodes
3732 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3735 :meth:`GetBoundingBox()`
3738 result = self.GetBoundingBox(objects, isElem)
3742 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3745 def GetBoundingBox(self, objects=None, isElem=False):
3747 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3750 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3751 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3752 False means that *objects* are nodes
3755 :class:`SMESH.Measure` structure
3758 :meth:`BoundingBox()`
3762 objects = [self.mesh]
3763 elif isinstance(objects, tuple):
3764 objects = list(objects)
3765 if not isinstance(objects, list):
3767 if len(objects) > 0 and isinstance(objects[0], int):
3770 unRegister = genObjUnRegister()
3772 if isinstance(o, Mesh):
3773 srclist.append(o.mesh)
3774 elif hasattr(o, "_narrow"):
3775 src = o._narrow(SMESH.SMESH_IDSource)
3776 if src: srclist.append(src)
3778 elif isinstance(o, list):
3780 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3782 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3783 unRegister.set( srclist[-1] )
3786 aMeasurements = self.smeshpyD.CreateMeasurements()
3787 unRegister.set( aMeasurements )
3788 aMeasure = aMeasurements.BoundingBox(srclist)
3791 # Mesh edition (SMESH_MeshEditor functionality):
3792 # ---------------------------------------------
3794 def RemoveElements(self, IDsOfElements):
3796 Remove the elements from the mesh by ids
3799 IDsOfElements: is a list of ids of elements to remove
3805 return self.editor.RemoveElements(IDsOfElements)
3807 def RemoveNodes(self, IDsOfNodes):
3809 Remove nodes from mesh by ids
3812 IDsOfNodes: is a list of ids of nodes to remove
3818 return self.editor.RemoveNodes(IDsOfNodes)
3820 def RemoveOrphanNodes(self):
3822 Remove all orphan (free) nodes from mesh
3825 number of the removed nodes
3828 return self.editor.RemoveOrphanNodes()
3830 def AddNode(self, x, y, z):
3832 Add a node to the mesh by coordinates
3838 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3839 if hasVars: self.mesh.SetParameters(Parameters)
3840 return self.editor.AddNode( x, y, z)
3842 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3844 Create a 0D element on a node with given number.
3847 IDOfNode: the ID of node for creation of the element.
3848 DuplicateElements: to add one more 0D element to a node or not
3851 ID of the new 0D element
3854 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3856 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3858 Create 0D elements on all nodes of the given elements except those
3859 nodes on which a 0D element already exists.
3862 theObject: an object on whose nodes 0D elements will be created.
3863 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3864 theGroupName: optional name of a group to add 0D elements created
3865 and/or found on nodes of *theObject*.
3866 DuplicateElements: to add one more 0D element to a node or not
3869 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3870 IDs of new and/or found 0D elements. IDs of 0D elements
3871 can be retrieved from the returned object by
3872 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3875 unRegister = genObjUnRegister()
3876 if isinstance( theObject, Mesh ):
3877 theObject = theObject.GetMesh()
3878 elif isinstance( theObject, list ):
3879 theObject = self.GetIDSource( theObject, SMESH.ALL )
3880 unRegister.set( theObject )
3881 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3883 def AddBall(self, IDOfNode, diameter):
3885 Create a ball element on a node with given ID.
3888 IDOfNode: the ID of node for creation of the element.
3889 diameter: the bal diameter.
3892 ID of the new ball element
3895 return self.editor.AddBall( IDOfNode, diameter )
3897 def AddEdge(self, IDsOfNodes):
3899 Create a linear or quadratic edge (this is determined
3900 by the number of given nodes).
3903 IDsOfNodes: list of node IDs for creation of the element.
3904 The order of nodes in this list should correspond to
3905 the :ref:`connectivity convention <connectivity_page>`.
3911 return self.editor.AddEdge(IDsOfNodes)
3913 def AddFace(self, IDsOfNodes):
3915 Create a linear or quadratic face (this is determined
3916 by the number of given nodes).
3919 IDsOfNodes: list of node IDs for creation of the element.
3920 The order of nodes in this list should correspond to
3921 the :ref:`connectivity convention <connectivity_page>`.
3927 return self.editor.AddFace(IDsOfNodes)
3929 def AddPolygonalFace(self, IdsOfNodes):
3931 Add a polygonal face defined by a list of node IDs
3934 IdsOfNodes: the list of node IDs for creation of the element.
3940 return self.editor.AddPolygonalFace(IdsOfNodes)
3942 def AddQuadPolygonalFace(self, IdsOfNodes):
3944 Add a quadratic polygonal face defined by a list of node IDs
3947 IdsOfNodes: the list of node IDs for creation of the element;
3948 corner nodes follow first.
3954 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3956 def AddVolume(self, IDsOfNodes):
3958 Create both simple and quadratic volume (this is determined
3959 by the number of given nodes).
3962 IDsOfNodes: list of node IDs for creation of the element.
3963 The order of nodes in this list should correspond to
3964 the :ref:`connectivity convention <connectivity_page>`.
3967 ID of the new volumic element
3970 return self.editor.AddVolume(IDsOfNodes)
3972 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3974 Create a volume of many faces, giving nodes for each face.
3977 IdsOfNodes: list of node IDs for volume creation, face by face.
3978 Quantities: list of integer values, Quantities[i]
3979 gives the quantity of nodes in face number i.
3982 ID of the new volumic element
3985 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3987 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3989 Create a volume of many faces, giving the IDs of the existing faces.
3992 The created volume will refer only to the nodes
3993 of the given faces, not to the faces themselves.
3996 IdsOfFaces: the list of face IDs for volume creation.
3999 ID of the new volumic element
4002 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4005 def SetNodeOnVertex(self, NodeID, Vertex):
4007 Bind a node to a vertex
4011 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4014 True if succeed else raises an exception
4017 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4018 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4022 self.editor.SetNodeOnVertex(NodeID, VertexID)
4023 except SALOME.SALOME_Exception as inst:
4024 raise ValueError(inst.details.text)
4028 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4030 Store the node position on an edge
4034 Edge: an edge (GEOM.GEOM_Object) or edge ID
4035 paramOnEdge: a parameter on the edge where the node is located
4038 True if succeed else raises an exception
4041 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4042 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4046 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4047 except SALOME.SALOME_Exception as inst:
4048 raise ValueError(inst.details.text)
4051 def SetNodeOnFace(self, NodeID, Face, u, v):
4053 Store node position on a face
4057 Face: a face (GEOM.GEOM_Object) or face ID
4058 u: U parameter on the face where the node is located
4059 v: V parameter on the face where the node is located
4062 True if succeed else raises an exception
4065 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4066 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4070 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4071 except SALOME.SALOME_Exception as inst:
4072 raise ValueError(inst.details.text)
4075 def SetNodeInVolume(self, NodeID, Solid):
4077 Bind a node to a solid
4081 Solid: a solid (GEOM.GEOM_Object) or solid ID
4084 True if succeed else raises an exception
4087 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4088 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4092 self.editor.SetNodeInVolume(NodeID, SolidID)
4093 except SALOME.SALOME_Exception as inst:
4094 raise ValueError(inst.details.text)
4097 def SetMeshElementOnShape(self, ElementID, Shape):
4099 Bind an element to a shape
4102 ElementID: an element ID
4103 Shape: a shape (GEOM.GEOM_Object) or shape ID
4106 True if succeed else raises an exception
4109 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4110 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4114 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4115 except SALOME.SALOME_Exception as inst:
4116 raise ValueError(inst.details.text)
4120 def MoveNode(self, NodeID, x, y, z):
4122 Move the node with the given id
4125 NodeID: the id of the node
4126 x: a new X coordinate
4127 y: a new Y coordinate
4128 z: a new Z coordinate
4131 True if succeed else False
4134 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4135 if hasVars: self.mesh.SetParameters(Parameters)
4136 return self.editor.MoveNode(NodeID, x, y, z)
4138 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4140 Find the node closest to a point and moves it to a point location
4143 x: the X coordinate of a point
4144 y: the Y coordinate of a point
4145 z: the Z coordinate of a point
4146 NodeID: if specified (>0), the node with this ID is moved,
4147 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4150 the ID of a moved node
4153 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4154 if hasVars: self.mesh.SetParameters(Parameters)
4155 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4157 def FindNodeClosestTo(self, x, y, z):
4159 Find the node closest to a point
4162 x: the X coordinate of a point
4163 y: the Y coordinate of a point
4164 z: the Z coordinate of a point
4170 #preview = self.mesh.GetMeshEditPreviewer()
4171 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4172 return self.editor.FindNodeClosestTo(x, y, z)
4174 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4176 Find the elements where a point lays IN or ON
4179 x,y,z (float): coordinates of the point
4180 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4181 means elements of any type excluding nodes, discrete and 0D elements.
4182 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4185 list of IDs of found elements
4188 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4190 return self.editor.FindElementsByPoint(x, y, z, elementType)
4192 def GetPointState(self, x, y, z):
4194 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4195 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4196 UNKNOWN state means that either mesh is wrong or the analysis fails.
4199 return self.editor.GetPointState(x, y, z)
4201 def IsManifold(self):
4203 Check if a 2D mesh is manifold
4206 return self.editor.IsManifold()
4208 def IsCoherentOrientation2D(self):
4210 Check if orientation of 2D elements is coherent
4213 return self.editor.IsCoherentOrientation2D()
4215 def MeshToPassThroughAPoint(self, x, y, z):
4217 Find the node closest to a point and moves it to a point location
4220 x: the X coordinate of a point
4221 y: the Y coordinate of a point
4222 z: the Z coordinate of a point
4225 the ID of a moved node
4228 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4230 def InverseDiag(self, NodeID1, NodeID2):
4232 Replace two neighbour triangles sharing Node1-Node2 link
4233 with the triangles built on the same 4 nodes but having other common link.
4236 NodeID1: the ID of the first node
4237 NodeID2: the ID of the second node
4240 False if proper faces were not found
4242 return self.editor.InverseDiag(NodeID1, NodeID2)
4244 def DeleteDiag(self, NodeID1, NodeID2):
4246 Replace two neighbour triangles sharing *Node1-Node2* link
4247 with a quadrangle built on the same 4 nodes.
4250 NodeID1: ID of the first node
4251 NodeID2: ID of the second node
4254 False if proper faces were not found
4257 return self.editor.DeleteDiag(NodeID1, NodeID2)
4259 def Reorient(self, IDsOfElements=None):
4261 Reorient elements by ids
4264 IDsOfElements: if undefined reorients all mesh elements
4267 True if succeed else False
4270 if IDsOfElements == None:
4271 IDsOfElements = self.GetElementsId()
4272 return self.editor.Reorient(IDsOfElements)
4274 def ReorientObject(self, theObject):
4276 Reorient all elements of the object
4279 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4282 True if succeed else False
4285 if ( isinstance( theObject, Mesh )):
4286 theObject = theObject.GetMesh()
4287 return self.editor.ReorientObject(theObject)
4289 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4291 Reorient faces contained in *the2DObject*.
4294 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4295 theDirection: is a desired direction of normal of *theFace*.
4296 It can be either a GEOM vector or a list of coordinates [x,y,z].
4297 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4298 compared with theDirection. It can be either ID of face or a point
4299 by which the face will be found. The point can be given as either
4300 a GEOM vertex or a list of point coordinates.
4303 number of reoriented faces
4306 unRegister = genObjUnRegister()
4308 if isinstance( the2DObject, Mesh ):
4309 the2DObject = the2DObject.GetMesh()
4310 if isinstance( the2DObject, list ):
4311 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4312 unRegister.set( the2DObject )
4313 # check theDirection
4314 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4315 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4316 if isinstance( theDirection, list ):
4317 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4318 # prepare theFace and thePoint
4319 theFace = theFaceOrPoint
4320 thePoint = PointStruct(0,0,0)
4321 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4322 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4324 if isinstance( theFaceOrPoint, list ):
4325 thePoint = PointStruct( *theFaceOrPoint )
4327 if isinstance( theFaceOrPoint, PointStruct ):
4328 thePoint = theFaceOrPoint
4330 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4332 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4334 Reorient faces according to adjacent volumes.
4337 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4338 either IDs of faces or face groups.
4339 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4340 theOutsideNormal: to orient faces to have their normals
4341 pointing either *outside* or *inside* the adjacent volumes.
4344 number of reoriented faces.
4347 unRegister = genObjUnRegister()
4349 if not isinstance( the2DObject, list ):
4350 the2DObject = [ the2DObject ]
4351 elif the2DObject and isinstance( the2DObject[0], int ):
4352 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4353 unRegister.set( the2DObject )
4354 the2DObject = [ the2DObject ]
4355 for i,obj2D in enumerate( the2DObject ):
4356 if isinstance( obj2D, Mesh ):
4357 the2DObject[i] = obj2D.GetMesh()
4358 if isinstance( obj2D, list ):
4359 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4360 unRegister.set( the2DObject[i] )
4362 if isinstance( the3DObject, Mesh ):
4363 the3DObject = the3DObject.GetMesh()
4364 if isinstance( the3DObject, list ):
4365 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4366 unRegister.set( the3DObject )
4367 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4369 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4371 Fuse the neighbouring triangles into quadrangles.
4374 IDsOfElements: The triangles to be fused.
4375 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4376 applied to possible quadrangles to choose a neighbour to fuse with.
4377 Note that not all items of :class:`SMESH.FunctorType` corresponds
4378 to numerical functors.
4379 MaxAngle: is the maximum angle between element normals at which the fusion
4380 is still performed; theMaxAngle is measured in radians.
4381 Also it could be a name of variable which defines angle in degrees.
4384 True in case of success, False otherwise.
4387 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4388 self.mesh.SetParameters(Parameters)
4389 if not IDsOfElements:
4390 IDsOfElements = self.GetElementsId()
4391 Functor = self.smeshpyD.GetFunctor(theCriterion)
4392 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4394 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4396 Fuse the neighbouring triangles of the object into quadrangles
4399 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4400 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4401 applied to possible quadrangles to choose a neighbour to fuse with.
4402 Note that not all items of :class:`SMESH.FunctorType` corresponds
4403 to numerical functors.
4404 MaxAngle: a max angle between element normals at which the fusion
4405 is still performed; theMaxAngle is measured in radians.
4408 True in case of success, False otherwise.
4411 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4412 self.mesh.SetParameters(Parameters)
4413 if isinstance( theObject, Mesh ):
4414 theObject = theObject.GetMesh()
4415 Functor = self.smeshpyD.GetFunctor(theCriterion)
4416 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4418 def QuadToTri (self, IDsOfElements, theCriterion = None):
4420 Split quadrangles into triangles.
4423 IDsOfElements: the faces to be splitted.
4424 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4425 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4426 value, then quadrangles will be split by the smallest diagonal.
4427 Note that not all items of :class:`SMESH.FunctorType` corresponds
4428 to numerical functors.
4431 True in case of success, False otherwise.
4433 if IDsOfElements == []:
4434 IDsOfElements = self.GetElementsId()
4435 if theCriterion is None:
4436 theCriterion = FT_MaxElementLength2D
4437 Functor = self.smeshpyD.GetFunctor(theCriterion)
4438 return self.editor.QuadToTri(IDsOfElements, Functor)
4440 def QuadToTriObject (self, theObject, theCriterion = None):
4442 Split quadrangles into triangles.
4445 theObject: the object from which the list of elements is taken,
4446 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4447 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4448 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4449 value, then quadrangles will be split by the smallest diagonal.
4450 Note that not all items of :class:`SMESH.FunctorType` corresponds
4451 to numerical functors.
4454 True in case of success, False otherwise.
4456 if ( isinstance( theObject, Mesh )):
4457 theObject = theObject.GetMesh()
4458 if theCriterion is None:
4459 theCriterion = FT_MaxElementLength2D
4460 Functor = self.smeshpyD.GetFunctor(theCriterion)
4461 return self.editor.QuadToTriObject(theObject, Functor)
4463 def QuadTo4Tri (self, theElements=[]):
4465 Split each of given quadrangles into 4 triangles. A node is added at the center of
4469 theElements: the faces to be splitted. This can be either
4470 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4471 or a list of face IDs. By default all quadrangles are split
4473 unRegister = genObjUnRegister()
4474 if isinstance( theElements, Mesh ):
4475 theElements = theElements.mesh
4476 elif not theElements:
4477 theElements = self.mesh
4478 elif isinstance( theElements, list ):
4479 theElements = self.GetIDSource( theElements, SMESH.FACE )
4480 unRegister.set( theElements )
4481 return self.editor.QuadTo4Tri( theElements )
4483 def SplitQuad (self, IDsOfElements, Diag13):
4485 Split quadrangles into triangles.
4488 IDsOfElements: the faces to be splitted
4489 Diag13: is used to choose a diagonal for splitting.
4492 True in case of success, False otherwise.
4494 if IDsOfElements == []:
4495 IDsOfElements = self.GetElementsId()
4496 return self.editor.SplitQuad(IDsOfElements, Diag13)
4498 def SplitQuadObject (self, theObject, Diag13):
4500 Split quadrangles into triangles.
4503 theObject: the object from which the list of elements is taken,
4504 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4505 Diag13: is used to choose a diagonal for splitting.
4508 True in case of success, False otherwise.
4510 if ( isinstance( theObject, Mesh )):
4511 theObject = theObject.GetMesh()
4512 return self.editor.SplitQuadObject(theObject, Diag13)
4514 def BestSplit (self, IDOfQuad, theCriterion):
4516 Find a better splitting of the given quadrangle.
4519 IDOfQuad: the ID of the quadrangle to be splitted.
4520 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4521 choose a diagonal for splitting.
4522 Note that not all items of :class:`SMESH.FunctorType` corresponds
4523 to numerical functors.
4526 * 1 if 1-3 diagonal is better,
4527 * 2 if 2-4 diagonal is better,
4528 * 0 if error occurs.
4530 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4532 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4534 Split volumic elements into tetrahedrons
4537 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4538 method: flags passing splitting method:
4539 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4540 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4542 unRegister = genObjUnRegister()
4543 if isinstance( elems, Mesh ):
4544 elems = elems.GetMesh()
4545 if ( isinstance( elems, list )):
4546 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4547 unRegister.set( elems )
4548 self.editor.SplitVolumesIntoTetra(elems, method)
4551 def SplitBiQuadraticIntoLinear(self, elems=None):
4553 Split bi-quadratic elements into linear ones without creation of additional nodes:
4555 - bi-quadratic triangle will be split into 3 linear quadrangles;
4556 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4557 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4559 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4560 will be split in order to keep the mesh conformal.
4563 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4564 if None (default), all bi-quadratic elements will be split
4566 unRegister = genObjUnRegister()
4567 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4568 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4569 unRegister.set( elems )
4571 elems = [ self.GetMesh() ]
4572 if isinstance( elems, Mesh ):
4573 elems = [ elems.GetMesh() ]
4574 if not isinstance( elems, list ):
4576 self.editor.SplitBiQuadraticIntoLinear( elems )
4578 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4579 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4581 Split hexahedra into prisms
4584 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4585 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4586 gives a normal vector defining facets to split into triangles.
4587 *startHexPoint* can be either a triple of coordinates or a vertex.
4588 facetNormal: a normal to a facet to split into triangles of a
4589 hexahedron found by *startHexPoint*.
4590 *facetNormal* can be either a triple of coordinates or an edge.
4591 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4592 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4593 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4594 to *startHexPoint* are split, else *startHexPoint*
4595 is used to find the facet to split in all domains present in *elems*.
4598 unRegister = genObjUnRegister()
4599 if isinstance( elems, Mesh ):
4600 elems = elems.GetMesh()
4601 if ( isinstance( elems, list )):
4602 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4603 unRegister.set( elems )
4606 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4607 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4608 elif isinstance( startHexPoint, list ):
4609 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4612 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4613 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4614 elif isinstance( facetNormal, list ):
4615 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4618 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4620 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4622 def SplitQuadsNearTriangularFacets(self):
4624 Split quadrangle faces near triangular facets of volumes
4626 faces_array = self.GetElementsByType(SMESH.FACE)
4627 for face_id in faces_array:
4628 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4629 quad_nodes = self.mesh.GetElemNodes(face_id)
4630 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4631 isVolumeFound = False
4632 for node1_elem in node1_elems:
4633 if not isVolumeFound:
4634 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4635 nb_nodes = self.GetElemNbNodes(node1_elem)
4636 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4637 volume_elem = node1_elem
4638 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4639 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4640 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4641 isVolumeFound = True
4642 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4643 self.SplitQuad([face_id], False) # diagonal 2-4
4644 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4645 isVolumeFound = True
4646 self.SplitQuad([face_id], True) # diagonal 1-3
4647 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4648 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4649 isVolumeFound = True
4650 self.SplitQuad([face_id], True) # diagonal 1-3
4652 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4654 Split hexahedrons into tetrahedrons.
4656 This operation uses :doc:`pattern_mapping` functionality for splitting.
4659 theObject: the object from which the list of hexahedrons is taken;
4660 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4661 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4662 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4663 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4664 key-point will be mapped into *theNode001*-th node of each volume.
4665 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4668 True in case of success, False otherwise.
4676 # (0,0,1) 4.---------.7 * |
4683 # (0,0,0) 0.---------.3
4684 pattern_tetra = "!!! Nb of points: \n 8 \n\
4694 !!! Indices of points of 6 tetras: \n\
4702 pattern = self.smeshpyD.GetPattern()
4703 isDone = pattern.LoadFromFile(pattern_tetra)
4705 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4708 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4709 isDone = pattern.MakeMesh(self.mesh, False, False)
4710 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4712 # split quafrangle faces near triangular facets of volumes
4713 self.SplitQuadsNearTriangularFacets()
4717 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4719 Split hexahedrons into prisms.
4721 Uses the :doc:`pattern_mapping` functionality for splitting.
4724 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4725 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4726 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4727 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4728 will be mapped into the *theNode001* -th node of each volume.
4729 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4732 True in case of success, False otherwise.
4734 # Pattern: 5.---------.6
4739 # (0,0,1) 4.---------.7 |
4746 # (0,0,0) 0.---------.3
4747 pattern_prism = "!!! Nb of points: \n 8 \n\
4757 !!! Indices of points of 2 prisms: \n\
4761 pattern = self.smeshpyD.GetPattern()
4762 isDone = pattern.LoadFromFile(pattern_prism)
4764 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4767 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4768 isDone = pattern.MakeMesh(self.mesh, False, False)
4769 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4771 # Split quafrangle faces near triangular facets of volumes
4772 self.SplitQuadsNearTriangularFacets()
4776 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4777 MaxNbOfIterations, MaxAspectRatio, Method):
4782 IDsOfElements: the list if ids of elements to smooth
4783 IDsOfFixedNodes: the list of ids of fixed nodes.
4784 Note that nodes built on edges and boundary nodes are always fixed.
4785 MaxNbOfIterations: the maximum number of iterations
4786 MaxAspectRatio: varies in range [1.0, inf]
4787 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4788 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4791 True in case of success, False otherwise.
4794 if IDsOfElements == []:
4795 IDsOfElements = self.GetElementsId()
4796 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4797 self.mesh.SetParameters(Parameters)
4798 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4799 MaxNbOfIterations, MaxAspectRatio, Method)
4801 def SmoothObject(self, theObject, IDsOfFixedNodes,
4802 MaxNbOfIterations, MaxAspectRatio, Method):
4804 Smooth elements which belong to the given object
4807 theObject: the object to smooth
4808 IDsOfFixedNodes: the list of ids of fixed nodes.
4809 Note that nodes built on edges and boundary nodes are always fixed.
4810 MaxNbOfIterations: the maximum number of iterations
4811 MaxAspectRatio: varies in range [1.0, inf]
4812 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4813 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4816 True in case of success, False otherwise.
4819 if ( isinstance( theObject, Mesh )):
4820 theObject = theObject.GetMesh()
4821 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4822 MaxNbOfIterations, MaxAspectRatio, Method)
4824 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4825 MaxNbOfIterations, MaxAspectRatio, Method):
4827 Parametrically smooth the given elements
4830 IDsOfElements: the list if ids of elements to smooth
4831 IDsOfFixedNodes: the list of ids of fixed nodes.
4832 Note that nodes built on edges and boundary nodes are always fixed.
4833 MaxNbOfIterations: the maximum number of iterations
4834 MaxAspectRatio: varies in range [1.0, inf]
4835 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4836 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4839 True in case of success, False otherwise.
4842 if IDsOfElements == []:
4843 IDsOfElements = self.GetElementsId()
4844 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4845 self.mesh.SetParameters(Parameters)
4846 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4847 MaxNbOfIterations, MaxAspectRatio, Method)
4849 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4850 MaxNbOfIterations, MaxAspectRatio, Method):
4852 Parametrically smooth the elements which belong to the given object
4855 theObject: the object to smooth
4856 IDsOfFixedNodes: the list of ids of fixed nodes.
4857 Note that nodes built on edges and boundary nodes are always fixed.
4858 MaxNbOfIterations: the maximum number of iterations
4859 MaxAspectRatio: varies in range [1.0, inf]
4860 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4861 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4864 True in case of success, False otherwise.
4867 if ( isinstance( theObject, Mesh )):
4868 theObject = theObject.GetMesh()
4869 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4870 MaxNbOfIterations, MaxAspectRatio, Method)
4872 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4874 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4875 them with quadratic with the same id.
4878 theForce3d: method of new node creation:
4880 * False - the medium node lies at the geometrical entity from which the mesh element is built
4881 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4882 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4883 theToBiQuad: If True, converts the mesh to bi-quadratic
4886 :class:`SMESH.ComputeError` which can hold a warning
4889 If *theSubMesh* is provided, the mesh can become non-conformal
4892 if isinstance( theSubMesh, Mesh ):
4893 theSubMesh = theSubMesh.mesh
4895 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4898 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4900 self.editor.ConvertToQuadratic(theForce3d)
4901 error = self.editor.GetLastError()
4902 if error and error.comment:
4903 print(error.comment)
4906 def ConvertFromQuadratic(self, theSubMesh=None):
4908 Convert the mesh from quadratic to ordinary,
4909 deletes old quadratic elements,
4910 replacing them with ordinary mesh elements with the same id.
4913 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4916 If *theSubMesh* is provided, the mesh can become non-conformal
4920 self.editor.ConvertFromQuadraticObject(theSubMesh)
4922 return self.editor.ConvertFromQuadratic()
4924 def Make2DMeshFrom3D(self):
4926 Create 2D mesh as skin on boundary faces of a 3D mesh
4929 True if operation has been completed successfully, False otherwise
4932 return self.editor.Make2DMeshFrom3D()
4934 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4935 toCopyElements=False, toCopyExistingBondary=False):
4937 Create missing boundary elements
4940 elements: elements whose boundary is to be checked:
4941 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4942 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4943 dimension: defines type of boundary elements to create, either of
4944 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4945 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4946 groupName: a name of group to store created boundary elements in,
4947 "" means not to create the group
4948 meshName: a name of new mesh to store created boundary elements in,
4949 "" means not to create the new mesh
4950 toCopyElements: if True, the checked elements will be copied into
4951 the new mesh else only boundary elements will be copied into the new mesh
4952 toCopyExistingBondary: if True, not only new but also pre-existing
4953 boundary elements will be copied into the new mesh
4956 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4959 unRegister = genObjUnRegister()
4960 if isinstance( elements, Mesh ):
4961 elements = elements.GetMesh()
4962 if ( isinstance( elements, list )):
4963 elemType = SMESH.ALL
4964 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4965 elements = self.editor.MakeIDSource(elements, elemType)
4966 unRegister.set( elements )
4967 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4968 toCopyElements,toCopyExistingBondary)
4969 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4972 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4973 toCopyAll=False, groups=[]):
4975 Create missing boundary elements around either the whole mesh or
4979 dimension: defines type of boundary elements to create, either of
4980 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4981 groupName: a name of group to store all boundary elements in,
4982 "" means not to create the group
4983 meshName: a name of a new mesh, which is a copy of the initial
4984 mesh + created boundary elements; "" means not to create the new mesh
4985 toCopyAll: if True, the whole initial mesh will be copied into
4986 the new mesh else only boundary elements will be copied into the new mesh
4987 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4990 tuple( long, mesh, groups )
4991 - long - number of added boundary elements
4992 - mesh - the :class:`Mesh` where elements were added to
4993 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4996 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4998 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4999 return nb, mesh, group
5001 def RenumberNodes(self):
5003 Renumber mesh nodes to remove unused node IDs
5005 self.editor.RenumberNodes()
5007 def RenumberElements(self):
5009 Renumber mesh elements to remove unused element IDs
5011 self.editor.RenumberElements()
5013 def _getIdSourceList(self, arg, idType, unRegister):
5015 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5017 if arg and isinstance( arg, list ):
5018 if isinstance( arg[0], int ):
5019 arg = self.GetIDSource( arg, idType )
5020 unRegister.set( arg )
5021 elif isinstance( arg[0], Mesh ):
5022 arg[0] = arg[0].GetMesh()
5023 elif isinstance( arg, Mesh ):
5025 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5029 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5030 MakeGroups=False, TotalAngle=False):
5032 Generate new elements by rotation of the given elements and nodes around the axis
5035 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5036 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5037 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5038 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5039 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5040 which defines angle in degrees
5041 NbOfSteps: the number of steps
5042 Tolerance: tolerance
5043 MakeGroups: forces the generation of new groups from existing ones
5044 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5045 of all steps, else - size of each step
5048 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5051 unRegister = genObjUnRegister()
5052 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5053 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5054 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5056 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5057 Axis = self.smeshpyD.GetAxisStruct( Axis )
5058 if isinstance( Axis, list ):
5059 Axis = SMESH.AxisStruct( *Axis )
5061 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5062 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5063 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5064 self.mesh.SetParameters(Parameters)
5065 if TotalAngle and NbOfSteps:
5066 AngleInRadians /= NbOfSteps
5067 return self.editor.RotationSweepObjects( nodes, edges, faces,
5068 Axis, AngleInRadians,
5069 NbOfSteps, Tolerance, MakeGroups)
5071 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5072 MakeGroups=False, TotalAngle=False):
5074 Generate new elements by rotation of the elements around the axis
5077 IDsOfElements: the list of ids of elements to sweep
5078 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5079 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5080 NbOfSteps: the number of steps
5081 Tolerance: tolerance
5082 MakeGroups: forces the generation of new groups from existing ones
5083 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5084 of all steps, else - size of each step
5087 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5090 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5091 AngleInRadians, NbOfSteps, Tolerance,
5092 MakeGroups, TotalAngle)
5094 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5095 MakeGroups=False, TotalAngle=False):
5097 Generate new elements by rotation of the elements of object around the axis
5098 theObject object which elements should be sweeped.
5099 It can be a mesh, a sub mesh or a group.
5102 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5103 AngleInRadians: the angle of Rotation
5104 NbOfSteps: number of steps
5105 Tolerance: tolerance
5106 MakeGroups: forces the generation of new groups from existing ones
5107 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5108 of all steps, else - size of each step
5111 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5114 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5115 AngleInRadians, NbOfSteps, Tolerance,
5116 MakeGroups, TotalAngle )
5118 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5119 MakeGroups=False, TotalAngle=False):
5121 Generate new elements by rotation of the elements of object around the axis
5122 theObject object which elements should be sweeped.
5123 It can be a mesh, a sub mesh or a group.
5126 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5127 AngleInRadians: the angle of Rotation
5128 NbOfSteps: number of steps
5129 Tolerance: tolerance
5130 MakeGroups: forces the generation of new groups from existing ones
5131 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5132 of all steps, else - size of each step
5135 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5136 empty list otherwise
5139 return self.RotationSweepObjects([],theObject,[], Axis,
5140 AngleInRadians, NbOfSteps, Tolerance,
5141 MakeGroups, TotalAngle)
5143 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5144 MakeGroups=False, TotalAngle=False):
5146 Generate new elements by rotation of the elements of object around the axis
5147 theObject object which elements should be sweeped.
5148 It can be a mesh, a sub mesh or a group.
5151 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5152 AngleInRadians: the angle of Rotation
5153 NbOfSteps: number of steps
5154 Tolerance: tolerance
5155 MakeGroups: forces the generation of new groups from existing ones
5156 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5157 of all steps, else - size of each step
5160 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5163 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5164 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5166 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5167 scaleFactors=[], linearVariation=False, basePoint=[] ):
5169 Generate new elements by extrusion of the given elements and nodes
5172 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5173 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5174 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5175 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5176 the direction and value of extrusion for one step (the total extrusion
5177 length will be NbOfSteps * ||StepVector||)
5178 NbOfSteps: the number of steps
5179 MakeGroups: forces the generation of new groups from existing ones
5180 scaleFactors: optional scale factors to apply during extrusion
5181 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5182 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5183 basePoint: optional scaling center; if not provided, a gravity center of
5184 nodes and elements being extruded is used as the scaling center.
5187 - a list of tree components of the point or
5191 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5193 Example: :ref:`tui_extrusion`
5195 unRegister = genObjUnRegister()
5196 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5197 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5198 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5200 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5201 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5202 if isinstance( StepVector, list ):
5203 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5205 if isinstance( basePoint, int):
5206 xyz = self.GetNodeXYZ( basePoint )
5208 raise RuntimeError("Invalid node ID: %s" % basePoint)
5210 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5211 basePoint = self.geompyD.PointCoordinates( basePoint )
5213 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5214 Parameters = StepVector.PS.parameters + var_separator + Parameters
5215 self.mesh.SetParameters(Parameters)
5217 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5218 StepVector, NbOfSteps,
5219 scaleFactors, linearVariation, basePoint,
5223 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5225 Generate new elements by extrusion of the elements with given ids
5228 IDsOfElements: the list of ids of elements or nodes for extrusion
5229 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5230 the direction and value of extrusion for one step (the total extrusion
5231 length will be NbOfSteps * ||StepVector||)
5232 NbOfSteps: the number of steps
5233 MakeGroups: forces the generation of new groups from existing ones
5234 IsNodes: is True if elements with given ids are nodes
5237 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5239 Example: :ref:`tui_extrusion`
5242 if IsNodes: n = IDsOfElements
5243 else : e,f, = IDsOfElements,IDsOfElements
5244 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5246 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5247 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5249 Generate new elements by extrusion along the normal to a discretized surface or wire
5252 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5253 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5254 StepSize: length of one extrusion step (the total extrusion
5255 length will be *NbOfSteps* *StepSize*).
5256 NbOfSteps: number of extrusion steps.
5257 ByAverageNormal: if True each node is translated by *StepSize*
5258 along the average of the normal vectors to the faces sharing the node;
5259 else each node is translated along the same average normal till
5260 intersection with the plane got by translation of the face sharing
5261 the node along its own normal by *StepSize*.
5262 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5263 for every node of *Elements*.
5264 MakeGroups: forces generation of new groups from existing ones.
5265 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5266 is not yet implemented. This parameter is used if *Elements* contains
5267 both faces and edges, i.e. *Elements* is a Mesh.
5270 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5271 empty list otherwise.
5272 Example: :ref:`tui_extrusion`
5275 unRegister = genObjUnRegister()
5276 if isinstance( Elements, Mesh ):
5277 Elements = [ Elements.GetMesh() ]
5278 if isinstance( Elements, list ):
5280 raise RuntimeError("Elements empty!")
5281 if isinstance( Elements[0], int ):
5282 Elements = self.GetIDSource( Elements, SMESH.ALL )
5283 unRegister.set( Elements )
5284 if not isinstance( Elements, list ):
5285 Elements = [ Elements ]
5286 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5287 self.mesh.SetParameters(Parameters)
5288 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5289 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5291 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5293 Generate new elements by extrusion of the elements or nodes which belong to the object
5296 theObject: the object whose elements or nodes should be processed.
5297 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5298 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5299 the direction and value of extrusion for one step (the total extrusion
5300 length will be NbOfSteps * ||StepVector||)
5301 NbOfSteps: the number of steps
5302 MakeGroups: forces the generation of new groups from existing ones
5303 IsNodes: is True if elements to extrude are nodes
5306 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5307 Example: :ref:`tui_extrusion`
5311 if IsNodes: n = theObject
5312 else : e,f, = theObject,theObject
5313 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5315 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5317 Generate new elements by extrusion of edges which belong to the object
5320 theObject: object whose 1D elements should be processed.
5321 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5322 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5323 the direction and value of extrusion for one step (the total extrusion
5324 length will be NbOfSteps * ||StepVector||)
5325 NbOfSteps: the number of steps
5326 MakeGroups: to generate new groups from existing ones
5329 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5330 Example: :ref:`tui_extrusion`
5333 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5335 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5337 Generate new elements by extrusion of faces which belong to the object
5340 theObject: object whose 2D elements should be processed.
5341 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5342 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5343 the direction and value of extrusion for one step (the total extrusion
5344 length will be NbOfSteps * ||StepVector||)
5345 NbOfSteps: the number of steps
5346 MakeGroups: forces the generation of new groups from existing ones
5349 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5350 Example: :ref:`tui_extrusion`
5353 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5355 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5356 ExtrFlags, SewTolerance, MakeGroups=False):
5358 Generate new elements by extrusion of the elements with given ids
5361 IDsOfElements: is ids of elements
5362 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5363 the direction and value of extrusion for one step (the total extrusion
5364 length will be NbOfSteps * ||StepVector||)
5365 NbOfSteps: the number of steps
5366 ExtrFlags: sets flags for extrusion
5367 SewTolerance: uses for comparing locations of nodes if flag
5368 EXTRUSION_FLAG_SEW is set
5369 MakeGroups: forces the generation of new groups from existing ones
5372 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5375 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5376 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5377 if isinstance( StepVector, list ):
5378 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5379 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5380 ExtrFlags, SewTolerance, MakeGroups)
5382 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5383 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5384 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5386 Generate new elements by extrusion of the given elements and nodes along the path.
5387 The path of extrusion must be a meshed edge.
5390 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5391 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5392 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5393 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5394 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5395 contains not only path segments, else it can be None
5396 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5397 HasAngles: allows the shape to be rotated around the path
5398 to get the resulting mesh in a helical fashion
5399 Angles: list of angles
5400 LinearVariation: forces the computation of rotation angles as linear
5401 variation of the given Angles along path steps
5402 HasRefPoint: allows using the reference point
5403 RefPoint: the reference point around which the shape is rotated (the mass center of the
5404 shape by default). The User can specify any point as the Reference Point.
5405 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5406 MakeGroups: forces the generation of new groups from existing ones
5409 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5410 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5411 Example: :ref:`tui_extrusion_along_path`
5414 unRegister = genObjUnRegister()
5415 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5416 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5417 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5419 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5420 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5421 if isinstance( RefPoint, list ):
5422 if not RefPoint: RefPoint = [0,0,0]
5423 RefPoint = SMESH.PointStruct( *RefPoint )
5424 if isinstance( PathMesh, Mesh ):
5425 PathMesh = PathMesh.GetMesh()
5426 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5427 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5428 self.mesh.SetParameters(Parameters)
5429 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5430 PathMesh, PathShape, NodeStart,
5431 HasAngles, Angles, LinearVariation,
5432 HasRefPoint, RefPoint, MakeGroups)
5434 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5435 HasAngles=False, Angles=[], LinearVariation=False,
5436 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5437 ElemType=SMESH.FACE):
5439 Generate new elements by extrusion of the given elements.
5440 The path of extrusion must be a meshed edge.
5443 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5444 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5445 NodeStart: the start node from Path. Defines the direction of extrusion
5446 HasAngles: allows the shape to be rotated around the path
5447 to get the resulting mesh in a helical fashion
5448 Angles: list of angles in radians
5449 LinearVariation: forces the computation of rotation angles as linear
5450 variation of the given Angles along path steps
5451 HasRefPoint: allows using the reference point
5452 RefPoint: the reference point around which the elements are rotated (the mass
5453 center of the elements by default).
5454 The User can specify any point as the Reference Point.
5455 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5456 MakeGroups: forces the generation of new groups from existing ones
5457 ElemType: type of elements for extrusion (if param Base is a mesh)
5460 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5461 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5462 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5464 Example: :ref:`tui_extrusion_along_path`
5468 if ElemType == SMESH.NODE: n = Base
5469 if ElemType == SMESH.EDGE: e = Base
5470 if ElemType == SMESH.FACE: f = Base
5471 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5472 HasAngles, Angles, LinearVariation,
5473 HasRefPoint, RefPoint, MakeGroups)
5474 if MakeGroups: return gr,er
5477 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5478 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5479 MakeGroups=False, LinearVariation=False):
5481 Generate new elements by extrusion of the given elements.
5482 The path of extrusion must be a meshed edge.
5485 IDsOfElements: ids of elements
5486 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5487 PathShape: shape (edge) defines the sub-mesh for the path
5488 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5489 HasAngles: allows the shape to be rotated around the path
5490 to get the resulting mesh in a helical fashion
5491 Angles: list of angles in radians
5492 HasRefPoint: allows using the reference point
5493 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5494 The User can specify any point as the Reference Point.
5495 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5496 MakeGroups: forces the generation of new groups from existing ones
5497 LinearVariation: forces the computation of rotation angles as linear
5498 variation of the given Angles along path steps
5501 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5502 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5503 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5504 Example: :ref:`tui_extrusion_along_path`
5507 n,e,f = [],IDsOfElements,IDsOfElements
5508 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5509 NodeStart, HasAngles, Angles,
5511 HasRefPoint, RefPoint, MakeGroups)
5512 if MakeGroups: return gr,er
5515 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5516 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5517 MakeGroups=False, LinearVariation=False):
5519 Generate new elements by extrusion of the elements which belong to the object.
5520 The path of extrusion must be a meshed edge.
5523 theObject: the object whose elements should be processed.
5524 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5525 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5526 PathShape: shape (edge) defines the sub-mesh for the path
5527 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5528 HasAngles: allows the shape to be rotated around the path
5529 to get the resulting mesh in a helical fashion
5530 Angles: list of angles
5531 HasRefPoint: allows using the reference point
5532 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5533 The User can specify any point as the Reference Point.
5534 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5535 MakeGroups: forces the generation of new groups from existing ones
5536 LinearVariation: forces the computation of rotation angles as linear
5537 variation of the given Angles along path steps
5540 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5541 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5542 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5543 Example: :ref:`tui_extrusion_along_path`
5546 n,e,f = [],theObject,theObject
5547 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5548 HasAngles, Angles, LinearVariation,
5549 HasRefPoint, RefPoint, MakeGroups)
5550 if MakeGroups: return gr,er
5553 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5554 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5555 MakeGroups=False, LinearVariation=False):
5557 Generate new elements by extrusion of mesh segments which belong to the object.
5558 The path of extrusion must be a meshed edge.
5561 theObject: the object whose 1D elements should be processed.
5562 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5563 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5564 PathShape: shape (edge) defines the sub-mesh for the path
5565 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5566 HasAngles: allows the shape to be rotated around the path
5567 to get the resulting mesh in a helical fashion
5568 Angles: list of angles
5569 HasRefPoint: allows using the reference point
5570 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5571 The User can specify any point as the Reference Point.
5572 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5573 MakeGroups: forces the generation of new groups from existing ones
5574 LinearVariation: forces the computation of rotation angles as linear
5575 variation of the given Angles along path steps
5578 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5579 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5580 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5581 Example: :ref:`tui_extrusion_along_path`
5584 n,e,f = [],theObject,[]
5585 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5586 HasAngles, Angles, LinearVariation,
5587 HasRefPoint, RefPoint, MakeGroups)
5588 if MakeGroups: return gr,er
5591 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5592 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5593 MakeGroups=False, LinearVariation=False):
5595 Generate new elements by extrusion of faces which belong to the object.
5596 The path of extrusion must be a meshed edge.
5599 theObject: the object whose 2D elements should be processed.
5600 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5601 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5602 PathShape: shape (edge) defines the sub-mesh for the path
5603 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5604 HasAngles: allows the shape to be rotated around the path
5605 to get the resulting mesh in a helical fashion
5606 Angles: list of angles
5607 HasRefPoint: allows using the reference point
5608 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5609 The User can specify any point as the Reference Point.
5610 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5611 MakeGroups: forces the generation of new groups from existing ones
5612 LinearVariation: forces the computation of rotation angles as linear
5613 variation of the given Angles along path steps
5616 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5617 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5618 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5619 Example: :ref:`tui_extrusion_along_path`
5622 n,e,f = [],[],theObject
5623 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5624 HasAngles, Angles, LinearVariation,
5625 HasRefPoint, RefPoint, MakeGroups)
5626 if MakeGroups: return gr,er
5629 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5631 Create a symmetrical copy of mesh elements
5634 IDsOfElements: list of elements ids
5635 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5636 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5637 If the *Mirror* is a geom object this parameter is unnecessary
5638 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5639 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5642 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5645 if IDsOfElements == []:
5646 IDsOfElements = self.GetElementsId()
5647 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5648 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5649 theMirrorType = Mirror._mirrorType
5651 self.mesh.SetParameters(Mirror.parameters)
5652 if Copy and MakeGroups:
5653 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5654 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5657 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5659 Create a new mesh by a symmetrical copy of mesh elements
5662 IDsOfElements: the list of elements ids
5663 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5664 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5665 If the *Mirror* is a geom object this parameter is unnecessary
5666 MakeGroups: to generate new groups from existing ones
5667 NewMeshName: a name of the new mesh to create
5670 instance of class :class:`Mesh`
5673 if IDsOfElements == []:
5674 IDsOfElements = self.GetElementsId()
5675 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5676 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5677 theMirrorType = Mirror._mirrorType
5679 self.mesh.SetParameters(Mirror.parameters)
5680 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5681 MakeGroups, NewMeshName)
5682 return Mesh(self.smeshpyD,self.geompyD,mesh)
5684 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5686 Create a symmetrical copy of the object
5689 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5690 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5691 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5692 If the *Mirror* is a geom object this parameter is unnecessary
5693 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5694 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5697 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5700 if ( isinstance( theObject, Mesh )):
5701 theObject = theObject.GetMesh()
5702 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5703 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5704 theMirrorType = Mirror._mirrorType
5706 self.mesh.SetParameters(Mirror.parameters)
5707 if Copy and MakeGroups:
5708 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5709 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5712 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5714 Create a new mesh by a symmetrical copy of the object
5717 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5718 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5719 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5720 If the *Mirror* is a geom object this parameter is unnecessary
5721 MakeGroups: forces the generation of new groups from existing ones
5722 NewMeshName: the name of the new mesh to create
5725 instance of class :class:`Mesh`
5728 if ( isinstance( theObject, Mesh )):
5729 theObject = theObject.GetMesh()
5730 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5731 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5732 theMirrorType = Mirror._mirrorType
5734 self.mesh.SetParameters(Mirror.parameters)
5735 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5736 MakeGroups, NewMeshName)
5737 return Mesh( self.smeshpyD,self.geompyD,mesh )
5739 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5741 Translate the elements
5744 IDsOfElements: list of elements ids
5745 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5746 Copy: allows copying the translated elements
5747 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5750 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5753 if IDsOfElements == []:
5754 IDsOfElements = self.GetElementsId()
5755 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5756 Vector = self.smeshpyD.GetDirStruct(Vector)
5757 if isinstance( Vector, list ):
5758 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5759 self.mesh.SetParameters(Vector.PS.parameters)
5760 if Copy and MakeGroups:
5761 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5762 self.editor.Translate(IDsOfElements, Vector, Copy)
5765 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5767 Create a new mesh of translated elements
5770 IDsOfElements: list of elements ids
5771 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5772 MakeGroups: forces the generation of new groups from existing ones
5773 NewMeshName: the name of the newly created mesh
5776 instance of class :class:`Mesh`
5779 if IDsOfElements == []:
5780 IDsOfElements = self.GetElementsId()
5781 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5782 Vector = self.smeshpyD.GetDirStruct(Vector)
5783 if isinstance( Vector, list ):
5784 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5785 self.mesh.SetParameters(Vector.PS.parameters)
5786 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5787 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5789 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5791 Translate the object
5794 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5795 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5796 Copy: allows copying the translated elements
5797 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5800 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5803 if ( isinstance( theObject, Mesh )):
5804 theObject = theObject.GetMesh()
5805 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5806 Vector = self.smeshpyD.GetDirStruct(Vector)
5807 if isinstance( Vector, list ):
5808 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5809 self.mesh.SetParameters(Vector.PS.parameters)
5810 if Copy and MakeGroups:
5811 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5812 self.editor.TranslateObject(theObject, Vector, Copy)
5815 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5817 Create a new mesh from the translated object
5820 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5821 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5822 MakeGroups: forces the generation of new groups from existing ones
5823 NewMeshName: the name of the newly created mesh
5826 instance of class :class:`Mesh`
5829 if isinstance( theObject, Mesh ):
5830 theObject = theObject.GetMesh()
5831 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5832 Vector = self.smeshpyD.GetDirStruct(Vector)
5833 if isinstance( Vector, list ):
5834 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5835 self.mesh.SetParameters(Vector.PS.parameters)
5836 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5837 return Mesh( self.smeshpyD, self.geompyD, mesh )
5841 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5846 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5847 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5848 theScaleFact: list of 1-3 scale factors for axises
5849 Copy: allows copying the translated elements
5850 MakeGroups: forces the generation of new groups from existing
5854 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5855 empty list otherwise
5857 unRegister = genObjUnRegister()
5858 if ( isinstance( theObject, Mesh )):
5859 theObject = theObject.GetMesh()
5860 if ( isinstance( theObject, list )):
5861 theObject = self.GetIDSource(theObject, SMESH.ALL)
5862 unRegister.set( theObject )
5863 if ( isinstance( thePoint, list )):
5864 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5865 if ( isinstance( theScaleFact, float )):
5866 theScaleFact = [theScaleFact]
5867 if ( isinstance( theScaleFact, int )):
5868 theScaleFact = [ float(theScaleFact)]
5870 self.mesh.SetParameters(thePoint.parameters)
5872 if Copy and MakeGroups:
5873 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5874 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5877 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5879 Create a new mesh from the translated object
5882 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5883 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5884 theScaleFact: list of 1-3 scale factors for axises
5885 MakeGroups: forces the generation of new groups from existing ones
5886 NewMeshName: the name of the newly created mesh
5889 instance of class :class:`Mesh`
5891 unRegister = genObjUnRegister()
5892 if (isinstance(theObject, Mesh)):
5893 theObject = theObject.GetMesh()
5894 if ( isinstance( theObject, list )):
5895 theObject = self.GetIDSource(theObject,SMESH.ALL)
5896 unRegister.set( theObject )
5897 if ( isinstance( thePoint, list )):
5898 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5899 if ( isinstance( theScaleFact, float )):
5900 theScaleFact = [theScaleFact]
5901 if ( isinstance( theScaleFact, int )):
5902 theScaleFact = [ float(theScaleFact)]
5904 self.mesh.SetParameters(thePoint.parameters)
5905 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5906 MakeGroups, NewMeshName)
5907 return Mesh( self.smeshpyD, self.geompyD, mesh )
5911 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5916 IDsOfElements: list of elements ids
5917 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5918 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5919 Copy: allows copying the rotated elements
5920 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5923 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5927 if IDsOfElements == []:
5928 IDsOfElements = self.GetElementsId()
5929 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5930 Axis = self.smeshpyD.GetAxisStruct(Axis)
5931 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5932 Parameters = Axis.parameters + var_separator + Parameters
5933 self.mesh.SetParameters(Parameters)
5934 if Copy and MakeGroups:
5935 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5936 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5939 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5941 Create a new mesh of rotated elements
5944 IDsOfElements: list of element ids
5945 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5946 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5947 MakeGroups: forces the generation of new groups from existing ones
5948 NewMeshName: the name of the newly created mesh
5951 instance of class :class:`Mesh`
5954 if IDsOfElements == []:
5955 IDsOfElements = self.GetElementsId()
5956 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5957 Axis = self.smeshpyD.GetAxisStruct(Axis)
5958 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5959 Parameters = Axis.parameters + var_separator + Parameters
5960 self.mesh.SetParameters(Parameters)
5961 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5962 MakeGroups, NewMeshName)
5963 return Mesh( self.smeshpyD, self.geompyD, mesh )
5965 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5970 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5971 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5972 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5973 Copy: allows copying the rotated elements
5974 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5977 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5980 if (isinstance(theObject, Mesh)):
5981 theObject = theObject.GetMesh()
5982 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5983 Axis = self.smeshpyD.GetAxisStruct(Axis)
5984 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5985 Parameters = Axis.parameters + ":" + Parameters
5986 self.mesh.SetParameters(Parameters)
5987 if Copy and MakeGroups:
5988 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5989 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5992 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5994 Create a new mesh from the rotated object
5997 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5998 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5999 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6000 MakeGroups: forces the generation of new groups from existing ones
6001 NewMeshName: the name of the newly created mesh
6004 instance of class :class:`Mesh`
6007 if (isinstance( theObject, Mesh )):
6008 theObject = theObject.GetMesh()
6009 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6010 Axis = self.smeshpyD.GetAxisStruct(Axis)
6011 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6012 Parameters = Axis.parameters + ":" + Parameters
6013 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6014 MakeGroups, NewMeshName)
6015 self.mesh.SetParameters(Parameters)
6016 return Mesh( self.smeshpyD, self.geompyD, mesh )
6018 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6020 Create an offset mesh from the given 2D object
6023 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6024 theValue (float): signed offset size
6025 MakeGroups (boolean): forces the generation of new groups from existing ones
6026 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6027 False means to remove original elements.
6028 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6031 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6034 if isinstance( theObject, Mesh ):
6035 theObject = theObject.GetMesh()
6036 theValue,Parameters,hasVars = ParseParameters(Value)
6037 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6038 self.mesh.SetParameters(Parameters)
6039 # if mesh_groups[0]:
6040 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6043 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6045 Find groups of adjacent nodes within Tolerance.
6048 Tolerance (float): the value of tolerance
6049 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6050 corner and medium nodes in separate groups thus preventing
6051 their further merge.
6054 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6057 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6059 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6060 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6062 Find groups of adjacent nodes within Tolerance.
6065 Tolerance: the value of tolerance
6066 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6067 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6068 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6069 corner and medium nodes in separate groups thus preventing
6070 their further merge.
6073 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6076 unRegister = genObjUnRegister()
6077 if (isinstance( SubMeshOrGroup, Mesh )):
6078 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6079 if not isinstance( exceptNodes, list ):
6080 exceptNodes = [ exceptNodes ]
6081 if exceptNodes and isinstance( exceptNodes[0], int ):
6082 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6083 unRegister.set( exceptNodes )
6084 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6085 exceptNodes, SeparateCornerAndMediumNodes)
6087 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6092 GroupsOfNodes: a list of groups of nodes IDs for merging.
6093 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6094 in all elements and groups by nodes 1 and 25 correspondingly
6095 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6096 If *NodesToKeep* does not include a node to keep for some group to merge,
6097 then the first node in the group is kept.
6098 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6101 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6102 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6104 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6106 Find the elements built on the same nodes.
6109 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6112 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6115 if not MeshOrSubMeshOrGroup:
6116 MeshOrSubMeshOrGroup=self.mesh
6117 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6118 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6119 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6121 def MergeElements(self, GroupsOfElementsID):
6123 Merge elements in each given group.
6126 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6127 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6128 replaced in all groups by elements 1 and 25)
6131 self.editor.MergeElements(GroupsOfElementsID)
6133 def MergeEqualElements(self):
6135 Leave one element and remove all other elements built on the same nodes.
6138 self.editor.MergeEqualElements()
6140 def FindFreeBorders(self, ClosedOnly=True):
6142 Returns all or only closed free borders
6145 list of SMESH.FreeBorder's
6148 return self.editor.FindFreeBorders( ClosedOnly )
6150 def FillHole(self, holeNodes, groupName=""):
6152 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6155 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6156 must describe all sequential nodes of the hole border. The first and the last
6157 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6158 groupName (string): name of a group to add new faces
6160 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if :option:`groupName` == ""
6164 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6165 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6166 if not isinstance( holeNodes, SMESH.FreeBorder ):
6167 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6168 self.editor.FillHole( holeNodes, groupName )
6170 def FindCoincidentFreeBorders (self, tolerance=0.):
6172 Return groups of FreeBorder's coincident within the given tolerance.
6175 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6176 size of elements adjacent to free borders being compared is used.
6179 SMESH.CoincidentFreeBorders structure
6182 return self.editor.FindCoincidentFreeBorders( tolerance )
6184 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6186 Sew FreeBorder's of each group
6189 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6190 where each enclosed list contains node IDs of a group of coincident free
6191 borders such that each consequent triple of IDs within a group describes
6192 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6193 last node of a border.
6194 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6195 groups of coincident free borders, each group including two borders.
6196 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6197 polygons if a node of opposite border falls on a face edge, else such
6198 faces are split into several ones.
6199 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6200 polyhedra if a node of opposite border falls on a volume edge, else such
6201 volumes, if any, remain intact and the mesh becomes non-conformal.
6204 a number of successfully sewed groups
6207 if freeBorders and isinstance( freeBorders, list ):
6208 # construct SMESH.CoincidentFreeBorders
6209 if isinstance( freeBorders[0], int ):
6210 freeBorders = [freeBorders]
6212 coincidentGroups = []
6213 for nodeList in freeBorders:
6214 if not nodeList or len( nodeList ) % 3:
6215 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6218 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6219 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6220 nodeList = nodeList[3:]
6222 coincidentGroups.append( group )
6224 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6226 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6228 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6229 FirstNodeID2, SecondNodeID2, LastNodeID2,
6230 CreatePolygons, CreatePolyedrs):
6235 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6238 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6239 FirstNodeID2, SecondNodeID2, LastNodeID2,
6240 CreatePolygons, CreatePolyedrs)
6242 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6243 FirstNodeID2, SecondNodeID2):
6245 Sew conform free borders
6248 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6251 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6252 FirstNodeID2, SecondNodeID2)
6254 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6255 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6260 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6263 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6264 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6266 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6267 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6268 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6270 Sew two sides of a mesh. The nodes belonging to Side1 are
6271 merged with the nodes of elements of Side2.
6272 The number of elements in theSide1 and in theSide2 must be
6273 equal and they should have similar nodal connectivity.
6274 The nodes to merge should belong to side borders and
6275 the first node should be linked to the second.
6278 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6281 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6282 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6283 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6285 def ChangeElemNodes(self, ide, newIDs):
6287 Set new nodes for the given element.
6294 False if the number of nodes does not correspond to the type of element
6297 return self.editor.ChangeElemNodes(ide, newIDs)
6299 def GetLastCreatedNodes(self):
6301 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6302 created, this method return the list of their IDs.
6303 If new nodes were not created - return empty list
6306 the list of integer values (can be empty)
6309 return self.editor.GetLastCreatedNodes()
6311 def GetLastCreatedElems(self):
6313 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6314 created this method return the list of their IDs.
6315 If new elements were not created - return empty list
6318 the list of integer values (can be empty)
6321 return self.editor.GetLastCreatedElems()
6323 def ClearLastCreated(self):
6325 Forget what nodes and elements were created by the last mesh edition operation
6328 self.editor.ClearLastCreated()
6330 def DoubleElements(self, theElements, theGroupName=""):
6332 Create duplicates of given elements, i.e. create new elements based on the
6333 same nodes as the given ones.
6336 theElements: container of elements to duplicate. It can be a
6337 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6338 or a list of element IDs. If *theElements* is
6339 a :class:`Mesh`, elements of highest dimension are duplicated
6340 theGroupName: a name of group to contain the generated elements.
6341 If a group with such a name already exists, the new elements
6342 are added to the existing group, else a new group is created.
6343 If *theGroupName* is empty, new elements are not added
6347 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6348 None if *theGroupName* == "".
6351 unRegister = genObjUnRegister()
6352 if isinstance( theElements, Mesh ):
6353 theElements = theElements.mesh
6354 elif isinstance( theElements, list ):
6355 theElements = self.GetIDSource( theElements, SMESH.ALL )
6356 unRegister.set( theElements )
6357 return self.editor.DoubleElements(theElements, theGroupName)
6359 def DoubleNodes(self, theNodes, theModifiedElems):
6361 Create a hole in a mesh by doubling the nodes of some particular elements
6364 theNodes: IDs of nodes to be doubled
6365 theModifiedElems: IDs of elements to be updated by the new (doubled)
6366 nodes. If list of element identifiers is empty then nodes are doubled but
6367 they not assigned to elements
6370 True if operation has been completed successfully, False otherwise
6373 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6375 def DoubleNode(self, theNodeId, theModifiedElems):
6377 Create a hole in a mesh by doubling the nodes of some particular elements.
6378 This method provided for convenience works as :meth:`DoubleNodes`.
6381 theNodeId: IDs of node to double
6382 theModifiedElems: IDs of elements to update
6385 True if operation has been completed successfully, False otherwise
6388 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6390 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6392 Create a hole in a mesh by doubling the nodes of some particular elements.
6393 This method provided for convenience works as :meth:`DoubleNodes`.
6396 theNodes: group of nodes to double.
6397 theModifiedElems: group of elements to update.
6398 theMakeGroup: forces the generation of a group containing new nodes.
6401 True or a created group if operation has been completed successfully,
6402 False or None otherwise
6406 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6407 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6409 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6411 Create a hole in a mesh by doubling the nodes of some particular elements.
6412 This method provided for convenience works as :meth:`DoubleNodes`.
6415 theNodes: list of groups of nodes to double.
6416 theModifiedElems: list of groups of elements to update.
6417 theMakeGroup: forces the generation of a group containing new nodes.
6420 True if operation has been completed successfully, False otherwise
6424 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6425 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6427 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6429 Create a hole in a mesh by doubling the nodes of some particular elements
6432 theElems: the list of elements (edges or faces) to replicate.
6433 The nodes for duplication could be found from these elements
6434 theNodesNot: list of nodes NOT to replicate
6435 theAffectedElems: the list of elements (cells and edges) to which the
6436 replicated nodes should be associated to
6439 True if operation has been completed successfully, False otherwise
6442 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6444 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6446 Create a hole in a mesh by doubling the nodes of some particular elements
6449 theElems: the list of elements (edges or faces) to replicate.
6450 The nodes for duplication could be found from these elements
6451 theNodesNot: list of nodes NOT to replicate
6452 theShape: shape to detect affected elements (element which geometric center
6453 located on or inside shape).
6454 The replicated nodes should be associated to affected elements.
6457 True if operation has been completed successfully, False otherwise
6460 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6462 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6463 theMakeGroup=False, theMakeNodeGroup=False):
6465 Create a hole in a mesh by doubling the nodes of some particular elements.
6466 This method provided for convenience works as :meth:`DoubleNodes`.
6469 theElems: group of of elements (edges or faces) to replicate.
6470 theNodesNot: group of nodes NOT to replicate.
6471 theAffectedElems: group of elements to which the replicated nodes
6472 should be associated to.
6473 theMakeGroup: forces the generation of a group containing new elements.
6474 theMakeNodeGroup: forces the generation of a group containing new nodes.
6477 True or created groups (one or two) if operation has been completed successfully,
6478 False or None otherwise
6481 if theMakeGroup or theMakeNodeGroup:
6482 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6484 theMakeGroup, theMakeNodeGroup)
6485 if theMakeGroup and theMakeNodeGroup:
6488 return twoGroups[ int(theMakeNodeGroup) ]
6489 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6491 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6493 Create a hole in a mesh by doubling the nodes of some particular elements.
6494 This method provided for convenience works as :meth:`DoubleNodes`.
6497 theElems: group of of elements (edges or faces) to replicate
6498 theNodesNot: group of nodes not to replicate
6499 theShape: shape to detect affected elements (element which geometric center
6500 located on or inside shape).
6501 The replicated nodes should be associated to affected elements
6504 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6506 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6507 theMakeGroup=False, theMakeNodeGroup=False):
6509 Create a hole in a mesh by doubling the nodes of some particular elements.
6510 This method provided for convenience works as :meth:`DoubleNodes`.
6513 theElems: list of groups of elements (edges or faces) to replicate
6514 theNodesNot: list of groups of nodes NOT to replicate
6515 theAffectedElems: group of elements to which the replicated nodes
6516 should be associated to
6517 theMakeGroup: forces generation of a group containing new elements.
6518 theMakeNodeGroup: forces generation of a group containing new nodes
6521 True or created groups (one or two) if operation has been completed successfully,
6522 False or None otherwise
6525 if theMakeGroup or theMakeNodeGroup:
6526 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6528 theMakeGroup, theMakeNodeGroup)
6529 if theMakeGroup and theMakeNodeGroup:
6532 return twoGroups[ int(theMakeNodeGroup) ]
6533 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6535 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6537 Create a hole in a mesh by doubling the nodes of some particular elements.
6538 This method provided for convenience works as :meth:`DoubleNodes`.
6541 theElems: list of groups of elements (edges or faces) to replicate
6542 theNodesNot: list of groups of nodes NOT to replicate
6543 theShape: shape to detect affected elements (element which geometric center
6544 located on or inside shape).
6545 The replicated nodes should be associated to affected elements
6548 True if operation has been completed successfully, False otherwise
6551 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6553 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6555 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6556 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6559 theElems: list of groups of nodes or elements (edges or faces) to replicate
6560 theNodesNot: list of groups of nodes NOT to replicate
6561 theShape: shape to detect affected elements (element which geometric center
6562 located on or inside shape).
6563 The replicated nodes should be associated to affected elements
6566 groups of affected elements in order: volumes, faces, edges
6569 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6571 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6574 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6575 The list of groups must describe a partition of the mesh volumes.
6576 The nodes of the internal faces at the boundaries of the groups are doubled.
6577 In option, the internal faces are replaced by flat elements.
6578 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6581 theDomains: list of groups of volumes
6582 createJointElems: if True, create the elements
6583 onAllBoundaries: if True, the nodes and elements are also created on
6584 the boundary between *theDomains* and the rest mesh
6587 True if operation has been completed successfully, False otherwise
6590 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6592 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6594 Double nodes on some external faces and create flat elements.
6595 Flat elements are mainly used by some types of mechanic calculations.
6597 Each group of the list must be constituted of faces.
6598 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6601 theGroupsOfFaces: list of groups of faces
6604 True if operation has been completed successfully, False otherwise
6607 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6609 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6611 Identify all the elements around a geom shape, get the faces delimiting the hole
6613 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6615 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6617 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6618 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6619 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6620 If there are several paths connecting a pair of points, the shortest path is
6621 selected by the module. Position of the cutting plane is defined by the two
6622 points and an optional vector lying on the plane specified by a PolySegment.
6623 By default the vector is defined by Mesh module as following. A middle point
6624 of the two given points is computed. The middle point is projected to the mesh.
6625 The vector goes from the middle point to the projection point. In case of planar
6626 mesh, the vector is normal to the mesh.
6628 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6631 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6632 groupName: optional name of a group where created mesh segments will be added.
6635 editor = self.editor
6637 editor = self.mesh.GetMeshEditPreviewer()
6638 segmentsRes = editor.MakePolyLine( segments, groupName )
6639 for i, seg in enumerate( segmentsRes ):
6640 segments[i].vector = seg.vector
6642 return editor.GetPreviewData()
6645 def GetFunctor(self, funcType ):
6647 Return a cached numerical functor by its type.
6650 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6651 Note that not all items correspond to numerical functors.
6654 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6657 fn = self.functors[ funcType._v ]
6659 fn = self.smeshpyD.GetFunctor(funcType)
6660 fn.SetMesh(self.mesh)
6661 self.functors[ funcType._v ] = fn
6664 def FunctorValue(self, funcType, elemId, isElem=True):
6666 Return value of a functor for a given element
6669 funcType: an item of :class:`SMESH.FunctorType` enum.
6670 elemId: element or node ID
6671 isElem: *elemId* is ID of element or node
6674 the functor value or zero in case of invalid arguments
6677 fn = self.GetFunctor( funcType )
6678 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6679 val = fn.GetValue(elemId)
6684 def GetLength(self, elemId=None):
6686 Get length of 1D element or sum of lengths of all 1D mesh elements
6689 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6692 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6697 length = self.smeshpyD.GetLength(self)
6699 length = self.FunctorValue(SMESH.FT_Length, elemId)
6702 def GetArea(self, elemId=None):
6704 Get area of 2D element or sum of areas of all 2D mesh elements
6705 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6708 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6713 area = self.smeshpyD.GetArea(self)
6715 area = self.FunctorValue(SMESH.FT_Area, elemId)
6718 def GetVolume(self, elemId=None):
6720 Get volume of 3D element or sum of volumes of all 3D mesh elements
6723 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6726 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6731 volume = self.smeshpyD.GetVolume(self)
6733 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6736 def GetMaxElementLength(self, elemId):
6738 Get maximum element length.
6741 elemId: mesh element ID
6744 element's maximum length value
6747 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6748 ftype = SMESH.FT_MaxElementLength3D
6750 ftype = SMESH.FT_MaxElementLength2D
6751 return self.FunctorValue(ftype, elemId)
6753 def GetAspectRatio(self, elemId):
6755 Get aspect ratio of 2D or 3D element.
6758 elemId: mesh element ID
6761 element's aspect ratio value
6764 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6765 ftype = SMESH.FT_AspectRatio3D
6767 ftype = SMESH.FT_AspectRatio
6768 return self.FunctorValue(ftype, elemId)
6770 def GetWarping(self, elemId):
6772 Get warping angle of 2D element.
6775 elemId: mesh element ID
6778 element's warping angle value
6781 return self.FunctorValue(SMESH.FT_Warping, elemId)
6783 def GetMinimumAngle(self, elemId):
6785 Get minimum angle of 2D element.
6788 elemId: mesh element ID
6791 element's minimum angle value
6794 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6796 def GetTaper(self, elemId):
6798 Get taper of 2D element.
6801 elemId: mesh element ID
6804 element's taper value
6807 return self.FunctorValue(SMESH.FT_Taper, elemId)
6809 def GetSkew(self, elemId):
6811 Get skew of 2D element.
6814 elemId: mesh element ID
6817 element's skew value
6820 return self.FunctorValue(SMESH.FT_Skew, elemId)
6822 def GetMinMax(self, funType, meshPart=None):
6824 Return minimal and maximal value of a given functor.
6827 funType (SMESH.FunctorType): a functor type.
6828 Note that not all items of :class:`SMESH.FunctorType` corresponds
6829 to numerical functors.
6830 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6836 unRegister = genObjUnRegister()
6837 if isinstance( meshPart, list ):
6838 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6839 unRegister.set( meshPart )
6840 if isinstance( meshPart, Mesh ):
6841 meshPart = meshPart.mesh
6842 fun = self.GetFunctor( funType )
6845 if hasattr( meshPart, "SetMesh" ):
6846 meshPart.SetMesh( self.mesh ) # set mesh to filter
6847 hist = fun.GetLocalHistogram( 1, False, meshPart )
6849 hist = fun.GetHistogram( 1, False )
6851 return hist[0].min, hist[0].max
6854 pass # end of Mesh class
6857 class meshProxy(SMESH._objref_SMESH_Mesh):
6859 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6860 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6862 def __init__(self,*args):
6863 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6864 def __deepcopy__(self, memo=None):
6865 new = self.__class__(self)
6867 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6868 if len( args ) == 3:
6869 args += SMESH.ALL_NODES, True
6870 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6871 def ExportToMEDX(self, *args): # function removed
6872 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6873 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6874 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6875 def ExportToMED(self, *args): # function removed
6876 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6877 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6878 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6880 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6881 def ExportPartToMED(self, *args): # 'version' parameter removed
6882 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6883 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6884 def ExportMED(self, *args): # signature of method changed
6885 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6886 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6888 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6890 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6893 class submeshProxy(SMESH._objref_SMESH_subMesh):
6896 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6898 def __init__(self,*args):
6899 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6901 def __deepcopy__(self, memo=None):
6902 new = self.__class__(self)
6905 def Compute(self,refresh=False):
6907 Compute the sub-mesh and return the status of the computation
6910 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6915 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6916 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6920 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6922 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6924 if salome.sg.hasDesktop():
6925 if refresh: salome.sg.updateObjBrowser()
6930 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6933 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6935 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6936 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6939 def __init__(self,*args):
6940 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6942 def __getattr__(self, name ): # method called if an attribute not found
6943 if not self.mesh: # look for name() method in Mesh class
6944 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6945 if hasattr( self.mesh, name ):
6946 return getattr( self.mesh, name )
6947 if name == "ExtrusionAlongPathObjX":
6948 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6949 print("meshEditor: attribute '%s' NOT FOUND" % name)
6951 def __deepcopy__(self, memo=None):
6952 new = self.__class__(self)
6954 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6955 if len( args ) == 1: args += False,
6956 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6957 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6958 if len( args ) == 2: args += False,
6959 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6960 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6961 if len( args ) == 1:
6962 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6963 NodesToKeep = args[1]
6964 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6965 unRegister = genObjUnRegister()
6967 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6968 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6969 if not isinstance( NodesToKeep, list ):
6970 NodesToKeep = [ NodesToKeep ]
6971 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6973 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6975 class Pattern(SMESH._objref_SMESH_Pattern):
6977 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6978 variables in some methods
6981 def LoadFromFile(self, patternTextOrFile ):
6982 text = patternTextOrFile
6983 if os.path.exists( text ):
6984 text = open( patternTextOrFile ).read()
6986 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6988 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6989 decrFun = lambda i: i-1
6990 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6991 theMesh.SetParameters(Parameters)
6992 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6994 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6995 decrFun = lambda i: i-1
6996 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6997 theMesh.SetParameters(Parameters)
6998 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7000 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7001 if isinstance( mesh, Mesh ):
7002 mesh = mesh.GetMesh()
7003 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7005 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7007 Registering the new proxy for Pattern
7012 Private class used to bind methods creating algorithms to the class Mesh
7015 def __init__(self, method):
7017 self.defaultAlgoType = ""
7018 self.algoTypeToClass = {}
7019 self.method = method
7021 def add(self, algoClass):
7023 Store a python class of algorithm
7025 if inspect.isclass(algoClass) and \
7026 hasattr( algoClass, "algoType"):
7027 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7028 if not self.defaultAlgoType and \
7029 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7030 self.defaultAlgoType = algoClass.algoType
7031 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7033 def copy(self, mesh):
7035 Create a copy of self and assign mesh to the copy
7038 other = algoCreator( self.method )
7039 other.defaultAlgoType = self.defaultAlgoType
7040 other.algoTypeToClass = self.algoTypeToClass
7044 def __call__(self,algo="",geom=0,*args):
7046 Create an instance of algorithm
7050 if isinstance( algo, str ):
7052 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7053 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7058 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7060 elif not algoType and isinstance( geom, str ):
7065 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7067 elif isinstance( arg, str ) and not algoType:
7070 import traceback, sys
7071 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7072 sys.stderr.write( msg + '\n' )
7073 tb = traceback.extract_stack(None,2)
7074 traceback.print_list( [tb[0]] )
7076 algoType = self.defaultAlgoType
7077 if not algoType and self.algoTypeToClass:
7078 algoType = sorted( self.algoTypeToClass.keys() )[0]
7079 if algoType in self.algoTypeToClass:
7080 #print("Create algo",algoType)
7081 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7082 raise RuntimeError( "No class found for algo type %s" % algoType)
7085 class hypMethodWrapper:
7087 Private class used to substitute and store variable parameters of hypotheses.
7090 def __init__(self, hyp, method):
7092 self.method = method
7093 #print("REBIND:", method.__name__)
7096 def __call__(self,*args):
7098 call a method of hypothesis with calling SetVarParameter() before
7102 return self.method( self.hyp, *args ) # hypothesis method with no args
7104 #print("MethWrapper.__call__", self.method.__name__, args)
7106 parsed = ParseParameters(*args) # replace variables with their values
7107 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7108 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7109 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7110 # maybe there is a replaced string arg which is not variable
7111 result = self.method( self.hyp, *args )
7112 except ValueError as detail: # raised by ParseParameters()
7114 result = self.method( self.hyp, *args )
7115 except omniORB.CORBA.BAD_PARAM:
7116 raise ValueError(detail) # wrong variable name
7121 class genObjUnRegister:
7123 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7126 def __init__(self, genObj=None):
7127 self.genObjList = []
7131 def set(self, genObj):
7132 "Store one or a list of of SALOME.GenericObj'es"
7133 if isinstance( genObj, list ):
7134 self.genObjList.extend( genObj )
7136 self.genObjList.append( genObj )
7140 for genObj in self.genObjList:
7141 if genObj and hasattr( genObj, "UnRegister" ):
7144 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7146 Bind methods creating mesher plug-ins to the Mesh class
7149 # print("pluginName: ", pluginName)
7150 pluginBuilderName = pluginName + "Builder"
7152 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7153 except Exception as e:
7154 from salome_utils import verbose
7155 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7157 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7158 plugin = eval( pluginBuilderName )
7159 # print(" plugin:" , str(plugin))
7161 # add methods creating algorithms to Mesh
7162 for k in dir( plugin ):
7163 if k[0] == '_': continue
7164 algo = getattr( plugin, k )
7165 #print(" algo:", str(algo))
7166 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7167 #print(" meshMethod:" , str(algo.meshMethod))
7168 if not hasattr( Mesh, algo.meshMethod ):
7169 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7171 _mmethod = getattr( Mesh, algo.meshMethod )
7172 if hasattr( _mmethod, "add" ):