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 = omniORB.EnumItem("MED_V2_1", 0) # back compatibility
29 SMESH.MED_V2_2 = omniORB.EnumItem("MED_V2_2", 1) # back compatibility
32 from salome.smesh.smesh_algorithm import Mesh_Algorithm
39 # In case the omniORBpy EnumItem class does not fully support Python 3
40 # (for instance in version 4.2.1-2), the comparison ordering methods must be
44 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
46 def enumitem_eq(self, other):
48 if isinstance(other, omniORB.EnumItem):
49 if other._parent_id == self._parent_id:
50 return self._v == other._v
52 return self._parent_id == other._parent_id
54 return id(self) == id(other)
56 return id(self) == id(other)
58 def enumitem_lt(self, other):
60 if isinstance(other, omniORB.EnumItem):
61 if other._parent_id == self._parent_id:
62 return self._v < other._v
64 return self._parent_id < other._parent_id
66 return id(self) < id(other)
68 return id(self) < id(other)
70 def enumitem_le(self, other):
72 if isinstance(other, omniORB.EnumItem):
73 if other._parent_id == self._parent_id:
74 return self._v <= other._v
76 return self._parent_id <= other._parent_id
78 return id(self) <= id(other)
80 return id(self) <= id(other)
82 def enumitem_gt(self, other):
84 if isinstance(other, omniORB.EnumItem):
85 if other._parent_id == self._parent_id:
86 return self._v > other._v
88 return self._parent_id > other._parent_id
90 return id(self) > id(other)
92 return id(self) > id(other)
94 def enumitem_ge(self, other):
96 if isinstance(other, omniORB.EnumItem):
97 if other._parent_id == self._parent_id:
98 return self._v >= other._v
100 return self._parent_id >= other._parent_id
102 return id(self) >= id(other)
104 return id(self) >= id(other)
106 omniORB.EnumItem.__eq__ = enumitem_eq
107 omniORB.EnumItem.__lt__ = enumitem_lt
108 omniORB.EnumItem.__le__ = enumitem_le
109 omniORB.EnumItem.__gt__ = enumitem_gt
110 omniORB.EnumItem.__ge__ = enumitem_ge
113 class MeshMeta(type):
114 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
116 def __instancecheck__(cls, inst):
117 """Implement isinstance(inst, cls)."""
118 return any(cls.__subclasscheck__(c)
119 for c in {type(inst), inst.__class__})
121 def __subclasscheck__(cls, sub):
122 """Implement issubclass(sub, cls)."""
123 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
125 def DegreesToRadians(AngleInDegrees):
126 """Convert an angle from degrees to radians
129 return AngleInDegrees * pi / 180.0
131 import salome_notebook
132 notebook = salome_notebook.notebook
133 # Salome notebook variable separator
136 def ParseParameters(*args):
138 Return list of variable values from salome notebook.
139 The last argument, if is callable, is used to modify values got from notebook
145 if args and callable(args[-1]):
146 args, varModifFun = args[:-1], args[-1]
147 for parameter in args:
149 Parameters += str(parameter) + var_separator
151 if isinstance(parameter,str):
152 # check if there is an inexistent variable name
153 if not notebook.isVariable(parameter):
154 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
155 parameter = notebook.get(parameter)
158 parameter = varModifFun(parameter)
161 Result.append(parameter)
164 Parameters = Parameters[:-1]
165 Result.append( Parameters )
166 Result.append( hasVariables )
169 def ParseAngles(*args):
171 Parse parameters while converting variables to radians
173 return ParseParameters( *( args + (DegreesToRadians, )))
175 def __initPointStruct(point,*args):
177 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
178 Parameters are stored in PointStruct.parameters attribute
180 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
182 SMESH.PointStruct.__init__ = __initPointStruct
184 def __initAxisStruct(ax,*args):
186 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
187 Parameters are stored in AxisStruct.parameters attribute
190 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
191 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
193 SMESH.AxisStruct.__init__ = __initAxisStruct
195 smeshPrecisionConfusion = 1.e-07
196 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
197 """Compare real values using smeshPrecisionConfusion as tolerance
199 if abs(val1 - val2) < tol:
207 Return a name of an object
214 if isinstance(obj, SALOMEDS._objref_SObject):
218 ior = salome.orb.object_to_string(obj)
222 sobj = salome.myStudy.FindObjectIOR(ior)
224 return sobj.GetName()
225 if hasattr(obj, "GetName"):
226 # unknown CORBA object, having GetName() method
229 # unknown CORBA object, no GetName() method
232 if hasattr(obj, "GetName"):
233 # unknown non-CORBA object, having GetName() method
236 raise RuntimeError("Null or invalid object")
238 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
240 Print error message if a hypothesis was not assigned.
243 hypType = "algorithm"
245 hypType = "hypothesis"
248 if hasattr( status, "__getitem__" ):
249 status, reason = status[0], status[1]
250 if status == HYP_UNKNOWN_FATAL:
251 reason = "for unknown reason"
252 elif status == HYP_INCOMPATIBLE:
253 reason = "this hypothesis mismatches the algorithm"
254 elif status == HYP_NOTCONFORM:
255 reason = "a non-conform mesh would be built"
256 elif status == HYP_ALREADY_EXIST:
257 if isAlgo: return # it does not influence anything
258 reason = hypType + " of the same dimension is already assigned to this shape"
259 elif status == HYP_BAD_DIM:
260 reason = hypType + " mismatches the shape"
261 elif status == HYP_CONCURRENT :
262 reason = "there are concurrent hypotheses on sub-shapes"
263 elif status == HYP_BAD_SUBSHAPE:
264 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
265 elif status == HYP_BAD_GEOMETRY:
266 reason = "the algorithm is not applicable to this geometry"
267 elif status == HYP_HIDDEN_ALGO:
268 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
269 elif status == HYP_HIDING_ALGO:
270 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
271 elif status == HYP_NEED_SHAPE:
272 reason = "algorithm can't work without shape"
273 elif status == HYP_INCOMPAT_HYPS:
279 where = '"%s"' % geomName
281 meshName = GetName( mesh )
282 if meshName and meshName != NO_NAME:
283 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
284 if status < HYP_UNKNOWN_FATAL and where:
285 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
287 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
289 print('"%s" was not assigned : %s' %( hypName, reason ))
292 def AssureGeomPublished(mesh, geom, name=''):
294 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
296 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
298 if not geom.GetStudyEntry():
300 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
301 # for all groups SubShapeName() return "Compound_-1"
302 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
304 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
306 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
309 def FirstVertexOnCurve(mesh, edge):
312 the first vertex of a geometrical edge by ignoring orientation
314 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
316 raise TypeError("Given object has no vertices")
317 if len( vv ) == 1: return vv[0]
318 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
319 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
320 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
321 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
324 dist1 += abs( xyz[i] - xyz1[i] )
325 dist2 += abs( xyz[i] - xyz2[i] )
334 smeshInst is a singleton
340 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
342 This class allows to create, load or manipulate meshes.
343 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
344 It also has methods to get infos and measure meshes.
347 # MirrorType enumeration
348 POINT = SMESH_MeshEditor.POINT
349 AXIS = SMESH_MeshEditor.AXIS
350 PLANE = SMESH_MeshEditor.PLANE
352 # Smooth_Method enumeration
353 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
354 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
356 PrecisionConfusion = smeshPrecisionConfusion
358 # TopAbs_State enumeration
359 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
361 # Methods of splitting a hexahedron into tetrahedra
362 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
364 def __new__(cls, *args):
368 #print("==== __new__", engine, smeshInst, doLcc)
370 if smeshInst is None:
371 # smesh engine is either retrieved from engine, or created
373 # Following test avoids a recursive loop
375 if smeshInst is not None:
376 # smesh engine not created: existing engine found
380 # FindOrLoadComponent called:
381 # 1. CORBA resolution of server
382 # 2. the __new__ method is called again
383 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
384 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
386 # FindOrLoadComponent not called
387 if smeshInst is None:
388 # smeshBuilder instance is created from lcc.FindOrLoadComponent
389 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
390 smeshInst = super(smeshBuilder,cls).__new__(cls)
392 # smesh engine not created: existing engine found
393 #print("==== existing ", engine, smeshInst, doLcc)
395 #print("====1 ", smeshInst)
398 #print("====2 ", smeshInst)
401 def __init__(self, *args):
403 #print("--------------- smeshbuilder __init__ ---", created)
406 SMESH._objref_SMESH_Gen.__init__(self, *args)
409 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
411 Dump component to the Python script.
412 This method overrides IDL function to allow default values for the parameters.
415 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
417 def SetDumpPythonHistorical(self, isHistorical):
419 Set mode of DumpPython(), *historical* or *snapshot*.
420 In the *historical* mode, the Python Dump script includes all commands
421 performed by SMESH engine. In the *snapshot* mode, commands
422 relating to objects removed from the Study are excluded from the script
423 as well as commands not influencing the current state of meshes
426 if isHistorical: val = "true"
428 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
430 def init_smesh(self,geompyD = None):
432 Set Geometry component
435 self.UpdateStudy(geompyD)
436 notebook.myStudy = salome.myStudy
438 def Mesh(self, obj=0, name=0):
440 Create a mesh. This mesh can be either
442 * an empty mesh not bound to geometry, if *obj* == 0
443 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
444 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
449 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
452 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
454 2. a geometrical object for meshing
456 name: the name for the new mesh.
459 an instance of class :class:`Mesh`.
462 if isinstance(obj,str):
464 return Mesh(self, self.geompyD, obj, name)
466 def EnumToLong(self,theItem):
468 Return a long value from enumeration
473 def ColorToString(self,c):
475 Convert SALOMEDS.Color to string.
476 To be used with filters.
479 c: color value (SALOMEDS.Color)
482 a string representation of the color.
486 if isinstance(c, SALOMEDS.Color):
487 val = "%s;%s;%s" % (c.R, c.G, c.B)
488 elif isinstance(c, str):
491 raise ValueError("Color value should be of string or SALOMEDS.Color type")
494 def GetPointStruct(self,theVertex):
496 Get :class:`SMESH.PointStruct` from vertex
499 theVertex (GEOM.GEOM_Object): vertex
502 :class:`SMESH.PointStruct`
505 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
506 return PointStruct(x,y,z)
508 def GetDirStruct(self,theVector):
510 Get :class:`SMESH.DirStruct` from vector
513 theVector (GEOM.GEOM_Object): vector
516 :class:`SMESH.DirStruct`
519 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
520 if(len(vertices) != 2):
521 print("Error: vector object is incorrect.")
523 p1 = self.geompyD.PointCoordinates(vertices[0])
524 p2 = self.geompyD.PointCoordinates(vertices[1])
525 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
526 dirst = DirStruct(pnt)
529 def MakeDirStruct(self,x,y,z):
531 Make :class:`SMESH.DirStruct` from a triplet of floats
534 x,y,z (float): vector components
537 :class:`SMESH.DirStruct`
540 pnt = PointStruct(x,y,z)
541 return DirStruct(pnt)
543 def GetAxisStruct(self,theObj):
545 Get :class:`SMESH.AxisStruct` from a geometrical object
548 theObj (GEOM.GEOM_Object): line or plane
551 :class:`SMESH.AxisStruct`
554 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
557 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
558 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
559 vertex1 = self.geompyD.PointCoordinates(vertex1)
560 vertex2 = self.geompyD.PointCoordinates(vertex2)
561 vertex3 = self.geompyD.PointCoordinates(vertex3)
562 vertex4 = self.geompyD.PointCoordinates(vertex4)
563 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
564 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
565 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] ]
566 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
567 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
568 elif len(edges) == 1:
569 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570 p1 = self.geompyD.PointCoordinates( vertex1 )
571 p2 = self.geompyD.PointCoordinates( vertex2 )
572 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
573 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
574 elif theObj.GetShapeType() == GEOM.VERTEX:
575 x,y,z = self.geompyD.PointCoordinates( theObj )
576 axis = AxisStruct( x,y,z, 1,0,0,)
577 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
580 # From SMESH_Gen interface:
581 # ------------------------
583 def SetName(self, obj, name):
585 Set the given name to an object
588 obj: the object to rename
589 name: a new object name
592 if isinstance( obj, Mesh ):
594 elif isinstance( obj, Mesh_Algorithm ):
595 obj = obj.GetAlgorithm()
596 ior = salome.orb.object_to_string(obj)
597 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
599 def SetEmbeddedMode( self,theMode ):
604 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
606 def IsEmbeddedMode(self):
611 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
613 def UpdateStudy( self, geompyD = None ):
615 Update the current study. Calling UpdateStudy() allows to
616 update meshes at switching GEOM->SMESH
620 from salome.geom import geomBuilder
621 geompyD = geomBuilder.geom
624 self.SetGeomEngine(geompyD)
625 SMESH._objref_SMESH_Gen.UpdateStudy(self)
626 sb = salome.myStudy.NewBuilder()
627 sc = salome.myStudy.FindComponent("SMESH")
629 sb.LoadWith(sc, self)
632 def SetEnablePublish( self, theIsEnablePublish ):
634 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
635 switch **off** publishing in the Study of mesh objects.
637 #self.SetEnablePublish(theIsEnablePublish)
638 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
640 notebook = salome_notebook.NoteBook( theIsEnablePublish )
643 def CreateMeshesFromUNV( self,theFileName ):
645 Create a Mesh object importing data from the given UNV file
648 an instance of class :class:`Mesh`
651 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
652 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
655 def CreateMeshesFromMED( self,theFileName ):
657 Create a Mesh object(s) importing data from the given MED file
660 a tuple ( list of class :class:`Mesh` instances,
661 :class:`SMESH.DriverMED_ReadStatus` )
664 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
665 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
666 return aMeshes, aStatus
668 def CreateMeshesFromSAUV( self,theFileName ):
670 Create a Mesh object(s) importing data from the given SAUV file
673 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
676 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
677 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
678 return aMeshes, aStatus
680 def CreateMeshesFromSTL( self, theFileName ):
682 Create a Mesh object importing data from the given STL file
685 an instance of class :class:`Mesh`
688 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
689 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
692 def CreateMeshesFromCGNS( self, theFileName ):
694 Create Mesh objects importing data from the given CGNS file
697 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
700 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
701 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
702 return aMeshes, aStatus
704 def CreateMeshesFromGMF( self, theFileName ):
706 Create a Mesh object importing data from the given GMF file.
707 GMF files must have .mesh extension for the ASCII format and .meshb for
711 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
714 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
717 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
718 return Mesh(self, self.geompyD, aSmeshMesh), error
720 def Concatenate( self, meshes, uniteIdenticalGroups,
721 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
724 Concatenate the given meshes into one mesh. All groups of input meshes will be
725 present in the new mesh.
728 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
729 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
730 mergeNodesAndElements: if True, equal nodes and elements are merged
731 mergeTolerance: tolerance for merging nodes
732 allGroups: forces creation of groups corresponding to every input mesh
733 name: name of a new mesh
736 an instance of class :class:`Mesh`
739 if not meshes: return None
740 for i,m in enumerate(meshes):
741 if isinstance(m, Mesh):
742 meshes[i] = m.GetMesh()
743 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
744 meshes[0].SetParameters(Parameters)
746 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
747 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
749 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
750 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
751 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
754 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
756 Create a mesh by copying a part of another mesh.
759 meshPart: a part of mesh to copy, either
760 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
761 To copy nodes or elements not forming any mesh object,
762 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
763 meshName: a name of the new mesh
764 toCopyGroups: to create in the new mesh groups the copied elements belongs to
765 toKeepIDs: to preserve order of the copied elements or not
768 an instance of class :class:`Mesh`
771 if (isinstance( meshPart, Mesh )):
772 meshPart = meshPart.GetMesh()
773 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
774 return Mesh(self, self.geompyD, mesh)
776 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
778 Return IDs of sub-shapes
781 theMainObject (GEOM.GEOM_Object): a shape
782 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
784 the list of integer values
787 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
789 def GetPattern(self):
791 Create a pattern mapper.
794 an instance of :class:`SMESH.SMESH_Pattern`
796 :ref:`Example of Patterns usage <tui_pattern_mapping>`
799 return SMESH._objref_SMESH_Gen.GetPattern(self)
801 def SetBoundaryBoxSegmentation(self, nbSegments):
803 Set number of segments per diagonal of boundary box of geometry, by which
804 default segment length of appropriate 1D hypotheses is defined in GUI.
808 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
810 # Filtering. Auxiliary functions:
811 # ------------------------------
813 def GetEmptyCriterion(self):
815 Create an empty criterion
818 :class:`SMESH.Filter.Criterion`
821 Type = self.EnumToLong(FT_Undefined)
822 Compare = self.EnumToLong(FT_Undefined)
826 UnaryOp = self.EnumToLong(FT_Undefined)
827 BinaryOp = self.EnumToLong(FT_Undefined)
830 Precision = -1 ##@1e-07
831 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
832 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
834 def GetCriterion(self,elementType,
836 Compare = FT_EqualTo,
838 UnaryOp=FT_Undefined,
839 BinaryOp=FT_Undefined,
842 Create a criterion by the given parameters
843 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
846 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
847 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
848 Note that the items starting from FT_LessThan are not suitable for *CritType*.
849 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
850 Threshold: the threshold value (range of ids as string, shape, numeric)
851 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
852 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
854 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
855 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
858 :class:`SMESH.Filter.Criterion`
860 Example: :ref:`combining_filters`
863 if not CritType in SMESH.FunctorType._items:
864 raise TypeError("CritType should be of SMESH.FunctorType")
865 aCriterion = self.GetEmptyCriterion()
866 aCriterion.TypeOfElement = elementType
867 aCriterion.Type = self.EnumToLong(CritType)
868 aCriterion.Tolerance = Tolerance
870 aThreshold = Threshold
872 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
873 aCriterion.Compare = self.EnumToLong(Compare)
874 elif Compare == "=" or Compare == "==":
875 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
877 aCriterion.Compare = self.EnumToLong(FT_LessThan)
879 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
880 elif Compare != FT_Undefined:
881 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
884 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
885 FT_BelongToCylinder, FT_LyingOnGeom]:
886 # Check that Threshold is GEOM object
887 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
888 aCriterion.ThresholdStr = GetName(aThreshold)
889 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
890 if not aCriterion.ThresholdID:
891 name = aCriterion.ThresholdStr
893 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
894 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
895 # or a name of GEOM object
896 elif isinstance( aThreshold, str ):
897 aCriterion.ThresholdStr = aThreshold
899 raise TypeError("The Threshold should be a shape.")
900 if isinstance(UnaryOp,float):
901 aCriterion.Tolerance = UnaryOp
902 UnaryOp = FT_Undefined
904 elif CritType == FT_BelongToMeshGroup:
905 # Check that Threshold is a group
906 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
907 if aThreshold.GetType() != elementType:
908 raise ValueError("Group type mismatches Element type")
909 aCriterion.ThresholdStr = aThreshold.GetName()
910 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
911 study = salome.myStudy
913 so = study.FindObjectIOR( aCriterion.ThresholdID )
917 aCriterion.ThresholdID = entry
919 raise TypeError("The Threshold should be a Mesh Group")
920 elif CritType == FT_RangeOfIds:
921 # Check that Threshold is string
922 if isinstance(aThreshold, str):
923 aCriterion.ThresholdStr = aThreshold
925 raise TypeError("The Threshold should be a string.")
926 elif CritType == FT_CoplanarFaces:
927 # Check the Threshold
928 if isinstance(aThreshold, int):
929 aCriterion.ThresholdID = str(aThreshold)
930 elif isinstance(aThreshold, str):
933 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
934 aCriterion.ThresholdID = aThreshold
936 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
937 elif CritType == FT_ConnectedElements:
938 # Check the Threshold
939 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
940 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
941 if not aCriterion.ThresholdID:
942 name = aThreshold.GetName()
944 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
945 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
946 elif isinstance(aThreshold, int): # node id
947 aCriterion.Threshold = aThreshold
948 elif isinstance(aThreshold, list): # 3 point coordinates
949 if len( aThreshold ) < 3:
950 raise ValueError("too few point coordinates, must be 3")
951 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
952 elif isinstance(aThreshold, str):
953 if aThreshold.isdigit():
954 aCriterion.Threshold = aThreshold # node id
956 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
958 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
959 "or a list of point coordinates and not '%s'"%aThreshold)
960 elif CritType == FT_ElemGeomType:
961 # Check the Threshold
963 aCriterion.Threshold = self.EnumToLong(aThreshold)
964 assert( aThreshold in SMESH.GeometryType._items )
966 if isinstance(aThreshold, int):
967 aCriterion.Threshold = aThreshold
969 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
972 elif CritType == FT_EntityType:
973 # Check the Threshold
975 aCriterion.Threshold = self.EnumToLong(aThreshold)
976 assert( aThreshold in SMESH.EntityType._items )
978 if isinstance(aThreshold, int):
979 aCriterion.Threshold = aThreshold
981 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
985 elif CritType == FT_GroupColor:
986 # Check the Threshold
988 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
990 raise TypeError("The threshold value should be of SALOMEDS.Color type")
992 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
993 FT_LinearOrQuadratic, FT_BadOrientedVolume,
994 FT_BareBorderFace, FT_BareBorderVolume,
995 FT_OverConstrainedFace, FT_OverConstrainedVolume,
996 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
997 # At this point the Threshold is unnecessary
998 if aThreshold == FT_LogicalNOT:
999 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1000 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1001 aCriterion.BinaryOp = aThreshold
1005 aThreshold = float(aThreshold)
1006 aCriterion.Threshold = aThreshold
1008 raise TypeError("The Threshold should be a number.")
1011 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1012 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1014 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1015 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1017 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1018 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1020 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1021 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1025 def GetFilter(self,elementType,
1026 CritType=FT_Undefined,
1029 UnaryOp=FT_Undefined,
1033 Create a filter with the given parameters
1036 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1037 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1038 Note that the items starting from FT_LessThan are not suitable for CritType.
1039 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1040 Threshold: the threshold value (range of ids as string, shape, numeric)
1041 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1042 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1043 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1044 mesh: the mesh to initialize the filter with
1047 :class:`SMESH.Filter`
1050 See :doc:`Filters usage examples <tui_filters>`
1053 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1054 aFilterMgr = self.CreateFilterManager()
1055 aFilter = aFilterMgr.CreateFilter()
1057 aCriteria.append(aCriterion)
1058 aFilter.SetCriteria(aCriteria)
1060 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1061 else : aFilter.SetMesh( mesh )
1062 aFilterMgr.UnRegister()
1065 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1067 Create a filter from criteria
1070 criteria: a list of :class:`SMESH.Filter.Criterion`
1071 binOp: binary operator used when binary operator of criteria is undefined
1074 :class:`SMESH.Filter`
1077 See :doc:`Filters usage examples <tui_filters>`
1080 for i in range( len( criteria ) - 1 ):
1081 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1082 criteria[i].BinaryOp = self.EnumToLong( binOp )
1083 aFilterMgr = self.CreateFilterManager()
1084 aFilter = aFilterMgr.CreateFilter()
1085 aFilter.SetCriteria(criteria)
1086 aFilterMgr.UnRegister()
1089 def GetFunctor(self,theCriterion):
1091 Create a numerical functor by its type
1094 theCriterion (SMESH.FunctorType): functor type.
1095 Note that not all items correspond to numerical functors.
1098 :class:`SMESH.NumericalFunctor`
1101 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1103 aFilterMgr = self.CreateFilterManager()
1105 if theCriterion == FT_AspectRatio:
1106 functor = aFilterMgr.CreateAspectRatio()
1107 elif theCriterion == FT_AspectRatio3D:
1108 functor = aFilterMgr.CreateAspectRatio3D()
1109 elif theCriterion == FT_Warping:
1110 functor = aFilterMgr.CreateWarping()
1111 elif theCriterion == FT_MinimumAngle:
1112 functor = aFilterMgr.CreateMinimumAngle()
1113 elif theCriterion == FT_Taper:
1114 functor = aFilterMgr.CreateTaper()
1115 elif theCriterion == FT_Skew:
1116 functor = aFilterMgr.CreateSkew()
1117 elif theCriterion == FT_Area:
1118 functor = aFilterMgr.CreateArea()
1119 elif theCriterion == FT_Volume3D:
1120 functor = aFilterMgr.CreateVolume3D()
1121 elif theCriterion == FT_MaxElementLength2D:
1122 functor = aFilterMgr.CreateMaxElementLength2D()
1123 elif theCriterion == FT_MaxElementLength3D:
1124 functor = aFilterMgr.CreateMaxElementLength3D()
1125 elif theCriterion == FT_MultiConnection:
1126 functor = aFilterMgr.CreateMultiConnection()
1127 elif theCriterion == FT_MultiConnection2D:
1128 functor = aFilterMgr.CreateMultiConnection2D()
1129 elif theCriterion == FT_Length:
1130 functor = aFilterMgr.CreateLength()
1131 elif theCriterion == FT_Length2D:
1132 functor = aFilterMgr.CreateLength2D()
1133 elif theCriterion == FT_Deflection2D:
1134 functor = aFilterMgr.CreateDeflection2D()
1135 elif theCriterion == FT_NodeConnectivityNumber:
1136 functor = aFilterMgr.CreateNodeConnectivityNumber()
1137 elif theCriterion == FT_BallDiameter:
1138 functor = aFilterMgr.CreateBallDiameter()
1140 print("Error: given parameter is not numerical functor type.")
1141 aFilterMgr.UnRegister()
1144 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1149 theHType (string): mesh hypothesis type
1150 theLibName (string): mesh plug-in library name
1153 created hypothesis instance
1155 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1157 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1160 # wrap hypothesis methods
1161 for meth_name in dir( hyp.__class__ ):
1162 if not meth_name.startswith("Get") and \
1163 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1164 method = getattr ( hyp.__class__, meth_name )
1165 if callable(method):
1166 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1170 def GetMeshInfo(self, obj):
1172 Get the mesh statistic.
1173 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1174 an item of :class:`SMESH.EntityType`.
1177 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1180 if isinstance( obj, Mesh ):
1183 if hasattr(obj, "GetMeshInfo"):
1184 values = obj.GetMeshInfo()
1185 for i in range(SMESH.Entity_Last._v):
1186 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1190 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1192 Get minimum distance between two objects
1194 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1195 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1198 src1 (SMESH.SMESH_IDSource): first source object
1199 src2 (SMESH.SMESH_IDSource): second source object
1200 id1 (int): node/element id from the first source
1201 id2 (int): node/element id from the second (or first) source
1202 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1203 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1206 minimum distance value
1209 :meth:`GetMinDistance`
1212 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1216 result = result.value
1219 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1221 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1223 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1224 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1227 src1 (SMESH.SMESH_IDSource): first source object
1228 src2 (SMESH.SMESH_IDSource): second source object
1229 id1 (int): node/element id from the first source
1230 id2 (int): node/element id from the second (or first) source
1231 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1232 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1235 :class:`SMESH.Measure` structure or None if input data is invalid
1240 if isinstance(src1, Mesh): src1 = src1.mesh
1241 if isinstance(src2, Mesh): src2 = src2.mesh
1242 if src2 is None and id2 != 0: src2 = src1
1243 if not hasattr(src1, "_narrow"): return None
1244 src1 = src1._narrow(SMESH.SMESH_IDSource)
1245 if not src1: return None
1246 unRegister = genObjUnRegister()
1249 e = m.GetMeshEditor()
1251 src1 = e.MakeIDSource([id1], SMESH.FACE)
1253 src1 = e.MakeIDSource([id1], SMESH.NODE)
1254 unRegister.set( src1 )
1256 if hasattr(src2, "_narrow"):
1257 src2 = src2._narrow(SMESH.SMESH_IDSource)
1258 if src2 and id2 != 0:
1260 e = m.GetMeshEditor()
1262 src2 = e.MakeIDSource([id2], SMESH.FACE)
1264 src2 = e.MakeIDSource([id2], SMESH.NODE)
1265 unRegister.set( src2 )
1268 aMeasurements = self.CreateMeasurements()
1269 unRegister.set( aMeasurements )
1270 result = aMeasurements.MinDistance(src1, src2)
1273 def BoundingBox(self, objects):
1275 Get bounding box of the specified object(s)
1278 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1281 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1284 :meth:`GetBoundingBox`
1287 result = self.GetBoundingBox(objects)
1291 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1294 def GetBoundingBox(self, objects):
1296 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1299 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1302 :class:`SMESH.Measure` structure
1308 if isinstance(objects, tuple):
1309 objects = list(objects)
1310 if not isinstance(objects, list):
1314 if isinstance(o, Mesh):
1315 srclist.append(o.mesh)
1316 elif hasattr(o, "_narrow"):
1317 src = o._narrow(SMESH.SMESH_IDSource)
1318 if src: srclist.append(src)
1321 aMeasurements = self.CreateMeasurements()
1322 result = aMeasurements.BoundingBox(srclist)
1323 aMeasurements.UnRegister()
1326 def GetLength(self, obj):
1328 Get sum of lengths of all 1D elements in the mesh object.
1331 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1334 sum of lengths of all 1D elements
1337 if isinstance(obj, Mesh): obj = obj.mesh
1338 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1339 aMeasurements = self.CreateMeasurements()
1340 value = aMeasurements.Length(obj)
1341 aMeasurements.UnRegister()
1344 def GetArea(self, obj):
1346 Get sum of areas of all 2D elements in the mesh object.
1349 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1352 sum of areas of all 2D elements
1355 if isinstance(obj, Mesh): obj = obj.mesh
1356 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1357 aMeasurements = self.CreateMeasurements()
1358 value = aMeasurements.Area(obj)
1359 aMeasurements.UnRegister()
1362 def GetVolume(self, obj):
1364 Get sum of volumes of all 3D elements in the mesh object.
1367 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1370 sum of volumes of all 3D elements
1373 if isinstance(obj, Mesh): obj = obj.mesh
1374 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1375 aMeasurements = self.CreateMeasurements()
1376 value = aMeasurements.Volume(obj)
1377 aMeasurements.UnRegister()
1380 def GetGravityCenter(self, obj):
1382 Get gravity center of all nodes of the mesh object.
1385 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1388 Three components of the gravity center (x,y,z)
1390 if isinstance(obj, Mesh): obj = obj.mesh
1391 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1392 aMeasurements = self.CreateMeasurements()
1393 pointStruct = aMeasurements.GravityCenter(obj)
1394 aMeasurements.UnRegister()
1395 return pointStruct.x, pointStruct.y, pointStruct.z
1397 pass # end of class smeshBuilder
1400 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1401 """Registering the new proxy for SMESH.SMESH_Gen"""
1404 def New( instance=None, instanceGeom=None):
1406 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1407 interface to create or load meshes.
1412 salome.salome_init()
1413 from salome.smesh import smeshBuilder
1414 smesh = smeshBuilder.New()
1417 study: SALOME study, generally obtained by salome.myStudy.
1418 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1419 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1421 :class:`smeshBuilder` instance
1429 smeshInst = smeshBuilder()
1430 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1431 smeshInst.init_smesh(instanceGeom)
1435 # Public class: Mesh
1436 # ==================
1439 class Mesh(metaclass = MeshMeta):
1441 This class allows defining and managing a mesh.
1442 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1443 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1444 new nodes and elements and by changing the existing entities), to get information
1445 about a mesh and to export a mesh in different formats.
1452 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1457 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1458 sets the GUI name of this mesh to *name*.
1461 smeshpyD: an instance of smeshBuilder class
1462 geompyD: an instance of geomBuilder class
1463 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1464 name: Study name of the mesh
1467 self.smeshpyD = smeshpyD
1468 self.geompyD = geompyD
1473 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1476 # publish geom of mesh (issue 0021122)
1477 if not self.geom.GetStudyEntry():
1481 geo_name = name + " shape"
1483 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1484 geompyD.addToStudy( self.geom, geo_name )
1485 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1487 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1490 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1492 self.smeshpyD.SetName(self.mesh, name)
1494 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1497 self.geom = self.mesh.GetShapeToMesh()
1499 self.editor = self.mesh.GetMeshEditor()
1500 self.functors = [None] * SMESH.FT_Undefined._v
1502 # set self to algoCreator's
1503 for attrName in dir(self):
1504 attr = getattr( self, attrName )
1505 if isinstance( attr, algoCreator ):
1506 setattr( self, attrName, attr.copy( self ))
1513 Destructor. Clean-up resources
1516 #self.mesh.UnRegister()
1520 def SetMesh(self, theMesh):
1522 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1525 theMesh: a :class:`SMESH.SMESH_Mesh` object
1529 # do not call Register() as this prevents mesh servant deletion at closing study
1530 #if self.mesh: self.mesh.UnRegister()
1533 #self.mesh.Register()
1534 self.geom = self.mesh.GetShapeToMesh()
1539 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1542 a :class:`SMESH.SMESH_Mesh` object
1549 Get the name of the mesh
1552 the name of the mesh as a string
1555 name = GetName(self.GetMesh())
1558 def SetName(self, name):
1560 Set a name to the mesh
1563 name: a new name of the mesh
1566 self.smeshpyD.SetName(self.GetMesh(), name)
1568 def GetSubMesh(self, geom, name):
1570 Get a sub-mesh object associated to a *geom* geometrical object.
1573 geom: a geometrical object (shape)
1574 name: a name for the sub-mesh in the Object Browser
1577 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1578 which lies on the given shape
1581 A sub-mesh is implicitly created when a sub-shape is specified at
1582 creating an algorithm, for example::
1584 algo1D = mesh.Segment(geom=Edge_1)
1586 creates a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1587 The created sub-mesh can be retrieved from the algorithm::
1589 submesh = algo1D.GetSubMesh()
1592 AssureGeomPublished( self, geom, name )
1593 submesh = self.mesh.GetSubMesh( geom, name )
1598 Return the shape associated to the mesh
1606 def SetShape(self, geom):
1608 Associate the given shape to the mesh (entails the recreation of the mesh)
1611 geom: the shape to be meshed (GEOM_Object)
1614 self.mesh = self.smeshpyD.CreateMesh(geom)
1618 Load mesh from the study after opening the study
1622 def IsReadyToCompute(self, theSubObject):
1624 Return true if the hypotheses are defined well
1627 theSubObject: a sub-shape of a mesh shape
1633 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1635 def GetAlgoState(self, theSubObject):
1637 Return errors of hypotheses definition.
1638 The list of errors is empty if everything is OK.
1641 theSubObject: a sub-shape of a mesh shape
1647 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1649 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1651 Return a geometrical object on which the given element was built.
1652 The returned geometrical object, if not nil, is either found in the
1653 study or published by this method with the given name
1656 theElementID: the id of the mesh element
1657 theGeomName: the user-defined name of the geometrical object
1660 GEOM.GEOM_Object instance
1663 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1665 def MeshDimension(self):
1667 Return the mesh dimension depending on the dimension of the underlying shape
1668 or, if the mesh is not based on any shape, basing on deimension of elements
1671 mesh dimension as an integer value [0,3]
1674 if self.mesh.HasShapeToMesh():
1675 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1676 if len( shells ) > 0 :
1678 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1680 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1685 if self.NbVolumes() > 0: return 3
1686 if self.NbFaces() > 0: return 2
1687 if self.NbEdges() > 0: return 1
1690 def Evaluate(self, geom=0):
1692 Evaluate size of prospective mesh on a shape
1695 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1696 To know predicted number of e.g. edges, inquire it this way::
1698 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1701 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1703 geom = self.mesh.GetShapeToMesh()
1706 return self.smeshpyD.Evaluate(self.mesh, geom)
1709 def Compute(self, geom=0, discardModifs=False, refresh=False):
1711 Compute the mesh and return the status of the computation
1714 geom: geomtrical shape on which mesh data should be computed
1715 discardModifs: if True and the mesh has been edited since
1716 a last total re-compute and that may prevent successful partial re-compute,
1717 then the mesh is cleaned before Compute()
1718 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1724 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1726 geom = self.mesh.GetShapeToMesh()
1731 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1733 ok = self.smeshpyD.Compute(self.mesh, geom)
1734 except SALOME.SALOME_Exception as ex:
1735 print("Mesh computation failed, exception caught:")
1736 print(" ", ex.details.text)
1739 print("Mesh computation failed, exception caught:")
1740 traceback.print_exc()
1744 # Treat compute errors
1745 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1747 for err in computeErrors:
1748 if self.mesh.HasShapeToMesh():
1749 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1751 stdErrors = ["OK", #COMPERR_OK
1752 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1753 "std::exception", #COMPERR_STD_EXCEPTION
1754 "OCC exception", #COMPERR_OCC_EXCEPTION
1755 "..", #COMPERR_SLM_EXCEPTION
1756 "Unknown exception", #COMPERR_EXCEPTION
1757 "Memory allocation problem", #COMPERR_MEMORY_PB
1758 "Algorithm failed", #COMPERR_ALGO_FAILED
1759 "Unexpected geometry", #COMPERR_BAD_SHAPE
1760 "Warning", #COMPERR_WARNING
1761 "Computation cancelled",#COMPERR_CANCELED
1762 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1764 if err.code < len(stdErrors): errText = stdErrors[err.code]
1766 errText = "code %s" % -err.code
1767 if errText: errText += ". "
1768 errText += err.comment
1769 if allReasons: allReasons += "\n"
1771 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1773 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1777 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1779 if err.isGlobalAlgo:
1787 reason = '%s %sD algorithm is missing' % (glob, dim)
1788 elif err.state == HYP_MISSING:
1789 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1790 % (glob, dim, name, dim))
1791 elif err.state == HYP_NOTCONFORM:
1792 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1793 elif err.state == HYP_BAD_PARAMETER:
1794 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1795 % ( glob, dim, name ))
1796 elif err.state == HYP_BAD_GEOMETRY:
1797 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1798 'geometry' % ( glob, dim, name ))
1799 elif err.state == HYP_HIDDEN_ALGO:
1800 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1801 'algorithm of upper dimension generating %sD mesh'
1802 % ( glob, dim, name, glob, dim ))
1804 reason = ("For unknown reason. "
1805 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1807 if allReasons: allReasons += "\n"
1808 allReasons += "- " + reason
1810 if not ok or allReasons != "":
1811 msg = '"' + GetName(self.mesh) + '"'
1812 if ok: msg += " has been computed with warnings"
1813 else: msg += " has not been computed"
1814 if allReasons != "": msg += ":"
1819 if salome.sg.hasDesktop():
1820 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1821 smeshgui = salome.ImportComponentGUI("SMESH")
1823 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
1824 if refresh: salome.sg.updateObjBrowser()
1828 def GetComputeErrors(self, shape=0 ):
1830 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1834 shape = self.mesh.GetShapeToMesh()
1835 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1837 def GetSubShapeName(self, subShapeID ):
1839 Return a name of a sub-shape by its ID.
1840 Possible variants (for *subShapeID* == 3):
1842 - **"Face_12"** - published sub-shape
1843 - **FACE #3** - not published sub-shape
1844 - **sub-shape #3** - invalid sub-shape ID
1845 - **#3** - error in this function
1848 subShapeID: a unique ID of a sub-shape
1851 a string describing the sub-shape
1855 if not self.mesh.HasShapeToMesh():
1859 mainIOR = salome.orb.object_to_string( self.GetShape() )
1861 mainSO = s.FindObjectIOR(mainIOR)
1864 shapeText = '"%s"' % mainSO.GetName()
1865 subIt = s.NewChildIterator(mainSO)
1867 subSO = subIt.Value()
1869 obj = subSO.GetObject()
1870 if not obj: continue
1871 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1874 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1877 if ids == subShapeID:
1878 shapeText = '"%s"' % subSO.GetName()
1881 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1883 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1885 shapeText = 'sub-shape #%s' % (subShapeID)
1887 shapeText = "#%s" % (subShapeID)
1890 def GetFailedShapes(self, publish=False):
1892 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1893 error of an algorithm
1896 publish: if *True*, the returned groups will be published in the study
1899 a list of GEOM groups each named after a failed algorithm
1904 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1905 for err in computeErrors:
1906 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1907 if not shape: continue
1908 if err.algoName in algo2shapes:
1909 algo2shapes[ err.algoName ].append( shape )
1911 algo2shapes[ err.algoName ] = [ shape ]
1915 for algoName, shapes in list(algo2shapes.items()):
1917 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1918 otherTypeShapes = []
1920 group = self.geompyD.CreateGroup( self.geom, groupType )
1921 for shape in shapes:
1922 if shape.GetShapeType() == shapes[0].GetShapeType():
1923 sameTypeShapes.append( shape )
1925 otherTypeShapes.append( shape )
1926 self.geompyD.UnionList( group, sameTypeShapes )
1928 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1930 group.SetName( algoName )
1931 groups.append( group )
1932 shapes = otherTypeShapes
1935 for group in groups:
1936 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1939 def GetMeshOrder(self):
1941 Return sub-mesh objects list in meshing order
1944 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1947 return self.mesh.GetMeshOrder()
1949 def SetMeshOrder(self, submeshes):
1951 Set order in which concurrent sub-meshes should be meshed
1954 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1957 return self.mesh.SetMeshOrder(submeshes)
1959 def Clear(self, refresh=False):
1961 Remove all nodes and elements generated on geometry. Imported elements remain.
1964 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1968 if ( salome.sg.hasDesktop() ):
1969 smeshgui = salome.ImportComponentGUI("SMESH")
1971 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1972 if refresh: salome.sg.updateObjBrowser()
1974 def ClearSubMesh(self, geomId, refresh=False):
1976 Remove all nodes and elements of indicated shape
1979 geomId: the ID of a sub-shape to remove elements on
1980 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1983 self.mesh.ClearSubMesh(geomId)
1984 if salome.sg.hasDesktop():
1985 smeshgui = salome.ImportComponentGUI("SMESH")
1987 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1988 if refresh: salome.sg.updateObjBrowser()
1990 def AutomaticTetrahedralization(self, fineness=0):
1992 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
1995 fineness: [0.0,1.0] defines mesh fineness
2001 dim = self.MeshDimension()
2003 self.RemoveGlobalHypotheses()
2004 self.Segment().AutomaticLength(fineness)
2006 self.Triangle().LengthFromEdges()
2011 return self.Compute()
2013 def AutomaticHexahedralization(self, fineness=0):
2015 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2018 fineness: [0.0, 1.0] defines mesh fineness
2024 dim = self.MeshDimension()
2025 # assign the hypotheses
2026 self.RemoveGlobalHypotheses()
2027 self.Segment().AutomaticLength(fineness)
2034 return self.Compute()
2036 def AddHypothesis(self, hyp, geom=0):
2041 hyp: a hypothesis to assign
2042 geom: a subhape of mesh geometry
2045 :class:`SMESH.Hypothesis_Status`
2048 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2049 hyp, geom = geom, hyp
2050 if isinstance( hyp, Mesh_Algorithm ):
2051 hyp = hyp.GetAlgorithm()
2056 geom = self.mesh.GetShapeToMesh()
2059 if self.mesh.HasShapeToMesh():
2060 hyp_type = hyp.GetName()
2061 lib_name = hyp.GetLibName()
2062 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2063 # if checkAll and geom:
2064 # checkAll = geom.GetType() == 37
2066 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2068 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2069 status = self.mesh.AddHypothesis(geom, hyp)
2071 status = HYP_BAD_GEOMETRY, ""
2072 hyp_name = GetName( hyp )
2075 geom_name = geom.GetName()
2076 isAlgo = hyp._narrow( SMESH_Algo )
2077 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2080 def IsUsedHypothesis(self, hyp, geom):
2082 Return True if an algorithm or hypothesis is assigned to a given shape
2085 hyp: an algorithm or hypothesis to check
2086 geom: a subhape of mesh geometry
2092 if not hyp: # or not geom
2094 if isinstance( hyp, Mesh_Algorithm ):
2095 hyp = hyp.GetAlgorithm()
2097 hyps = self.GetHypothesisList(geom)
2099 if h.GetId() == hyp.GetId():
2103 def RemoveHypothesis(self, hyp, geom=0):
2105 Unassign a hypothesis
2108 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2109 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2112 :class:`SMESH.Hypothesis_Status`
2117 if isinstance( hyp, Mesh_Algorithm ):
2118 hyp = hyp.GetAlgorithm()
2124 if self.IsUsedHypothesis( hyp, shape ):
2125 return self.mesh.RemoveHypothesis( shape, hyp )
2126 hypName = GetName( hyp )
2127 geoName = GetName( shape )
2128 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2131 def GetHypothesisList(self, geom):
2133 Get the list of hypotheses added on a geometry
2136 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2139 the sequence of :class:`SMESH.SMESH_Hypothesis`
2142 return self.mesh.GetHypothesisList( geom )
2144 def RemoveGlobalHypotheses(self):
2146 Remove all global hypotheses
2149 current_hyps = self.mesh.GetHypothesisList( self.geom )
2150 for hyp in current_hyps:
2151 self.mesh.RemoveHypothesis( self.geom, hyp )
2154 def ExportMED(self, *args, **kwargs):
2156 Export the mesh in a file in MED format
2157 allowing to overwrite the file if it exists or add the exported data to its contents
2160 fileName: is the file name
2161 auto_groups (boolean): parameter for creating/not creating
2162 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2163 the typical use is auto_groups=False.
2164 overwrite (boolean): parameter for overwriting/not overwriting the file
2165 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2166 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2168 - 1D if all mesh nodes lie on OX coordinate axis, or
2169 - 2D if all mesh nodes lie on XOY coordinate plane, or
2170 - 3D in the rest cases.
2172 If *autoDimension* is *False*, the space dimension is always 3.
2173 fields: list of GEOM fields defined on the shape to mesh.
2174 geomAssocFields: each character of this string means a need to export a
2175 corresponding field; correspondence between fields and characters is following:
2176 - 'v' stands for "_vertices _" field;
2177 - 'e' stands for "_edges _" field;
2178 - 'f' stands for "_faces _" field;
2179 - 's' stands for "_solids _" field.
2181 # process positional arguments
2182 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2184 auto_groups = args[1] if len(args) > 1 else False
2185 overwrite = args[2] if len(args) > 2 else True
2186 meshPart = args[3] if len(args) > 3 else None
2187 autoDimension = args[4] if len(args) > 4 else True
2188 fields = args[5] if len(args) > 5 else []
2189 geomAssocFields = args[6] if len(args) > 6 else ''
2190 # process keywords arguments
2191 auto_groups = kwargs.get("auto_groups", auto_groups)
2192 overwrite = kwargs.get("overwrite", overwrite)
2193 meshPart = kwargs.get("meshPart", meshPart)
2194 autoDimension = kwargs.get("autoDimension", autoDimension)
2195 fields = kwargs.get("fields", fields)
2196 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2197 # invoke engine's function
2198 if meshPart or fields or geomAssocFields:
2199 unRegister = genObjUnRegister()
2200 if isinstance( meshPart, list ):
2201 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2202 unRegister.set( meshPart )
2203 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, overwrite, autoDimension,
2204 fields, geomAssocFields)
2206 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2208 def ExportSAUV(self, f, auto_groups=0):
2210 Export the mesh in a file in SAUV format
2215 auto_groups: boolean parameter for creating/not creating
2216 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2217 the typical use is auto_groups=False.
2220 self.mesh.ExportSAUV(f, auto_groups)
2222 def ExportDAT(self, f, meshPart=None):
2224 Export the mesh in a file in DAT format
2228 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2232 unRegister = genObjUnRegister()
2233 if isinstance( meshPart, list ):
2234 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2235 unRegister.set( meshPart )
2236 self.mesh.ExportPartToDAT( meshPart, f )
2238 self.mesh.ExportDAT(f)
2240 def ExportUNV(self, f, meshPart=None):
2242 Export the mesh in a file in UNV format
2246 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2250 unRegister = genObjUnRegister()
2251 if isinstance( meshPart, list ):
2252 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2253 unRegister.set( meshPart )
2254 self.mesh.ExportPartToUNV( meshPart, f )
2256 self.mesh.ExportUNV(f)
2258 def ExportSTL(self, f, ascii=1, meshPart=None):
2260 Export the mesh in a file in STL format
2264 ascii: defines the file encoding
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.ExportPartToSTL( meshPart, f, ascii )
2275 self.mesh.ExportSTL(f, ascii)
2277 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2279 Export the mesh in a file in CGNS format
2283 overwrite: boolean parameter for overwriting/not overwriting the file
2284 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2285 groupElemsByType: if True all elements of same entity type are exported at ones,
2286 else elements are exported in order of their IDs which can cause creation
2287 of multiple cgns sections
2290 unRegister = genObjUnRegister()
2291 if isinstance( meshPart, list ):
2292 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2293 unRegister.set( meshPart )
2294 if isinstance( meshPart, Mesh ):
2295 meshPart = meshPart.mesh
2297 meshPart = self.mesh
2298 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2300 def ExportGMF(self, f, meshPart=None):
2302 Export the mesh in a file in GMF format.
2303 GMF files must have .mesh extension for the ASCII format and .meshb for
2304 the bynary format. Other extensions are not allowed.
2308 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2311 unRegister = genObjUnRegister()
2312 if isinstance( meshPart, list ):
2313 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2314 unRegister.set( meshPart )
2315 if isinstance( meshPart, Mesh ):
2316 meshPart = meshPart.mesh
2318 meshPart = self.mesh
2319 self.mesh.ExportGMF(meshPart, f, True)
2321 def ExportToMED(self, *args, **kwargs):
2323 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2324 Export the mesh in a file in MED format
2325 allowing to overwrite the file if it exists or add the exported data to its contents
2328 fileName: the file name
2329 opt (boolean): parameter for creating/not creating
2330 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2331 overwrite: boolean parameter for overwriting/not overwriting the file
2332 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2334 - 1D if all mesh nodes lie on OX coordinate axis, or
2335 - 2D if all mesh nodes lie on XOY coordinate plane, or
2336 - 3D in the rest cases.
2338 If **autoDimension** is *False*, the space dimension is always 3.
2341 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2342 # process positional arguments
2343 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2345 auto_groups = args[1] if len(args) > 1 else False
2346 overwrite = args[2] if len(args) > 2 else True
2347 autoDimension = args[3] if len(args) > 3 else True
2348 # process keywords arguments
2349 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2350 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2351 overwrite = kwargs.get("overwrite", overwrite)
2352 autoDimension = kwargs.get("autoDimension", autoDimension)
2353 # invoke engine's function
2354 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2356 def ExportToMEDX(self, *args, **kwargs):
2358 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2359 Export the mesh in a file in MED format
2362 fileName: the file name
2363 opt (boolean): parameter for creating/not creating
2364 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2365 overwrite: boolean parameter for overwriting/not overwriting the file
2366 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2368 - 1D if all mesh nodes lie on OX coordinate axis, or
2369 - 2D if all mesh nodes lie on XOY coordinate plane, or
2370 - 3D in the rest cases.
2372 If **autoDimension** is *False*, the space dimension is always 3.
2375 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2376 # process positional arguments
2377 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2379 auto_groups = args[1] if len(args) > 1 else False
2380 overwrite = args[2] if len(args) > 2 else True
2381 autoDimension = args[3] if len(args) > 3 else True
2382 # process keywords arguments
2383 auto_groups = kwargs.get("auto_groups", auto_groups)
2384 overwrite = kwargs.get("overwrite", overwrite)
2385 autoDimension = kwargs.get("autoDimension", autoDimension)
2386 # invoke engine's function
2387 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2389 # Operations with groups:
2390 # ----------------------
2391 def CreateEmptyGroup(self, elementType, name):
2393 Create an empty mesh group
2396 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2397 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2398 name: the name of the mesh group
2401 :class:`SMESH.SMESH_Group`
2404 return self.mesh.CreateGroup(elementType, name)
2406 def Group(self, grp, name=""):
2408 Create a mesh group based on the geometric object *grp*
2409 and give it a *name*.
2410 If *name* is not defined the name of the geometric group is used
2413 Works like :meth:`GroupOnGeom`.
2416 grp: a geometric group, a vertex, an edge, a face or a solid
2417 name: the name of the mesh group
2420 :class:`SMESH.SMESH_GroupOnGeom`
2423 return self.GroupOnGeom(grp, name)
2425 def GroupOnGeom(self, grp, name="", typ=None):
2427 Create a mesh group based on the geometrical object *grp*
2429 if *name* is not defined the name of the geometric group is used
2432 grp: a geometrical group, a vertex, an edge, a face or a solid
2433 name: the name of the mesh group
2434 typ: the type of elements in the group; either of
2435 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2436 automatically detected by the type of the geometry
2439 :class:`SMESH.SMESH_GroupOnGeom`
2442 AssureGeomPublished( self, grp, name )
2444 name = grp.GetName()
2446 typ = self._groupTypeFromShape( grp )
2447 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2449 def _groupTypeFromShape( self, shape ):
2451 Pivate method to get a type of group on geometry
2453 tgeo = str(shape.GetShapeType())
2454 if tgeo == "VERTEX":
2456 elif tgeo == "EDGE":
2458 elif tgeo == "FACE" or tgeo == "SHELL":
2460 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2462 elif tgeo == "COMPOUND":
2463 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2465 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2466 return self._groupTypeFromShape( sub[0] )
2468 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2471 def GroupOnFilter(self, typ, name, filter):
2473 Create a mesh group with given *name* based on the *filter* which
2474 is a special type of group dynamically updating it's contents during
2478 typ: the type of elements in the group; either of
2479 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2480 name: the name of the mesh group
2481 filter (SMESH.Filter): the filter defining group contents
2484 :class:`SMESH.SMESH_GroupOnFilter`
2487 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2489 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2491 Create a mesh group by the given ids of elements
2494 groupName: the name of the mesh group
2495 elementType: the type of elements in the group; either of
2496 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2497 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2500 :class:`SMESH.SMESH_Group`
2503 group = self.mesh.CreateGroup(elementType, groupName)
2504 if isinstance( elemIDs, Mesh ):
2505 elemIDs = elemIDs.GetMesh()
2506 if hasattr( elemIDs, "GetIDs" ):
2507 if hasattr( elemIDs, "SetMesh" ):
2508 elemIDs.SetMesh( self.GetMesh() )
2509 group.AddFrom( elemIDs )
2517 CritType=FT_Undefined,
2520 UnaryOp=FT_Undefined,
2523 Create a mesh group by the given conditions
2526 groupName: the name of the mesh group
2527 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2528 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2529 Note that the items starting from FT_LessThan are not suitable for CritType.
2530 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2531 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2532 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2533 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2534 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2537 :class:`SMESH.SMESH_GroupOnFilter`
2540 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2541 group = self.MakeGroupByCriterion(groupName, aCriterion)
2544 def MakeGroupByCriterion(self, groupName, Criterion):
2546 Create a mesh group by the given criterion
2549 groupName: the name of the mesh group
2550 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2553 :class:`SMESH.SMESH_GroupOnFilter`
2556 :meth:`smeshBuilder.GetCriterion`
2559 return self.MakeGroupByCriteria( groupName, [Criterion] )
2561 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2563 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2566 groupName: the name of the mesh group
2567 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2568 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2571 :class:`SMESH.SMESH_GroupOnFilter`
2574 :meth:`smeshBuilder.GetCriterion`
2577 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2578 group = self.MakeGroupByFilter(groupName, aFilter)
2581 def MakeGroupByFilter(self, groupName, theFilter):
2583 Create a mesh group by the given filter
2586 groupName (string): the name of the mesh group
2587 theFilter (SMESH.Filter): the filter
2590 :class:`SMESH.SMESH_GroupOnFilter`
2593 :meth:`smeshBuilder.GetFilter`
2596 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2597 #theFilter.SetMesh( self.mesh )
2598 #group.AddFrom( theFilter )
2599 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2602 def RemoveGroup(self, group):
2607 group (SMESH.SMESH_GroupBase): group to remove
2610 self.mesh.RemoveGroup(group)
2612 def RemoveGroupWithContents(self, group):
2614 Remove a group with its contents
2617 group (SMESH.SMESH_GroupBase): group to remove
2620 self.mesh.RemoveGroupWithContents(group)
2622 def GetGroups(self, elemType = SMESH.ALL):
2624 Get the list of groups existing in the mesh in the order
2625 of creation (starting from the oldest one)
2628 elemType (SMESH.ElementType): type of elements the groups contain;
2629 by default groups of elements of all types are returned
2632 a sequence of :class:`SMESH.SMESH_GroupBase`
2635 groups = self.mesh.GetGroups()
2636 if elemType == SMESH.ALL:
2640 if g.GetType() == elemType:
2641 typedGroups.append( g )
2648 Get the number of groups existing in the mesh
2651 the quantity of groups as an integer value
2654 return self.mesh.NbGroups()
2656 def GetGroupNames(self):
2658 Get the list of names of groups existing in the mesh
2664 groups = self.GetGroups()
2666 for group in groups:
2667 names.append(group.GetName())
2670 def GetGroupByName(self, name, elemType = None):
2672 Find groups by name and type
2675 name (string): name of the group of interest
2676 elemType (SMESH.ElementType): type of elements the groups contain;
2677 by default one group of any type is returned;
2678 if elemType == SMESH.ALL then all groups of any type are returned
2681 a list of :class:`SMESH.SMESH_GroupBase`
2685 for group in self.GetGroups():
2686 if group.GetName() == name:
2687 if elemType is None:
2689 if ( elemType == SMESH.ALL or
2690 group.GetType() == elemType ):
2691 groups.append( group )
2694 def UnionGroups(self, group1, group2, name):
2696 Produce a union of two groups.
2697 A new group is created. All mesh elements that are
2698 present in the initial groups are added to the new one
2701 group1 (SMESH.SMESH_GroupBase): a group
2702 group2 (SMESH.SMESH_GroupBase): another group
2705 instance of :class:`SMESH.SMESH_Group`
2708 return self.mesh.UnionGroups(group1, group2, name)
2710 def UnionListOfGroups(self, groups, name):
2712 Produce a union list of groups.
2713 New group is created. All mesh elements that are present in
2714 initial groups are added to the new one
2717 groups: list of :class:`SMESH.SMESH_GroupBase`
2720 instance of :class:`SMESH.SMESH_Group`
2722 return self.mesh.UnionListOfGroups(groups, name)
2724 def IntersectGroups(self, group1, group2, name):
2726 Prodice an intersection of two groups.
2727 A new group is created. All mesh elements that are common
2728 for the two initial groups are added to the new one.
2731 group1 (SMESH.SMESH_GroupBase): a group
2732 group2 (SMESH.SMESH_GroupBase): another group
2735 instance of :class:`SMESH.SMESH_Group`
2738 return self.mesh.IntersectGroups(group1, group2, name)
2740 def IntersectListOfGroups(self, groups, name):
2742 Produce an intersection of groups.
2743 New group is created. All mesh elements that are present in all
2744 initial groups simultaneously are added to the new one
2747 groups: a list of :class:`SMESH.SMESH_GroupBase`
2750 instance of :class:`SMESH.SMESH_Group`
2752 return self.mesh.IntersectListOfGroups(groups, name)
2754 def CutGroups(self, main_group, tool_group, name):
2756 Produce a cut of two groups.
2757 A new group is created. All mesh elements that are present in
2758 the main group but are not present in the tool group are added to the new one
2761 main_group (SMESH.SMESH_GroupBase): a group to cut from
2762 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2765 an instance of :class:`SMESH.SMESH_Group`
2768 return self.mesh.CutGroups(main_group, tool_group, name)
2770 def CutListOfGroups(self, main_groups, tool_groups, name):
2772 Produce a cut of groups.
2773 A new group is created. All mesh elements that are present in main groups
2774 but do not present in tool groups are added to the new one
2777 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2778 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2781 an instance of :class:`SMESH.SMESH_Group`
2784 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2786 def CreateDimGroup(self, groups, elemType, name,
2787 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2789 Create a standalone group of entities basing on nodes of other groups.
2792 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2793 elemType: a type of elements to include to the new group; either of
2794 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2795 name: a name of the new group.
2796 nbCommonNodes: a criterion of inclusion of an element to the new group
2797 basing on number of element nodes common with reference *groups*.
2798 Meaning of possible values are:
2800 - SMESH.ALL_NODES - include if all nodes are common,
2801 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2802 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2803 - SMEHS.MAJORITY - include if half of nodes or more are common.
2804 underlyingOnly: if *True* (default), an element is included to the
2805 new group provided that it is based on nodes of an element of *groups*;
2806 in this case the reference *groups* are supposed to be of higher dimension
2807 than *elemType*, which can be useful for example to get all faces lying on
2808 volumes of the reference *groups*.
2811 an instance of :class:`SMESH.SMESH_Group`
2814 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2816 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2819 def ConvertToStandalone(self, group):
2821 Convert group on geom into standalone group
2824 return self.mesh.ConvertToStandalone(group)
2826 # Get some info about mesh:
2827 # ------------------------
2829 def GetLog(self, clearAfterGet):
2831 Return the log of nodes and elements added or removed
2832 since the previous clear of the log.
2835 clearAfterGet: log is emptied after Get (safe if concurrents access)
2838 list of SMESH.log_block structures { commandType, number, coords, indexes }
2841 return self.mesh.GetLog(clearAfterGet)
2845 Clear the log of nodes and elements added or removed since the previous
2846 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2849 self.mesh.ClearLog()
2851 def SetAutoColor(self, theAutoColor):
2853 Toggle auto color mode on the object.
2854 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2857 theAutoColor (boolean): the flag which toggles auto color mode.
2860 self.mesh.SetAutoColor(theAutoColor)
2862 def GetAutoColor(self):
2864 Get flag of object auto color mode.
2870 return self.mesh.GetAutoColor()
2877 integer value, which is the internal Id of the mesh
2880 return self.mesh.GetId()
2882 def HasDuplicatedGroupNamesMED(self):
2884 Check the group names for duplications.
2885 Consider the maximum group name length stored in MED file.
2891 return self.mesh.HasDuplicatedGroupNamesMED()
2893 def GetMeshEditor(self):
2895 Obtain the mesh editor tool
2898 an instance of :class:`SMESH.SMESH_MeshEditor`
2903 def GetIDSource(self, ids, elemType = SMESH.ALL):
2905 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2906 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2910 elemType: type of elements; this parameter is used to distinguish
2911 IDs of nodes from IDs of elements; by default ids are treated as
2912 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2915 an instance of :class:`SMESH.SMESH_IDSource`
2918 call UnRegister() for the returned object as soon as it is no more useful::
2920 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2921 mesh.DoSomething( idSrc )
2925 if isinstance( ids, int ):
2927 return self.editor.MakeIDSource(ids, elemType)
2930 # Get information about mesh contents:
2931 # ------------------------------------
2933 def GetMeshInfo(self, obj = None):
2935 Get the mesh statistic.
2936 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2937 an item of :class:`SMESH.EntityType`.
2940 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2943 if not obj: obj = self.mesh
2944 return self.smeshpyD.GetMeshInfo(obj)
2948 Return the number of nodes in the mesh
2954 return self.mesh.NbNodes()
2956 def NbElements(self):
2958 Return the number of elements in the mesh
2964 return self.mesh.NbElements()
2966 def Nb0DElements(self):
2968 Return the number of 0d elements in the mesh
2974 return self.mesh.Nb0DElements()
2978 Return the number of ball discrete elements in the mesh
2984 return self.mesh.NbBalls()
2988 Return the number of edges in the mesh
2994 return self.mesh.NbEdges()
2996 def NbEdgesOfOrder(self, elementOrder):
2998 Return the number of edges with the given order in the mesh
3001 elementOrder: the order of elements
3002 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3008 return self.mesh.NbEdgesOfOrder(elementOrder)
3012 Return the number of faces in the mesh
3018 return self.mesh.NbFaces()
3020 def NbFacesOfOrder(self, elementOrder):
3022 Return the number of faces with the given order in the mesh
3025 elementOrder: the order of elements
3026 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3032 return self.mesh.NbFacesOfOrder(elementOrder)
3034 def NbTriangles(self):
3036 Return the number of triangles in the mesh
3042 return self.mesh.NbTriangles()
3044 def NbTrianglesOfOrder(self, elementOrder):
3046 Return the number of triangles with the given order in the mesh
3049 elementOrder: is the order of elements
3050 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3056 return self.mesh.NbTrianglesOfOrder(elementOrder)
3058 def NbBiQuadTriangles(self):
3060 Return the number of biquadratic triangles in the mesh
3066 return self.mesh.NbBiQuadTriangles()
3068 def NbQuadrangles(self):
3070 Return the number of quadrangles in the mesh
3076 return self.mesh.NbQuadrangles()
3078 def NbQuadranglesOfOrder(self, elementOrder):
3080 Return the number of quadrangles with the given order in the mesh
3083 elementOrder: the order of elements
3084 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3090 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3092 def NbBiQuadQuadrangles(self):
3094 Return the number of biquadratic quadrangles in the mesh
3100 return self.mesh.NbBiQuadQuadrangles()
3102 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3104 Return the number of polygons of given order in the mesh
3107 elementOrder: the order of elements
3108 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3114 return self.mesh.NbPolygonsOfOrder(elementOrder)
3116 def NbVolumes(self):
3118 Return the number of volumes in the mesh
3124 return self.mesh.NbVolumes()
3127 def NbVolumesOfOrder(self, elementOrder):
3129 Return the number of volumes with the given order in the mesh
3132 elementOrder: the order of elements
3133 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3139 return self.mesh.NbVolumesOfOrder(elementOrder)
3143 Return the number of tetrahedrons in the mesh
3149 return self.mesh.NbTetras()
3151 def NbTetrasOfOrder(self, elementOrder):
3153 Return the number of tetrahedrons with the given order in the mesh
3156 elementOrder: the order of elements
3157 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3163 return self.mesh.NbTetrasOfOrder(elementOrder)
3167 Return the number of hexahedrons in the mesh
3173 return self.mesh.NbHexas()
3175 def NbHexasOfOrder(self, elementOrder):
3177 Return the number of hexahedrons with the given order in the mesh
3180 elementOrder: the order of elements
3181 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3187 return self.mesh.NbHexasOfOrder(elementOrder)
3189 def NbTriQuadraticHexas(self):
3191 Return the number of triquadratic hexahedrons in the mesh
3197 return self.mesh.NbTriQuadraticHexas()
3199 def NbPyramids(self):
3201 Return the number of pyramids in the mesh
3207 return self.mesh.NbPyramids()
3209 def NbPyramidsOfOrder(self, elementOrder):
3211 Return the number of pyramids with the given order in the mesh
3214 elementOrder: the order of elements
3215 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3221 return self.mesh.NbPyramidsOfOrder(elementOrder)
3225 Return the number of prisms in the mesh
3231 return self.mesh.NbPrisms()
3233 def NbPrismsOfOrder(self, elementOrder):
3235 Return the number of prisms with the given order in the mesh
3238 elementOrder: the order of elements
3239 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3245 return self.mesh.NbPrismsOfOrder(elementOrder)
3247 def NbHexagonalPrisms(self):
3249 Return the number of hexagonal prisms in the mesh
3255 return self.mesh.NbHexagonalPrisms()
3257 def NbPolyhedrons(self):
3259 Return the number of polyhedrons in the mesh
3265 return self.mesh.NbPolyhedrons()
3267 def NbSubMesh(self):
3269 Return the number of submeshes in the mesh
3275 return self.mesh.NbSubMesh()
3277 def GetElementsId(self):
3279 Return the list of all mesh elements IDs
3282 the list of integer values
3285 :meth:`GetElementsByType`
3288 return self.mesh.GetElementsId()
3290 def GetElementsByType(self, elementType):
3292 Return the list of IDs of mesh elements with the given type
3295 elementType (SMESH.ElementType): the required type of elements
3298 list of integer values
3301 return self.mesh.GetElementsByType(elementType)
3303 def GetNodesId(self):
3305 Return the list of mesh nodes IDs
3308 the list of integer values
3311 return self.mesh.GetNodesId()
3313 # Get the information about mesh elements:
3314 # ------------------------------------
3316 def GetElementType(self, id, iselem=True):
3318 Return the type of mesh element or node
3321 the value from :class:`SMESH.ElementType` enumeration.
3322 Return SMESH.ALL if element or node with the given ID does not exist
3325 return self.mesh.GetElementType(id, iselem)
3327 def GetElementGeomType(self, id):
3329 Return the geometric type of mesh element
3332 the value from :class:`SMESH.EntityType` enumeration.
3335 return self.mesh.GetElementGeomType(id)
3337 def GetElementShape(self, id):
3339 Return the shape type of mesh element
3342 the value from :class:`SMESH.GeometryType` enumeration.
3345 return self.mesh.GetElementShape(id)
3347 def GetSubMeshElementsId(self, Shape):
3349 Return the list of sub-mesh elements IDs
3352 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3353 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3356 list of integer values
3359 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3360 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3363 return self.mesh.GetSubMeshElementsId(ShapeID)
3365 def GetSubMeshNodesId(self, Shape, all):
3367 Return the list of sub-mesh nodes IDs
3370 Shape: a geom object (sub-shape).
3371 *Shape* must be the sub-shape of a :meth:`GetShape`
3372 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3375 list of integer values
3378 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3379 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3382 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3384 def GetSubMeshElementType(self, Shape):
3386 Return type of elements on given shape
3389 Shape: a geom object (sub-shape).
3390 *Shape* must be a sub-shape of a ShapeToMesh()
3393 :class:`SMESH.ElementType`
3396 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3397 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3400 return self.mesh.GetSubMeshElementType(ShapeID)
3404 Get the mesh description
3410 return self.mesh.Dump()
3413 # Get the information about nodes and elements of a mesh by its IDs:
3414 # -----------------------------------------------------------
3416 def GetNodeXYZ(self, id):
3418 Get XYZ coordinates of a node.
3419 If there is no node for the given ID - return an empty list
3422 list of float values
3425 return self.mesh.GetNodeXYZ(id)
3427 def GetNodeInverseElements(self, id):
3429 Return list of IDs of inverse elements for the given node.
3430 If there is no node for the given ID - return an empty list
3433 list of integer values
3436 return self.mesh.GetNodeInverseElements(id)
3438 def GetNodePosition(self,NodeID):
3440 Return the position of a node on the shape
3443 :class:`SMESH.NodePosition`
3446 return self.mesh.GetNodePosition(NodeID)
3448 def GetElementPosition(self,ElemID):
3450 Return the position of an element on the shape
3453 :class:`SMESH.ElementPosition`
3456 return self.mesh.GetElementPosition(ElemID)
3458 def GetShapeID(self, id):
3460 Return the ID of the shape, on which the given node was generated.
3463 an integer value > 0 or -1 if there is no node for the given
3464 ID or the node is not assigned to any geometry
3467 return self.mesh.GetShapeID(id)
3469 def GetShapeIDForElem(self,id):
3471 Return the ID of the shape, on which the given element was generated.
3474 an integer value > 0 or -1 if there is no element for the given
3475 ID or the element is not assigned to any geometry
3478 return self.mesh.GetShapeIDForElem(id)
3480 def GetElemNbNodes(self, id):
3482 Return the number of nodes of the given element
3485 an integer value > 0 or -1 if there is no element for the given ID
3488 return self.mesh.GetElemNbNodes(id)
3490 def GetElemNode(self, id, index):
3492 Return the node ID the given (zero based) index for the given element.
3494 * If there is no element for the given ID - return -1.
3495 * If there is no node for the given index - return -2.
3498 id (int): element ID
3499 index (int): node index within the element
3502 an integer value (ID)
3505 :meth:`GetElemNodes`
3508 return self.mesh.GetElemNode(id, index)
3510 def GetElemNodes(self, id):
3512 Return the IDs of nodes of the given element
3515 a list of integer values
3518 return self.mesh.GetElemNodes(id)
3520 def IsMediumNode(self, elementID, nodeID):
3522 Return true if the given node is the medium node in the given quadratic element
3525 return self.mesh.IsMediumNode(elementID, nodeID)
3527 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3529 Return true if the given node is the medium node in one of quadratic elements
3532 nodeID: ID of the node
3533 elementType: the type of elements to check a state of the node, either of
3534 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3537 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3539 def ElemNbEdges(self, id):
3541 Return the number of edges for the given element
3544 return self.mesh.ElemNbEdges(id)
3546 def ElemNbFaces(self, id):
3548 Return the number of faces for the given element
3551 return self.mesh.ElemNbFaces(id)
3553 def GetElemFaceNodes(self,elemId, faceIndex):
3555 Return nodes of given face (counted from zero) for given volumic element.
3558 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3560 def GetFaceNormal(self, faceId, normalized=False):
3562 Return three components of normal of given mesh face
3563 (or an empty array in KO case)
3566 return self.mesh.GetFaceNormal(faceId,normalized)
3568 def FindElementByNodes(self, nodes):
3570 Return an element based on all given nodes.
3573 return self.mesh.FindElementByNodes(nodes)
3575 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3577 Return elements including all given nodes.
3580 return self.mesh.GetElementsByNodes( nodes, elemType )
3582 def IsPoly(self, id):
3584 Return true if the given element is a polygon
3587 return self.mesh.IsPoly(id)
3589 def IsQuadratic(self, id):
3591 Return true if the given element is quadratic
3594 return self.mesh.IsQuadratic(id)
3596 def GetBallDiameter(self, id):
3598 Return diameter of a ball discrete element or zero in case of an invalid *id*
3601 return self.mesh.GetBallDiameter(id)
3603 def BaryCenter(self, id):
3605 Return XYZ coordinates of the barycenter of the given element.
3606 If there is no element for the given ID - return an empty list
3609 a list of three double values
3612 return self.mesh.BaryCenter(id)
3614 def GetIdsFromFilter(self, theFilter):
3616 Pass mesh elements through the given filter and return IDs of fitting elements
3619 theFilter: :class:`SMESH.Filter`
3625 :meth:`SMESH.Filter.GetIDs`
3628 theFilter.SetMesh( self.mesh )
3629 return theFilter.GetIDs()
3631 # Get mesh measurements information:
3632 # ------------------------------------
3634 def GetFreeBorders(self):
3636 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3637 Return a list of special structures (borders).
3640 a list of :class:`SMESH.FreeEdges.Border`
3643 aFilterMgr = self.smeshpyD.CreateFilterManager()
3644 aPredicate = aFilterMgr.CreateFreeEdges()
3645 aPredicate.SetMesh(self.mesh)
3646 aBorders = aPredicate.GetBorders()
3647 aFilterMgr.UnRegister()
3650 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3652 Get minimum distance between two nodes, elements or distance to the origin
3655 id1: first node/element id
3656 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3657 isElem1: *True* if *id1* is element id, *False* if it is node id
3658 isElem2: *True* if *id2* is element id, *False* if it is node id
3661 minimum distance value **GetMinDistance()**
3664 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3665 return aMeasure.value
3667 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3669 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3672 id1: first node/element id
3673 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3674 isElem1: *True* if *id1* is element id, *False* if it is node id
3675 isElem2: *True* if *id2* is element id, *False* if it is node id
3678 :class:`SMESH.Measure` structure
3684 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3686 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3689 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3691 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3696 aMeasurements = self.smeshpyD.CreateMeasurements()
3697 aMeasure = aMeasurements.MinDistance(id1, id2)
3698 genObjUnRegister([aMeasurements,id1, id2])
3701 def BoundingBox(self, objects=None, isElem=False):
3703 Get bounding box of the specified object(s)
3706 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3707 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3708 *False* specifies that *objects* are nodes
3711 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3714 :meth:`GetBoundingBox()`
3717 result = self.GetBoundingBox(objects, isElem)
3721 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3724 def GetBoundingBox(self, objects=None, isElem=False):
3726 Get :class:`SMESH.Measure` structure specifying bounding box data 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 means that *objects* are elements,
3731 False means that *objects* are nodes
3734 :class:`SMESH.Measure` structure
3737 :meth:`BoundingBox()`
3741 objects = [self.mesh]
3742 elif isinstance(objects, tuple):
3743 objects = list(objects)
3744 if not isinstance(objects, list):
3746 if len(objects) > 0 and isinstance(objects[0], int):
3749 unRegister = genObjUnRegister()
3751 if isinstance(o, Mesh):
3752 srclist.append(o.mesh)
3753 elif hasattr(o, "_narrow"):
3754 src = o._narrow(SMESH.SMESH_IDSource)
3755 if src: srclist.append(src)
3757 elif isinstance(o, list):
3759 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3761 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3762 unRegister.set( srclist[-1] )
3765 aMeasurements = self.smeshpyD.CreateMeasurements()
3766 unRegister.set( aMeasurements )
3767 aMeasure = aMeasurements.BoundingBox(srclist)
3770 # Mesh edition (SMESH_MeshEditor functionality):
3771 # ---------------------------------------------
3773 def RemoveElements(self, IDsOfElements):
3775 Remove the elements from the mesh by ids
3778 IDsOfElements: is a list of ids of elements to remove
3784 return self.editor.RemoveElements(IDsOfElements)
3786 def RemoveNodes(self, IDsOfNodes):
3788 Remove nodes from mesh by ids
3791 IDsOfNodes: is a list of ids of nodes to remove
3797 return self.editor.RemoveNodes(IDsOfNodes)
3799 def RemoveOrphanNodes(self):
3801 Remove all orphan (free) nodes from mesh
3804 number of the removed nodes
3807 return self.editor.RemoveOrphanNodes()
3809 def AddNode(self, x, y, z):
3811 Add a node to the mesh by coordinates
3817 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3818 if hasVars: self.mesh.SetParameters(Parameters)
3819 return self.editor.AddNode( x, y, z)
3821 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3823 Create a 0D element on a node with given number.
3826 IDOfNode: the ID of node for creation of the element.
3827 DuplicateElements: to add one more 0D element to a node or not
3830 ID of the new 0D element
3833 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3835 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3837 Create 0D elements on all nodes of the given elements except those
3838 nodes on which a 0D element already exists.
3841 theObject: an object on whose nodes 0D elements will be created.
3842 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3843 theGroupName: optional name of a group to add 0D elements created
3844 and/or found on nodes of *theObject*.
3845 DuplicateElements: to add one more 0D element to a node or not
3848 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3849 IDs of new and/or found 0D elements. IDs of 0D elements
3850 can be retrieved from the returned object by
3851 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3854 unRegister = genObjUnRegister()
3855 if isinstance( theObject, Mesh ):
3856 theObject = theObject.GetMesh()
3857 elif isinstance( theObject, list ):
3858 theObject = self.GetIDSource( theObject, SMESH.ALL )
3859 unRegister.set( theObject )
3860 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3862 def AddBall(self, IDOfNode, diameter):
3864 Create a ball element on a node with given ID.
3867 IDOfNode: the ID of node for creation of the element.
3868 diameter: the bal diameter.
3871 ID of the new ball element
3874 return self.editor.AddBall( IDOfNode, diameter )
3876 def AddEdge(self, IDsOfNodes):
3878 Create a linear or quadratic edge (this is determined
3879 by the number of given nodes).
3882 IDsOfNodes: list of node IDs for creation of the element.
3883 The order of nodes in this list should correspond to
3884 the :ref:`connectivity convention <connectivity_page>`.
3890 return self.editor.AddEdge(IDsOfNodes)
3892 def AddFace(self, IDsOfNodes):
3894 Create a linear or quadratic face (this is determined
3895 by the number of given nodes).
3898 IDsOfNodes: list of node IDs for creation of the element.
3899 The order of nodes in this list should correspond to
3900 the :ref:`connectivity convention <connectivity_page>`.
3906 return self.editor.AddFace(IDsOfNodes)
3908 def AddPolygonalFace(self, IdsOfNodes):
3910 Add a polygonal face defined by a list of node IDs
3913 IdsOfNodes: the list of node IDs for creation of the element.
3919 return self.editor.AddPolygonalFace(IdsOfNodes)
3921 def AddQuadPolygonalFace(self, IdsOfNodes):
3923 Add a quadratic polygonal face defined by a list of node IDs
3926 IdsOfNodes: the list of node IDs for creation of the element;
3927 corner nodes follow first.
3933 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3935 def AddVolume(self, IDsOfNodes):
3937 Create both simple and quadratic volume (this is determined
3938 by the number of given nodes).
3941 IDsOfNodes: list of node IDs for creation of the element.
3942 The order of nodes in this list should correspond to
3943 the :ref:`connectivity convention <connectivity_page>`.
3946 ID of the new volumic element
3949 return self.editor.AddVolume(IDsOfNodes)
3951 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3953 Create a volume of many faces, giving nodes for each face.
3956 IdsOfNodes: list of node IDs for volume creation, face by face.
3957 Quantities: list of integer values, Quantities[i]
3958 gives the quantity of nodes in face number i.
3961 ID of the new volumic element
3964 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3966 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3968 Create a volume of many faces, giving the IDs of the existing faces.
3971 The created volume will refer only to the nodes
3972 of the given faces, not to the faces themselves.
3975 IdsOfFaces: the list of face IDs for volume creation.
3978 ID of the new volumic element
3981 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
3984 def SetNodeOnVertex(self, NodeID, Vertex):
3986 Binds a node to a vertex
3990 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
3993 True if succeed else raises an exception
3996 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
3997 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4001 self.editor.SetNodeOnVertex(NodeID, VertexID)
4002 except SALOME.SALOME_Exception as inst:
4003 raise ValueError(inst.details.text)
4007 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4009 Stores the node position on an edge
4013 Edge: an edge (GEOM.GEOM_Object) or edge ID
4014 paramOnEdge: a parameter on the edge where the node is located
4017 True if succeed else raises an exception
4020 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4021 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4025 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4026 except SALOME.SALOME_Exception as inst:
4027 raise ValueError(inst.details.text)
4030 def SetNodeOnFace(self, NodeID, Face, u, v):
4032 Stores node position on a face
4036 Face: a face (GEOM.GEOM_Object) or face ID
4037 u: U parameter on the face where the node is located
4038 v: V parameter on the face where the node is located
4041 True if succeed else raises an exception
4044 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4045 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4049 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4050 except SALOME.SALOME_Exception as inst:
4051 raise ValueError(inst.details.text)
4054 def SetNodeInVolume(self, NodeID, Solid):
4056 Binds a node to a solid
4060 Solid: a solid (GEOM.GEOM_Object) or solid ID
4063 True if succeed else raises an exception
4066 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4067 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4071 self.editor.SetNodeInVolume(NodeID, SolidID)
4072 except SALOME.SALOME_Exception as inst:
4073 raise ValueError(inst.details.text)
4076 def SetMeshElementOnShape(self, ElementID, Shape):
4078 Bind an element to a shape
4081 ElementID: an element ID
4082 Shape: a shape (GEOM.GEOM_Object) or shape ID
4085 True if succeed else raises an exception
4088 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4089 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4093 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4094 except SALOME.SALOME_Exception as inst:
4095 raise ValueError(inst.details.text)
4099 def MoveNode(self, NodeID, x, y, z):
4101 Move the node with the given id
4104 NodeID: the id of the node
4105 x: a new X coordinate
4106 y: a new Y coordinate
4107 z: a new Z coordinate
4110 True if succeed else False
4113 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4114 if hasVars: self.mesh.SetParameters(Parameters)
4115 return self.editor.MoveNode(NodeID, x, y, z)
4117 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4119 Find the node closest to a point and moves it to a point location
4122 x: the X coordinate of a point
4123 y: the Y coordinate of a point
4124 z: the Z coordinate of a point
4125 NodeID: if specified (>0), the node with this ID is moved,
4126 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4129 the ID of a moved node
4132 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4133 if hasVars: self.mesh.SetParameters(Parameters)
4134 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4136 def FindNodeClosestTo(self, x, y, z):
4138 Find the node closest to a point
4141 x: the X coordinate of a point
4142 y: the Y coordinate of a point
4143 z: the Z coordinate of a point
4149 #preview = self.mesh.GetMeshEditPreviewer()
4150 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4151 return self.editor.FindNodeClosestTo(x, y, z)
4153 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4155 Find the elements where a point lays IN or ON
4158 x,y,z (float): coordinates of the point
4159 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4160 means elements of any type excluding nodes, discrete and 0D elements.
4161 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4164 list of IDs of found elements
4167 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4169 return self.editor.FindElementsByPoint(x, y, z, elementType)
4171 def GetPointState(self, x, y, z):
4173 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4174 0-IN, 1-OUT, 2-ON, 3-UNKNOWN.
4175 UNKNOWN state means that either mesh is wrong or the analysis fails.
4178 return self.editor.GetPointState(x, y, z)
4180 def IsManifold(self):
4182 Check if a 2D mesh is manifold
4185 return self.editor.IsManifold()
4187 def IsCoherentOrientation2D(self):
4189 Check if orientation of 2D elements is coherent
4192 return self.editor.IsCoherentOrientation2D()
4194 def MeshToPassThroughAPoint(self, x, y, z):
4196 Find the node closest to a point and moves it to a point location
4199 x: the X coordinate of a point
4200 y: the Y coordinate of a point
4201 z: the Z coordinate of a point
4204 the ID of a moved node
4207 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4209 def InverseDiag(self, NodeID1, NodeID2):
4211 Replace two neighbour triangles sharing Node1-Node2 link
4212 with the triangles built on the same 4 nodes but having other common link.
4215 NodeID1: the ID of the first node
4216 NodeID2: the ID of the second node
4219 False if proper faces were not found
4221 return self.editor.InverseDiag(NodeID1, NodeID2)
4223 def DeleteDiag(self, NodeID1, NodeID2):
4225 Replace two neighbour triangles sharing *Node1-Node2* link
4226 with a quadrangle built on the same 4 nodes.
4229 NodeID1: ID of the first node
4230 NodeID2: ID of the second node
4233 False if proper faces were not found
4236 return self.editor.DeleteDiag(NodeID1, NodeID2)
4238 def Reorient(self, IDsOfElements=None):
4240 Reorient elements by ids
4243 IDsOfElements: if undefined reorients all mesh elements
4246 True if succeed else False
4249 if IDsOfElements == None:
4250 IDsOfElements = self.GetElementsId()
4251 return self.editor.Reorient(IDsOfElements)
4253 def ReorientObject(self, theObject):
4255 Reorient all elements of the object
4258 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4261 True if succeed else False
4264 if ( isinstance( theObject, Mesh )):
4265 theObject = theObject.GetMesh()
4266 return self.editor.ReorientObject(theObject)
4268 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4270 Reorient faces contained in *the2DObject*.
4273 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4274 theDirection: is a desired direction of normal of *theFace*.
4275 It can be either a GEOM vector or a list of coordinates [x,y,z].
4276 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4277 compared with theDirection. It can be either ID of face or a point
4278 by which the face will be found. The point can be given as either
4279 a GEOM vertex or a list of point coordinates.
4282 number of reoriented faces
4285 unRegister = genObjUnRegister()
4287 if isinstance( the2DObject, Mesh ):
4288 the2DObject = the2DObject.GetMesh()
4289 if isinstance( the2DObject, list ):
4290 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4291 unRegister.set( the2DObject )
4292 # check theDirection
4293 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4294 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4295 if isinstance( theDirection, list ):
4296 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4297 # prepare theFace and thePoint
4298 theFace = theFaceOrPoint
4299 thePoint = PointStruct(0,0,0)
4300 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4301 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4303 if isinstance( theFaceOrPoint, list ):
4304 thePoint = PointStruct( *theFaceOrPoint )
4306 if isinstance( theFaceOrPoint, PointStruct ):
4307 thePoint = theFaceOrPoint
4309 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4311 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4313 Reorient faces according to adjacent volumes.
4316 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4317 either IDs of faces or face groups.
4318 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4319 theOutsideNormal: to orient faces to have their normals
4320 pointing either *outside* or *inside* the adjacent volumes.
4323 number of reoriented faces.
4326 unRegister = genObjUnRegister()
4328 if not isinstance( the2DObject, list ):
4329 the2DObject = [ the2DObject ]
4330 elif the2DObject and isinstance( the2DObject[0], int ):
4331 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4332 unRegister.set( the2DObject )
4333 the2DObject = [ the2DObject ]
4334 for i,obj2D in enumerate( the2DObject ):
4335 if isinstance( obj2D, Mesh ):
4336 the2DObject[i] = obj2D.GetMesh()
4337 if isinstance( obj2D, list ):
4338 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4339 unRegister.set( the2DObject[i] )
4341 if isinstance( the3DObject, Mesh ):
4342 the3DObject = the3DObject.GetMesh()
4343 if isinstance( the3DObject, list ):
4344 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4345 unRegister.set( the3DObject )
4346 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4348 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4350 Fuse the neighbouring triangles into quadrangles.
4353 IDsOfElements: The triangles to be fused.
4354 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4355 applied to possible quadrangles to choose a neighbour to fuse with.
4356 Note that not all items of :class:`SMESH.FunctorType` corresponds
4357 to numerical functors.
4358 MaxAngle: is the maximum angle between element normals at which the fusion
4359 is still performed; theMaxAngle is measured in radians.
4360 Also it could be a name of variable which defines angle in degrees.
4363 True in case of success, False otherwise.
4366 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4367 self.mesh.SetParameters(Parameters)
4368 if not IDsOfElements:
4369 IDsOfElements = self.GetElementsId()
4370 Functor = self.smeshpyD.GetFunctor(theCriterion)
4371 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4373 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4375 Fuse the neighbouring triangles of the object into quadrangles
4378 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4379 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4380 applied to possible quadrangles to choose a neighbour to fuse with.
4381 Note that not all items of :class:`SMESH.FunctorType` corresponds
4382 to numerical functors.
4383 MaxAngle: a max angle between element normals at which the fusion
4384 is still performed; theMaxAngle is measured in radians.
4387 True in case of success, False otherwise.
4390 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4391 self.mesh.SetParameters(Parameters)
4392 if isinstance( theObject, Mesh ):
4393 theObject = theObject.GetMesh()
4394 Functor = self.smeshpyD.GetFunctor(theCriterion)
4395 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4397 def QuadToTri (self, IDsOfElements, theCriterion = None):
4399 Split quadrangles into triangles.
4402 IDsOfElements: the faces to be splitted.
4403 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4404 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4405 value, then quadrangles will be split by the smallest diagonal.
4406 Note that not all items of :class:`SMESH.FunctorType` corresponds
4407 to numerical functors.
4410 True in case of success, False otherwise.
4412 if IDsOfElements == []:
4413 IDsOfElements = self.GetElementsId()
4414 if theCriterion is None:
4415 theCriterion = FT_MaxElementLength2D
4416 Functor = self.smeshpyD.GetFunctor(theCriterion)
4417 return self.editor.QuadToTri(IDsOfElements, Functor)
4419 def QuadToTriObject (self, theObject, theCriterion = None):
4421 Split quadrangles into triangles.
4424 theObject: the object from which the list of elements is taken,
4425 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
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 ( isinstance( theObject, Mesh )):
4436 theObject = theObject.GetMesh()
4437 if theCriterion is None:
4438 theCriterion = FT_MaxElementLength2D
4439 Functor = self.smeshpyD.GetFunctor(theCriterion)
4440 return self.editor.QuadToTriObject(theObject, Functor)
4442 def QuadTo4Tri (self, theElements=[]):
4444 Split each of given quadrangles into 4 triangles. A node is added at the center of
4448 theElements: the faces to be splitted. This can be either
4449 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4450 or a list of face IDs. By default all quadrangles are split
4452 unRegister = genObjUnRegister()
4453 if isinstance( theElements, Mesh ):
4454 theElements = theElements.mesh
4455 elif not theElements:
4456 theElements = self.mesh
4457 elif isinstance( theElements, list ):
4458 theElements = self.GetIDSource( theElements, SMESH.FACE )
4459 unRegister.set( theElements )
4460 return self.editor.QuadTo4Tri( theElements )
4462 def SplitQuad (self, IDsOfElements, Diag13):
4464 Split quadrangles into triangles.
4467 IDsOfElements: the faces to be splitted
4468 Diag13: is used to choose a diagonal for splitting.
4471 True in case of success, False otherwise.
4473 if IDsOfElements == []:
4474 IDsOfElements = self.GetElementsId()
4475 return self.editor.SplitQuad(IDsOfElements, Diag13)
4477 def SplitQuadObject (self, theObject, Diag13):
4479 Split quadrangles into triangles.
4482 theObject: the object from which the list of elements is taken,
4483 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4484 Diag13: is used to choose a diagonal for splitting.
4487 True in case of success, False otherwise.
4489 if ( isinstance( theObject, Mesh )):
4490 theObject = theObject.GetMesh()
4491 return self.editor.SplitQuadObject(theObject, Diag13)
4493 def BestSplit (self, IDOfQuad, theCriterion):
4495 Find a better splitting of the given quadrangle.
4498 IDOfQuad: the ID of the quadrangle to be splitted.
4499 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4500 choose a diagonal for splitting.
4501 Note that not all items of :class:`SMESH.FunctorType` corresponds
4502 to numerical functors.
4505 * 1 if 1-3 diagonal is better,
4506 * 2 if 2-4 diagonal is better,
4507 * 0 if error occurs.
4509 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4511 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4513 Split volumic elements into tetrahedrons
4516 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4517 method: flags passing splitting method:
4518 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4519 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4521 unRegister = genObjUnRegister()
4522 if isinstance( elems, Mesh ):
4523 elems = elems.GetMesh()
4524 if ( isinstance( elems, list )):
4525 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4526 unRegister.set( elems )
4527 self.editor.SplitVolumesIntoTetra(elems, method)
4530 def SplitBiQuadraticIntoLinear(self, elems=None):
4532 Split bi-quadratic elements into linear ones without creation of additional nodes:
4534 - bi-quadratic triangle will be split into 3 linear quadrangles;
4535 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4536 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4538 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4539 will be split in order to keep the mesh conformal.
4542 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4543 if None (default), all bi-quadratic elements will be split
4545 unRegister = genObjUnRegister()
4546 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4547 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4548 unRegister.set( elems )
4550 elems = [ self.GetMesh() ]
4551 if isinstance( elems, Mesh ):
4552 elems = [ elems.GetMesh() ]
4553 if not isinstance( elems, list ):
4555 self.editor.SplitBiQuadraticIntoLinear( elems )
4557 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4558 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4560 Split hexahedra into prisms
4563 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4564 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4565 gives a normal vector defining facets to split into triangles.
4566 *startHexPoint* can be either a triple of coordinates or a vertex.
4567 facetNormal: a normal to a facet to split into triangles of a
4568 hexahedron found by *startHexPoint*.
4569 *facetNormal* can be either a triple of coordinates or an edge.
4570 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4571 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4572 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4573 to *startHexPoint* are split, else *startHexPoint*
4574 is used to find the facet to split in all domains present in *elems*.
4577 unRegister = genObjUnRegister()
4578 if isinstance( elems, Mesh ):
4579 elems = elems.GetMesh()
4580 if ( isinstance( elems, list )):
4581 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4582 unRegister.set( elems )
4585 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4586 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4587 elif isinstance( startHexPoint, list ):
4588 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4591 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4592 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4593 elif isinstance( facetNormal, list ):
4594 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4597 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4599 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4601 def SplitQuadsNearTriangularFacets(self):
4603 Split quadrangle faces near triangular facets of volumes
4605 faces_array = self.GetElementsByType(SMESH.FACE)
4606 for face_id in faces_array:
4607 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4608 quad_nodes = self.mesh.GetElemNodes(face_id)
4609 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4610 isVolumeFound = False
4611 for node1_elem in node1_elems:
4612 if not isVolumeFound:
4613 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4614 nb_nodes = self.GetElemNbNodes(node1_elem)
4615 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4616 volume_elem = node1_elem
4617 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4618 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4619 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4620 isVolumeFound = True
4621 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4622 self.SplitQuad([face_id], False) # diagonal 2-4
4623 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4624 isVolumeFound = True
4625 self.SplitQuad([face_id], True) # diagonal 1-3
4626 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4627 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4628 isVolumeFound = True
4629 self.SplitQuad([face_id], True) # diagonal 1-3
4631 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4633 Split hexahedrons into tetrahedrons.
4635 This operation uses :doc:`pattern_mapping` functionality for splitting.
4638 theObject: the object from which the list of hexahedrons is taken;
4639 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4640 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4641 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4642 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4643 key-point will be mapped into *theNode001*-th node of each volume.
4644 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4647 True in case of success, False otherwise.
4655 # (0,0,1) 4.---------.7 * |
4662 # (0,0,0) 0.---------.3
4663 pattern_tetra = "!!! Nb of points: \n 8 \n\
4673 !!! Indices of points of 6 tetras: \n\
4681 pattern = self.smeshpyD.GetPattern()
4682 isDone = pattern.LoadFromFile(pattern_tetra)
4684 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4687 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4688 isDone = pattern.MakeMesh(self.mesh, False, False)
4689 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4691 # split quafrangle faces near triangular facets of volumes
4692 self.SplitQuadsNearTriangularFacets()
4696 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4698 Split hexahedrons into prisms.
4700 Uses the :doc:`pattern_mapping` functionality for splitting.
4703 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4704 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4705 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4706 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4707 will be mapped into the *theNode001* -th node of each volume.
4708 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4711 True in case of success, False otherwise.
4713 # Pattern: 5.---------.6
4718 # (0,0,1) 4.---------.7 |
4725 # (0,0,0) 0.---------.3
4726 pattern_prism = "!!! Nb of points: \n 8 \n\
4736 !!! Indices of points of 2 prisms: \n\
4740 pattern = self.smeshpyD.GetPattern()
4741 isDone = pattern.LoadFromFile(pattern_prism)
4743 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4746 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4747 isDone = pattern.MakeMesh(self.mesh, False, False)
4748 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4750 # Split quafrangle faces near triangular facets of volumes
4751 self.SplitQuadsNearTriangularFacets()
4755 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4756 MaxNbOfIterations, MaxAspectRatio, Method):
4761 IDsOfElements: the list if ids of elements to smooth
4762 IDsOfFixedNodes: the list of ids of fixed nodes.
4763 Note that nodes built on edges and boundary nodes are always fixed.
4764 MaxNbOfIterations: the maximum number of iterations
4765 MaxAspectRatio: varies in range [1.0, inf]
4766 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4767 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4770 True in case of success, False otherwise.
4773 if IDsOfElements == []:
4774 IDsOfElements = self.GetElementsId()
4775 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4776 self.mesh.SetParameters(Parameters)
4777 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4778 MaxNbOfIterations, MaxAspectRatio, Method)
4780 def SmoothObject(self, theObject, IDsOfFixedNodes,
4781 MaxNbOfIterations, MaxAspectRatio, Method):
4783 Smooth elements which belong to the given object
4786 theObject: the object to smooth
4787 IDsOfFixedNodes: the list of ids of fixed nodes.
4788 Note that nodes built on edges and boundary nodes are always fixed.
4789 MaxNbOfIterations: the maximum number of iterations
4790 MaxAspectRatio: varies in range [1.0, inf]
4791 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4792 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4795 True in case of success, False otherwise.
4798 if ( isinstance( theObject, Mesh )):
4799 theObject = theObject.GetMesh()
4800 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4801 MaxNbOfIterations, MaxAspectRatio, Method)
4803 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4804 MaxNbOfIterations, MaxAspectRatio, Method):
4806 Parametrically smooth the given elements
4809 IDsOfElements: the list if ids of elements 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 IDsOfElements == []:
4822 IDsOfElements = self.GetElementsId()
4823 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4824 self.mesh.SetParameters(Parameters)
4825 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4826 MaxNbOfIterations, MaxAspectRatio, Method)
4828 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4829 MaxNbOfIterations, MaxAspectRatio, Method):
4831 Parametrically smooth the elements which belong to the given object
4834 theObject: the object to smooth
4835 IDsOfFixedNodes: the list of ids of fixed nodes.
4836 Note that nodes built on edges and boundary nodes are always fixed.
4837 MaxNbOfIterations: the maximum number of iterations
4838 MaxAspectRatio: varies in range [1.0, inf]
4839 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4840 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4843 True in case of success, False otherwise.
4846 if ( isinstance( theObject, Mesh )):
4847 theObject = theObject.GetMesh()
4848 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4849 MaxNbOfIterations, MaxAspectRatio, Method)
4851 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4853 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4854 them with quadratic with the same id.
4857 theForce3d: method of new node creation:
4859 * False - the medium node lies at the geometrical entity from which the mesh element is built
4860 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4861 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4862 theToBiQuad: If True, converts the mesh to bi-quadratic
4865 :class:`SMESH.ComputeError` which can hold a warning
4868 If *theSubMesh* is provided, the mesh can become non-conformal
4871 if isinstance( theSubMesh, Mesh ):
4872 theSubMesh = theSubMesh.mesh
4874 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4877 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4879 self.editor.ConvertToQuadratic(theForce3d)
4880 error = self.editor.GetLastError()
4881 if error and error.comment:
4882 print(error.comment)
4885 def ConvertFromQuadratic(self, theSubMesh=None):
4887 Convert the mesh from quadratic to ordinary,
4888 deletes old quadratic elements,
4889 replacing them with ordinary mesh elements with the same id.
4892 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4895 If *theSubMesh* is provided, the mesh can become non-conformal
4899 self.editor.ConvertFromQuadraticObject(theSubMesh)
4901 return self.editor.ConvertFromQuadratic()
4903 def Make2DMeshFrom3D(self):
4905 Create 2D mesh as skin on boundary faces of a 3D mesh
4908 True if operation has been completed successfully, False otherwise
4911 return self.editor.Make2DMeshFrom3D()
4913 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4914 toCopyElements=False, toCopyExistingBondary=False):
4916 Create missing boundary elements
4919 elements: elements whose boundary is to be checked:
4920 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4921 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4922 dimension: defines type of boundary elements to create, either of
4923 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4924 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4925 groupName: a name of group to store created boundary elements in,
4926 "" means not to create the group
4927 meshName: a name of new mesh to store created boundary elements in,
4928 "" means not to create the new mesh
4929 toCopyElements: if True, the checked elements will be copied into
4930 the new mesh else only boundary elements will be copied into the new mesh
4931 toCopyExistingBondary: if True, not only new but also pre-existing
4932 boundary elements will be copied into the new mesh
4935 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4938 unRegister = genObjUnRegister()
4939 if isinstance( elements, Mesh ):
4940 elements = elements.GetMesh()
4941 if ( isinstance( elements, list )):
4942 elemType = SMESH.ALL
4943 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4944 elements = self.editor.MakeIDSource(elements, elemType)
4945 unRegister.set( elements )
4946 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4947 toCopyElements,toCopyExistingBondary)
4948 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4951 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4952 toCopyAll=False, groups=[]):
4954 Create missing boundary elements around either the whole mesh or
4958 dimension: defines type of boundary elements to create, either of
4959 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4960 groupName: a name of group to store all boundary elements in,
4961 "" means not to create the group
4962 meshName: a name of a new mesh, which is a copy of the initial
4963 mesh + created boundary elements; "" means not to create the new mesh
4964 toCopyAll: if True, the whole initial mesh will be copied into
4965 the new mesh else only boundary elements will be copied into the new mesh
4966 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4969 tuple( long, mesh, groups )
4970 - long - number of added boundary elements
4971 - mesh - the :class:`Mesh` where elements were added to
4972 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4975 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4977 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4978 return nb, mesh, group
4980 def RenumberNodes(self):
4982 Renumber mesh nodes to remove unused node IDs
4984 self.editor.RenumberNodes()
4986 def RenumberElements(self):
4988 Renumber mesh elements to remove unused element IDs
4990 self.editor.RenumberElements()
4992 def _getIdSourceList(self, arg, idType, unRegister):
4994 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
4996 if arg and isinstance( arg, list ):
4997 if isinstance( arg[0], int ):
4998 arg = self.GetIDSource( arg, idType )
4999 unRegister.set( arg )
5000 elif isinstance( arg[0], Mesh ):
5001 arg[0] = arg[0].GetMesh()
5002 elif isinstance( arg, Mesh ):
5004 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5008 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5009 MakeGroups=False, TotalAngle=False):
5011 Generate new elements by rotation of the given elements and nodes around the axis
5014 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5015 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5016 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5017 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5018 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5019 which defines angle in degrees
5020 NbOfSteps: the number of steps
5021 Tolerance: tolerance
5022 MakeGroups: forces the generation of new groups from existing ones
5023 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5024 of all steps, else - size of each step
5027 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5030 unRegister = genObjUnRegister()
5031 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5032 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5033 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5035 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5036 Axis = self.smeshpyD.GetAxisStruct( Axis )
5037 if isinstance( Axis, list ):
5038 Axis = SMESH.AxisStruct( *Axis )
5040 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5041 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5042 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5043 self.mesh.SetParameters(Parameters)
5044 if TotalAngle and NbOfSteps:
5045 AngleInRadians /= NbOfSteps
5046 return self.editor.RotationSweepObjects( nodes, edges, faces,
5047 Axis, AngleInRadians,
5048 NbOfSteps, Tolerance, MakeGroups)
5050 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5051 MakeGroups=False, TotalAngle=False):
5053 Generate new elements by rotation of the elements around the axis
5056 IDsOfElements: the list of ids of elements to sweep
5057 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5058 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5059 NbOfSteps: the number of steps
5060 Tolerance: tolerance
5061 MakeGroups: forces the generation of new groups from existing ones
5062 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5063 of all steps, else - size of each step
5066 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5069 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5070 AngleInRadians, NbOfSteps, Tolerance,
5071 MakeGroups, TotalAngle)
5073 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5074 MakeGroups=False, TotalAngle=False):
5076 Generate new elements by rotation of the elements of object around the axis
5077 theObject object which elements should be sweeped.
5078 It can be a mesh, a sub mesh or a group.
5081 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5082 AngleInRadians: the angle of Rotation
5083 NbOfSteps: number of steps
5084 Tolerance: tolerance
5085 MakeGroups: forces the generation of new groups from existing ones
5086 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5087 of all steps, else - size of each step
5090 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5093 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5094 AngleInRadians, NbOfSteps, Tolerance,
5095 MakeGroups, TotalAngle )
5097 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5098 MakeGroups=False, TotalAngle=False):
5100 Generate new elements by rotation of the elements of object around the axis
5101 theObject object which elements should be sweeped.
5102 It can be a mesh, a sub mesh or a group.
5105 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5106 AngleInRadians: the angle of Rotation
5107 NbOfSteps: number of steps
5108 Tolerance: tolerance
5109 MakeGroups: forces the generation of new groups from existing ones
5110 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5111 of all steps, else - size of each step
5114 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5115 empty list otherwise
5118 return self.RotationSweepObjects([],theObject,[], Axis,
5119 AngleInRadians, NbOfSteps, Tolerance,
5120 MakeGroups, TotalAngle)
5122 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5123 MakeGroups=False, TotalAngle=False):
5125 Generate new elements by rotation of the elements of object around the axis
5126 theObject object which elements should be sweeped.
5127 It can be a mesh, a sub mesh or a group.
5130 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5131 AngleInRadians: the angle of Rotation
5132 NbOfSteps: number of steps
5133 Tolerance: tolerance
5134 MakeGroups: forces the generation of new groups from existing ones
5135 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5136 of all steps, else - size of each step
5139 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5142 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5143 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5145 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5146 scaleFactors=[], linearVariation=False, basePoint=[] ):
5148 Generate new elements by extrusion of the given elements and nodes
5151 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5152 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5153 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5154 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5155 the direction and value of extrusion for one step (the total extrusion
5156 length will be NbOfSteps * ||StepVector||)
5157 NbOfSteps: the number of steps
5158 MakeGroups: forces the generation of new groups from existing ones
5159 scaleFactors: optional scale factors to apply during extrusion
5160 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5161 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5162 basePoint: optional scaling center; if not provided, a gravity center of
5163 nodes and elements being extruded is used as the scaling center.
5166 - a list of tree components of the point or
5170 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5172 Example: :ref:`tui_extrusion`
5174 unRegister = genObjUnRegister()
5175 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5176 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5177 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5179 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5180 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5181 if isinstance( StepVector, list ):
5182 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5184 if isinstance( basePoint, int):
5185 xyz = self.GetNodeXYZ( basePoint )
5187 raise RuntimeError("Invalid node ID: %s" % basePoint)
5189 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5190 basePoint = self.geompyD.PointCoordinates( basePoint )
5192 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5193 Parameters = StepVector.PS.parameters + var_separator + Parameters
5194 self.mesh.SetParameters(Parameters)
5196 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5197 StepVector, NbOfSteps,
5198 scaleFactors, linearVariation, basePoint,
5202 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5204 Generate new elements by extrusion of the elements with given ids
5207 IDsOfElements: the list of ids of elements or nodes for extrusion
5208 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5209 the direction and value of extrusion for one step (the total extrusion
5210 length will be NbOfSteps * ||StepVector||)
5211 NbOfSteps: the number of steps
5212 MakeGroups: forces the generation of new groups from existing ones
5213 IsNodes: is True if elements with given ids are nodes
5216 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5218 Example: :ref:`tui_extrusion`
5221 if IsNodes: n = IDsOfElements
5222 else : e,f, = IDsOfElements,IDsOfElements
5223 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5225 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5226 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5228 Generate new elements by extrusion along the normal to a discretized surface or wire
5231 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5232 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5233 StepSize: length of one extrusion step (the total extrusion
5234 length will be *NbOfSteps* *StepSize*).
5235 NbOfSteps: number of extrusion steps.
5236 ByAverageNormal: if True each node is translated by *StepSize*
5237 along the average of the normal vectors to the faces sharing the node;
5238 else each node is translated along the same average normal till
5239 intersection with the plane got by translation of the face sharing
5240 the node along its own normal by *StepSize*.
5241 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5242 for every node of *Elements*.
5243 MakeGroups: forces generation of new groups from existing ones.
5244 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5245 is not yet implemented. This parameter is used if *Elements* contains
5246 both faces and edges, i.e. *Elements* is a Mesh.
5249 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5250 empty list otherwise.
5251 Example: :ref:`tui_extrusion`
5254 unRegister = genObjUnRegister()
5255 if isinstance( Elements, Mesh ):
5256 Elements = [ Elements.GetMesh() ]
5257 if isinstance( Elements, list ):
5259 raise RuntimeError("Elements empty!")
5260 if isinstance( Elements[0], int ):
5261 Elements = self.GetIDSource( Elements, SMESH.ALL )
5262 unRegister.set( Elements )
5263 if not isinstance( Elements, list ):
5264 Elements = [ Elements ]
5265 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5266 self.mesh.SetParameters(Parameters)
5267 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5268 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5270 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5272 Generate new elements by extrusion of the elements or nodes which belong to the object
5275 theObject: the object whose elements or nodes should be processed.
5276 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5277 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5278 the direction and value of extrusion for one step (the total extrusion
5279 length will be NbOfSteps * ||StepVector||)
5280 NbOfSteps: the number of steps
5281 MakeGroups: forces the generation of new groups from existing ones
5282 IsNodes: is True if elements to extrude are nodes
5285 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5286 Example: :ref:`tui_extrusion`
5290 if IsNodes: n = theObject
5291 else : e,f, = theObject,theObject
5292 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5294 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5296 Generate new elements by extrusion of edges which belong to the object
5299 theObject: object whose 1D elements should be processed.
5300 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5301 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5302 the direction and value of extrusion for one step (the total extrusion
5303 length will be NbOfSteps * ||StepVector||)
5304 NbOfSteps: the number of steps
5305 MakeGroups: to generate new groups from existing ones
5308 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5309 Example: :ref:`tui_extrusion`
5312 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5314 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5316 Generate new elements by extrusion of faces which belong to the object
5319 theObject: object whose 2D elements should be processed.
5320 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5321 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5322 the direction and value of extrusion for one step (the total extrusion
5323 length will be NbOfSteps * ||StepVector||)
5324 NbOfSteps: the number of steps
5325 MakeGroups: forces the generation of new groups from existing ones
5328 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5329 Example: :ref:`tui_extrusion`
5332 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5334 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5335 ExtrFlags, SewTolerance, MakeGroups=False):
5337 Generate new elements by extrusion of the elements with given ids
5340 IDsOfElements: is ids of elements
5341 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5342 the direction and value of extrusion for one step (the total extrusion
5343 length will be NbOfSteps * ||StepVector||)
5344 NbOfSteps: the number of steps
5345 ExtrFlags: sets flags for extrusion
5346 SewTolerance: uses for comparing locations of nodes if flag
5347 EXTRUSION_FLAG_SEW is set
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
5354 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5355 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5356 if isinstance( StepVector, list ):
5357 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5358 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5359 ExtrFlags, SewTolerance, MakeGroups)
5361 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5362 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5363 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5365 Generate new elements by extrusion of the given elements and nodes along the path.
5366 The path of extrusion must be a meshed edge.
5369 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5370 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5371 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5372 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5373 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5374 contains not only path segments, else it can be None
5375 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5376 HasAngles: allows the shape to be rotated around the path
5377 to get the resulting mesh in a helical fashion
5378 Angles: list of angles
5379 LinearVariation: forces the computation of rotation angles as linear
5380 variation of the given Angles along path steps
5381 HasRefPoint: allows using the reference point
5382 RefPoint: the reference point around which the shape is rotated (the mass center of the
5383 shape by default). The User can specify any point as the Reference Point.
5384 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5385 MakeGroups: forces the generation of new groups from existing ones
5388 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5389 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5390 Example: :ref:`tui_extrusion_along_path`
5393 unRegister = genObjUnRegister()
5394 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5395 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5396 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5398 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5399 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5400 if isinstance( RefPoint, list ):
5401 if not RefPoint: RefPoint = [0,0,0]
5402 RefPoint = SMESH.PointStruct( *RefPoint )
5403 if isinstance( PathMesh, Mesh ):
5404 PathMesh = PathMesh.GetMesh()
5405 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5406 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5407 self.mesh.SetParameters(Parameters)
5408 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5409 PathMesh, PathShape, NodeStart,
5410 HasAngles, Angles, LinearVariation,
5411 HasRefPoint, RefPoint, MakeGroups)
5413 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5414 HasAngles=False, Angles=[], LinearVariation=False,
5415 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5416 ElemType=SMESH.FACE):
5418 Generate new elements by extrusion of the given elements.
5419 The path of extrusion must be a meshed edge.
5422 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5423 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5424 NodeStart: the start node from Path. Defines the direction of extrusion
5425 HasAngles: allows the shape to be rotated around the path
5426 to get the resulting mesh in a helical fashion
5427 Angles: list of angles in radians
5428 LinearVariation: forces the computation of rotation angles as linear
5429 variation of the given Angles along path steps
5430 HasRefPoint: allows using the reference point
5431 RefPoint: the reference point around which the elements are rotated (the mass
5432 center of the elements by default).
5433 The User can specify any point as the Reference Point.
5434 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5435 MakeGroups: forces the generation of new groups from existing ones
5436 ElemType: type of elements for extrusion (if param Base is a mesh)
5439 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5440 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5441 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5443 Example: :ref:`tui_extrusion_along_path`
5447 if ElemType == SMESH.NODE: n = Base
5448 if ElemType == SMESH.EDGE: e = Base
5449 if ElemType == SMESH.FACE: f = Base
5450 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5451 HasAngles, Angles, LinearVariation,
5452 HasRefPoint, RefPoint, MakeGroups)
5453 if MakeGroups: return gr,er
5456 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5457 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5458 MakeGroups=False, LinearVariation=False):
5460 Generate new elements by extrusion of the given elements.
5461 The path of extrusion must be a meshed edge.
5464 IDsOfElements: ids of elements
5465 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5466 PathShape: shape (edge) defines the sub-mesh for the path
5467 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5468 HasAngles: allows the shape to be rotated around the path
5469 to get the resulting mesh in a helical fashion
5470 Angles: list of angles in radians
5471 HasRefPoint: allows using the reference point
5472 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5473 The User can specify any point as the Reference Point.
5474 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5475 MakeGroups: forces the generation of new groups from existing ones
5476 LinearVariation: forces the computation of rotation angles as linear
5477 variation of the given Angles along path steps
5480 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5481 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5482 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5483 Example: :ref:`tui_extrusion_along_path`
5486 n,e,f = [],IDsOfElements,IDsOfElements
5487 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5488 NodeStart, HasAngles, Angles,
5490 HasRefPoint, RefPoint, MakeGroups)
5491 if MakeGroups: return gr,er
5494 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5495 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5496 MakeGroups=False, LinearVariation=False):
5498 Generate new elements by extrusion of the elements which belong to the object.
5499 The path of extrusion must be a meshed edge.
5502 theObject: the object whose elements should be processed.
5503 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5504 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5505 PathShape: shape (edge) defines the sub-mesh for the path
5506 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5507 HasAngles: allows the shape to be rotated around the path
5508 to get the resulting mesh in a helical fashion
5509 Angles: list of angles
5510 HasRefPoint: allows using the reference point
5511 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5512 The User can specify any point as the Reference Point.
5513 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5514 MakeGroups: forces the generation of new groups from existing ones
5515 LinearVariation: forces the computation of rotation angles as linear
5516 variation of the given Angles along path steps
5519 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5520 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5521 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5522 Example: :ref:`tui_extrusion_along_path`
5525 n,e,f = [],theObject,theObject
5526 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5527 HasAngles, Angles, LinearVariation,
5528 HasRefPoint, RefPoint, MakeGroups)
5529 if MakeGroups: return gr,er
5532 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5533 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5534 MakeGroups=False, LinearVariation=False):
5536 Generate new elements by extrusion of mesh segments which belong to the object.
5537 The path of extrusion must be a meshed edge.
5540 theObject: the object whose 1D elements should be processed.
5541 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5542 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5543 PathShape: shape (edge) defines the sub-mesh for the path
5544 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5545 HasAngles: allows the shape to be rotated around the path
5546 to get the resulting mesh in a helical fashion
5547 Angles: list of angles
5548 HasRefPoint: allows using the reference point
5549 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5550 The User can specify any point as the Reference Point.
5551 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5552 MakeGroups: forces the generation of new groups from existing ones
5553 LinearVariation: forces the computation of rotation angles as linear
5554 variation of the given Angles along path steps
5557 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5558 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5559 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5560 Example: :ref:`tui_extrusion_along_path`
5563 n,e,f = [],theObject,[]
5564 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5565 HasAngles, Angles, LinearVariation,
5566 HasRefPoint, RefPoint, MakeGroups)
5567 if MakeGroups: return gr,er
5570 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5571 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5572 MakeGroups=False, LinearVariation=False):
5574 Generate new elements by extrusion of faces which belong to the object.
5575 The path of extrusion must be a meshed edge.
5578 theObject: the object whose 2D elements should be processed.
5579 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5580 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5581 PathShape: shape (edge) defines the sub-mesh for the path
5582 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5583 HasAngles: allows the shape to be rotated around the path
5584 to get the resulting mesh in a helical fashion
5585 Angles: list of angles
5586 HasRefPoint: allows using the reference point
5587 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5588 The User can specify any point as the Reference Point.
5589 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5590 MakeGroups: forces the generation of new groups from existing ones
5591 LinearVariation: forces the computation of rotation angles as linear
5592 variation of the given Angles along path steps
5595 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5596 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5597 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5598 Example: :ref:`tui_extrusion_along_path`
5601 n,e,f = [],[],theObject
5602 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5603 HasAngles, Angles, LinearVariation,
5604 HasRefPoint, RefPoint, MakeGroups)
5605 if MakeGroups: return gr,er
5608 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5610 Create a symmetrical copy of mesh elements
5613 IDsOfElements: list of elements ids
5614 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5615 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5616 If the *Mirror* is a geom object this parameter is unnecessary
5617 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5618 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5621 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5624 if IDsOfElements == []:
5625 IDsOfElements = self.GetElementsId()
5626 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5627 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5628 theMirrorType = Mirror._mirrorType
5630 self.mesh.SetParameters(Mirror.parameters)
5631 if Copy and MakeGroups:
5632 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5633 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5636 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5638 Create a new mesh by a symmetrical copy of mesh elements
5641 IDsOfElements: the list of elements ids
5642 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5643 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5644 If the *Mirror* is a geom object this parameter is unnecessary
5645 MakeGroups: to generate new groups from existing ones
5646 NewMeshName: a name of the new mesh to create
5649 instance of class :class:`Mesh`
5652 if IDsOfElements == []:
5653 IDsOfElements = self.GetElementsId()
5654 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5655 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5656 theMirrorType = Mirror._mirrorType
5658 self.mesh.SetParameters(Mirror.parameters)
5659 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5660 MakeGroups, NewMeshName)
5661 return Mesh(self.smeshpyD,self.geompyD,mesh)
5663 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5665 Create a symmetrical copy of the object
5668 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5669 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5670 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5671 If the *Mirror* is a geom object this parameter is unnecessary
5672 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5673 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5676 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5679 if ( isinstance( theObject, Mesh )):
5680 theObject = theObject.GetMesh()
5681 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5682 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5683 theMirrorType = Mirror._mirrorType
5685 self.mesh.SetParameters(Mirror.parameters)
5686 if Copy and MakeGroups:
5687 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5688 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5691 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5693 Create a new mesh by a symmetrical copy of the object
5696 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5697 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5698 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5699 If the *Mirror* is a geom object this parameter is unnecessary
5700 MakeGroups: forces the generation of new groups from existing ones
5701 NewMeshName: the name of the new mesh to create
5704 instance of class :class:`Mesh`
5707 if ( isinstance( theObject, Mesh )):
5708 theObject = theObject.GetMesh()
5709 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5710 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5711 theMirrorType = Mirror._mirrorType
5713 self.mesh.SetParameters(Mirror.parameters)
5714 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5715 MakeGroups, NewMeshName)
5716 return Mesh( self.smeshpyD,self.geompyD,mesh )
5718 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5720 Translate the elements
5723 IDsOfElements: list of elements ids
5724 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5725 Copy: allows copying the translated elements
5726 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5729 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5732 if IDsOfElements == []:
5733 IDsOfElements = self.GetElementsId()
5734 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5735 Vector = self.smeshpyD.GetDirStruct(Vector)
5736 if isinstance( Vector, list ):
5737 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5738 self.mesh.SetParameters(Vector.PS.parameters)
5739 if Copy and MakeGroups:
5740 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5741 self.editor.Translate(IDsOfElements, Vector, Copy)
5744 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5746 Create a new mesh of translated elements
5749 IDsOfElements: list of elements ids
5750 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5751 MakeGroups: forces the generation of new groups from existing ones
5752 NewMeshName: the name of the newly created mesh
5755 instance of class :class:`Mesh`
5758 if IDsOfElements == []:
5759 IDsOfElements = self.GetElementsId()
5760 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5761 Vector = self.smeshpyD.GetDirStruct(Vector)
5762 if isinstance( Vector, list ):
5763 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5764 self.mesh.SetParameters(Vector.PS.parameters)
5765 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5766 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5768 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5770 Translate the object
5773 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5774 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5775 Copy: allows copying the translated elements
5776 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5779 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5782 if ( isinstance( theObject, Mesh )):
5783 theObject = theObject.GetMesh()
5784 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5785 Vector = self.smeshpyD.GetDirStruct(Vector)
5786 if isinstance( Vector, list ):
5787 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5788 self.mesh.SetParameters(Vector.PS.parameters)
5789 if Copy and MakeGroups:
5790 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5791 self.editor.TranslateObject(theObject, Vector, Copy)
5794 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5796 Create a new mesh from the translated object
5799 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5800 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5801 MakeGroups: forces the generation of new groups from existing ones
5802 NewMeshName: the name of the newly created mesh
5805 instance of class :class:`Mesh`
5808 if isinstance( theObject, Mesh ):
5809 theObject = theObject.GetMesh()
5810 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5811 Vector = self.smeshpyD.GetDirStruct(Vector)
5812 if isinstance( Vector, list ):
5813 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5814 self.mesh.SetParameters(Vector.PS.parameters)
5815 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5816 return Mesh( self.smeshpyD, self.geompyD, mesh )
5820 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5825 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5826 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5827 theScaleFact: list of 1-3 scale factors for axises
5828 Copy: allows copying the translated elements
5829 MakeGroups: forces the generation of new groups from existing
5833 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5834 empty list otherwise
5836 unRegister = genObjUnRegister()
5837 if ( isinstance( theObject, Mesh )):
5838 theObject = theObject.GetMesh()
5839 if ( isinstance( theObject, list )):
5840 theObject = self.GetIDSource(theObject, SMESH.ALL)
5841 unRegister.set( theObject )
5842 if ( isinstance( thePoint, list )):
5843 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5844 if ( isinstance( theScaleFact, float )):
5845 theScaleFact = [theScaleFact]
5846 if ( isinstance( theScaleFact, int )):
5847 theScaleFact = [ float(theScaleFact)]
5849 self.mesh.SetParameters(thePoint.parameters)
5851 if Copy and MakeGroups:
5852 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5853 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5856 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5858 Create a new mesh from the translated object
5861 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5862 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5863 theScaleFact: list of 1-3 scale factors for axises
5864 MakeGroups: forces the generation of new groups from existing ones
5865 NewMeshName: the name of the newly created mesh
5868 instance of class :class:`Mesh`
5870 unRegister = genObjUnRegister()
5871 if (isinstance(theObject, Mesh)):
5872 theObject = theObject.GetMesh()
5873 if ( isinstance( theObject, list )):
5874 theObject = self.GetIDSource(theObject,SMESH.ALL)
5875 unRegister.set( theObject )
5876 if ( isinstance( thePoint, list )):
5877 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5878 if ( isinstance( theScaleFact, float )):
5879 theScaleFact = [theScaleFact]
5880 if ( isinstance( theScaleFact, int )):
5881 theScaleFact = [ float(theScaleFact)]
5883 self.mesh.SetParameters(thePoint.parameters)
5884 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5885 MakeGroups, NewMeshName)
5886 return Mesh( self.smeshpyD, self.geompyD, mesh )
5890 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5895 IDsOfElements: list of elements ids
5896 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5897 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5898 Copy: allows copying the rotated elements
5899 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5902 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5906 if IDsOfElements == []:
5907 IDsOfElements = self.GetElementsId()
5908 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5909 Axis = self.smeshpyD.GetAxisStruct(Axis)
5910 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5911 Parameters = Axis.parameters + var_separator + Parameters
5912 self.mesh.SetParameters(Parameters)
5913 if Copy and MakeGroups:
5914 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5915 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5918 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5920 Create a new mesh of rotated elements
5923 IDsOfElements: list of element ids
5924 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5925 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5926 MakeGroups: forces the generation of new groups from existing ones
5927 NewMeshName: the name of the newly created mesh
5930 instance of class :class:`Mesh`
5933 if IDsOfElements == []:
5934 IDsOfElements = self.GetElementsId()
5935 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5936 Axis = self.smeshpyD.GetAxisStruct(Axis)
5937 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5938 Parameters = Axis.parameters + var_separator + Parameters
5939 self.mesh.SetParameters(Parameters)
5940 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5941 MakeGroups, NewMeshName)
5942 return Mesh( self.smeshpyD, self.geompyD, mesh )
5944 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5949 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5950 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5951 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5952 Copy: allows copying the rotated elements
5953 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5956 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5959 if (isinstance(theObject, Mesh)):
5960 theObject = theObject.GetMesh()
5961 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5962 Axis = self.smeshpyD.GetAxisStruct(Axis)
5963 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5964 Parameters = Axis.parameters + ":" + Parameters
5965 self.mesh.SetParameters(Parameters)
5966 if Copy and MakeGroups:
5967 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5968 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5971 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5973 Create a new mesh from the rotated object
5976 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5977 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5978 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5979 MakeGroups: forces the generation of new groups from existing ones
5980 NewMeshName: the name of the newly created mesh
5983 instance of class :class:`Mesh`
5986 if (isinstance( theObject, Mesh )):
5987 theObject = theObject.GetMesh()
5988 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5989 Axis = self.smeshpyD.GetAxisStruct(Axis)
5990 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5991 Parameters = Axis.parameters + ":" + Parameters
5992 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
5993 MakeGroups, NewMeshName)
5994 self.mesh.SetParameters(Parameters)
5995 return Mesh( self.smeshpyD, self.geompyD, mesh )
5997 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
5999 Create an offset mesh from the given 2D object
6002 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6003 theValue (float): signed offset size
6004 MakeGroups (boolean): forces the generation of new groups from existing ones
6005 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6006 False means to remove original elements.
6007 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6010 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6013 if isinstance( theObject, Mesh ):
6014 theObject = theObject.GetMesh()
6015 theValue,Parameters,hasVars = ParseParameters(Value)
6016 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6017 self.mesh.SetParameters(Parameters)
6018 # if mesh_groups[0]:
6019 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6022 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6024 Find groups of adjacent nodes within Tolerance.
6027 Tolerance (float): the value of tolerance
6028 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6029 corner and medium nodes in separate groups thus preventing
6030 their further merge.
6033 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6036 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6038 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6039 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6041 Find groups of adjacent nodes within Tolerance.
6044 Tolerance: the value of tolerance
6045 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6046 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6047 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6048 corner and medium nodes in separate groups thus preventing
6049 their further merge.
6052 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6055 unRegister = genObjUnRegister()
6056 if (isinstance( SubMeshOrGroup, Mesh )):
6057 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6058 if not isinstance( exceptNodes, list ):
6059 exceptNodes = [ exceptNodes ]
6060 if exceptNodes and isinstance( exceptNodes[0], int ):
6061 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6062 unRegister.set( exceptNodes )
6063 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6064 exceptNodes, SeparateCornerAndMediumNodes)
6066 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6071 GroupsOfNodes: a list of groups of nodes IDs for merging.
6072 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6073 in all elements and groups by nodes 1 and 25 correspondingly
6074 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6075 If *NodesToKeep* does not include a node to keep for some group to merge,
6076 then the first node in the group is kept.
6077 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6080 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6081 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6083 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6085 Find the elements built on the same nodes.
6088 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6091 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6094 if not MeshOrSubMeshOrGroup:
6095 MeshOrSubMeshOrGroup=self.mesh
6096 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6097 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6098 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6100 def MergeElements(self, GroupsOfElementsID):
6102 Merge elements in each given group.
6105 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6106 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6107 replaced in all groups by elements 1 and 25)
6110 self.editor.MergeElements(GroupsOfElementsID)
6112 def MergeEqualElements(self):
6114 Leave one element and remove all other elements built on the same nodes.
6117 self.editor.MergeEqualElements()
6119 def FindFreeBorders(self, ClosedOnly=True):
6121 Returns all or only closed free borders
6124 list of SMESH.FreeBorder's
6127 return self.editor.FindFreeBorders( ClosedOnly )
6129 def FillHole(self, holeNodes):
6131 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6134 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6135 must describe all sequential nodes of the hole border. The first and the last
6136 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6140 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6141 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6142 if not isinstance( holeNodes, SMESH.FreeBorder ):
6143 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6144 self.editor.FillHole( holeNodes )
6146 def FindCoincidentFreeBorders (self, tolerance=0.):
6148 Return groups of FreeBorder's coincident within the given tolerance.
6151 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6152 size of elements adjacent to free borders being compared is used.
6155 SMESH.CoincidentFreeBorders structure
6158 return self.editor.FindCoincidentFreeBorders( tolerance )
6160 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6162 Sew FreeBorder's of each group
6165 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6166 where each enclosed list contains node IDs of a group of coincident free
6167 borders such that each consequent triple of IDs within a group describes
6168 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6169 last node of a border.
6170 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6171 groups of coincident free borders, each group including two borders.
6172 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6173 polygons if a node of opposite border falls on a face edge, else such
6174 faces are split into several ones.
6175 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6176 polyhedra if a node of opposite border falls on a volume edge, else such
6177 volumes, if any, remain intact and the mesh becomes non-conformal.
6180 a number of successfully sewed groups
6183 if freeBorders and isinstance( freeBorders, list ):
6184 # construct SMESH.CoincidentFreeBorders
6185 if isinstance( freeBorders[0], int ):
6186 freeBorders = [freeBorders]
6188 coincidentGroups = []
6189 for nodeList in freeBorders:
6190 if not nodeList or len( nodeList ) % 3:
6191 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6194 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6195 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6196 nodeList = nodeList[3:]
6198 coincidentGroups.append( group )
6200 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6202 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6204 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6205 FirstNodeID2, SecondNodeID2, LastNodeID2,
6206 CreatePolygons, CreatePolyedrs):
6211 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6214 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6215 FirstNodeID2, SecondNodeID2, LastNodeID2,
6216 CreatePolygons, CreatePolyedrs)
6218 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6219 FirstNodeID2, SecondNodeID2):
6221 Sew conform free borders
6224 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6227 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6228 FirstNodeID2, SecondNodeID2)
6230 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6231 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6236 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6239 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6240 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6242 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6243 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6244 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6246 Sew two sides of a mesh. The nodes belonging to Side1 are
6247 merged with the nodes of elements of Side2.
6248 The number of elements in theSide1 and in theSide2 must be
6249 equal and they should have similar nodal connectivity.
6250 The nodes to merge should belong to side borders and
6251 the first node should be linked to the second.
6254 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6257 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6258 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6259 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6261 def ChangeElemNodes(self, ide, newIDs):
6263 Set new nodes for the given element.
6270 False if the number of nodes does not correspond to the type of element
6273 return self.editor.ChangeElemNodes(ide, newIDs)
6275 def GetLastCreatedNodes(self):
6277 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6278 created, this method return the list of their IDs.
6279 If new nodes were not created - return empty list
6282 the list of integer values (can be empty)
6285 return self.editor.GetLastCreatedNodes()
6287 def GetLastCreatedElems(self):
6289 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6290 created this method return the list of their IDs.
6291 If new elements were not created - return empty list
6294 the list of integer values (can be empty)
6297 return self.editor.GetLastCreatedElems()
6299 def ClearLastCreated(self):
6301 Forget what nodes and elements were created by the last mesh edition operation
6304 self.editor.ClearLastCreated()
6306 def DoubleElements(self, theElements, theGroupName=""):
6308 Create duplicates of given elements, i.e. create new elements based on the
6309 same nodes as the given ones.
6312 theElements: container of elements to duplicate. It can be a
6313 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6314 or a list of element IDs. If *theElements* is
6315 a :class:`Mesh`, elements of highest dimension are duplicated
6316 theGroupName: a name of group to contain the generated elements.
6317 If a group with such a name already exists, the new elements
6318 are added to the existing group, else a new group is created.
6319 If *theGroupName* is empty, new elements are not added
6323 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6324 None if *theGroupName* == "".
6327 unRegister = genObjUnRegister()
6328 if isinstance( theElements, Mesh ):
6329 theElements = theElements.mesh
6330 elif isinstance( theElements, list ):
6331 theElements = self.GetIDSource( theElements, SMESH.ALL )
6332 unRegister.set( theElements )
6333 return self.editor.DoubleElements(theElements, theGroupName)
6335 def DoubleNodes(self, theNodes, theModifiedElems):
6337 Create a hole in a mesh by doubling the nodes of some particular elements
6340 theNodes: IDs of nodes to be doubled
6341 theModifiedElems: IDs of elements to be updated by the new (doubled)
6342 nodes. If list of element identifiers is empty then nodes are doubled but
6343 they not assigned to elements
6346 True if operation has been completed successfully, False otherwise
6349 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6351 def DoubleNode(self, theNodeId, theModifiedElems):
6353 Create a hole in a mesh by doubling the nodes of some particular elements.
6354 This method provided for convenience works as :meth:`DoubleNodes`.
6357 theNodeId: IDs of node to double
6358 theModifiedElems: IDs of elements to update
6361 True if operation has been completed successfully, False otherwise
6364 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6366 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6368 Create a hole in a mesh by doubling the nodes of some particular elements.
6369 This method provided for convenience works as :meth:`DoubleNodes`.
6372 theNodes: group of nodes to double.
6373 theModifiedElems: group of elements to update.
6374 theMakeGroup: forces the generation of a group containing new nodes.
6377 True or a created group if operation has been completed successfully,
6378 False or None otherwise
6382 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6383 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6385 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6387 Create a hole in a mesh by doubling the nodes of some particular elements.
6388 This method provided for convenience works as :meth:`DoubleNodes`.
6391 theNodes: list of groups of nodes to double.
6392 theModifiedElems: list of groups of elements to update.
6393 theMakeGroup: forces the generation of a group containing new nodes.
6396 True if operation has been completed successfully, False otherwise
6400 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6401 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6403 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6405 Create a hole in a mesh by doubling the nodes of some particular elements
6408 theElems: the list of elements (edges or faces) to replicate.
6409 The nodes for duplication could be found from these elements
6410 theNodesNot: list of nodes NOT to replicate
6411 theAffectedElems: the list of elements (cells and edges) to which the
6412 replicated nodes should be associated to
6415 True if operation has been completed successfully, False otherwise
6418 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6420 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6422 Create a hole in a mesh by doubling the nodes of some particular elements
6425 theElems: the list of elements (edges or faces) to replicate.
6426 The nodes for duplication could be found from these elements
6427 theNodesNot: list of nodes NOT to replicate
6428 theShape: shape to detect affected elements (element which geometric center
6429 located on or inside shape).
6430 The replicated nodes should be associated to affected elements.
6433 True if operation has been completed successfully, False otherwise
6436 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6438 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6439 theMakeGroup=False, theMakeNodeGroup=False):
6441 Create a hole in a mesh by doubling the nodes of some particular elements.
6442 This method provided for convenience works as :meth:`DoubleNodes`.
6445 theElems: group of of elements (edges or faces) to replicate.
6446 theNodesNot: group of nodes NOT to replicate.
6447 theAffectedElems: group of elements to which the replicated nodes
6448 should be associated to.
6449 theMakeGroup: forces the generation of a group containing new elements.
6450 theMakeNodeGroup: forces the generation of a group containing new nodes.
6453 True or created groups (one or two) if operation has been completed successfully,
6454 False or None otherwise
6457 if theMakeGroup or theMakeNodeGroup:
6458 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6460 theMakeGroup, theMakeNodeGroup)
6461 if theMakeGroup and theMakeNodeGroup:
6464 return twoGroups[ int(theMakeNodeGroup) ]
6465 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6467 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6469 Create a hole in a mesh by doubling the nodes of some particular elements.
6470 This method provided for convenience works as :meth:`DoubleNodes`.
6473 theElems: group of of elements (edges or faces) to replicate
6474 theNodesNot: group of nodes not to replicate
6475 theShape: shape to detect affected elements (element which geometric center
6476 located on or inside shape).
6477 The replicated nodes should be associated to affected elements
6480 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6482 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6483 theMakeGroup=False, theMakeNodeGroup=False):
6485 Create a hole in a mesh by doubling the nodes of some particular elements.
6486 This method provided for convenience works as :meth:`DoubleNodes`.
6489 theElems: list of groups of elements (edges or faces) to replicate
6490 theNodesNot: list of groups of nodes NOT to replicate
6491 theAffectedElems: group of elements to which the replicated nodes
6492 should be associated to
6493 theMakeGroup: forces generation of a group containing new elements.
6494 theMakeNodeGroup: forces generation of a group containing new nodes
6497 True or created groups (one or two) if operation has been completed successfully,
6498 False or None otherwise
6501 if theMakeGroup or theMakeNodeGroup:
6502 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6504 theMakeGroup, theMakeNodeGroup)
6505 if theMakeGroup and theMakeNodeGroup:
6508 return twoGroups[ int(theMakeNodeGroup) ]
6509 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6511 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6513 Create a hole in a mesh by doubling the nodes of some particular elements.
6514 This method provided for convenience works as :meth:`DoubleNodes`.
6517 theElems: list of groups of elements (edges or faces) to replicate
6518 theNodesNot: list of groups of nodes NOT to replicate
6519 theShape: shape to detect affected elements (element which geometric center
6520 located on or inside shape).
6521 The replicated nodes should be associated to affected elements
6524 True if operation has been completed successfully, False otherwise
6527 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6529 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6531 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6532 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6535 theElems: list of groups of nodes or elements (edges or faces) to replicate
6536 theNodesNot: list of groups of nodes NOT to replicate
6537 theShape: shape to detect affected elements (element which geometric center
6538 located on or inside shape).
6539 The replicated nodes should be associated to affected elements
6542 groups of affected elements in order: volumes, faces, edges
6545 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6547 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6550 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6551 The list of groups must describe a partition of the mesh volumes.
6552 The nodes of the internal faces at the boundaries of the groups are doubled.
6553 In option, the internal faces are replaced by flat elements.
6554 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6557 theDomains: list of groups of volumes
6558 createJointElems: if True, create the elements
6559 onAllBoundaries: if True, the nodes and elements are also created on
6560 the boundary between *theDomains* and the rest mesh
6563 True if operation has been completed successfully, False otherwise
6566 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6568 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6570 Double nodes on some external faces and create flat elements.
6571 Flat elements are mainly used by some types of mechanic calculations.
6573 Each group of the list must be constituted of faces.
6574 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6577 theGroupsOfFaces: list of groups of faces
6580 True if operation has been completed successfully, False otherwise
6583 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6585 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6587 Identify all the elements around a geom shape, get the faces delimiting the hole
6589 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6591 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6593 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6594 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6595 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6596 If there are several paths connecting a pair of points, the shortest path is
6597 selected by the module. Position of the cutting plane is defined by the two
6598 points and an optional vector lying on the plane specified by a PolySegment.
6599 By default the vector is defined by Mesh module as following. A middle point
6600 of the two given points is computed. The middle point is projected to the mesh.
6601 The vector goes from the middle point to the projection point. In case of planar
6602 mesh, the vector is normal to the mesh.
6604 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6607 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6608 groupName: optional name of a group where created mesh segments will be added.
6611 editor = self.editor
6613 editor = self.mesh.GetMeshEditPreviewer()
6614 segmentsRes = editor.MakePolyLine( segments, groupName )
6615 for i, seg in enumerate( segmentsRes ):
6616 segments[i].vector = seg.vector
6618 return editor.GetPreviewData()
6621 def GetFunctor(self, funcType ):
6623 Return a cached numerical functor by its type.
6626 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6627 Note that not all items correspond to numerical functors.
6630 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6633 fn = self.functors[ funcType._v ]
6635 fn = self.smeshpyD.GetFunctor(funcType)
6636 fn.SetMesh(self.mesh)
6637 self.functors[ funcType._v ] = fn
6640 def FunctorValue(self, funcType, elemId, isElem=True):
6642 Return value of a functor for a given element
6645 funcType: an item of :class:`SMESH.FunctorType` enum.
6646 elemId: element or node ID
6647 isElem: *elemId* is ID of element or node
6650 the functor value or zero in case of invalid arguments
6653 fn = self.GetFunctor( funcType )
6654 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6655 val = fn.GetValue(elemId)
6660 def GetLength(self, elemId=None):
6662 Get length of 1D element or sum of lengths of all 1D mesh elements
6665 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6668 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6673 length = self.smeshpyD.GetLength(self)
6675 length = self.FunctorValue(SMESH.FT_Length, elemId)
6678 def GetArea(self, elemId=None):
6680 Get area of 2D element or sum of areas of all 2D mesh elements
6681 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6684 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6689 area = self.smeshpyD.GetArea(self)
6691 area = self.FunctorValue(SMESH.FT_Area, elemId)
6694 def GetVolume(self, elemId=None):
6696 Get volume of 3D element or sum of volumes of all 3D mesh elements
6699 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6702 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6707 volume = self.smeshpyD.GetVolume(self)
6709 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6712 def GetMaxElementLength(self, elemId):
6714 Get maximum element length.
6717 elemId: mesh element ID
6720 element's maximum length value
6723 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6724 ftype = SMESH.FT_MaxElementLength3D
6726 ftype = SMESH.FT_MaxElementLength2D
6727 return self.FunctorValue(ftype, elemId)
6729 def GetAspectRatio(self, elemId):
6731 Get aspect ratio of 2D or 3D element.
6734 elemId: mesh element ID
6737 element's aspect ratio value
6740 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6741 ftype = SMESH.FT_AspectRatio3D
6743 ftype = SMESH.FT_AspectRatio
6744 return self.FunctorValue(ftype, elemId)
6746 def GetWarping(self, elemId):
6748 Get warping angle of 2D element.
6751 elemId: mesh element ID
6754 element's warping angle value
6757 return self.FunctorValue(SMESH.FT_Warping, elemId)
6759 def GetMinimumAngle(self, elemId):
6761 Get minimum angle of 2D element.
6764 elemId: mesh element ID
6767 element's minimum angle value
6770 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6772 def GetTaper(self, elemId):
6774 Get taper of 2D element.
6777 elemId: mesh element ID
6780 element's taper value
6783 return self.FunctorValue(SMESH.FT_Taper, elemId)
6785 def GetSkew(self, elemId):
6787 Get skew of 2D element.
6790 elemId: mesh element ID
6793 element's skew value
6796 return self.FunctorValue(SMESH.FT_Skew, elemId)
6798 def GetMinMax(self, funType, meshPart=None):
6800 Return minimal and maximal value of a given functor.
6803 funType (SMESH.FunctorType): a functor type.
6804 Note that not all items of :class:`SMESH.FunctorType` corresponds
6805 to numerical functors.
6806 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6812 unRegister = genObjUnRegister()
6813 if isinstance( meshPart, list ):
6814 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6815 unRegister.set( meshPart )
6816 if isinstance( meshPart, Mesh ):
6817 meshPart = meshPart.mesh
6818 fun = self.GetFunctor( funType )
6821 if hasattr( meshPart, "SetMesh" ):
6822 meshPart.SetMesh( self.mesh ) # set mesh to filter
6823 hist = fun.GetLocalHistogram( 1, False, meshPart )
6825 hist = fun.GetHistogram( 1, False )
6827 return hist[0].min, hist[0].max
6830 pass # end of Mesh class
6833 class meshProxy(SMESH._objref_SMESH_Mesh):
6835 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6836 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6838 def __init__(self,*args):
6839 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6840 def __deepcopy__(self, memo=None):
6841 new = self.__class__(self)
6843 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6844 if len( args ) == 3:
6845 args += SMESH.ALL_NODES, True
6846 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6847 def ExportToMEDX(self, *args): # function removed
6848 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6849 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6850 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6851 def ExportToMED(self, *args): # function removed
6852 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6853 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6854 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6856 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6857 def ExportPartToMED(self, *args): # 'version' parameter removed
6858 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6859 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6860 def ExportMED(self, *args): # signature of method changed
6861 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6862 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6864 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6866 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6869 class submeshProxy(SMESH._objref_SMESH_subMesh):
6872 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6874 def __init__(self,*args):
6875 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6877 def __deepcopy__(self, memo=None):
6878 new = self.__class__(self)
6881 def Compute(self,refresh=False):
6883 Compute the sub-mesh and return the status of the computation
6886 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6891 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6892 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6896 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6898 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6900 if salome.sg.hasDesktop():
6901 smeshgui = salome.ImportComponentGUI("SMESH")
6903 smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
6904 if refresh: salome.sg.updateObjBrowser()
6909 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6912 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6914 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6915 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6918 def __init__(self,*args):
6919 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6921 def __getattr__(self, name ): # method called if an attribute not found
6922 if not self.mesh: # look for name() method in Mesh class
6923 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6924 if hasattr( self.mesh, name ):
6925 return getattr( self.mesh, name )
6926 if name == "ExtrusionAlongPathObjX":
6927 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6928 print("meshEditor: attribute '%s' NOT FOUND" % name)
6930 def __deepcopy__(self, memo=None):
6931 new = self.__class__(self)
6933 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6934 if len( args ) == 1: args += False,
6935 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6936 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6937 if len( args ) == 2: args += False,
6938 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6939 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6940 if len( args ) == 1:
6941 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6942 NodesToKeep = args[1]
6943 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6944 unRegister = genObjUnRegister()
6946 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6947 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6948 if not isinstance( NodesToKeep, list ):
6949 NodesToKeep = [ NodesToKeep ]
6950 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6952 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6954 class Pattern(SMESH._objref_SMESH_Pattern):
6956 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6957 variables in some methods
6960 def LoadFromFile(self, patternTextOrFile ):
6961 text = patternTextOrFile
6962 if os.path.exists( text ):
6963 text = open( patternTextOrFile ).read()
6965 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6967 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6968 decrFun = lambda i: i-1
6969 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6970 theMesh.SetParameters(Parameters)
6971 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6973 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6974 decrFun = lambda i: i-1
6975 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6976 theMesh.SetParameters(Parameters)
6977 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
6979 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
6980 if isinstance( mesh, Mesh ):
6981 mesh = mesh.GetMesh()
6982 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
6984 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
6986 Registering the new proxy for Pattern
6991 Private class used to bind methods creating algorithms to the class Mesh
6994 def __init__(self, method):
6996 self.defaultAlgoType = ""
6997 self.algoTypeToClass = {}
6998 self.method = method
7000 def add(self, algoClass):
7002 Store a python class of algorithm
7004 if inspect.isclass(algoClass) and \
7005 hasattr( algoClass, "algoType"):
7006 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7007 if not self.defaultAlgoType and \
7008 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7009 self.defaultAlgoType = algoClass.algoType
7010 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7012 def copy(self, mesh):
7014 Create a copy of self and assign mesh to the copy
7017 other = algoCreator( self.method )
7018 other.defaultAlgoType = self.defaultAlgoType
7019 other.algoTypeToClass = self.algoTypeToClass
7023 def __call__(self,algo="",geom=0,*args):
7025 Create an instance of algorithm
7029 if isinstance( algo, str ):
7031 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7032 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7037 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7039 elif not algoType and isinstance( geom, str ):
7044 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7046 elif isinstance( arg, str ) and not algoType:
7049 import traceback, sys
7050 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7051 sys.stderr.write( msg + '\n' )
7052 tb = traceback.extract_stack(None,2)
7053 traceback.print_list( [tb[0]] )
7055 algoType = self.defaultAlgoType
7056 if not algoType and self.algoTypeToClass:
7057 algoType = sorted( self.algoTypeToClass.keys() )[0]
7058 if algoType in self.algoTypeToClass:
7059 #print("Create algo",algoType)
7060 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7061 raise RuntimeError( "No class found for algo type %s" % algoType)
7064 class hypMethodWrapper:
7066 Private class used to substitute and store variable parameters of hypotheses.
7069 def __init__(self, hyp, method):
7071 self.method = method
7072 #print("REBIND:", method.__name__)
7075 def __call__(self,*args):
7077 call a method of hypothesis with calling SetVarParameter() before
7081 return self.method( self.hyp, *args ) # hypothesis method with no args
7083 #print("MethWrapper.__call__", self.method.__name__, args)
7085 parsed = ParseParameters(*args) # replace variables with their values
7086 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7087 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7088 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7089 # maybe there is a replaced string arg which is not variable
7090 result = self.method( self.hyp, *args )
7091 except ValueError as detail: # raised by ParseParameters()
7093 result = self.method( self.hyp, *args )
7094 except omniORB.CORBA.BAD_PARAM:
7095 raise ValueError(detail) # wrong variable name
7100 class genObjUnRegister:
7102 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7105 def __init__(self, genObj=None):
7106 self.genObjList = []
7110 def set(self, genObj):
7111 "Store one or a list of of SALOME.GenericObj'es"
7112 if isinstance( genObj, list ):
7113 self.genObjList.extend( genObj )
7115 self.genObjList.append( genObj )
7119 for genObj in self.genObjList:
7120 if genObj and hasattr( genObj, "UnRegister" ):
7123 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7125 Bind methods creating mesher plug-ins to the Mesh class
7128 # print("pluginName: ", pluginName)
7129 pluginBuilderName = pluginName + "Builder"
7131 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7132 except Exception as e:
7133 from salome_utils import verbose
7134 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7136 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7137 plugin = eval( pluginBuilderName )
7138 # print(" plugin:" , str(plugin))
7140 # add methods creating algorithms to Mesh
7141 for k in dir( plugin ):
7142 if k[0] == '_': continue
7143 algo = getattr( plugin, k )
7144 #print(" algo:", str(algo))
7145 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7146 #print(" meshMethod:" , str(algo.meshMethod))
7147 if not hasattr( Mesh, algo.meshMethod ):
7148 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7150 _mmethod = getattr( Mesh, algo.meshMethod )
7151 if hasattr( _mmethod, "add" ):