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
3684 :meth:`GetMinDistance`
3687 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3688 return aMeasure.value
3690 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3692 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3695 id1: first node/element id
3696 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3697 isElem1: *True* if *id1* is element id, *False* if it is node id
3698 isElem2: *True* if *id2* is element id, *False* if it is node id
3701 :class:`SMESH.Measure` structure
3707 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3709 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3712 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3714 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3719 aMeasurements = self.smeshpyD.CreateMeasurements()
3720 aMeasure = aMeasurements.MinDistance(id1, id2)
3721 genObjUnRegister([aMeasurements,id1, id2])
3724 def BoundingBox(self, objects=None, isElem=False):
3726 Get bounding box of the specified object(s)
3729 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3730 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3731 *False* specifies that *objects* are nodes
3734 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3737 :meth:`GetBoundingBox()`
3740 result = self.GetBoundingBox(objects, isElem)
3744 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3747 def GetBoundingBox(self, objects=None, isElem=False):
3749 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3752 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3753 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3754 False means that *objects* are nodes
3757 :class:`SMESH.Measure` structure
3760 :meth:`BoundingBox()`
3764 objects = [self.mesh]
3765 elif isinstance(objects, tuple):
3766 objects = list(objects)
3767 if not isinstance(objects, list):
3769 if len(objects) > 0 and isinstance(objects[0], int):
3772 unRegister = genObjUnRegister()
3774 if isinstance(o, Mesh):
3775 srclist.append(o.mesh)
3776 elif hasattr(o, "_narrow"):
3777 src = o._narrow(SMESH.SMESH_IDSource)
3778 if src: srclist.append(src)
3780 elif isinstance(o, list):
3782 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3784 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3785 unRegister.set( srclist[-1] )
3788 aMeasurements = self.smeshpyD.CreateMeasurements()
3789 unRegister.set( aMeasurements )
3790 aMeasure = aMeasurements.BoundingBox(srclist)
3793 # Mesh edition (SMESH_MeshEditor functionality):
3794 # ---------------------------------------------
3796 def RemoveElements(self, IDsOfElements):
3798 Remove the elements from the mesh by ids
3801 IDsOfElements: is a list of ids of elements to remove
3807 return self.editor.RemoveElements(IDsOfElements)
3809 def RemoveNodes(self, IDsOfNodes):
3811 Remove nodes from mesh by ids
3814 IDsOfNodes: is a list of ids of nodes to remove
3820 return self.editor.RemoveNodes(IDsOfNodes)
3822 def RemoveOrphanNodes(self):
3824 Remove all orphan (free) nodes from mesh
3827 number of the removed nodes
3830 return self.editor.RemoveOrphanNodes()
3832 def AddNode(self, x, y, z):
3834 Add a node to the mesh by coordinates
3840 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3841 if hasVars: self.mesh.SetParameters(Parameters)
3842 return self.editor.AddNode( x, y, z)
3844 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3846 Create a 0D element on a node with given number.
3849 IDOfNode: the ID of node for creation of the element.
3850 DuplicateElements: to add one more 0D element to a node or not
3853 ID of the new 0D element
3856 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3858 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3860 Create 0D elements on all nodes of the given elements except those
3861 nodes on which a 0D element already exists.
3864 theObject: an object on whose nodes 0D elements will be created.
3865 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3866 theGroupName: optional name of a group to add 0D elements created
3867 and/or found on nodes of *theObject*.
3868 DuplicateElements: to add one more 0D element to a node or not
3871 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3872 IDs of new and/or found 0D elements. IDs of 0D elements
3873 can be retrieved from the returned object by
3874 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3877 unRegister = genObjUnRegister()
3878 if isinstance( theObject, Mesh ):
3879 theObject = theObject.GetMesh()
3880 elif isinstance( theObject, list ):
3881 theObject = self.GetIDSource( theObject, SMESH.ALL )
3882 unRegister.set( theObject )
3883 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3885 def AddBall(self, IDOfNode, diameter):
3887 Create a ball element on a node with given ID.
3890 IDOfNode: the ID of node for creation of the element.
3891 diameter: the bal diameter.
3894 ID of the new ball element
3897 return self.editor.AddBall( IDOfNode, diameter )
3899 def AddEdge(self, IDsOfNodes):
3901 Create a linear or quadratic edge (this is determined
3902 by the number of given nodes).
3905 IDsOfNodes: list of node IDs for creation of the element.
3906 The order of nodes in this list should correspond to
3907 the :ref:`connectivity convention <connectivity_page>`.
3913 return self.editor.AddEdge(IDsOfNodes)
3915 def AddFace(self, IDsOfNodes):
3917 Create a linear or quadratic face (this is determined
3918 by the number of given nodes).
3921 IDsOfNodes: list of node IDs for creation of the element.
3922 The order of nodes in this list should correspond to
3923 the :ref:`connectivity convention <connectivity_page>`.
3929 return self.editor.AddFace(IDsOfNodes)
3931 def AddPolygonalFace(self, IdsOfNodes):
3933 Add a polygonal face defined by a list of node IDs
3936 IdsOfNodes: the list of node IDs for creation of the element.
3942 return self.editor.AddPolygonalFace(IdsOfNodes)
3944 def AddQuadPolygonalFace(self, IdsOfNodes):
3946 Add a quadratic polygonal face defined by a list of node IDs
3949 IdsOfNodes: the list of node IDs for creation of the element;
3950 corner nodes follow first.
3956 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3958 def AddVolume(self, IDsOfNodes):
3960 Create both simple and quadratic volume (this is determined
3961 by the number of given nodes).
3964 IDsOfNodes: list of node IDs for creation of the element.
3965 The order of nodes in this list should correspond to
3966 the :ref:`connectivity convention <connectivity_page>`.
3969 ID of the new volumic element
3972 return self.editor.AddVolume(IDsOfNodes)
3974 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3976 Create a volume of many faces, giving nodes for each face.
3979 IdsOfNodes: list of node IDs for volume creation, face by face.
3980 Quantities: list of integer values, Quantities[i]
3981 gives the quantity of nodes in face number i.
3984 ID of the new volumic element
3987 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3989 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3991 Create a volume of many faces, giving the IDs of the existing faces.
3994 The created volume will refer only to the nodes
3995 of the given faces, not to the faces themselves.
3998 IdsOfFaces: the list of face IDs for volume creation.
4001 ID of the new volumic element
4004 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4007 def SetNodeOnVertex(self, NodeID, Vertex):
4009 Bind a node to a vertex
4013 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4016 True if succeed else raises an exception
4019 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4020 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4024 self.editor.SetNodeOnVertex(NodeID, VertexID)
4025 except SALOME.SALOME_Exception as inst:
4026 raise ValueError(inst.details.text)
4030 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4032 Store the node position on an edge
4036 Edge: an edge (GEOM.GEOM_Object) or edge ID
4037 paramOnEdge: a parameter on the edge where the node is located
4040 True if succeed else raises an exception
4043 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4044 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4048 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4049 except SALOME.SALOME_Exception as inst:
4050 raise ValueError(inst.details.text)
4053 def SetNodeOnFace(self, NodeID, Face, u, v):
4055 Store node position on a face
4059 Face: a face (GEOM.GEOM_Object) or face ID
4060 u: U parameter on the face where the node is located
4061 v: V parameter on the face where the node is located
4064 True if succeed else raises an exception
4067 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4068 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4072 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4073 except SALOME.SALOME_Exception as inst:
4074 raise ValueError(inst.details.text)
4077 def SetNodeInVolume(self, NodeID, Solid):
4079 Bind a node to a solid
4083 Solid: a solid (GEOM.GEOM_Object) or solid ID
4086 True if succeed else raises an exception
4089 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4090 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4094 self.editor.SetNodeInVolume(NodeID, SolidID)
4095 except SALOME.SALOME_Exception as inst:
4096 raise ValueError(inst.details.text)
4099 def SetMeshElementOnShape(self, ElementID, Shape):
4101 Bind an element to a shape
4104 ElementID: an element ID
4105 Shape: a shape (GEOM.GEOM_Object) or shape ID
4108 True if succeed else raises an exception
4111 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4112 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4116 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4117 except SALOME.SALOME_Exception as inst:
4118 raise ValueError(inst.details.text)
4122 def MoveNode(self, NodeID, x, y, z):
4124 Move the node with the given id
4127 NodeID: the id of the node
4128 x: a new X coordinate
4129 y: a new Y coordinate
4130 z: a new Z coordinate
4133 True if succeed else False
4136 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4137 if hasVars: self.mesh.SetParameters(Parameters)
4138 return self.editor.MoveNode(NodeID, x, y, z)
4140 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4142 Find the node closest to a point and moves it to a point location
4145 x: the X coordinate of a point
4146 y: the Y coordinate of a point
4147 z: the Z coordinate of a point
4148 NodeID: if specified (>0), the node with this ID is moved,
4149 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4152 the ID of a moved node
4155 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4156 if hasVars: self.mesh.SetParameters(Parameters)
4157 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4159 def FindNodeClosestTo(self, x, y, z):
4161 Find the node closest to a point
4164 x: the X coordinate of a point
4165 y: the Y coordinate of a point
4166 z: the Z coordinate of a point
4172 #preview = self.mesh.GetMeshEditPreviewer()
4173 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4174 return self.editor.FindNodeClosestTo(x, y, z)
4176 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4178 Find the elements where a point lays IN or ON
4181 x,y,z (float): coordinates of the point
4182 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4183 means elements of any type excluding nodes, discrete and 0D elements.
4184 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4187 list of IDs of found elements
4190 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4192 return self.editor.FindElementsByPoint(x, y, z, elementType)
4194 def GetPointState(self, x, y, z):
4196 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4197 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4198 UNKNOWN state means that either mesh is wrong or the analysis fails.
4201 return self.editor.GetPointState(x, y, z)
4203 def IsManifold(self):
4205 Check if a 2D mesh is manifold
4208 return self.editor.IsManifold()
4210 def IsCoherentOrientation2D(self):
4212 Check if orientation of 2D elements is coherent
4215 return self.editor.IsCoherentOrientation2D()
4217 def MeshToPassThroughAPoint(self, x, y, z):
4219 Find the node closest to a point and moves it to a point location
4222 x: the X coordinate of a point
4223 y: the Y coordinate of a point
4224 z: the Z coordinate of a point
4227 the ID of a moved node
4230 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4232 def InverseDiag(self, NodeID1, NodeID2):
4234 Replace two neighbour triangles sharing Node1-Node2 link
4235 with the triangles built on the same 4 nodes but having other common link.
4238 NodeID1: the ID of the first node
4239 NodeID2: the ID of the second node
4242 False if proper faces were not found
4244 return self.editor.InverseDiag(NodeID1, NodeID2)
4246 def DeleteDiag(self, NodeID1, NodeID2):
4248 Replace two neighbour triangles sharing *Node1-Node2* link
4249 with a quadrangle built on the same 4 nodes.
4252 NodeID1: ID of the first node
4253 NodeID2: ID of the second node
4256 False if proper faces were not found
4259 return self.editor.DeleteDiag(NodeID1, NodeID2)
4261 def Reorient(self, IDsOfElements=None):
4263 Reorient elements by ids
4266 IDsOfElements: if undefined reorients all mesh elements
4269 True if succeed else False
4272 if IDsOfElements == None:
4273 IDsOfElements = self.GetElementsId()
4274 return self.editor.Reorient(IDsOfElements)
4276 def ReorientObject(self, theObject):
4278 Reorient all elements of the object
4281 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4284 True if succeed else False
4287 if ( isinstance( theObject, Mesh )):
4288 theObject = theObject.GetMesh()
4289 return self.editor.ReorientObject(theObject)
4291 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4293 Reorient faces contained in *the2DObject*.
4296 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4297 theDirection: is a desired direction of normal of *theFace*.
4298 It can be either a GEOM vector or a list of coordinates [x,y,z].
4299 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4300 compared with theDirection. It can be either ID of face or a point
4301 by which the face will be found. The point can be given as either
4302 a GEOM vertex or a list of point coordinates.
4305 number of reoriented faces
4308 unRegister = genObjUnRegister()
4310 if isinstance( the2DObject, Mesh ):
4311 the2DObject = the2DObject.GetMesh()
4312 if isinstance( the2DObject, list ):
4313 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4314 unRegister.set( the2DObject )
4315 # check theDirection
4316 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4317 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4318 if isinstance( theDirection, list ):
4319 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4320 # prepare theFace and thePoint
4321 theFace = theFaceOrPoint
4322 thePoint = PointStruct(0,0,0)
4323 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4324 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4326 if isinstance( theFaceOrPoint, list ):
4327 thePoint = PointStruct( *theFaceOrPoint )
4329 if isinstance( theFaceOrPoint, PointStruct ):
4330 thePoint = theFaceOrPoint
4332 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4334 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4336 Reorient faces according to adjacent volumes.
4339 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4340 either IDs of faces or face groups.
4341 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4342 theOutsideNormal: to orient faces to have their normals
4343 pointing either *outside* or *inside* the adjacent volumes.
4346 number of reoriented faces.
4349 unRegister = genObjUnRegister()
4351 if not isinstance( the2DObject, list ):
4352 the2DObject = [ the2DObject ]
4353 elif the2DObject and isinstance( the2DObject[0], int ):
4354 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4355 unRegister.set( the2DObject )
4356 the2DObject = [ the2DObject ]
4357 for i,obj2D in enumerate( the2DObject ):
4358 if isinstance( obj2D, Mesh ):
4359 the2DObject[i] = obj2D.GetMesh()
4360 if isinstance( obj2D, list ):
4361 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4362 unRegister.set( the2DObject[i] )
4364 if isinstance( the3DObject, Mesh ):
4365 the3DObject = the3DObject.GetMesh()
4366 if isinstance( the3DObject, list ):
4367 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4368 unRegister.set( the3DObject )
4369 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4371 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4373 Fuse the neighbouring triangles into quadrangles.
4376 IDsOfElements: The triangles to be fused.
4377 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4378 applied to possible quadrangles to choose a neighbour to fuse with.
4379 Note that not all items of :class:`SMESH.FunctorType` corresponds
4380 to numerical functors.
4381 MaxAngle: is the maximum angle between element normals at which the fusion
4382 is still performed; theMaxAngle is measured in radians.
4383 Also it could be a name of variable which defines angle in degrees.
4386 True in case of success, False otherwise.
4389 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4390 self.mesh.SetParameters(Parameters)
4391 if not IDsOfElements:
4392 IDsOfElements = self.GetElementsId()
4393 Functor = self.smeshpyD.GetFunctor(theCriterion)
4394 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4396 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4398 Fuse the neighbouring triangles of the object into quadrangles
4401 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4402 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4403 applied to possible quadrangles to choose a neighbour to fuse with.
4404 Note that not all items of :class:`SMESH.FunctorType` corresponds
4405 to numerical functors.
4406 MaxAngle: a max angle between element normals at which the fusion
4407 is still performed; theMaxAngle is measured in radians.
4410 True in case of success, False otherwise.
4413 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4414 self.mesh.SetParameters(Parameters)
4415 if isinstance( theObject, Mesh ):
4416 theObject = theObject.GetMesh()
4417 Functor = self.smeshpyD.GetFunctor(theCriterion)
4418 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4420 def QuadToTri (self, IDsOfElements, theCriterion = None):
4422 Split quadrangles into triangles.
4425 IDsOfElements: the faces to be splitted.
4426 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4427 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4428 value, then quadrangles will be split by the smallest diagonal.
4429 Note that not all items of :class:`SMESH.FunctorType` corresponds
4430 to numerical functors.
4433 True in case of success, False otherwise.
4435 if IDsOfElements == []:
4436 IDsOfElements = self.GetElementsId()
4437 if theCriterion is None:
4438 theCriterion = FT_MaxElementLength2D
4439 Functor = self.smeshpyD.GetFunctor(theCriterion)
4440 return self.editor.QuadToTri(IDsOfElements, Functor)
4442 def QuadToTriObject (self, theObject, theCriterion = None):
4444 Split quadrangles into triangles.
4447 theObject: the object from which the list of elements is taken,
4448 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4449 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4450 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4451 value, then quadrangles will be split by the smallest diagonal.
4452 Note that not all items of :class:`SMESH.FunctorType` corresponds
4453 to numerical functors.
4456 True in case of success, False otherwise.
4458 if ( isinstance( theObject, Mesh )):
4459 theObject = theObject.GetMesh()
4460 if theCriterion is None:
4461 theCriterion = FT_MaxElementLength2D
4462 Functor = self.smeshpyD.GetFunctor(theCriterion)
4463 return self.editor.QuadToTriObject(theObject, Functor)
4465 def QuadTo4Tri (self, theElements=[]):
4467 Split each of given quadrangles into 4 triangles. A node is added at the center of
4471 theElements: the faces to be splitted. This can be either
4472 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4473 or a list of face IDs. By default all quadrangles are split
4475 unRegister = genObjUnRegister()
4476 if isinstance( theElements, Mesh ):
4477 theElements = theElements.mesh
4478 elif not theElements:
4479 theElements = self.mesh
4480 elif isinstance( theElements, list ):
4481 theElements = self.GetIDSource( theElements, SMESH.FACE )
4482 unRegister.set( theElements )
4483 return self.editor.QuadTo4Tri( theElements )
4485 def SplitQuad (self, IDsOfElements, Diag13):
4487 Split quadrangles into triangles.
4490 IDsOfElements: the faces to be splitted
4491 Diag13: is used to choose a diagonal for splitting.
4494 True in case of success, False otherwise.
4496 if IDsOfElements == []:
4497 IDsOfElements = self.GetElementsId()
4498 return self.editor.SplitQuad(IDsOfElements, Diag13)
4500 def SplitQuadObject (self, theObject, Diag13):
4502 Split quadrangles into triangles.
4505 theObject: the object from which the list of elements is taken,
4506 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4507 Diag13: is used to choose a diagonal for splitting.
4510 True in case of success, False otherwise.
4512 if ( isinstance( theObject, Mesh )):
4513 theObject = theObject.GetMesh()
4514 return self.editor.SplitQuadObject(theObject, Diag13)
4516 def BestSplit (self, IDOfQuad, theCriterion):
4518 Find a better splitting of the given quadrangle.
4521 IDOfQuad: the ID of the quadrangle to be splitted.
4522 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4523 choose a diagonal for splitting.
4524 Note that not all items of :class:`SMESH.FunctorType` corresponds
4525 to numerical functors.
4528 * 1 if 1-3 diagonal is better,
4529 * 2 if 2-4 diagonal is better,
4530 * 0 if error occurs.
4532 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4534 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4536 Split volumic elements into tetrahedrons
4539 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4540 method: flags passing splitting method:
4541 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4542 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4544 unRegister = genObjUnRegister()
4545 if isinstance( elems, Mesh ):
4546 elems = elems.GetMesh()
4547 if ( isinstance( elems, list )):
4548 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4549 unRegister.set( elems )
4550 self.editor.SplitVolumesIntoTetra(elems, method)
4553 def SplitBiQuadraticIntoLinear(self, elems=None):
4555 Split bi-quadratic elements into linear ones without creation of additional nodes:
4557 - bi-quadratic triangle will be split into 3 linear quadrangles;
4558 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4559 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4561 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4562 will be split in order to keep the mesh conformal.
4565 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4566 if None (default), all bi-quadratic elements will be split
4568 unRegister = genObjUnRegister()
4569 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4570 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4571 unRegister.set( elems )
4573 elems = [ self.GetMesh() ]
4574 if isinstance( elems, Mesh ):
4575 elems = [ elems.GetMesh() ]
4576 if not isinstance( elems, list ):
4578 self.editor.SplitBiQuadraticIntoLinear( elems )
4580 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4581 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4583 Split hexahedra into prisms
4586 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4587 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4588 gives a normal vector defining facets to split into triangles.
4589 *startHexPoint* can be either a triple of coordinates or a vertex.
4590 facetNormal: a normal to a facet to split into triangles of a
4591 hexahedron found by *startHexPoint*.
4592 *facetNormal* can be either a triple of coordinates or an edge.
4593 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4594 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4595 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4596 to *startHexPoint* are split, else *startHexPoint*
4597 is used to find the facet to split in all domains present in *elems*.
4600 unRegister = genObjUnRegister()
4601 if isinstance( elems, Mesh ):
4602 elems = elems.GetMesh()
4603 if ( isinstance( elems, list )):
4604 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4605 unRegister.set( elems )
4608 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4609 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4610 elif isinstance( startHexPoint, list ):
4611 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4614 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4615 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4616 elif isinstance( facetNormal, list ):
4617 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4620 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4622 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4624 def SplitQuadsNearTriangularFacets(self):
4626 Split quadrangle faces near triangular facets of volumes
4628 faces_array = self.GetElementsByType(SMESH.FACE)
4629 for face_id in faces_array:
4630 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4631 quad_nodes = self.mesh.GetElemNodes(face_id)
4632 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4633 isVolumeFound = False
4634 for node1_elem in node1_elems:
4635 if not isVolumeFound:
4636 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4637 nb_nodes = self.GetElemNbNodes(node1_elem)
4638 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4639 volume_elem = node1_elem
4640 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4641 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4642 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4643 isVolumeFound = True
4644 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4645 self.SplitQuad([face_id], False) # diagonal 2-4
4646 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4647 isVolumeFound = True
4648 self.SplitQuad([face_id], True) # diagonal 1-3
4649 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4650 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4651 isVolumeFound = True
4652 self.SplitQuad([face_id], True) # diagonal 1-3
4654 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4656 Split hexahedrons into tetrahedrons.
4658 This operation uses :doc:`pattern_mapping` functionality for splitting.
4661 theObject: the object from which the list of hexahedrons is taken;
4662 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4663 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4664 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4665 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4666 key-point will be mapped into *theNode001*-th node of each volume.
4667 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4670 True in case of success, False otherwise.
4678 # (0,0,1) 4.---------.7 * |
4685 # (0,0,0) 0.---------.3
4686 pattern_tetra = "!!! Nb of points: \n 8 \n\
4696 !!! Indices of points of 6 tetras: \n\
4704 pattern = self.smeshpyD.GetPattern()
4705 isDone = pattern.LoadFromFile(pattern_tetra)
4707 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4710 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4711 isDone = pattern.MakeMesh(self.mesh, False, False)
4712 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4714 # split quafrangle faces near triangular facets of volumes
4715 self.SplitQuadsNearTriangularFacets()
4719 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4721 Split hexahedrons into prisms.
4723 Uses the :doc:`pattern_mapping` functionality for splitting.
4726 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4727 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4728 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4729 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4730 will be mapped into the *theNode001* -th node of each volume.
4731 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4734 True in case of success, False otherwise.
4736 # Pattern: 5.---------.6
4741 # (0,0,1) 4.---------.7 |
4748 # (0,0,0) 0.---------.3
4749 pattern_prism = "!!! Nb of points: \n 8 \n\
4759 !!! Indices of points of 2 prisms: \n\
4763 pattern = self.smeshpyD.GetPattern()
4764 isDone = pattern.LoadFromFile(pattern_prism)
4766 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4769 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4770 isDone = pattern.MakeMesh(self.mesh, False, False)
4771 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4773 # Split quafrangle faces near triangular facets of volumes
4774 self.SplitQuadsNearTriangularFacets()
4778 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4779 MaxNbOfIterations, MaxAspectRatio, Method):
4784 IDsOfElements: the list if ids of elements to smooth
4785 IDsOfFixedNodes: the list of ids of fixed nodes.
4786 Note that nodes built on edges and boundary nodes are always fixed.
4787 MaxNbOfIterations: the maximum number of iterations
4788 MaxAspectRatio: varies in range [1.0, inf]
4789 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4790 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4793 True in case of success, False otherwise.
4796 if IDsOfElements == []:
4797 IDsOfElements = self.GetElementsId()
4798 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4799 self.mesh.SetParameters(Parameters)
4800 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4801 MaxNbOfIterations, MaxAspectRatio, Method)
4803 def SmoothObject(self, theObject, IDsOfFixedNodes,
4804 MaxNbOfIterations, MaxAspectRatio, Method):
4806 Smooth elements which belong to the given object
4809 theObject: the object to smooth
4810 IDsOfFixedNodes: the list of ids of fixed nodes.
4811 Note that nodes built on edges and boundary nodes are always fixed.
4812 MaxNbOfIterations: the maximum number of iterations
4813 MaxAspectRatio: varies in range [1.0, inf]
4814 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4815 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4818 True in case of success, False otherwise.
4821 if ( isinstance( theObject, Mesh )):
4822 theObject = theObject.GetMesh()
4823 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4824 MaxNbOfIterations, MaxAspectRatio, Method)
4826 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4827 MaxNbOfIterations, MaxAspectRatio, Method):
4829 Parametrically smooth the given elements
4832 IDsOfElements: the list if ids of elements to smooth
4833 IDsOfFixedNodes: the list of ids of fixed nodes.
4834 Note that nodes built on edges and boundary nodes are always fixed.
4835 MaxNbOfIterations: the maximum number of iterations
4836 MaxAspectRatio: varies in range [1.0, inf]
4837 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4838 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4841 True in case of success, False otherwise.
4844 if IDsOfElements == []:
4845 IDsOfElements = self.GetElementsId()
4846 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4847 self.mesh.SetParameters(Parameters)
4848 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4849 MaxNbOfIterations, MaxAspectRatio, Method)
4851 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4852 MaxNbOfIterations, MaxAspectRatio, Method):
4854 Parametrically smooth the elements which belong to the given object
4857 theObject: the object to smooth
4858 IDsOfFixedNodes: the list of ids of fixed nodes.
4859 Note that nodes built on edges and boundary nodes are always fixed.
4860 MaxNbOfIterations: the maximum number of iterations
4861 MaxAspectRatio: varies in range [1.0, inf]
4862 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4863 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4866 True in case of success, False otherwise.
4869 if ( isinstance( theObject, Mesh )):
4870 theObject = theObject.GetMesh()
4871 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4872 MaxNbOfIterations, MaxAspectRatio, Method)
4874 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4876 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4877 them with quadratic with the same id.
4880 theForce3d: method of new node creation:
4882 * False - the medium node lies at the geometrical entity from which the mesh element is built
4883 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4884 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4885 theToBiQuad: If True, converts the mesh to bi-quadratic
4888 :class:`SMESH.ComputeError` which can hold a warning
4891 If *theSubMesh* is provided, the mesh can become non-conformal
4894 if isinstance( theSubMesh, Mesh ):
4895 theSubMesh = theSubMesh.mesh
4897 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4900 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4902 self.editor.ConvertToQuadratic(theForce3d)
4903 error = self.editor.GetLastError()
4904 if error and error.comment:
4905 print(error.comment)
4908 def ConvertFromQuadratic(self, theSubMesh=None):
4910 Convert the mesh from quadratic to ordinary,
4911 deletes old quadratic elements,
4912 replacing them with ordinary mesh elements with the same id.
4915 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4918 If *theSubMesh* is provided, the mesh can become non-conformal
4922 self.editor.ConvertFromQuadraticObject(theSubMesh)
4924 return self.editor.ConvertFromQuadratic()
4926 def Make2DMeshFrom3D(self):
4928 Create 2D mesh as skin on boundary faces of a 3D mesh
4931 True if operation has been completed successfully, False otherwise
4934 return self.editor.Make2DMeshFrom3D()
4936 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4937 toCopyElements=False, toCopyExistingBondary=False):
4939 Create missing boundary elements
4942 elements: elements whose boundary is to be checked:
4943 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4944 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4945 dimension: defines type of boundary elements to create, either of
4946 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4947 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4948 groupName: a name of group to store created boundary elements in,
4949 "" means not to create the group
4950 meshName: a name of new mesh to store created boundary elements in,
4951 "" means not to create the new mesh
4952 toCopyElements: if True, the checked elements will be copied into
4953 the new mesh else only boundary elements will be copied into the new mesh
4954 toCopyExistingBondary: if True, not only new but also pre-existing
4955 boundary elements will be copied into the new mesh
4958 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4961 unRegister = genObjUnRegister()
4962 if isinstance( elements, Mesh ):
4963 elements = elements.GetMesh()
4964 if ( isinstance( elements, list )):
4965 elemType = SMESH.ALL
4966 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4967 elements = self.editor.MakeIDSource(elements, elemType)
4968 unRegister.set( elements )
4969 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4970 toCopyElements,toCopyExistingBondary)
4971 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4974 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4975 toCopyAll=False, groups=[]):
4977 Create missing boundary elements around either the whole mesh or
4981 dimension: defines type of boundary elements to create, either of
4982 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4983 groupName: a name of group to store all boundary elements in,
4984 "" means not to create the group
4985 meshName: a name of a new mesh, which is a copy of the initial
4986 mesh + created boundary elements; "" means not to create the new mesh
4987 toCopyAll: if True, the whole initial mesh will be copied into
4988 the new mesh else only boundary elements will be copied into the new mesh
4989 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4992 tuple( long, mesh, groups )
4993 - long - number of added boundary elements
4994 - mesh - the :class:`Mesh` where elements were added to
4995 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4998 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5000 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5001 return nb, mesh, group
5003 def RenumberNodes(self):
5005 Renumber mesh nodes to remove unused node IDs
5007 self.editor.RenumberNodes()
5009 def RenumberElements(self):
5011 Renumber mesh elements to remove unused element IDs
5013 self.editor.RenumberElements()
5015 def _getIdSourceList(self, arg, idType, unRegister):
5017 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5019 if arg and isinstance( arg, list ):
5020 if isinstance( arg[0], int ):
5021 arg = self.GetIDSource( arg, idType )
5022 unRegister.set( arg )
5023 elif isinstance( arg[0], Mesh ):
5024 arg[0] = arg[0].GetMesh()
5025 elif isinstance( arg, Mesh ):
5027 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5031 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5032 MakeGroups=False, TotalAngle=False):
5034 Generate new elements by rotation of the given elements and nodes around the axis
5037 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5038 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5039 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5040 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5041 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5042 which defines angle in degrees
5043 NbOfSteps: the number of steps
5044 Tolerance: tolerance
5045 MakeGroups: forces the generation of new groups from existing ones
5046 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5047 of all steps, else - size of each step
5050 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5053 unRegister = genObjUnRegister()
5054 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5055 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5056 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5058 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5059 Axis = self.smeshpyD.GetAxisStruct( Axis )
5060 if isinstance( Axis, list ):
5061 Axis = SMESH.AxisStruct( *Axis )
5063 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5064 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5065 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5066 self.mesh.SetParameters(Parameters)
5067 if TotalAngle and NbOfSteps:
5068 AngleInRadians /= NbOfSteps
5069 return self.editor.RotationSweepObjects( nodes, edges, faces,
5070 Axis, AngleInRadians,
5071 NbOfSteps, Tolerance, MakeGroups)
5073 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5074 MakeGroups=False, TotalAngle=False):
5076 Generate new elements by rotation of the elements around the axis
5079 IDsOfElements: the list of ids of elements to sweep
5080 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5081 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5082 NbOfSteps: the number of steps
5083 Tolerance: tolerance
5084 MakeGroups: forces the generation of new groups from existing ones
5085 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5086 of all steps, else - size of each step
5089 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5092 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5093 AngleInRadians, NbOfSteps, Tolerance,
5094 MakeGroups, TotalAngle)
5096 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5097 MakeGroups=False, TotalAngle=False):
5099 Generate new elements by rotation of the elements of object around the axis
5100 theObject object which elements should be sweeped.
5101 It can be a mesh, a sub mesh or a group.
5104 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5105 AngleInRadians: the angle of Rotation
5106 NbOfSteps: number of steps
5107 Tolerance: tolerance
5108 MakeGroups: forces the generation of new groups from existing ones
5109 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5110 of all steps, else - size of each step
5113 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5116 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5117 AngleInRadians, NbOfSteps, Tolerance,
5118 MakeGroups, TotalAngle )
5120 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5121 MakeGroups=False, TotalAngle=False):
5123 Generate new elements by rotation of the elements of object around the axis
5124 theObject object which elements should be sweeped.
5125 It can be a mesh, a sub mesh or a group.
5128 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5129 AngleInRadians: the angle of Rotation
5130 NbOfSteps: number of steps
5131 Tolerance: tolerance
5132 MakeGroups: forces the generation of new groups from existing ones
5133 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5134 of all steps, else - size of each step
5137 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5138 empty list otherwise
5141 return self.RotationSweepObjects([],theObject,[], Axis,
5142 AngleInRadians, NbOfSteps, Tolerance,
5143 MakeGroups, TotalAngle)
5145 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5146 MakeGroups=False, TotalAngle=False):
5148 Generate new elements by rotation of the elements of object around the axis
5149 theObject object which elements should be sweeped.
5150 It can be a mesh, a sub mesh or a group.
5153 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5154 AngleInRadians: the angle of Rotation
5155 NbOfSteps: number of steps
5156 Tolerance: tolerance
5157 MakeGroups: forces the generation of new groups from existing ones
5158 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5159 of all steps, else - size of each step
5162 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5165 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5166 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5168 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5169 scaleFactors=[], linearVariation=False, basePoint=[] ):
5171 Generate new elements by extrusion of the given elements and nodes
5174 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5175 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5176 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5177 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5178 the direction and value of extrusion for one step (the total extrusion
5179 length will be NbOfSteps * ||StepVector||)
5180 NbOfSteps: the number of steps
5181 MakeGroups: forces the generation of new groups from existing ones
5182 scaleFactors: optional scale factors to apply during extrusion
5183 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5184 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5185 basePoint: optional scaling center; if not provided, a gravity center of
5186 nodes and elements being extruded is used as the scaling center.
5189 - a list of tree components of the point or
5193 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5195 Example: :ref:`tui_extrusion`
5197 unRegister = genObjUnRegister()
5198 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5199 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5200 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5202 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5203 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5204 if isinstance( StepVector, list ):
5205 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5207 if isinstance( basePoint, int):
5208 xyz = self.GetNodeXYZ( basePoint )
5210 raise RuntimeError("Invalid node ID: %s" % basePoint)
5212 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5213 basePoint = self.geompyD.PointCoordinates( basePoint )
5215 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5216 Parameters = StepVector.PS.parameters + var_separator + Parameters
5217 self.mesh.SetParameters(Parameters)
5219 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5220 StepVector, NbOfSteps,
5221 scaleFactors, linearVariation, basePoint,
5225 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5227 Generate new elements by extrusion of the elements with given ids
5230 IDsOfElements: the list of ids of elements or nodes for extrusion
5231 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5232 the direction and value of extrusion for one step (the total extrusion
5233 length will be NbOfSteps * ||StepVector||)
5234 NbOfSteps: the number of steps
5235 MakeGroups: forces the generation of new groups from existing ones
5236 IsNodes: is True if elements with given ids are nodes
5239 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5241 Example: :ref:`tui_extrusion`
5244 if IsNodes: n = IDsOfElements
5245 else : e,f, = IDsOfElements,IDsOfElements
5246 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5248 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5249 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5251 Generate new elements by extrusion along the normal to a discretized surface or wire
5254 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5255 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5256 StepSize: length of one extrusion step (the total extrusion
5257 length will be *NbOfSteps* *StepSize*).
5258 NbOfSteps: number of extrusion steps.
5259 ByAverageNormal: if True each node is translated by *StepSize*
5260 along the average of the normal vectors to the faces sharing the node;
5261 else each node is translated along the same average normal till
5262 intersection with the plane got by translation of the face sharing
5263 the node along its own normal by *StepSize*.
5264 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5265 for every node of *Elements*.
5266 MakeGroups: forces generation of new groups from existing ones.
5267 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5268 is not yet implemented. This parameter is used if *Elements* contains
5269 both faces and edges, i.e. *Elements* is a Mesh.
5272 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5273 empty list otherwise.
5274 Example: :ref:`tui_extrusion`
5277 unRegister = genObjUnRegister()
5278 if isinstance( Elements, Mesh ):
5279 Elements = [ Elements.GetMesh() ]
5280 if isinstance( Elements, list ):
5282 raise RuntimeError("Elements empty!")
5283 if isinstance( Elements[0], int ):
5284 Elements = self.GetIDSource( Elements, SMESH.ALL )
5285 unRegister.set( Elements )
5286 if not isinstance( Elements, list ):
5287 Elements = [ Elements ]
5288 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5289 self.mesh.SetParameters(Parameters)
5290 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5291 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5293 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5295 Generate new elements by extrusion of the elements or nodes which belong to the object
5298 theObject: the object whose elements or nodes should be processed.
5299 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5300 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5301 the direction and value of extrusion for one step (the total extrusion
5302 length will be NbOfSteps * ||StepVector||)
5303 NbOfSteps: the number of steps
5304 MakeGroups: forces the generation of new groups from existing ones
5305 IsNodes: is True if elements to extrude are nodes
5308 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5309 Example: :ref:`tui_extrusion`
5313 if IsNodes: n = theObject
5314 else : e,f, = theObject,theObject
5315 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5317 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5319 Generate new elements by extrusion of edges which belong to the object
5322 theObject: object whose 1D elements should be processed.
5323 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5324 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5325 the direction and value of extrusion for one step (the total extrusion
5326 length will be NbOfSteps * ||StepVector||)
5327 NbOfSteps: the number of steps
5328 MakeGroups: to generate new groups from existing ones
5331 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5332 Example: :ref:`tui_extrusion`
5335 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5337 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5339 Generate new elements by extrusion of faces which belong to the object
5342 theObject: object whose 2D elements should be processed.
5343 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5344 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5345 the direction and value of extrusion for one step (the total extrusion
5346 length will be NbOfSteps * ||StepVector||)
5347 NbOfSteps: the number of steps
5348 MakeGroups: forces the generation of new groups from existing ones
5351 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5352 Example: :ref:`tui_extrusion`
5355 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5357 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5358 ExtrFlags, SewTolerance, MakeGroups=False):
5360 Generate new elements by extrusion of the elements with given ids
5363 IDsOfElements: is ids of elements
5364 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5365 the direction and value of extrusion for one step (the total extrusion
5366 length will be NbOfSteps * ||StepVector||)
5367 NbOfSteps: the number of steps
5368 ExtrFlags: sets flags for extrusion
5369 SewTolerance: uses for comparing locations of nodes if flag
5370 EXTRUSION_FLAG_SEW is set
5371 MakeGroups: forces the generation of new groups from existing ones
5374 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5377 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5378 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5379 if isinstance( StepVector, list ):
5380 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5381 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5382 ExtrFlags, SewTolerance, MakeGroups)
5384 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5385 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5386 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5388 Generate new elements by extrusion of the given elements and nodes along the path.
5389 The path of extrusion must be a meshed edge.
5392 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5393 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5394 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5395 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5396 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5397 contains not only path segments, else it can be None
5398 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5399 HasAngles: allows the shape to be rotated around the path
5400 to get the resulting mesh in a helical fashion
5401 Angles: list of angles
5402 LinearVariation: forces the computation of rotation angles as linear
5403 variation of the given Angles along path steps
5404 HasRefPoint: allows using the reference point
5405 RefPoint: the reference point around which the shape is rotated (the mass center of the
5406 shape by default). The User can specify any point as the Reference Point.
5407 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5408 MakeGroups: forces the generation of new groups from existing ones
5411 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5412 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5413 Example: :ref:`tui_extrusion_along_path`
5416 unRegister = genObjUnRegister()
5417 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5418 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5419 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5421 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5422 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5423 if isinstance( RefPoint, list ):
5424 if not RefPoint: RefPoint = [0,0,0]
5425 RefPoint = SMESH.PointStruct( *RefPoint )
5426 if isinstance( PathMesh, Mesh ):
5427 PathMesh = PathMesh.GetMesh()
5428 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5429 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5430 self.mesh.SetParameters(Parameters)
5431 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5432 PathMesh, PathShape, NodeStart,
5433 HasAngles, Angles, LinearVariation,
5434 HasRefPoint, RefPoint, MakeGroups)
5436 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5437 HasAngles=False, Angles=[], LinearVariation=False,
5438 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5439 ElemType=SMESH.FACE):
5441 Generate new elements by extrusion of the given elements.
5442 The path of extrusion must be a meshed edge.
5445 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5446 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5447 NodeStart: the start node from Path. Defines the direction of extrusion
5448 HasAngles: allows the shape to be rotated around the path
5449 to get the resulting mesh in a helical fashion
5450 Angles: list of angles in radians
5451 LinearVariation: forces the computation of rotation angles as linear
5452 variation of the given Angles along path steps
5453 HasRefPoint: allows using the reference point
5454 RefPoint: the reference point around which the elements are rotated (the mass
5455 center of the elements by default).
5456 The User can specify any point as the Reference Point.
5457 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5458 MakeGroups: forces the generation of new groups from existing ones
5459 ElemType: type of elements for extrusion (if param Base is a mesh)
5462 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5463 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5464 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5466 Example: :ref:`tui_extrusion_along_path`
5470 if ElemType == SMESH.NODE: n = Base
5471 if ElemType == SMESH.EDGE: e = Base
5472 if ElemType == SMESH.FACE: f = Base
5473 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5474 HasAngles, Angles, LinearVariation,
5475 HasRefPoint, RefPoint, MakeGroups)
5476 if MakeGroups: return gr,er
5479 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5480 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5481 MakeGroups=False, LinearVariation=False):
5483 Generate new elements by extrusion of the given elements.
5484 The path of extrusion must be a meshed edge.
5487 IDsOfElements: ids of elements
5488 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5489 PathShape: shape (edge) defines the sub-mesh for the path
5490 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5491 HasAngles: allows the shape to be rotated around the path
5492 to get the resulting mesh in a helical fashion
5493 Angles: list of angles in radians
5494 HasRefPoint: allows using the reference point
5495 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5496 The User can specify any point as the Reference Point.
5497 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5498 MakeGroups: forces the generation of new groups from existing ones
5499 LinearVariation: forces the computation of rotation angles as linear
5500 variation of the given Angles along path steps
5503 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5504 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5505 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5506 Example: :ref:`tui_extrusion_along_path`
5509 n,e,f = [],IDsOfElements,IDsOfElements
5510 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5511 NodeStart, HasAngles, Angles,
5513 HasRefPoint, RefPoint, MakeGroups)
5514 if MakeGroups: return gr,er
5517 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5518 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5519 MakeGroups=False, LinearVariation=False):
5521 Generate new elements by extrusion of the elements which belong to the object.
5522 The path of extrusion must be a meshed edge.
5525 theObject: the object whose elements should be processed.
5526 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5527 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5528 PathShape: shape (edge) defines the sub-mesh for the path
5529 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5530 HasAngles: allows the shape to be rotated around the path
5531 to get the resulting mesh in a helical fashion
5532 Angles: list of angles
5533 HasRefPoint: allows using the reference point
5534 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5535 The User can specify any point as the Reference Point.
5536 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5537 MakeGroups: forces the generation of new groups from existing ones
5538 LinearVariation: forces the computation of rotation angles as linear
5539 variation of the given Angles along path steps
5542 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5543 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5544 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5545 Example: :ref:`tui_extrusion_along_path`
5548 n,e,f = [],theObject,theObject
5549 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5550 HasAngles, Angles, LinearVariation,
5551 HasRefPoint, RefPoint, MakeGroups)
5552 if MakeGroups: return gr,er
5555 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5556 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5557 MakeGroups=False, LinearVariation=False):
5559 Generate new elements by extrusion of mesh segments which belong to the object.
5560 The path of extrusion must be a meshed edge.
5563 theObject: the object whose 1D elements should be processed.
5564 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5565 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5566 PathShape: shape (edge) defines the sub-mesh for the path
5567 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5568 HasAngles: allows the shape to be rotated around the path
5569 to get the resulting mesh in a helical fashion
5570 Angles: list of angles
5571 HasRefPoint: allows using the reference point
5572 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5573 The User can specify any point as the Reference Point.
5574 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5575 MakeGroups: forces the generation of new groups from existing ones
5576 LinearVariation: forces the computation of rotation angles as linear
5577 variation of the given Angles along path steps
5580 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5581 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5582 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5583 Example: :ref:`tui_extrusion_along_path`
5586 n,e,f = [],theObject,[]
5587 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5588 HasAngles, Angles, LinearVariation,
5589 HasRefPoint, RefPoint, MakeGroups)
5590 if MakeGroups: return gr,er
5593 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5594 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5595 MakeGroups=False, LinearVariation=False):
5597 Generate new elements by extrusion of faces which belong to the object.
5598 The path of extrusion must be a meshed edge.
5601 theObject: the object whose 2D elements should be processed.
5602 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5603 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5604 PathShape: shape (edge) defines the sub-mesh for the path
5605 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5606 HasAngles: allows the shape to be rotated around the path
5607 to get the resulting mesh in a helical fashion
5608 Angles: list of angles
5609 HasRefPoint: allows using the reference point
5610 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5611 The User can specify any point as the Reference Point.
5612 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5613 MakeGroups: forces the generation of new groups from existing ones
5614 LinearVariation: forces the computation of rotation angles as linear
5615 variation of the given Angles along path steps
5618 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5619 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5620 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5621 Example: :ref:`tui_extrusion_along_path`
5624 n,e,f = [],[],theObject
5625 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5626 HasAngles, Angles, LinearVariation,
5627 HasRefPoint, RefPoint, MakeGroups)
5628 if MakeGroups: return gr,er
5631 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5633 Create a symmetrical copy of mesh elements
5636 IDsOfElements: list of elements ids
5637 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5638 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5639 If the *Mirror* is a geom object this parameter is unnecessary
5640 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5641 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5644 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5647 if IDsOfElements == []:
5648 IDsOfElements = self.GetElementsId()
5649 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5650 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5651 theMirrorType = Mirror._mirrorType
5653 self.mesh.SetParameters(Mirror.parameters)
5654 if Copy and MakeGroups:
5655 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5656 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5659 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5661 Create a new mesh by a symmetrical copy of mesh elements
5664 IDsOfElements: the list of elements ids
5665 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5666 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5667 If the *Mirror* is a geom object this parameter is unnecessary
5668 MakeGroups: to generate new groups from existing ones
5669 NewMeshName: a name of the new mesh to create
5672 instance of class :class:`Mesh`
5675 if IDsOfElements == []:
5676 IDsOfElements = self.GetElementsId()
5677 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5678 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5679 theMirrorType = Mirror._mirrorType
5681 self.mesh.SetParameters(Mirror.parameters)
5682 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5683 MakeGroups, NewMeshName)
5684 return Mesh(self.smeshpyD,self.geompyD,mesh)
5686 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5688 Create a symmetrical copy of the object
5691 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5692 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5693 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5694 If the *Mirror* is a geom object this parameter is unnecessary
5695 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5696 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5699 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5702 if ( isinstance( theObject, Mesh )):
5703 theObject = theObject.GetMesh()
5704 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5705 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5706 theMirrorType = Mirror._mirrorType
5708 self.mesh.SetParameters(Mirror.parameters)
5709 if Copy and MakeGroups:
5710 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5711 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5714 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5716 Create a new mesh by a symmetrical copy of the object
5719 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5720 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5721 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5722 If the *Mirror* is a geom object this parameter is unnecessary
5723 MakeGroups: forces the generation of new groups from existing ones
5724 NewMeshName: the name of the new mesh to create
5727 instance of class :class:`Mesh`
5730 if ( isinstance( theObject, Mesh )):
5731 theObject = theObject.GetMesh()
5732 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5733 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5734 theMirrorType = Mirror._mirrorType
5736 self.mesh.SetParameters(Mirror.parameters)
5737 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5738 MakeGroups, NewMeshName)
5739 return Mesh( self.smeshpyD,self.geompyD,mesh )
5741 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5743 Translate the elements
5746 IDsOfElements: list of elements ids
5747 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5748 Copy: allows copying the translated elements
5749 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5752 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5755 if IDsOfElements == []:
5756 IDsOfElements = self.GetElementsId()
5757 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5758 Vector = self.smeshpyD.GetDirStruct(Vector)
5759 if isinstance( Vector, list ):
5760 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5761 self.mesh.SetParameters(Vector.PS.parameters)
5762 if Copy and MakeGroups:
5763 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5764 self.editor.Translate(IDsOfElements, Vector, Copy)
5767 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5769 Create a new mesh of translated elements
5772 IDsOfElements: list of elements ids
5773 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5774 MakeGroups: forces the generation of new groups from existing ones
5775 NewMeshName: the name of the newly created mesh
5778 instance of class :class:`Mesh`
5781 if IDsOfElements == []:
5782 IDsOfElements = self.GetElementsId()
5783 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5784 Vector = self.smeshpyD.GetDirStruct(Vector)
5785 if isinstance( Vector, list ):
5786 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5787 self.mesh.SetParameters(Vector.PS.parameters)
5788 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5789 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5791 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5793 Translate the object
5796 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5797 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5798 Copy: allows copying the translated elements
5799 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5802 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5805 if ( isinstance( theObject, Mesh )):
5806 theObject = theObject.GetMesh()
5807 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5808 Vector = self.smeshpyD.GetDirStruct(Vector)
5809 if isinstance( Vector, list ):
5810 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5811 self.mesh.SetParameters(Vector.PS.parameters)
5812 if Copy and MakeGroups:
5813 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5814 self.editor.TranslateObject(theObject, Vector, Copy)
5817 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5819 Create a new mesh from the translated object
5822 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5823 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5824 MakeGroups: forces the generation of new groups from existing ones
5825 NewMeshName: the name of the newly created mesh
5828 instance of class :class:`Mesh`
5831 if isinstance( theObject, Mesh ):
5832 theObject = theObject.GetMesh()
5833 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5834 Vector = self.smeshpyD.GetDirStruct(Vector)
5835 if isinstance( Vector, list ):
5836 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5837 self.mesh.SetParameters(Vector.PS.parameters)
5838 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5839 return Mesh( self.smeshpyD, self.geompyD, mesh )
5843 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5848 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5849 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5850 theScaleFact: list of 1-3 scale factors for axises
5851 Copy: allows copying the translated elements
5852 MakeGroups: forces the generation of new groups from existing
5856 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5857 empty list otherwise
5859 unRegister = genObjUnRegister()
5860 if ( isinstance( theObject, Mesh )):
5861 theObject = theObject.GetMesh()
5862 if ( isinstance( theObject, list )):
5863 theObject = self.GetIDSource(theObject, SMESH.ALL)
5864 unRegister.set( theObject )
5865 if ( isinstance( thePoint, list )):
5866 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5867 if ( isinstance( theScaleFact, float )):
5868 theScaleFact = [theScaleFact]
5869 if ( isinstance( theScaleFact, int )):
5870 theScaleFact = [ float(theScaleFact)]
5872 self.mesh.SetParameters(thePoint.parameters)
5874 if Copy and MakeGroups:
5875 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5876 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5879 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5881 Create a new mesh from the translated object
5884 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5885 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5886 theScaleFact: list of 1-3 scale factors for axises
5887 MakeGroups: forces the generation of new groups from existing ones
5888 NewMeshName: the name of the newly created mesh
5891 instance of class :class:`Mesh`
5893 unRegister = genObjUnRegister()
5894 if (isinstance(theObject, Mesh)):
5895 theObject = theObject.GetMesh()
5896 if ( isinstance( theObject, list )):
5897 theObject = self.GetIDSource(theObject,SMESH.ALL)
5898 unRegister.set( theObject )
5899 if ( isinstance( thePoint, list )):
5900 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5901 if ( isinstance( theScaleFact, float )):
5902 theScaleFact = [theScaleFact]
5903 if ( isinstance( theScaleFact, int )):
5904 theScaleFact = [ float(theScaleFact)]
5906 self.mesh.SetParameters(thePoint.parameters)
5907 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5908 MakeGroups, NewMeshName)
5909 return Mesh( self.smeshpyD, self.geompyD, mesh )
5913 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5918 IDsOfElements: list of elements ids
5919 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5920 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5921 Copy: allows copying the rotated elements
5922 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5925 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5929 if IDsOfElements == []:
5930 IDsOfElements = self.GetElementsId()
5931 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5932 Axis = self.smeshpyD.GetAxisStruct(Axis)
5933 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5934 Parameters = Axis.parameters + var_separator + Parameters
5935 self.mesh.SetParameters(Parameters)
5936 if Copy and MakeGroups:
5937 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5938 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5941 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5943 Create a new mesh of rotated elements
5946 IDsOfElements: list of element ids
5947 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5948 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5949 MakeGroups: forces the generation of new groups from existing ones
5950 NewMeshName: the name of the newly created mesh
5953 instance of class :class:`Mesh`
5956 if IDsOfElements == []:
5957 IDsOfElements = self.GetElementsId()
5958 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5959 Axis = self.smeshpyD.GetAxisStruct(Axis)
5960 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5961 Parameters = Axis.parameters + var_separator + Parameters
5962 self.mesh.SetParameters(Parameters)
5963 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5964 MakeGroups, NewMeshName)
5965 return Mesh( self.smeshpyD, self.geompyD, mesh )
5967 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5972 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5973 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5974 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5975 Copy: allows copying the rotated elements
5976 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5979 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5982 if (isinstance(theObject, Mesh)):
5983 theObject = theObject.GetMesh()
5984 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5985 Axis = self.smeshpyD.GetAxisStruct(Axis)
5986 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5987 Parameters = Axis.parameters + ":" + Parameters
5988 self.mesh.SetParameters(Parameters)
5989 if Copy and MakeGroups:
5990 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5991 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5994 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5996 Create a new mesh from the rotated object
5999 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6000 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6001 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6002 MakeGroups: forces the generation of new groups from existing ones
6003 NewMeshName: the name of the newly created mesh
6006 instance of class :class:`Mesh`
6009 if (isinstance( theObject, Mesh )):
6010 theObject = theObject.GetMesh()
6011 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6012 Axis = self.smeshpyD.GetAxisStruct(Axis)
6013 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6014 Parameters = Axis.parameters + ":" + Parameters
6015 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6016 MakeGroups, NewMeshName)
6017 self.mesh.SetParameters(Parameters)
6018 return Mesh( self.smeshpyD, self.geompyD, mesh )
6020 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6022 Create an offset mesh from the given 2D object
6025 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6026 theValue (float): signed offset size
6027 MakeGroups (boolean): forces the generation of new groups from existing ones
6028 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6029 False means to remove original elements.
6030 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6033 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6036 if isinstance( theObject, Mesh ):
6037 theObject = theObject.GetMesh()
6038 theValue,Parameters,hasVars = ParseParameters(Value)
6039 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6040 self.mesh.SetParameters(Parameters)
6041 # if mesh_groups[0]:
6042 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6045 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6047 Find groups of adjacent nodes within Tolerance.
6050 Tolerance (float): the value of tolerance
6051 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6052 corner and medium nodes in separate groups thus preventing
6053 their further merge.
6056 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6059 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6061 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6062 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6064 Find groups of adjacent nodes within Tolerance.
6067 Tolerance: the value of tolerance
6068 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6069 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6070 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6071 corner and medium nodes in separate groups thus preventing
6072 their further merge.
6075 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6078 unRegister = genObjUnRegister()
6079 if (isinstance( SubMeshOrGroup, Mesh )):
6080 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6081 if not isinstance( exceptNodes, list ):
6082 exceptNodes = [ exceptNodes ]
6083 if exceptNodes and isinstance( exceptNodes[0], int ):
6084 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6085 unRegister.set( exceptNodes )
6086 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6087 exceptNodes, SeparateCornerAndMediumNodes)
6089 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6094 GroupsOfNodes: a list of groups of nodes IDs for merging.
6095 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6096 in all elements and groups by nodes 1 and 25 correspondingly
6097 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6098 If *NodesToKeep* does not include a node to keep for some group to merge,
6099 then the first node in the group is kept.
6100 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6103 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6104 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6106 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6108 Find the elements built on the same nodes.
6111 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6114 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6117 if not MeshOrSubMeshOrGroup:
6118 MeshOrSubMeshOrGroup=self.mesh
6119 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6120 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6121 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6123 def MergeElements(self, GroupsOfElementsID):
6125 Merge elements in each given group.
6128 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6129 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6130 replaced in all groups by elements 1 and 25)
6133 self.editor.MergeElements(GroupsOfElementsID)
6135 def MergeEqualElements(self):
6137 Leave one element and remove all other elements built on the same nodes.
6140 self.editor.MergeEqualElements()
6142 def FindFreeBorders(self, ClosedOnly=True):
6144 Returns all or only closed free borders
6147 list of SMESH.FreeBorder's
6150 return self.editor.FindFreeBorders( ClosedOnly )
6152 def FillHole(self, holeNodes, groupName=""):
6154 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6157 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6158 must describe all sequential nodes of the hole border. The first and the last
6159 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6160 groupName (string): name of a group to add new faces
6162 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if :option:`groupName` == ""
6166 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6167 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6168 if not isinstance( holeNodes, SMESH.FreeBorder ):
6169 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6170 self.editor.FillHole( holeNodes, groupName )
6172 def FindCoincidentFreeBorders (self, tolerance=0.):
6174 Return groups of FreeBorder's coincident within the given tolerance.
6177 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6178 size of elements adjacent to free borders being compared is used.
6181 SMESH.CoincidentFreeBorders structure
6184 return self.editor.FindCoincidentFreeBorders( tolerance )
6186 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6188 Sew FreeBorder's of each group
6191 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6192 where each enclosed list contains node IDs of a group of coincident free
6193 borders such that each consequent triple of IDs within a group describes
6194 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6195 last node of a border.
6196 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6197 groups of coincident free borders, each group including two borders.
6198 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6199 polygons if a node of opposite border falls on a face edge, else such
6200 faces are split into several ones.
6201 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6202 polyhedra if a node of opposite border falls on a volume edge, else such
6203 volumes, if any, remain intact and the mesh becomes non-conformal.
6206 a number of successfully sewed groups
6209 if freeBorders and isinstance( freeBorders, list ):
6210 # construct SMESH.CoincidentFreeBorders
6211 if isinstance( freeBorders[0], int ):
6212 freeBorders = [freeBorders]
6214 coincidentGroups = []
6215 for nodeList in freeBorders:
6216 if not nodeList or len( nodeList ) % 3:
6217 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6220 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6221 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6222 nodeList = nodeList[3:]
6224 coincidentGroups.append( group )
6226 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6228 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6230 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6231 FirstNodeID2, SecondNodeID2, LastNodeID2,
6232 CreatePolygons, CreatePolyedrs):
6237 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6240 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6241 FirstNodeID2, SecondNodeID2, LastNodeID2,
6242 CreatePolygons, CreatePolyedrs)
6244 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6245 FirstNodeID2, SecondNodeID2):
6247 Sew conform free borders
6250 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6253 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6254 FirstNodeID2, SecondNodeID2)
6256 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6257 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6262 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6265 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6266 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6268 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6269 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6270 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6272 Sew two sides of a mesh. The nodes belonging to Side1 are
6273 merged with the nodes of elements of Side2.
6274 The number of elements in theSide1 and in theSide2 must be
6275 equal and they should have similar nodal connectivity.
6276 The nodes to merge should belong to side borders and
6277 the first node should be linked to the second.
6280 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6283 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6284 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6285 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6287 def ChangeElemNodes(self, ide, newIDs):
6289 Set new nodes for the given element.
6296 False if the number of nodes does not correspond to the type of element
6299 return self.editor.ChangeElemNodes(ide, newIDs)
6301 def GetLastCreatedNodes(self):
6303 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6304 created, this method return the list of their IDs.
6305 If new nodes were not created - return empty list
6308 the list of integer values (can be empty)
6311 return self.editor.GetLastCreatedNodes()
6313 def GetLastCreatedElems(self):
6315 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6316 created this method return the list of their IDs.
6317 If new elements were not created - return empty list
6320 the list of integer values (can be empty)
6323 return self.editor.GetLastCreatedElems()
6325 def ClearLastCreated(self):
6327 Forget what nodes and elements were created by the last mesh edition operation
6330 self.editor.ClearLastCreated()
6332 def DoubleElements(self, theElements, theGroupName=""):
6334 Create duplicates of given elements, i.e. create new elements based on the
6335 same nodes as the given ones.
6338 theElements: container of elements to duplicate. It can be a
6339 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6340 or a list of element IDs. If *theElements* is
6341 a :class:`Mesh`, elements of highest dimension are duplicated
6342 theGroupName: a name of group to contain the generated elements.
6343 If a group with such a name already exists, the new elements
6344 are added to the existing group, else a new group is created.
6345 If *theGroupName* is empty, new elements are not added
6349 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6350 None if *theGroupName* == "".
6353 unRegister = genObjUnRegister()
6354 if isinstance( theElements, Mesh ):
6355 theElements = theElements.mesh
6356 elif isinstance( theElements, list ):
6357 theElements = self.GetIDSource( theElements, SMESH.ALL )
6358 unRegister.set( theElements )
6359 return self.editor.DoubleElements(theElements, theGroupName)
6361 def DoubleNodes(self, theNodes, theModifiedElems):
6363 Create a hole in a mesh by doubling the nodes of some particular elements
6366 theNodes: IDs of nodes to be doubled
6367 theModifiedElems: IDs of elements to be updated by the new (doubled)
6368 nodes. If list of element identifiers is empty then nodes are doubled but
6369 they not assigned to elements
6372 True if operation has been completed successfully, False otherwise
6375 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6377 def DoubleNode(self, theNodeId, theModifiedElems):
6379 Create a hole in a mesh by doubling the nodes of some particular elements.
6380 This method provided for convenience works as :meth:`DoubleNodes`.
6383 theNodeId: IDs of node to double
6384 theModifiedElems: IDs of elements to update
6387 True if operation has been completed successfully, False otherwise
6390 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6392 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6394 Create a hole in a mesh by doubling the nodes of some particular elements.
6395 This method provided for convenience works as :meth:`DoubleNodes`.
6398 theNodes: group of nodes to double.
6399 theModifiedElems: group of elements to update.
6400 theMakeGroup: forces the generation of a group containing new nodes.
6403 True or a created group if operation has been completed successfully,
6404 False or None otherwise
6408 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6409 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6411 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6413 Create a hole in a mesh by doubling the nodes of some particular elements.
6414 This method provided for convenience works as :meth:`DoubleNodes`.
6417 theNodes: list of groups of nodes to double.
6418 theModifiedElems: list of groups of elements to update.
6419 theMakeGroup: forces the generation of a group containing new nodes.
6422 True if operation has been completed successfully, False otherwise
6426 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6427 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6429 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6431 Create a hole in a mesh by doubling the nodes of some particular elements
6434 theElems: the list of elements (edges or faces) to replicate.
6435 The nodes for duplication could be found from these elements
6436 theNodesNot: list of nodes NOT to replicate
6437 theAffectedElems: the list of elements (cells and edges) to which the
6438 replicated nodes should be associated to
6441 True if operation has been completed successfully, False otherwise
6444 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6446 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6448 Create a hole in a mesh by doubling the nodes of some particular elements
6451 theElems: the list of elements (edges or faces) to replicate.
6452 The nodes for duplication could be found from these elements
6453 theNodesNot: list of nodes NOT to replicate
6454 theShape: shape to detect affected elements (element which geometric center
6455 located on or inside shape).
6456 The replicated nodes should be associated to affected elements.
6459 True if operation has been completed successfully, False otherwise
6462 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6464 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6465 theMakeGroup=False, theMakeNodeGroup=False):
6467 Create a hole in a mesh by doubling the nodes of some particular elements.
6468 This method provided for convenience works as :meth:`DoubleNodes`.
6471 theElems: group of of elements (edges or faces) to replicate.
6472 theNodesNot: group of nodes NOT to replicate.
6473 theAffectedElems: group of elements to which the replicated nodes
6474 should be associated to.
6475 theMakeGroup: forces the generation of a group containing new elements.
6476 theMakeNodeGroup: forces the generation of a group containing new nodes.
6479 True or created groups (one or two) if operation has been completed successfully,
6480 False or None otherwise
6483 if theMakeGroup or theMakeNodeGroup:
6484 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6486 theMakeGroup, theMakeNodeGroup)
6487 if theMakeGroup and theMakeNodeGroup:
6490 return twoGroups[ int(theMakeNodeGroup) ]
6491 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6493 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6495 Create a hole in a mesh by doubling the nodes of some particular elements.
6496 This method provided for convenience works as :meth:`DoubleNodes`.
6499 theElems: group of of elements (edges or faces) to replicate
6500 theNodesNot: group of nodes not to replicate
6501 theShape: shape to detect affected elements (element which geometric center
6502 located on or inside shape).
6503 The replicated nodes should be associated to affected elements
6506 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6508 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6509 theMakeGroup=False, theMakeNodeGroup=False):
6511 Create a hole in a mesh by doubling the nodes of some particular elements.
6512 This method provided for convenience works as :meth:`DoubleNodes`.
6515 theElems: list of groups of elements (edges or faces) to replicate
6516 theNodesNot: list of groups of nodes NOT to replicate
6517 theAffectedElems: group of elements to which the replicated nodes
6518 should be associated to
6519 theMakeGroup: forces generation of a group containing new elements.
6520 theMakeNodeGroup: forces generation of a group containing new nodes
6523 True or created groups (one or two) if operation has been completed successfully,
6524 False or None otherwise
6527 if theMakeGroup or theMakeNodeGroup:
6528 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6530 theMakeGroup, theMakeNodeGroup)
6531 if theMakeGroup and theMakeNodeGroup:
6534 return twoGroups[ int(theMakeNodeGroup) ]
6535 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6537 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6539 Create a hole in a mesh by doubling the nodes of some particular elements.
6540 This method provided for convenience works as :meth:`DoubleNodes`.
6543 theElems: list of groups of elements (edges or faces) to replicate
6544 theNodesNot: list of groups of nodes NOT to replicate
6545 theShape: shape to detect affected elements (element which geometric center
6546 located on or inside shape).
6547 The replicated nodes should be associated to affected elements
6550 True if operation has been completed successfully, False otherwise
6553 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6555 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6557 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6558 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6561 theElems: list of groups of nodes or elements (edges or faces) to replicate
6562 theNodesNot: list of groups of nodes NOT to replicate
6563 theShape: shape to detect affected elements (element which geometric center
6564 located on or inside shape).
6565 The replicated nodes should be associated to affected elements
6568 groups of affected elements in order: volumes, faces, edges
6571 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6573 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6576 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6577 The list of groups must describe a partition of the mesh volumes.
6578 The nodes of the internal faces at the boundaries of the groups are doubled.
6579 In option, the internal faces are replaced by flat elements.
6580 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6583 theDomains: list of groups of volumes
6584 createJointElems: if True, create the elements
6585 onAllBoundaries: if True, the nodes and elements are also created on
6586 the boundary between *theDomains* and the rest mesh
6589 True if operation has been completed successfully, False otherwise
6592 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6594 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6596 Double nodes on some external faces and create flat elements.
6597 Flat elements are mainly used by some types of mechanic calculations.
6599 Each group of the list must be constituted of faces.
6600 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6603 theGroupsOfFaces: list of groups of faces
6606 True if operation has been completed successfully, False otherwise
6609 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6611 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6613 Identify all the elements around a geom shape, get the faces delimiting the hole
6615 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6617 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6619 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6620 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6621 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6622 If there are several paths connecting a pair of points, the shortest path is
6623 selected by the module. Position of the cutting plane is defined by the two
6624 points and an optional vector lying on the plane specified by a PolySegment.
6625 By default the vector is defined by Mesh module as following. A middle point
6626 of the two given points is computed. The middle point is projected to the mesh.
6627 The vector goes from the middle point to the projection point. In case of planar
6628 mesh, the vector is normal to the mesh.
6630 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6633 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6634 groupName: optional name of a group where created mesh segments will be added.
6637 editor = self.editor
6639 editor = self.mesh.GetMeshEditPreviewer()
6640 segmentsRes = editor.MakePolyLine( segments, groupName )
6641 for i, seg in enumerate( segmentsRes ):
6642 segments[i].vector = seg.vector
6644 return editor.GetPreviewData()
6647 def GetFunctor(self, funcType ):
6649 Return a cached numerical functor by its type.
6652 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6653 Note that not all items correspond to numerical functors.
6656 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6659 fn = self.functors[ funcType._v ]
6661 fn = self.smeshpyD.GetFunctor(funcType)
6662 fn.SetMesh(self.mesh)
6663 self.functors[ funcType._v ] = fn
6666 def FunctorValue(self, funcType, elemId, isElem=True):
6668 Return value of a functor for a given element
6671 funcType: an item of :class:`SMESH.FunctorType` enum.
6672 elemId: element or node ID
6673 isElem: *elemId* is ID of element or node
6676 the functor value or zero in case of invalid arguments
6679 fn = self.GetFunctor( funcType )
6680 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6681 val = fn.GetValue(elemId)
6686 def GetLength(self, elemId=None):
6688 Get length of 1D element or sum of lengths of all 1D mesh elements
6691 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6694 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6699 length = self.smeshpyD.GetLength(self)
6701 length = self.FunctorValue(SMESH.FT_Length, elemId)
6704 def GetArea(self, elemId=None):
6706 Get area of 2D element or sum of areas of all 2D mesh elements
6707 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6710 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6715 area = self.smeshpyD.GetArea(self)
6717 area = self.FunctorValue(SMESH.FT_Area, elemId)
6720 def GetVolume(self, elemId=None):
6722 Get volume of 3D element or sum of volumes of all 3D mesh elements
6725 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6728 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6733 volume = self.smeshpyD.GetVolume(self)
6735 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6738 def GetMaxElementLength(self, elemId):
6740 Get maximum element length.
6743 elemId: mesh element ID
6746 element's maximum length value
6749 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6750 ftype = SMESH.FT_MaxElementLength3D
6752 ftype = SMESH.FT_MaxElementLength2D
6753 return self.FunctorValue(ftype, elemId)
6755 def GetAspectRatio(self, elemId):
6757 Get aspect ratio of 2D or 3D element.
6760 elemId: mesh element ID
6763 element's aspect ratio value
6766 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6767 ftype = SMESH.FT_AspectRatio3D
6769 ftype = SMESH.FT_AspectRatio
6770 return self.FunctorValue(ftype, elemId)
6772 def GetWarping(self, elemId):
6774 Get warping angle of 2D element.
6777 elemId: mesh element ID
6780 element's warping angle value
6783 return self.FunctorValue(SMESH.FT_Warping, elemId)
6785 def GetMinimumAngle(self, elemId):
6787 Get minimum angle of 2D element.
6790 elemId: mesh element ID
6793 element's minimum angle value
6796 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6798 def GetTaper(self, elemId):
6800 Get taper of 2D element.
6803 elemId: mesh element ID
6806 element's taper value
6809 return self.FunctorValue(SMESH.FT_Taper, elemId)
6811 def GetSkew(self, elemId):
6813 Get skew of 2D element.
6816 elemId: mesh element ID
6819 element's skew value
6822 return self.FunctorValue(SMESH.FT_Skew, elemId)
6824 def GetMinMax(self, funType, meshPart=None):
6826 Return minimal and maximal value of a given functor.
6829 funType (SMESH.FunctorType): a functor type.
6830 Note that not all items of :class:`SMESH.FunctorType` corresponds
6831 to numerical functors.
6832 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6838 unRegister = genObjUnRegister()
6839 if isinstance( meshPart, list ):
6840 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6841 unRegister.set( meshPart )
6842 if isinstance( meshPart, Mesh ):
6843 meshPart = meshPart.mesh
6844 fun = self.GetFunctor( funType )
6847 if hasattr( meshPart, "SetMesh" ):
6848 meshPart.SetMesh( self.mesh ) # set mesh to filter
6849 hist = fun.GetLocalHistogram( 1, False, meshPart )
6851 hist = fun.GetHistogram( 1, False )
6853 return hist[0].min, hist[0].max
6856 pass # end of Mesh class
6859 class meshProxy(SMESH._objref_SMESH_Mesh):
6861 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6862 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6864 def __init__(self,*args):
6865 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6866 def __deepcopy__(self, memo=None):
6867 new = self.__class__(self)
6869 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6870 if len( args ) == 3:
6871 args += SMESH.ALL_NODES, True
6872 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6873 def ExportToMEDX(self, *args): # function removed
6874 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6875 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6876 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6877 def ExportToMED(self, *args): # function removed
6878 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6879 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6881 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6883 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6884 def ExportPartToMED(self, *args): # 'version' parameter removed
6885 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6886 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6887 def ExportMED(self, *args): # signature of method changed
6888 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6890 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6892 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6894 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6897 class submeshProxy(SMESH._objref_SMESH_subMesh):
6900 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6902 def __init__(self,*args):
6903 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6905 def __deepcopy__(self, memo=None):
6906 new = self.__class__(self)
6909 def Compute(self,refresh=False):
6911 Compute the sub-mesh and return the status of the computation
6914 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6919 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6920 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6924 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6926 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6928 if salome.sg.hasDesktop():
6929 if refresh: salome.sg.updateObjBrowser()
6934 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6937 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6939 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6940 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6943 def __init__(self,*args):
6944 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6946 def __getattr__(self, name ): # method called if an attribute not found
6947 if not self.mesh: # look for name() method in Mesh class
6948 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6949 if hasattr( self.mesh, name ):
6950 return getattr( self.mesh, name )
6951 if name == "ExtrusionAlongPathObjX":
6952 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6953 print("meshEditor: attribute '%s' NOT FOUND" % name)
6955 def __deepcopy__(self, memo=None):
6956 new = self.__class__(self)
6958 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6959 if len( args ) == 1: args += False,
6960 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6961 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6962 if len( args ) == 2: args += False,
6963 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6964 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6965 if len( args ) == 1:
6966 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6967 NodesToKeep = args[1]
6968 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6969 unRegister = genObjUnRegister()
6971 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6972 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6973 if not isinstance( NodesToKeep, list ):
6974 NodesToKeep = [ NodesToKeep ]
6975 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6977 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6979 class Pattern(SMESH._objref_SMESH_Pattern):
6981 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6982 variables in some methods
6985 def LoadFromFile(self, patternTextOrFile ):
6986 text = patternTextOrFile
6987 if os.path.exists( text ):
6988 text = open( patternTextOrFile ).read()
6990 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6992 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6993 decrFun = lambda i: i-1
6994 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6995 theMesh.SetParameters(Parameters)
6996 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6998 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6999 decrFun = lambda i: i-1
7000 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7001 theMesh.SetParameters(Parameters)
7002 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7004 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7005 if isinstance( mesh, Mesh ):
7006 mesh = mesh.GetMesh()
7007 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7009 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7011 Registering the new proxy for Pattern
7016 Private class used to bind methods creating algorithms to the class Mesh
7019 def __init__(self, method):
7021 self.defaultAlgoType = ""
7022 self.algoTypeToClass = {}
7023 self.method = method
7025 def add(self, algoClass):
7027 Store a python class of algorithm
7029 if inspect.isclass(algoClass) and \
7030 hasattr( algoClass, "algoType"):
7031 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7032 if not self.defaultAlgoType and \
7033 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7034 self.defaultAlgoType = algoClass.algoType
7035 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7037 def copy(self, mesh):
7039 Create a copy of self and assign mesh to the copy
7042 other = algoCreator( self.method )
7043 other.defaultAlgoType = self.defaultAlgoType
7044 other.algoTypeToClass = self.algoTypeToClass
7048 def __call__(self,algo="",geom=0,*args):
7050 Create an instance of algorithm
7054 if isinstance( algo, str ):
7056 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7057 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7062 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7064 elif not algoType and isinstance( geom, str ):
7069 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7071 elif isinstance( arg, str ) and not algoType:
7074 import traceback, sys
7075 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7076 sys.stderr.write( msg + '\n' )
7077 tb = traceback.extract_stack(None,2)
7078 traceback.print_list( [tb[0]] )
7080 algoType = self.defaultAlgoType
7081 if not algoType and self.algoTypeToClass:
7082 algoType = sorted( self.algoTypeToClass.keys() )[0]
7083 if algoType in self.algoTypeToClass:
7084 #print("Create algo",algoType)
7085 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7086 raise RuntimeError( "No class found for algo type %s" % algoType)
7089 class hypMethodWrapper:
7091 Private class used to substitute and store variable parameters of hypotheses.
7094 def __init__(self, hyp, method):
7096 self.method = method
7097 #print("REBIND:", method.__name__)
7100 def __call__(self,*args):
7102 call a method of hypothesis with calling SetVarParameter() before
7106 return self.method( self.hyp, *args ) # hypothesis method with no args
7108 #print("MethWrapper.__call__", self.method.__name__, args)
7110 parsed = ParseParameters(*args) # replace variables with their values
7111 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7112 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7113 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7114 # maybe there is a replaced string arg which is not variable
7115 result = self.method( self.hyp, *args )
7116 except ValueError as detail: # raised by ParseParameters()
7118 result = self.method( self.hyp, *args )
7119 except omniORB.CORBA.BAD_PARAM:
7120 raise ValueError(detail) # wrong variable name
7125 class genObjUnRegister:
7127 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7130 def __init__(self, genObj=None):
7131 self.genObjList = []
7135 def set(self, genObj):
7136 "Store one or a list of of SALOME.GenericObj'es"
7137 if isinstance( genObj, list ):
7138 self.genObjList.extend( genObj )
7140 self.genObjList.append( genObj )
7144 for genObj in self.genObjList:
7145 if genObj and hasattr( genObj, "UnRegister" ):
7148 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7150 Bind methods creating mesher plug-ins to the Mesh class
7153 # print("pluginName: ", pluginName)
7154 pluginBuilderName = pluginName + "Builder"
7156 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7157 except Exception as e:
7158 from salome_utils import verbose
7159 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7161 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7162 plugin = eval( pluginBuilderName )
7163 # print(" plugin:" , str(plugin))
7165 # add methods creating algorithms to Mesh
7166 for k in dir( plugin ):
7167 if k[0] == '_': continue
7168 algo = getattr( plugin, k )
7169 #print(" algo:", str(algo))
7170 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7171 #print(" meshMethod:" , str(algo.meshMethod))
7172 if not hasattr( Mesh, algo.meshMethod ):
7173 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7175 _mmethod = getattr( Mesh, algo.meshMethod )
7176 if hasattr( _mmethod, "add" ):