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
623 geompyD = geomBuilder.New()
626 self.SetGeomEngine(geompyD)
627 SMESH._objref_SMESH_Gen.UpdateStudy(self)
628 sb = salome.myStudy.NewBuilder()
629 sc = salome.myStudy.FindComponent("SMESH")
631 sb.LoadWith(sc, self)
634 def SetEnablePublish( self, theIsEnablePublish ):
636 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
637 switch **off** publishing in the Study of mesh objects.
639 #self.SetEnablePublish(theIsEnablePublish)
640 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
642 notebook = salome_notebook.NoteBook( theIsEnablePublish )
645 def CreateMeshesFromUNV( self,theFileName ):
647 Create a Mesh object importing data from the given UNV file
650 an instance of class :class:`Mesh`
653 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
654 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
657 def CreateMeshesFromMED( self,theFileName ):
659 Create a Mesh object(s) importing data from the given MED file
662 a tuple ( list of class :class:`Mesh` instances,
663 :class:`SMESH.DriverMED_ReadStatus` )
666 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
667 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
668 return aMeshes, aStatus
670 def CreateMeshesFromSAUV( self,theFileName ):
672 Create a Mesh object(s) importing data from the given SAUV file
675 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
678 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
679 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680 return aMeshes, aStatus
682 def CreateMeshesFromSTL( self, theFileName ):
684 Create a Mesh object importing data from the given STL file
687 an instance of class :class:`Mesh`
690 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
691 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
694 def CreateMeshesFromCGNS( self, theFileName ):
696 Create Mesh objects importing data from the given CGNS file
699 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
702 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
703 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
704 return aMeshes, aStatus
706 def CreateMeshesFromGMF( self, theFileName ):
708 Create a Mesh object importing data from the given GMF file.
709 GMF files must have .mesh extension for the ASCII format and .meshb for
713 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
716 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
719 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
720 return Mesh(self, self.geompyD, aSmeshMesh), error
722 def Concatenate( self, meshes, uniteIdenticalGroups,
723 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
726 Concatenate the given meshes into one mesh. All groups of input meshes will be
727 present in the new mesh.
730 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
731 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
732 mergeNodesAndElements: if True, equal nodes and elements are merged
733 mergeTolerance: tolerance for merging nodes
734 allGroups: forces creation of groups corresponding to every input mesh
735 name: name of a new mesh
738 an instance of class :class:`Mesh`
741 if not meshes: return None
742 for i,m in enumerate(meshes):
743 if isinstance(m, Mesh):
744 meshes[i] = m.GetMesh()
745 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
746 meshes[0].SetParameters(Parameters)
748 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
749 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
751 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
752 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
753 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
756 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
758 Create a mesh by copying a part of another mesh.
761 meshPart: a part of mesh to copy, either
762 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
763 To copy nodes or elements not forming any mesh object,
764 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
765 meshName: a name of the new mesh
766 toCopyGroups: to create in the new mesh groups the copied elements belongs to
767 toKeepIDs: to preserve order of the copied elements or not
770 an instance of class :class:`Mesh`
773 if (isinstance( meshPart, Mesh )):
774 meshPart = meshPart.GetMesh()
775 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
776 return Mesh(self, self.geompyD, mesh)
778 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
780 Return IDs of sub-shapes
783 theMainObject (GEOM.GEOM_Object): a shape
784 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
786 the list of integer values
789 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
791 def GetPattern(self):
793 Create a pattern mapper.
796 an instance of :class:`SMESH.SMESH_Pattern`
798 :ref:`Example of Patterns usage <tui_pattern_mapping>`
801 return SMESH._objref_SMESH_Gen.GetPattern(self)
803 def SetBoundaryBoxSegmentation(self, nbSegments):
805 Set number of segments per diagonal of boundary box of geometry, by which
806 default segment length of appropriate 1D hypotheses is defined in GUI.
810 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
812 # Filtering. Auxiliary functions:
813 # ------------------------------
815 def GetEmptyCriterion(self):
817 Create an empty criterion
820 :class:`SMESH.Filter.Criterion`
823 Type = self.EnumToLong(FT_Undefined)
824 Compare = self.EnumToLong(FT_Undefined)
828 UnaryOp = self.EnumToLong(FT_Undefined)
829 BinaryOp = self.EnumToLong(FT_Undefined)
832 Precision = -1 ##@1e-07
833 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
834 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
836 def GetCriterion(self,elementType,
838 Compare = FT_EqualTo,
840 UnaryOp=FT_Undefined,
841 BinaryOp=FT_Undefined,
844 Create a criterion by the given parameters
845 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
848 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
849 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
850 Note that the items starting from FT_LessThan are not suitable for *CritType*.
851 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
852 Threshold: the threshold value (range of ids as string, shape, numeric)
853 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
854 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
856 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
857 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
860 :class:`SMESH.Filter.Criterion`
862 Example: :ref:`combining_filters`
865 if not CritType in SMESH.FunctorType._items:
866 raise TypeError("CritType should be of SMESH.FunctorType")
867 aCriterion = self.GetEmptyCriterion()
868 aCriterion.TypeOfElement = elementType
869 aCriterion.Type = self.EnumToLong(CritType)
870 aCriterion.Tolerance = Tolerance
872 aThreshold = Threshold
874 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
875 aCriterion.Compare = self.EnumToLong(Compare)
876 elif Compare == "=" or Compare == "==":
877 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
879 aCriterion.Compare = self.EnumToLong(FT_LessThan)
881 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
882 elif Compare != FT_Undefined:
883 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
886 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
887 FT_BelongToCylinder, FT_LyingOnGeom]:
888 # Check that Threshold is GEOM object
889 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
890 aCriterion.ThresholdStr = GetName(aThreshold)
891 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
892 if not aCriterion.ThresholdID:
893 name = aCriterion.ThresholdStr
895 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
896 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
897 # or a name of GEOM object
898 elif isinstance( aThreshold, str ):
899 aCriterion.ThresholdStr = aThreshold
901 raise TypeError("The Threshold should be a shape.")
902 if isinstance(UnaryOp,float):
903 aCriterion.Tolerance = UnaryOp
904 UnaryOp = FT_Undefined
906 elif CritType == FT_BelongToMeshGroup:
907 # Check that Threshold is a group
908 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
909 if aThreshold.GetType() != elementType:
910 raise ValueError("Group type mismatches Element type")
911 aCriterion.ThresholdStr = aThreshold.GetName()
912 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
913 study = salome.myStudy
915 so = study.FindObjectIOR( aCriterion.ThresholdID )
919 aCriterion.ThresholdID = entry
921 raise TypeError("The Threshold should be a Mesh Group")
922 elif CritType == FT_RangeOfIds:
923 # Check that Threshold is string
924 if isinstance(aThreshold, str):
925 aCriterion.ThresholdStr = aThreshold
927 raise TypeError("The Threshold should be a string.")
928 elif CritType == FT_CoplanarFaces:
929 # Check the Threshold
930 if isinstance(aThreshold, int):
931 aCriterion.ThresholdID = str(aThreshold)
932 elif isinstance(aThreshold, str):
935 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
936 aCriterion.ThresholdID = aThreshold
938 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
939 elif CritType == FT_ConnectedElements:
940 # Check the Threshold
941 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
942 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
943 if not aCriterion.ThresholdID:
944 name = aThreshold.GetName()
946 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
947 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
948 elif isinstance(aThreshold, int): # node id
949 aCriterion.Threshold = aThreshold
950 elif isinstance(aThreshold, list): # 3 point coordinates
951 if len( aThreshold ) < 3:
952 raise ValueError("too few point coordinates, must be 3")
953 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
954 elif isinstance(aThreshold, str):
955 if aThreshold.isdigit():
956 aCriterion.Threshold = aThreshold # node id
958 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
960 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
961 "or a list of point coordinates and not '%s'"%aThreshold)
962 elif CritType == FT_ElemGeomType:
963 # Check the Threshold
965 aCriterion.Threshold = self.EnumToLong(aThreshold)
966 assert( aThreshold in SMESH.GeometryType._items )
968 if isinstance(aThreshold, int):
969 aCriterion.Threshold = aThreshold
971 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
974 elif CritType == FT_EntityType:
975 # Check the Threshold
977 aCriterion.Threshold = self.EnumToLong(aThreshold)
978 assert( aThreshold in SMESH.EntityType._items )
980 if isinstance(aThreshold, int):
981 aCriterion.Threshold = aThreshold
983 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
987 elif CritType == FT_GroupColor:
988 # Check the Threshold
990 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
992 raise TypeError("The threshold value should be of SALOMEDS.Color type")
994 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
995 FT_LinearOrQuadratic, FT_BadOrientedVolume,
996 FT_BareBorderFace, FT_BareBorderVolume,
997 FT_OverConstrainedFace, FT_OverConstrainedVolume,
998 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
999 # At this point the Threshold is unnecessary
1000 if aThreshold == FT_LogicalNOT:
1001 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1002 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1003 aCriterion.BinaryOp = aThreshold
1007 aThreshold = float(aThreshold)
1008 aCriterion.Threshold = aThreshold
1010 raise TypeError("The Threshold should be a number.")
1013 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1014 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1016 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1017 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1019 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1020 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1022 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1023 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1027 def GetFilter(self,elementType,
1028 CritType=FT_Undefined,
1031 UnaryOp=FT_Undefined,
1035 Create a filter with the given parameters
1038 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1039 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1040 Note that the items starting from FT_LessThan are not suitable for CritType.
1041 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1042 Threshold: the threshold value (range of ids as string, shape, numeric)
1043 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1044 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1045 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1046 mesh: the mesh to initialize the filter with
1049 :class:`SMESH.Filter`
1052 See :doc:`Filters usage examples <tui_filters>`
1055 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1056 aFilterMgr = self.CreateFilterManager()
1057 aFilter = aFilterMgr.CreateFilter()
1059 aCriteria.append(aCriterion)
1060 aFilter.SetCriteria(aCriteria)
1062 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1063 else : aFilter.SetMesh( mesh )
1064 aFilterMgr.UnRegister()
1067 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1069 Create a filter from criteria
1072 criteria: a list of :class:`SMESH.Filter.Criterion`
1073 binOp: binary operator used when binary operator of criteria is undefined
1076 :class:`SMESH.Filter`
1079 See :doc:`Filters usage examples <tui_filters>`
1082 for i in range( len( criteria ) - 1 ):
1083 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1084 criteria[i].BinaryOp = self.EnumToLong( binOp )
1085 aFilterMgr = self.CreateFilterManager()
1086 aFilter = aFilterMgr.CreateFilter()
1087 aFilter.SetCriteria(criteria)
1088 aFilterMgr.UnRegister()
1091 def GetFunctor(self,theCriterion):
1093 Create a numerical functor by its type
1096 theCriterion (SMESH.FunctorType): functor type.
1097 Note that not all items correspond to numerical functors.
1100 :class:`SMESH.NumericalFunctor`
1103 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1105 aFilterMgr = self.CreateFilterManager()
1107 if theCriterion == FT_AspectRatio:
1108 functor = aFilterMgr.CreateAspectRatio()
1109 elif theCriterion == FT_AspectRatio3D:
1110 functor = aFilterMgr.CreateAspectRatio3D()
1111 elif theCriterion == FT_Warping:
1112 functor = aFilterMgr.CreateWarping()
1113 elif theCriterion == FT_MinimumAngle:
1114 functor = aFilterMgr.CreateMinimumAngle()
1115 elif theCriterion == FT_Taper:
1116 functor = aFilterMgr.CreateTaper()
1117 elif theCriterion == FT_Skew:
1118 functor = aFilterMgr.CreateSkew()
1119 elif theCriterion == FT_Area:
1120 functor = aFilterMgr.CreateArea()
1121 elif theCriterion == FT_Volume3D:
1122 functor = aFilterMgr.CreateVolume3D()
1123 elif theCriterion == FT_MaxElementLength2D:
1124 functor = aFilterMgr.CreateMaxElementLength2D()
1125 elif theCriterion == FT_MaxElementLength3D:
1126 functor = aFilterMgr.CreateMaxElementLength3D()
1127 elif theCriterion == FT_MultiConnection:
1128 functor = aFilterMgr.CreateMultiConnection()
1129 elif theCriterion == FT_MultiConnection2D:
1130 functor = aFilterMgr.CreateMultiConnection2D()
1131 elif theCriterion == FT_Length:
1132 functor = aFilterMgr.CreateLength()
1133 elif theCriterion == FT_Length2D:
1134 functor = aFilterMgr.CreateLength2D()
1135 elif theCriterion == FT_Deflection2D:
1136 functor = aFilterMgr.CreateDeflection2D()
1137 elif theCriterion == FT_NodeConnectivityNumber:
1138 functor = aFilterMgr.CreateNodeConnectivityNumber()
1139 elif theCriterion == FT_BallDiameter:
1140 functor = aFilterMgr.CreateBallDiameter()
1142 print("Error: given parameter is not numerical functor type.")
1143 aFilterMgr.UnRegister()
1146 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1151 theHType (string): mesh hypothesis type
1152 theLibName (string): mesh plug-in library name
1155 created hypothesis instance
1157 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1159 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1162 # wrap hypothesis methods
1163 for meth_name in dir( hyp.__class__ ):
1164 if not meth_name.startswith("Get") and \
1165 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1166 method = getattr ( hyp.__class__, meth_name )
1167 if callable(method):
1168 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1172 def GetMeshInfo(self, obj):
1174 Get the mesh statistic.
1175 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1176 an item of :class:`SMESH.EntityType`.
1179 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1182 if isinstance( obj, Mesh ):
1185 if hasattr(obj, "GetMeshInfo"):
1186 values = obj.GetMeshInfo()
1187 for i in range(SMESH.Entity_Last._v):
1188 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1192 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1194 Get minimum distance between two objects
1196 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1197 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1200 src1 (SMESH.SMESH_IDSource): first source object
1201 src2 (SMESH.SMESH_IDSource): second source object
1202 id1 (int): node/element id from the first source
1203 id2 (int): node/element id from the second (or first) source
1204 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1205 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1208 minimum distance value
1211 :meth:`GetMinDistance`
1214 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1218 result = result.value
1221 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1223 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1225 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1226 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1229 src1 (SMESH.SMESH_IDSource): first source object
1230 src2 (SMESH.SMESH_IDSource): second source object
1231 id1 (int): node/element id from the first source
1232 id2 (int): node/element id from the second (or first) source
1233 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1234 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1237 :class:`SMESH.Measure` structure or None if input data is invalid
1242 if isinstance(src1, Mesh): src1 = src1.mesh
1243 if isinstance(src2, Mesh): src2 = src2.mesh
1244 if src2 is None and id2 != 0: src2 = src1
1245 if not hasattr(src1, "_narrow"): return None
1246 src1 = src1._narrow(SMESH.SMESH_IDSource)
1247 if not src1: return None
1248 unRegister = genObjUnRegister()
1251 e = m.GetMeshEditor()
1253 src1 = e.MakeIDSource([id1], SMESH.FACE)
1255 src1 = e.MakeIDSource([id1], SMESH.NODE)
1256 unRegister.set( src1 )
1258 if hasattr(src2, "_narrow"):
1259 src2 = src2._narrow(SMESH.SMESH_IDSource)
1260 if src2 and id2 != 0:
1262 e = m.GetMeshEditor()
1264 src2 = e.MakeIDSource([id2], SMESH.FACE)
1266 src2 = e.MakeIDSource([id2], SMESH.NODE)
1267 unRegister.set( src2 )
1270 aMeasurements = self.CreateMeasurements()
1271 unRegister.set( aMeasurements )
1272 result = aMeasurements.MinDistance(src1, src2)
1275 def BoundingBox(self, objects):
1277 Get bounding box of the specified object(s)
1280 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1283 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1286 :meth:`GetBoundingBox`
1289 result = self.GetBoundingBox(objects)
1293 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1296 def GetBoundingBox(self, objects):
1298 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1301 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1304 :class:`SMESH.Measure` structure
1310 if isinstance(objects, tuple):
1311 objects = list(objects)
1312 if not isinstance(objects, list):
1316 if isinstance(o, Mesh):
1317 srclist.append(o.mesh)
1318 elif hasattr(o, "_narrow"):
1319 src = o._narrow(SMESH.SMESH_IDSource)
1320 if src: srclist.append(src)
1323 aMeasurements = self.CreateMeasurements()
1324 result = aMeasurements.BoundingBox(srclist)
1325 aMeasurements.UnRegister()
1328 def GetLength(self, obj):
1330 Get sum of lengths of all 1D elements in the mesh object.
1333 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1336 sum of lengths of all 1D elements
1339 if isinstance(obj, Mesh): obj = obj.mesh
1340 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1341 aMeasurements = self.CreateMeasurements()
1342 value = aMeasurements.Length(obj)
1343 aMeasurements.UnRegister()
1346 def GetArea(self, obj):
1348 Get sum of areas of all 2D elements in the mesh object.
1351 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1354 sum of areas of all 2D elements
1357 if isinstance(obj, Mesh): obj = obj.mesh
1358 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1359 aMeasurements = self.CreateMeasurements()
1360 value = aMeasurements.Area(obj)
1361 aMeasurements.UnRegister()
1364 def GetVolume(self, obj):
1366 Get sum of volumes of all 3D elements in the mesh object.
1369 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1372 sum of volumes of all 3D elements
1375 if isinstance(obj, Mesh): obj = obj.mesh
1376 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1377 aMeasurements = self.CreateMeasurements()
1378 value = aMeasurements.Volume(obj)
1379 aMeasurements.UnRegister()
1382 def GetGravityCenter(self, obj):
1384 Get gravity center of all nodes of the mesh object.
1387 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1390 Three components of the gravity center (x,y,z)
1392 if isinstance(obj, Mesh): obj = obj.mesh
1393 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1394 aMeasurements = self.CreateMeasurements()
1395 pointStruct = aMeasurements.GravityCenter(obj)
1396 aMeasurements.UnRegister()
1397 return pointStruct.x, pointStruct.y, pointStruct.z
1399 pass # end of class smeshBuilder
1402 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1403 """Registering the new proxy for SMESH.SMESH_Gen"""
1406 def New( instance=None, instanceGeom=None):
1408 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1409 interface to create or load meshes.
1414 salome.salome_init()
1415 from salome.smesh import smeshBuilder
1416 smesh = smeshBuilder.New()
1419 study: SALOME study, generally obtained by salome.myStudy.
1420 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1421 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1423 :class:`smeshBuilder` instance
1431 smeshInst = smeshBuilder()
1432 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1433 smeshInst.init_smesh(instanceGeom)
1437 # Public class: Mesh
1438 # ==================
1441 class Mesh(metaclass = MeshMeta):
1443 This class allows defining and managing a mesh.
1444 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1445 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1446 new nodes and elements and by changing the existing entities), to get information
1447 about a mesh and to export a mesh in different formats.
1454 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1459 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1460 sets the GUI name of this mesh to *name*.
1463 smeshpyD: an instance of smeshBuilder class
1464 geompyD: an instance of geomBuilder class
1465 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1466 name: Study name of the mesh
1469 self.smeshpyD = smeshpyD
1470 self.geompyD = geompyD
1475 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1478 # publish geom of mesh (issue 0021122)
1479 if not self.geom.GetStudyEntry():
1483 geo_name = name + " shape"
1485 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1486 geompyD.addToStudy( self.geom, geo_name )
1487 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1489 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1492 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1494 self.smeshpyD.SetName(self.mesh, name)
1496 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1499 self.geom = self.mesh.GetShapeToMesh()
1501 self.editor = self.mesh.GetMeshEditor()
1502 self.functors = [None] * SMESH.FT_Undefined._v
1504 # set self to algoCreator's
1505 for attrName in dir(self):
1506 attr = getattr( self, attrName )
1507 if isinstance( attr, algoCreator ):
1508 setattr( self, attrName, attr.copy( self ))
1515 Destructor. Clean-up resources
1518 #self.mesh.UnRegister()
1522 def SetMesh(self, theMesh):
1524 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1527 theMesh: a :class:`SMESH.SMESH_Mesh` object
1531 # do not call Register() as this prevents mesh servant deletion at closing study
1532 #if self.mesh: self.mesh.UnRegister()
1535 #self.mesh.Register()
1536 self.geom = self.mesh.GetShapeToMesh()
1541 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1544 a :class:`SMESH.SMESH_Mesh` object
1551 Get the name of the mesh
1554 the name of the mesh as a string
1557 name = GetName(self.GetMesh())
1560 def SetName(self, name):
1562 Set a name to the mesh
1565 name: a new name of the mesh
1568 self.smeshpyD.SetName(self.GetMesh(), name)
1570 def GetSubMesh(self, geom, name):
1572 Get a sub-mesh object associated to a *geom* geometrical object.
1575 geom: a geometrical object (shape)
1576 name: a name for the sub-mesh in the Object Browser
1579 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1580 which lies on the given shape
1583 A sub-mesh is implicitly created when a sub-shape is specified at
1584 creating an algorithm, for example::
1586 algo1D = mesh.Segment(geom=Edge_1)
1588 creates a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1589 The created sub-mesh can be retrieved from the algorithm::
1591 submesh = algo1D.GetSubMesh()
1594 AssureGeomPublished( self, geom, name )
1595 submesh = self.mesh.GetSubMesh( geom, name )
1600 Return the shape associated to the mesh
1608 def SetShape(self, geom):
1610 Associate the given shape to the mesh (entails the recreation of the mesh)
1613 geom: the shape to be meshed (GEOM_Object)
1616 self.mesh = self.smeshpyD.CreateMesh(geom)
1620 Load mesh from the study after opening the study
1624 def IsReadyToCompute(self, theSubObject):
1626 Return true if the hypotheses are defined well
1629 theSubObject: a sub-shape of a mesh shape
1635 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1637 def GetAlgoState(self, theSubObject):
1639 Return errors of hypotheses definition.
1640 The list of errors is empty if everything is OK.
1643 theSubObject: a sub-shape of a mesh shape
1649 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1651 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1653 Return a geometrical object on which the given element was built.
1654 The returned geometrical object, if not nil, is either found in the
1655 study or published by this method with the given name
1658 theElementID: the id of the mesh element
1659 theGeomName: the user-defined name of the geometrical object
1662 GEOM.GEOM_Object instance
1665 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1667 def MeshDimension(self):
1669 Return the mesh dimension depending on the dimension of the underlying shape
1670 or, if the mesh is not based on any shape, basing on deimension of elements
1673 mesh dimension as an integer value [0,3]
1676 if self.mesh.HasShapeToMesh():
1677 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1678 if len( shells ) > 0 :
1680 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1682 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1687 if self.NbVolumes() > 0: return 3
1688 if self.NbFaces() > 0: return 2
1689 if self.NbEdges() > 0: return 1
1692 def Evaluate(self, geom=0):
1694 Evaluate size of prospective mesh on a shape
1697 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1698 To know predicted number of e.g. edges, inquire it this way::
1700 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1703 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1705 geom = self.mesh.GetShapeToMesh()
1708 return self.smeshpyD.Evaluate(self.mesh, geom)
1711 def Compute(self, geom=0, discardModifs=False, refresh=False):
1713 Compute the mesh and return the status of the computation
1716 geom: geomtrical shape on which mesh data should be computed
1717 discardModifs: if True and the mesh has been edited since
1718 a last total re-compute and that may prevent successful partial re-compute,
1719 then the mesh is cleaned before Compute()
1720 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1726 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1728 geom = self.mesh.GetShapeToMesh()
1733 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1735 ok = self.smeshpyD.Compute(self.mesh, geom)
1736 except SALOME.SALOME_Exception as ex:
1737 print("Mesh computation failed, exception caught:")
1738 print(" ", ex.details.text)
1741 print("Mesh computation failed, exception caught:")
1742 traceback.print_exc()
1746 # Treat compute errors
1747 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1749 for err in computeErrors:
1750 if self.mesh.HasShapeToMesh():
1751 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1753 stdErrors = ["OK", #COMPERR_OK
1754 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1755 "std::exception", #COMPERR_STD_EXCEPTION
1756 "OCC exception", #COMPERR_OCC_EXCEPTION
1757 "..", #COMPERR_SLM_EXCEPTION
1758 "Unknown exception", #COMPERR_EXCEPTION
1759 "Memory allocation problem", #COMPERR_MEMORY_PB
1760 "Algorithm failed", #COMPERR_ALGO_FAILED
1761 "Unexpected geometry", #COMPERR_BAD_SHAPE
1762 "Warning", #COMPERR_WARNING
1763 "Computation cancelled",#COMPERR_CANCELED
1764 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1766 if err.code < len(stdErrors): errText = stdErrors[err.code]
1768 errText = "code %s" % -err.code
1769 if errText: errText += ". "
1770 errText += err.comment
1771 if allReasons: allReasons += "\n"
1773 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1775 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1779 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1781 if err.isGlobalAlgo:
1789 reason = '%s %sD algorithm is missing' % (glob, dim)
1790 elif err.state == HYP_MISSING:
1791 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1792 % (glob, dim, name, dim))
1793 elif err.state == HYP_NOTCONFORM:
1794 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1795 elif err.state == HYP_BAD_PARAMETER:
1796 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1797 % ( glob, dim, name ))
1798 elif err.state == HYP_BAD_GEOMETRY:
1799 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1800 'geometry' % ( glob, dim, name ))
1801 elif err.state == HYP_HIDDEN_ALGO:
1802 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1803 'algorithm of upper dimension generating %sD mesh'
1804 % ( glob, dim, name, glob, dim ))
1806 reason = ("For unknown reason. "
1807 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1809 if allReasons: allReasons += "\n"
1810 allReasons += "- " + reason
1812 if not ok or allReasons != "":
1813 msg = '"' + GetName(self.mesh) + '"'
1814 if ok: msg += " has been computed with warnings"
1815 else: msg += " has not been computed"
1816 if allReasons != "": msg += ":"
1821 if salome.sg.hasDesktop():
1822 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1823 smeshgui = salome.ImportComponentGUI("SMESH")
1825 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
1826 if refresh: salome.sg.updateObjBrowser()
1830 def GetComputeErrors(self, shape=0 ):
1832 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1836 shape = self.mesh.GetShapeToMesh()
1837 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1839 def GetSubShapeName(self, subShapeID ):
1841 Return a name of a sub-shape by its ID.
1842 Possible variants (for *subShapeID* == 3):
1844 - **"Face_12"** - published sub-shape
1845 - **FACE #3** - not published sub-shape
1846 - **sub-shape #3** - invalid sub-shape ID
1847 - **#3** - error in this function
1850 subShapeID: a unique ID of a sub-shape
1853 a string describing the sub-shape
1857 if not self.mesh.HasShapeToMesh():
1861 mainIOR = salome.orb.object_to_string( self.GetShape() )
1863 mainSO = s.FindObjectIOR(mainIOR)
1866 shapeText = '"%s"' % mainSO.GetName()
1867 subIt = s.NewChildIterator(mainSO)
1869 subSO = subIt.Value()
1871 obj = subSO.GetObject()
1872 if not obj: continue
1873 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1876 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1879 if ids == subShapeID:
1880 shapeText = '"%s"' % subSO.GetName()
1883 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1885 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1887 shapeText = 'sub-shape #%s' % (subShapeID)
1889 shapeText = "#%s" % (subShapeID)
1892 def GetFailedShapes(self, publish=False):
1894 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1895 error of an algorithm
1898 publish: if *True*, the returned groups will be published in the study
1901 a list of GEOM groups each named after a failed algorithm
1906 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1907 for err in computeErrors:
1908 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1909 if not shape: continue
1910 if err.algoName in algo2shapes:
1911 algo2shapes[ err.algoName ].append( shape )
1913 algo2shapes[ err.algoName ] = [ shape ]
1917 for algoName, shapes in list(algo2shapes.items()):
1919 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1920 otherTypeShapes = []
1922 group = self.geompyD.CreateGroup( self.geom, groupType )
1923 for shape in shapes:
1924 if shape.GetShapeType() == shapes[0].GetShapeType():
1925 sameTypeShapes.append( shape )
1927 otherTypeShapes.append( shape )
1928 self.geompyD.UnionList( group, sameTypeShapes )
1930 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1932 group.SetName( algoName )
1933 groups.append( group )
1934 shapes = otherTypeShapes
1937 for group in groups:
1938 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1941 def GetMeshOrder(self):
1943 Return sub-mesh objects list in meshing order
1946 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1949 return self.mesh.GetMeshOrder()
1951 def SetMeshOrder(self, submeshes):
1953 Set order in which concurrent sub-meshes should be meshed
1956 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1959 return self.mesh.SetMeshOrder(submeshes)
1961 def Clear(self, refresh=False):
1963 Remove all nodes and elements generated on geometry. Imported elements remain.
1966 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1970 if ( salome.sg.hasDesktop() ):
1971 smeshgui = salome.ImportComponentGUI("SMESH")
1973 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1974 if refresh: salome.sg.updateObjBrowser()
1976 def ClearSubMesh(self, geomId, refresh=False):
1978 Remove all nodes and elements of indicated shape
1981 geomId: the ID of a sub-shape to remove elements on
1982 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1985 self.mesh.ClearSubMesh(geomId)
1986 if salome.sg.hasDesktop():
1987 smeshgui = salome.ImportComponentGUI("SMESH")
1989 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1990 if refresh: salome.sg.updateObjBrowser()
1992 def AutomaticTetrahedralization(self, fineness=0):
1994 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
1997 fineness: [0.0,1.0] defines mesh fineness
2003 dim = self.MeshDimension()
2005 self.RemoveGlobalHypotheses()
2006 self.Segment().AutomaticLength(fineness)
2008 self.Triangle().LengthFromEdges()
2013 return self.Compute()
2015 def AutomaticHexahedralization(self, fineness=0):
2017 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2020 fineness: [0.0, 1.0] defines mesh fineness
2026 dim = self.MeshDimension()
2027 # assign the hypotheses
2028 self.RemoveGlobalHypotheses()
2029 self.Segment().AutomaticLength(fineness)
2036 return self.Compute()
2038 def AddHypothesis(self, hyp, geom=0):
2043 hyp: a hypothesis to assign
2044 geom: a subhape of mesh geometry
2047 :class:`SMESH.Hypothesis_Status`
2050 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2051 hyp, geom = geom, hyp
2052 if isinstance( hyp, Mesh_Algorithm ):
2053 hyp = hyp.GetAlgorithm()
2058 geom = self.mesh.GetShapeToMesh()
2061 if self.mesh.HasShapeToMesh():
2062 hyp_type = hyp.GetName()
2063 lib_name = hyp.GetLibName()
2064 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2065 # if checkAll and geom:
2066 # checkAll = geom.GetType() == 37
2068 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2070 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2071 status = self.mesh.AddHypothesis(geom, hyp)
2073 status = HYP_BAD_GEOMETRY, ""
2074 hyp_name = GetName( hyp )
2077 geom_name = geom.GetName()
2078 isAlgo = hyp._narrow( SMESH_Algo )
2079 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2082 def IsUsedHypothesis(self, hyp, geom):
2084 Return True if an algorithm or hypothesis is assigned to a given shape
2087 hyp: an algorithm or hypothesis to check
2088 geom: a subhape of mesh geometry
2094 if not hyp: # or not geom
2096 if isinstance( hyp, Mesh_Algorithm ):
2097 hyp = hyp.GetAlgorithm()
2099 hyps = self.GetHypothesisList(geom)
2101 if h.GetId() == hyp.GetId():
2105 def RemoveHypothesis(self, hyp, geom=0):
2107 Unassign a hypothesis
2110 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2111 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2114 :class:`SMESH.Hypothesis_Status`
2119 if isinstance( hyp, Mesh_Algorithm ):
2120 hyp = hyp.GetAlgorithm()
2126 if self.IsUsedHypothesis( hyp, shape ):
2127 return self.mesh.RemoveHypothesis( shape, hyp )
2128 hypName = GetName( hyp )
2129 geoName = GetName( shape )
2130 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2133 def GetHypothesisList(self, geom):
2135 Get the list of hypotheses added on a geometry
2138 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2141 the sequence of :class:`SMESH.SMESH_Hypothesis`
2144 return self.mesh.GetHypothesisList( geom )
2146 def RemoveGlobalHypotheses(self):
2148 Remove all global hypotheses
2151 current_hyps = self.mesh.GetHypothesisList( self.geom )
2152 for hyp in current_hyps:
2153 self.mesh.RemoveHypothesis( self.geom, hyp )
2156 def ExportMED(self, *args, **kwargs):
2158 Export the mesh in a file in MED format
2159 allowing to overwrite the file if it exists or add the exported data to its contents
2162 fileName: is the file name
2163 auto_groups (boolean): parameter for creating/not creating
2164 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2165 the typical use is auto_groups=False.
2166 overwrite (boolean): parameter for overwriting/not overwriting the file
2167 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2168 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2170 - 1D if all mesh nodes lie on OX coordinate axis, or
2171 - 2D if all mesh nodes lie on XOY coordinate plane, or
2172 - 3D in the rest cases.
2174 If *autoDimension* is *False*, the space dimension is always 3.
2175 fields: list of GEOM fields defined on the shape to mesh.
2176 geomAssocFields: each character of this string means a need to export a
2177 corresponding field; correspondence between fields and characters is following:
2178 - 'v' stands for "_vertices _" field;
2179 - 'e' stands for "_edges _" field;
2180 - 'f' stands for "_faces _" field;
2181 - 's' stands for "_solids _" field.
2183 # process positional arguments
2184 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2186 auto_groups = args[1] if len(args) > 1 else False
2187 overwrite = args[2] if len(args) > 2 else True
2188 meshPart = args[3] if len(args) > 3 else None
2189 autoDimension = args[4] if len(args) > 4 else True
2190 fields = args[5] if len(args) > 5 else []
2191 geomAssocFields = args[6] if len(args) > 6 else ''
2192 # process keywords arguments
2193 auto_groups = kwargs.get("auto_groups", auto_groups)
2194 overwrite = kwargs.get("overwrite", overwrite)
2195 meshPart = kwargs.get("meshPart", meshPart)
2196 autoDimension = kwargs.get("autoDimension", autoDimension)
2197 fields = kwargs.get("fields", fields)
2198 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2199 # invoke engine's function
2200 if meshPart or fields or geomAssocFields:
2201 unRegister = genObjUnRegister()
2202 if isinstance( meshPart, list ):
2203 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2204 unRegister.set( meshPart )
2205 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, overwrite, autoDimension,
2206 fields, geomAssocFields)
2208 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2210 def ExportSAUV(self, f, auto_groups=0):
2212 Export the mesh in a file in SAUV format
2217 auto_groups: boolean parameter for creating/not creating
2218 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2219 the typical use is auto_groups=False.
2222 self.mesh.ExportSAUV(f, auto_groups)
2224 def ExportDAT(self, f, meshPart=None):
2226 Export the mesh in a file in DAT format
2230 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2234 unRegister = genObjUnRegister()
2235 if isinstance( meshPart, list ):
2236 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2237 unRegister.set( meshPart )
2238 self.mesh.ExportPartToDAT( meshPart, f )
2240 self.mesh.ExportDAT(f)
2242 def ExportUNV(self, f, meshPart=None):
2244 Export the mesh in a file in UNV format
2248 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2252 unRegister = genObjUnRegister()
2253 if isinstance( meshPart, list ):
2254 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2255 unRegister.set( meshPart )
2256 self.mesh.ExportPartToUNV( meshPart, f )
2258 self.mesh.ExportUNV(f)
2260 def ExportSTL(self, f, ascii=1, meshPart=None):
2262 Export the mesh in a file in STL format
2266 ascii: defines the file encoding
2267 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2271 unRegister = genObjUnRegister()
2272 if isinstance( meshPart, list ):
2273 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2274 unRegister.set( meshPart )
2275 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2277 self.mesh.ExportSTL(f, ascii)
2279 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2281 Export the mesh in a file in CGNS format
2285 overwrite: boolean parameter for overwriting/not overwriting the file
2286 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2287 groupElemsByType: if True all elements of same entity type are exported at ones,
2288 else elements are exported in order of their IDs which can cause creation
2289 of multiple cgns sections
2292 unRegister = genObjUnRegister()
2293 if isinstance( meshPart, list ):
2294 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2295 unRegister.set( meshPart )
2296 if isinstance( meshPart, Mesh ):
2297 meshPart = meshPart.mesh
2299 meshPart = self.mesh
2300 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2302 def ExportGMF(self, f, meshPart=None):
2304 Export the mesh in a file in GMF format.
2305 GMF files must have .mesh extension for the ASCII format and .meshb for
2306 the bynary format. Other extensions are not allowed.
2310 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2313 unRegister = genObjUnRegister()
2314 if isinstance( meshPart, list ):
2315 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2316 unRegister.set( meshPart )
2317 if isinstance( meshPart, Mesh ):
2318 meshPart = meshPart.mesh
2320 meshPart = self.mesh
2321 self.mesh.ExportGMF(meshPart, f, True)
2323 def ExportToMED(self, *args, **kwargs):
2325 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2326 Export the mesh in a file in MED format
2327 allowing to overwrite the file if it exists or add the exported data to its contents
2330 fileName: the file name
2331 opt (boolean): parameter for creating/not creating
2332 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2333 overwrite: boolean parameter for overwriting/not overwriting the file
2334 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2336 - 1D if all mesh nodes lie on OX coordinate axis, or
2337 - 2D if all mesh nodes lie on XOY coordinate plane, or
2338 - 3D in the rest cases.
2340 If **autoDimension** is *False*, the space dimension is always 3.
2343 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2344 # process positional arguments
2345 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2347 auto_groups = args[1] if len(args) > 1 else False
2348 overwrite = args[2] if len(args) > 2 else True
2349 autoDimension = args[3] if len(args) > 3 else True
2350 # process keywords arguments
2351 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2352 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2353 overwrite = kwargs.get("overwrite", overwrite)
2354 autoDimension = kwargs.get("autoDimension", autoDimension)
2355 # invoke engine's function
2356 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2358 def ExportToMEDX(self, *args, **kwargs):
2360 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2361 Export the mesh in a file in MED format
2364 fileName: the file name
2365 opt (boolean): parameter for creating/not creating
2366 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2367 overwrite: boolean parameter for overwriting/not overwriting the file
2368 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2370 - 1D if all mesh nodes lie on OX coordinate axis, or
2371 - 2D if all mesh nodes lie on XOY coordinate plane, or
2372 - 3D in the rest cases.
2374 If **autoDimension** is *False*, the space dimension is always 3.
2377 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2378 # process positional arguments
2379 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2381 auto_groups = args[1] if len(args) > 1 else False
2382 overwrite = args[2] if len(args) > 2 else True
2383 autoDimension = args[3] if len(args) > 3 else True
2384 # process keywords arguments
2385 auto_groups = kwargs.get("auto_groups", auto_groups)
2386 overwrite = kwargs.get("overwrite", overwrite)
2387 autoDimension = kwargs.get("autoDimension", autoDimension)
2388 # invoke engine's function
2389 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2391 # Operations with groups:
2392 # ----------------------
2393 def CreateEmptyGroup(self, elementType, name):
2395 Create an empty mesh group
2398 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2399 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2400 name: the name of the mesh group
2403 :class:`SMESH.SMESH_Group`
2406 return self.mesh.CreateGroup(elementType, name)
2408 def Group(self, grp, name=""):
2410 Create a mesh group based on the geometric object *grp*
2411 and give it a *name*.
2412 If *name* is not defined the name of the geometric group is used
2415 Works like :meth:`GroupOnGeom`.
2418 grp: a geometric group, a vertex, an edge, a face or a solid
2419 name: the name of the mesh group
2422 :class:`SMESH.SMESH_GroupOnGeom`
2425 return self.GroupOnGeom(grp, name)
2427 def GroupOnGeom(self, grp, name="", typ=None):
2429 Create a mesh group based on the geometrical object *grp*
2431 if *name* is not defined the name of the geometric group is used
2434 grp: a geometrical group, a vertex, an edge, a face or a solid
2435 name: the name of the mesh group
2436 typ: the type of elements in the group; either of
2437 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2438 automatically detected by the type of the geometry
2441 :class:`SMESH.SMESH_GroupOnGeom`
2444 AssureGeomPublished( self, grp, name )
2446 name = grp.GetName()
2448 typ = self._groupTypeFromShape( grp )
2449 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2451 def _groupTypeFromShape( self, shape ):
2453 Pivate method to get a type of group on geometry
2455 tgeo = str(shape.GetShapeType())
2456 if tgeo == "VERTEX":
2458 elif tgeo == "EDGE":
2460 elif tgeo == "FACE" or tgeo == "SHELL":
2462 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2464 elif tgeo == "COMPOUND":
2465 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2467 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2468 return self._groupTypeFromShape( sub[0] )
2470 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2473 def GroupOnFilter(self, typ, name, filter):
2475 Create a mesh group with given *name* based on the *filter* which
2476 is a special type of group dynamically updating it's contents during
2480 typ: the type of elements in the group; either of
2481 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2482 name: the name of the mesh group
2483 filter (SMESH.Filter): the filter defining group contents
2486 :class:`SMESH.SMESH_GroupOnFilter`
2489 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2491 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2493 Create a mesh group by the given ids of elements
2496 groupName: the name of the mesh group
2497 elementType: the type of elements in the group; either of
2498 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2499 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2502 :class:`SMESH.SMESH_Group`
2505 group = self.mesh.CreateGroup(elementType, groupName)
2506 if isinstance( elemIDs, Mesh ):
2507 elemIDs = elemIDs.GetMesh()
2508 if hasattr( elemIDs, "GetIDs" ):
2509 if hasattr( elemIDs, "SetMesh" ):
2510 elemIDs.SetMesh( self.GetMesh() )
2511 group.AddFrom( elemIDs )
2519 CritType=FT_Undefined,
2522 UnaryOp=FT_Undefined,
2525 Create a mesh group by the given conditions
2528 groupName: the name of the mesh group
2529 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2530 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2531 Note that the items starting from FT_LessThan are not suitable for CritType.
2532 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2533 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2534 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2535 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2536 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2539 :class:`SMESH.SMESH_GroupOnFilter`
2542 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2543 group = self.MakeGroupByCriterion(groupName, aCriterion)
2546 def MakeGroupByCriterion(self, groupName, Criterion):
2548 Create a mesh group by the given criterion
2551 groupName: the name of the mesh group
2552 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2555 :class:`SMESH.SMESH_GroupOnFilter`
2558 :meth:`smeshBuilder.GetCriterion`
2561 return self.MakeGroupByCriteria( groupName, [Criterion] )
2563 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2565 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2568 groupName: the name of the mesh group
2569 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2570 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2573 :class:`SMESH.SMESH_GroupOnFilter`
2576 :meth:`smeshBuilder.GetCriterion`
2579 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2580 group = self.MakeGroupByFilter(groupName, aFilter)
2583 def MakeGroupByFilter(self, groupName, theFilter):
2585 Create a mesh group by the given filter
2588 groupName (string): the name of the mesh group
2589 theFilter (SMESH.Filter): the filter
2592 :class:`SMESH.SMESH_GroupOnFilter`
2595 :meth:`smeshBuilder.GetFilter`
2598 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2599 #theFilter.SetMesh( self.mesh )
2600 #group.AddFrom( theFilter )
2601 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2604 def RemoveGroup(self, group):
2609 group (SMESH.SMESH_GroupBase): group to remove
2612 self.mesh.RemoveGroup(group)
2614 def RemoveGroupWithContents(self, group):
2616 Remove a group with its contents
2619 group (SMESH.SMESH_GroupBase): group to remove
2622 self.mesh.RemoveGroupWithContents(group)
2624 def GetGroups(self, elemType = SMESH.ALL):
2626 Get the list of groups existing in the mesh in the order
2627 of creation (starting from the oldest one)
2630 elemType (SMESH.ElementType): type of elements the groups contain;
2631 by default groups of elements of all types are returned
2634 a sequence of :class:`SMESH.SMESH_GroupBase`
2637 groups = self.mesh.GetGroups()
2638 if elemType == SMESH.ALL:
2642 if g.GetType() == elemType:
2643 typedGroups.append( g )
2650 Get the number of groups existing in the mesh
2653 the quantity of groups as an integer value
2656 return self.mesh.NbGroups()
2658 def GetGroupNames(self):
2660 Get the list of names of groups existing in the mesh
2666 groups = self.GetGroups()
2668 for group in groups:
2669 names.append(group.GetName())
2672 def GetGroupByName(self, name, elemType = None):
2674 Find groups by name and type
2677 name (string): name of the group of interest
2678 elemType (SMESH.ElementType): type of elements the groups contain;
2679 by default one group of any type is returned;
2680 if elemType == SMESH.ALL then all groups of any type are returned
2683 a list of :class:`SMESH.SMESH_GroupBase`
2687 for group in self.GetGroups():
2688 if group.GetName() == name:
2689 if elemType is None:
2691 if ( elemType == SMESH.ALL or
2692 group.GetType() == elemType ):
2693 groups.append( group )
2696 def UnionGroups(self, group1, group2, name):
2698 Produce a union of two groups.
2699 A new group is created. All mesh elements that are
2700 present in the initial groups are added to the new one
2703 group1 (SMESH.SMESH_GroupBase): a group
2704 group2 (SMESH.SMESH_GroupBase): another group
2707 instance of :class:`SMESH.SMESH_Group`
2710 return self.mesh.UnionGroups(group1, group2, name)
2712 def UnionListOfGroups(self, groups, name):
2714 Produce a union list of groups.
2715 New group is created. All mesh elements that are present in
2716 initial groups are added to the new one
2719 groups: list of :class:`SMESH.SMESH_GroupBase`
2722 instance of :class:`SMESH.SMESH_Group`
2724 return self.mesh.UnionListOfGroups(groups, name)
2726 def IntersectGroups(self, group1, group2, name):
2728 Prodice an intersection of two groups.
2729 A new group is created. All mesh elements that are common
2730 for the two initial groups are added to the new one.
2733 group1 (SMESH.SMESH_GroupBase): a group
2734 group2 (SMESH.SMESH_GroupBase): another group
2737 instance of :class:`SMESH.SMESH_Group`
2740 return self.mesh.IntersectGroups(group1, group2, name)
2742 def IntersectListOfGroups(self, groups, name):
2744 Produce an intersection of groups.
2745 New group is created. All mesh elements that are present in all
2746 initial groups simultaneously are added to the new one
2749 groups: a list of :class:`SMESH.SMESH_GroupBase`
2752 instance of :class:`SMESH.SMESH_Group`
2754 return self.mesh.IntersectListOfGroups(groups, name)
2756 def CutGroups(self, main_group, tool_group, name):
2758 Produce a cut of two groups.
2759 A new group is created. All mesh elements that are present in
2760 the main group but are not present in the tool group are added to the new one
2763 main_group (SMESH.SMESH_GroupBase): a group to cut from
2764 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2767 an instance of :class:`SMESH.SMESH_Group`
2770 return self.mesh.CutGroups(main_group, tool_group, name)
2772 def CutListOfGroups(self, main_groups, tool_groups, name):
2774 Produce a cut of groups.
2775 A new group is created. All mesh elements that are present in main groups
2776 but do not present in tool groups are added to the new one
2779 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2780 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2783 an instance of :class:`SMESH.SMESH_Group`
2786 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2788 def CreateDimGroup(self, groups, elemType, name,
2789 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2791 Create a standalone group of entities basing on nodes of other groups.
2794 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2795 elemType: a type of elements to include to the new group; either of
2796 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2797 name: a name of the new group.
2798 nbCommonNodes: a criterion of inclusion of an element to the new group
2799 basing on number of element nodes common with reference *groups*.
2800 Meaning of possible values are:
2802 - SMESH.ALL_NODES - include if all nodes are common,
2803 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2804 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2805 - SMEHS.MAJORITY - include if half of nodes or more are common.
2806 underlyingOnly: if *True* (default), an element is included to the
2807 new group provided that it is based on nodes of an element of *groups*;
2808 in this case the reference *groups* are supposed to be of higher dimension
2809 than *elemType*, which can be useful for example to get all faces lying on
2810 volumes of the reference *groups*.
2813 an instance of :class:`SMESH.SMESH_Group`
2816 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2818 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2821 def ConvertToStandalone(self, group):
2823 Convert group on geom into standalone group
2826 return self.mesh.ConvertToStandalone(group)
2828 # Get some info about mesh:
2829 # ------------------------
2831 def GetLog(self, clearAfterGet):
2833 Return the log of nodes and elements added or removed
2834 since the previous clear of the log.
2837 clearAfterGet: log is emptied after Get (safe if concurrents access)
2840 list of SMESH.log_block structures { commandType, number, coords, indexes }
2843 return self.mesh.GetLog(clearAfterGet)
2847 Clear the log of nodes and elements added or removed since the previous
2848 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2851 self.mesh.ClearLog()
2853 def SetAutoColor(self, theAutoColor):
2855 Toggle auto color mode on the object.
2856 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2859 theAutoColor (boolean): the flag which toggles auto color mode.
2862 self.mesh.SetAutoColor(theAutoColor)
2864 def GetAutoColor(self):
2866 Get flag of object auto color mode.
2872 return self.mesh.GetAutoColor()
2879 integer value, which is the internal Id of the mesh
2882 return self.mesh.GetId()
2884 def HasDuplicatedGroupNamesMED(self):
2886 Check the group names for duplications.
2887 Consider the maximum group name length stored in MED file.
2893 return self.mesh.HasDuplicatedGroupNamesMED()
2895 def GetMeshEditor(self):
2897 Obtain the mesh editor tool
2900 an instance of :class:`SMESH.SMESH_MeshEditor`
2905 def GetIDSource(self, ids, elemType = SMESH.ALL):
2907 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2908 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2912 elemType: type of elements; this parameter is used to distinguish
2913 IDs of nodes from IDs of elements; by default ids are treated as
2914 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2917 an instance of :class:`SMESH.SMESH_IDSource`
2920 call UnRegister() for the returned object as soon as it is no more useful::
2922 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2923 mesh.DoSomething( idSrc )
2927 if isinstance( ids, int ):
2929 return self.editor.MakeIDSource(ids, elemType)
2932 # Get information about mesh contents:
2933 # ------------------------------------
2935 def GetMeshInfo(self, obj = None):
2937 Get the mesh statistic.
2938 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2939 an item of :class:`SMESH.EntityType`.
2942 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2945 if not obj: obj = self.mesh
2946 return self.smeshpyD.GetMeshInfo(obj)
2950 Return the number of nodes in the mesh
2956 return self.mesh.NbNodes()
2958 def NbElements(self):
2960 Return the number of elements in the mesh
2966 return self.mesh.NbElements()
2968 def Nb0DElements(self):
2970 Return the number of 0d elements in the mesh
2976 return self.mesh.Nb0DElements()
2980 Return the number of ball discrete elements in the mesh
2986 return self.mesh.NbBalls()
2990 Return the number of edges in the mesh
2996 return self.mesh.NbEdges()
2998 def NbEdgesOfOrder(self, elementOrder):
3000 Return the number of edges with the given order in the mesh
3003 elementOrder: the order of elements
3004 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3010 return self.mesh.NbEdgesOfOrder(elementOrder)
3014 Return the number of faces in the mesh
3020 return self.mesh.NbFaces()
3022 def NbFacesOfOrder(self, elementOrder):
3024 Return the number of faces with the given order in the mesh
3027 elementOrder: the order of elements
3028 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3034 return self.mesh.NbFacesOfOrder(elementOrder)
3036 def NbTriangles(self):
3038 Return the number of triangles in the mesh
3044 return self.mesh.NbTriangles()
3046 def NbTrianglesOfOrder(self, elementOrder):
3048 Return the number of triangles with the given order in the mesh
3051 elementOrder: is the order of elements
3052 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3058 return self.mesh.NbTrianglesOfOrder(elementOrder)
3060 def NbBiQuadTriangles(self):
3062 Return the number of biquadratic triangles in the mesh
3068 return self.mesh.NbBiQuadTriangles()
3070 def NbQuadrangles(self):
3072 Return the number of quadrangles in the mesh
3078 return self.mesh.NbQuadrangles()
3080 def NbQuadranglesOfOrder(self, elementOrder):
3082 Return the number of quadrangles with the given order in the mesh
3085 elementOrder: the order of elements
3086 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3092 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3094 def NbBiQuadQuadrangles(self):
3096 Return the number of biquadratic quadrangles in the mesh
3102 return self.mesh.NbBiQuadQuadrangles()
3104 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3106 Return the number of polygons of given order in the mesh
3109 elementOrder: the order of elements
3110 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3116 return self.mesh.NbPolygonsOfOrder(elementOrder)
3118 def NbVolumes(self):
3120 Return the number of volumes in the mesh
3126 return self.mesh.NbVolumes()
3129 def NbVolumesOfOrder(self, elementOrder):
3131 Return the number of volumes with the given order in the mesh
3134 elementOrder: the order of elements
3135 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3141 return self.mesh.NbVolumesOfOrder(elementOrder)
3145 Return the number of tetrahedrons in the mesh
3151 return self.mesh.NbTetras()
3153 def NbTetrasOfOrder(self, elementOrder):
3155 Return the number of tetrahedrons with the given order in the mesh
3158 elementOrder: the order of elements
3159 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3165 return self.mesh.NbTetrasOfOrder(elementOrder)
3169 Return the number of hexahedrons in the mesh
3175 return self.mesh.NbHexas()
3177 def NbHexasOfOrder(self, elementOrder):
3179 Return the number of hexahedrons with the given order in the mesh
3182 elementOrder: the order of elements
3183 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3189 return self.mesh.NbHexasOfOrder(elementOrder)
3191 def NbTriQuadraticHexas(self):
3193 Return the number of triquadratic hexahedrons in the mesh
3199 return self.mesh.NbTriQuadraticHexas()
3201 def NbPyramids(self):
3203 Return the number of pyramids in the mesh
3209 return self.mesh.NbPyramids()
3211 def NbPyramidsOfOrder(self, elementOrder):
3213 Return the number of pyramids with the given order in the mesh
3216 elementOrder: the order of elements
3217 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3223 return self.mesh.NbPyramidsOfOrder(elementOrder)
3227 Return the number of prisms in the mesh
3233 return self.mesh.NbPrisms()
3235 def NbPrismsOfOrder(self, elementOrder):
3237 Return the number of prisms with the given order in the mesh
3240 elementOrder: the order of elements
3241 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3247 return self.mesh.NbPrismsOfOrder(elementOrder)
3249 def NbHexagonalPrisms(self):
3251 Return the number of hexagonal prisms in the mesh
3257 return self.mesh.NbHexagonalPrisms()
3259 def NbPolyhedrons(self):
3261 Return the number of polyhedrons in the mesh
3267 return self.mesh.NbPolyhedrons()
3269 def NbSubMesh(self):
3271 Return the number of submeshes in the mesh
3277 return self.mesh.NbSubMesh()
3279 def GetElementsId(self):
3281 Return the list of all mesh elements IDs
3284 the list of integer values
3287 :meth:`GetElementsByType`
3290 return self.mesh.GetElementsId()
3292 def GetElementsByType(self, elementType):
3294 Return the list of IDs of mesh elements with the given type
3297 elementType (SMESH.ElementType): the required type of elements
3300 list of integer values
3303 return self.mesh.GetElementsByType(elementType)
3305 def GetNodesId(self):
3307 Return the list of mesh nodes IDs
3310 the list of integer values
3313 return self.mesh.GetNodesId()
3315 # Get the information about mesh elements:
3316 # ------------------------------------
3318 def GetElementType(self, id, iselem=True):
3320 Return the type of mesh element or node
3323 the value from :class:`SMESH.ElementType` enumeration.
3324 Return SMESH.ALL if element or node with the given ID does not exist
3327 return self.mesh.GetElementType(id, iselem)
3329 def GetElementGeomType(self, id):
3331 Return the geometric type of mesh element
3334 the value from :class:`SMESH.EntityType` enumeration.
3337 return self.mesh.GetElementGeomType(id)
3339 def GetElementShape(self, id):
3341 Return the shape type of mesh element
3344 the value from :class:`SMESH.GeometryType` enumeration.
3347 return self.mesh.GetElementShape(id)
3349 def GetSubMeshElementsId(self, Shape):
3351 Return the list of sub-mesh elements IDs
3354 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3355 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3358 list of integer values
3361 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3362 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3365 return self.mesh.GetSubMeshElementsId(ShapeID)
3367 def GetSubMeshNodesId(self, Shape, all):
3369 Return the list of sub-mesh nodes IDs
3372 Shape: a geom object (sub-shape).
3373 *Shape* must be the sub-shape of a :meth:`GetShape`
3374 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3377 list of integer values
3380 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3381 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3384 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3386 def GetSubMeshElementType(self, Shape):
3388 Return type of elements on given shape
3391 Shape: a geom object (sub-shape).
3392 *Shape* must be a sub-shape of a ShapeToMesh()
3395 :class:`SMESH.ElementType`
3398 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3399 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3402 return self.mesh.GetSubMeshElementType(ShapeID)
3406 Get the mesh description
3412 return self.mesh.Dump()
3415 # Get the information about nodes and elements of a mesh by its IDs:
3416 # -----------------------------------------------------------
3418 def GetNodeXYZ(self, id):
3420 Get XYZ coordinates of a node.
3421 If there is no node for the given ID - return an empty list
3424 list of float values
3427 return self.mesh.GetNodeXYZ(id)
3429 def GetNodeInverseElements(self, id):
3431 Return list of IDs of inverse elements for the given node.
3432 If there is no node for the given ID - return an empty list
3435 list of integer values
3438 return self.mesh.GetNodeInverseElements(id)
3440 def GetNodePosition(self,NodeID):
3442 Return the position of a node on the shape
3445 :class:`SMESH.NodePosition`
3448 return self.mesh.GetNodePosition(NodeID)
3450 def GetElementPosition(self,ElemID):
3452 Return the position of an element on the shape
3455 :class:`SMESH.ElementPosition`
3458 return self.mesh.GetElementPosition(ElemID)
3460 def GetShapeID(self, id):
3462 Return the ID of the shape, on which the given node was generated.
3465 an integer value > 0 or -1 if there is no node for the given
3466 ID or the node is not assigned to any geometry
3469 return self.mesh.GetShapeID(id)
3471 def GetShapeIDForElem(self,id):
3473 Return the ID of the shape, on which the given element was generated.
3476 an integer value > 0 or -1 if there is no element for the given
3477 ID or the element is not assigned to any geometry
3480 return self.mesh.GetShapeIDForElem(id)
3482 def GetElemNbNodes(self, id):
3484 Return the number of nodes of the given element
3487 an integer value > 0 or -1 if there is no element for the given ID
3490 return self.mesh.GetElemNbNodes(id)
3492 def GetElemNode(self, id, index):
3494 Return the node ID the given (zero based) index for the given element.
3496 * If there is no element for the given ID - return -1.
3497 * If there is no node for the given index - return -2.
3500 id (int): element ID
3501 index (int): node index within the element
3504 an integer value (ID)
3507 :meth:`GetElemNodes`
3510 return self.mesh.GetElemNode(id, index)
3512 def GetElemNodes(self, id):
3514 Return the IDs of nodes of the given element
3517 a list of integer values
3520 return self.mesh.GetElemNodes(id)
3522 def IsMediumNode(self, elementID, nodeID):
3524 Return true if the given node is the medium node in the given quadratic element
3527 return self.mesh.IsMediumNode(elementID, nodeID)
3529 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3531 Return true if the given node is the medium node in one of quadratic elements
3534 nodeID: ID of the node
3535 elementType: the type of elements to check a state of the node, either of
3536 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3539 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3541 def ElemNbEdges(self, id):
3543 Return the number of edges for the given element
3546 return self.mesh.ElemNbEdges(id)
3548 def ElemNbFaces(self, id):
3550 Return the number of faces for the given element
3553 return self.mesh.ElemNbFaces(id)
3555 def GetElemFaceNodes(self,elemId, faceIndex):
3557 Return nodes of given face (counted from zero) for given volumic element.
3560 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3562 def GetFaceNormal(self, faceId, normalized=False):
3564 Return three components of normal of given mesh face
3565 (or an empty array in KO case)
3568 return self.mesh.GetFaceNormal(faceId,normalized)
3570 def FindElementByNodes(self, nodes):
3572 Return an element based on all given nodes.
3575 return self.mesh.FindElementByNodes(nodes)
3577 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3579 Return elements including all given nodes.
3582 return self.mesh.GetElementsByNodes( nodes, elemType )
3584 def IsPoly(self, id):
3586 Return true if the given element is a polygon
3589 return self.mesh.IsPoly(id)
3591 def IsQuadratic(self, id):
3593 Return true if the given element is quadratic
3596 return self.mesh.IsQuadratic(id)
3598 def GetBallDiameter(self, id):
3600 Return diameter of a ball discrete element or zero in case of an invalid *id*
3603 return self.mesh.GetBallDiameter(id)
3605 def BaryCenter(self, id):
3607 Return XYZ coordinates of the barycenter of the given element.
3608 If there is no element for the given ID - return an empty list
3611 a list of three double values
3614 return self.mesh.BaryCenter(id)
3616 def GetIdsFromFilter(self, theFilter):
3618 Pass mesh elements through the given filter and return IDs of fitting elements
3621 theFilter: :class:`SMESH.Filter`
3627 :meth:`SMESH.Filter.GetIDs`
3630 theFilter.SetMesh( self.mesh )
3631 return theFilter.GetIDs()
3633 # Get mesh measurements information:
3634 # ------------------------------------
3636 def GetFreeBorders(self):
3638 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3639 Return a list of special structures (borders).
3642 a list of :class:`SMESH.FreeEdges.Border`
3645 aFilterMgr = self.smeshpyD.CreateFilterManager()
3646 aPredicate = aFilterMgr.CreateFreeEdges()
3647 aPredicate.SetMesh(self.mesh)
3648 aBorders = aPredicate.GetBorders()
3649 aFilterMgr.UnRegister()
3652 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3654 Get minimum distance between two nodes, elements or distance to the origin
3657 id1: first node/element id
3658 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3659 isElem1: *True* if *id1* is element id, *False* if it is node id
3660 isElem2: *True* if *id2* is element id, *False* if it is node id
3663 minimum distance value **GetMinDistance()**
3666 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3667 return aMeasure.value
3669 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3671 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3674 id1: first node/element id
3675 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3676 isElem1: *True* if *id1* is element id, *False* if it is node id
3677 isElem2: *True* if *id2* is element id, *False* if it is node id
3680 :class:`SMESH.Measure` structure
3686 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3688 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3691 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3693 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3698 aMeasurements = self.smeshpyD.CreateMeasurements()
3699 aMeasure = aMeasurements.MinDistance(id1, id2)
3700 genObjUnRegister([aMeasurements,id1, id2])
3703 def BoundingBox(self, objects=None, isElem=False):
3705 Get bounding box of the specified object(s)
3708 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3709 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3710 *False* specifies that *objects* are nodes
3713 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3716 :meth:`GetBoundingBox()`
3719 result = self.GetBoundingBox(objects, isElem)
3723 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3726 def GetBoundingBox(self, objects=None, isElem=False):
3728 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3731 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3732 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3733 False means that *objects* are nodes
3736 :class:`SMESH.Measure` structure
3739 :meth:`BoundingBox()`
3743 objects = [self.mesh]
3744 elif isinstance(objects, tuple):
3745 objects = list(objects)
3746 if not isinstance(objects, list):
3748 if len(objects) > 0 and isinstance(objects[0], int):
3751 unRegister = genObjUnRegister()
3753 if isinstance(o, Mesh):
3754 srclist.append(o.mesh)
3755 elif hasattr(o, "_narrow"):
3756 src = o._narrow(SMESH.SMESH_IDSource)
3757 if src: srclist.append(src)
3759 elif isinstance(o, list):
3761 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3763 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3764 unRegister.set( srclist[-1] )
3767 aMeasurements = self.smeshpyD.CreateMeasurements()
3768 unRegister.set( aMeasurements )
3769 aMeasure = aMeasurements.BoundingBox(srclist)
3772 # Mesh edition (SMESH_MeshEditor functionality):
3773 # ---------------------------------------------
3775 def RemoveElements(self, IDsOfElements):
3777 Remove the elements from the mesh by ids
3780 IDsOfElements: is a list of ids of elements to remove
3786 return self.editor.RemoveElements(IDsOfElements)
3788 def RemoveNodes(self, IDsOfNodes):
3790 Remove nodes from mesh by ids
3793 IDsOfNodes: is a list of ids of nodes to remove
3799 return self.editor.RemoveNodes(IDsOfNodes)
3801 def RemoveOrphanNodes(self):
3803 Remove all orphan (free) nodes from mesh
3806 number of the removed nodes
3809 return self.editor.RemoveOrphanNodes()
3811 def AddNode(self, x, y, z):
3813 Add a node to the mesh by coordinates
3819 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3820 if hasVars: self.mesh.SetParameters(Parameters)
3821 return self.editor.AddNode( x, y, z)
3823 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3825 Create a 0D element on a node with given number.
3828 IDOfNode: the ID of node for creation of the element.
3829 DuplicateElements: to add one more 0D element to a node or not
3832 ID of the new 0D element
3835 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3837 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3839 Create 0D elements on all nodes of the given elements except those
3840 nodes on which a 0D element already exists.
3843 theObject: an object on whose nodes 0D elements will be created.
3844 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3845 theGroupName: optional name of a group to add 0D elements created
3846 and/or found on nodes of *theObject*.
3847 DuplicateElements: to add one more 0D element to a node or not
3850 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3851 IDs of new and/or found 0D elements. IDs of 0D elements
3852 can be retrieved from the returned object by
3853 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3856 unRegister = genObjUnRegister()
3857 if isinstance( theObject, Mesh ):
3858 theObject = theObject.GetMesh()
3859 elif isinstance( theObject, list ):
3860 theObject = self.GetIDSource( theObject, SMESH.ALL )
3861 unRegister.set( theObject )
3862 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3864 def AddBall(self, IDOfNode, diameter):
3866 Create a ball element on a node with given ID.
3869 IDOfNode: the ID of node for creation of the element.
3870 diameter: the bal diameter.
3873 ID of the new ball element
3876 return self.editor.AddBall( IDOfNode, diameter )
3878 def AddEdge(self, IDsOfNodes):
3880 Create a linear or quadratic edge (this is determined
3881 by the number of given nodes).
3884 IDsOfNodes: list of node IDs for creation of the element.
3885 The order of nodes in this list should correspond to
3886 the :ref:`connectivity convention <connectivity_page>`.
3892 return self.editor.AddEdge(IDsOfNodes)
3894 def AddFace(self, IDsOfNodes):
3896 Create a linear or quadratic face (this is determined
3897 by the number of given nodes).
3900 IDsOfNodes: list of node IDs for creation of the element.
3901 The order of nodes in this list should correspond to
3902 the :ref:`connectivity convention <connectivity_page>`.
3908 return self.editor.AddFace(IDsOfNodes)
3910 def AddPolygonalFace(self, IdsOfNodes):
3912 Add a polygonal face defined by a list of node IDs
3915 IdsOfNodes: the list of node IDs for creation of the element.
3921 return self.editor.AddPolygonalFace(IdsOfNodes)
3923 def AddQuadPolygonalFace(self, IdsOfNodes):
3925 Add a quadratic polygonal face defined by a list of node IDs
3928 IdsOfNodes: the list of node IDs for creation of the element;
3929 corner nodes follow first.
3935 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3937 def AddVolume(self, IDsOfNodes):
3939 Create both simple and quadratic volume (this is determined
3940 by the number of given nodes).
3943 IDsOfNodes: list of node IDs for creation of the element.
3944 The order of nodes in this list should correspond to
3945 the :ref:`connectivity convention <connectivity_page>`.
3948 ID of the new volumic element
3951 return self.editor.AddVolume(IDsOfNodes)
3953 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3955 Create a volume of many faces, giving nodes for each face.
3958 IdsOfNodes: list of node IDs for volume creation, face by face.
3959 Quantities: list of integer values, Quantities[i]
3960 gives the quantity of nodes in face number i.
3963 ID of the new volumic element
3966 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3968 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3970 Create a volume of many faces, giving the IDs of the existing faces.
3973 The created volume will refer only to the nodes
3974 of the given faces, not to the faces themselves.
3977 IdsOfFaces: the list of face IDs for volume creation.
3980 ID of the new volumic element
3983 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
3986 def SetNodeOnVertex(self, NodeID, Vertex):
3988 Binds a node to a vertex
3992 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
3995 True if succeed else raises an exception
3998 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
3999 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4003 self.editor.SetNodeOnVertex(NodeID, VertexID)
4004 except SALOME.SALOME_Exception as inst:
4005 raise ValueError(inst.details.text)
4009 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4011 Stores the node position on an edge
4015 Edge: an edge (GEOM.GEOM_Object) or edge ID
4016 paramOnEdge: a parameter on the edge where the node is located
4019 True if succeed else raises an exception
4022 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4023 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4027 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4028 except SALOME.SALOME_Exception as inst:
4029 raise ValueError(inst.details.text)
4032 def SetNodeOnFace(self, NodeID, Face, u, v):
4034 Stores node position on a face
4038 Face: a face (GEOM.GEOM_Object) or face ID
4039 u: U parameter on the face where the node is located
4040 v: V parameter on the face where the node is located
4043 True if succeed else raises an exception
4046 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4047 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4051 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4052 except SALOME.SALOME_Exception as inst:
4053 raise ValueError(inst.details.text)
4056 def SetNodeInVolume(self, NodeID, Solid):
4058 Binds a node to a solid
4062 Solid: a solid (GEOM.GEOM_Object) or solid ID
4065 True if succeed else raises an exception
4068 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4069 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4073 self.editor.SetNodeInVolume(NodeID, SolidID)
4074 except SALOME.SALOME_Exception as inst:
4075 raise ValueError(inst.details.text)
4078 def SetMeshElementOnShape(self, ElementID, Shape):
4080 Bind an element to a shape
4083 ElementID: an element ID
4084 Shape: a shape (GEOM.GEOM_Object) or shape ID
4087 True if succeed else raises an exception
4090 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4091 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4095 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4096 except SALOME.SALOME_Exception as inst:
4097 raise ValueError(inst.details.text)
4101 def MoveNode(self, NodeID, x, y, z):
4103 Move the node with the given id
4106 NodeID: the id of the node
4107 x: a new X coordinate
4108 y: a new Y coordinate
4109 z: a new Z coordinate
4112 True if succeed else False
4115 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4116 if hasVars: self.mesh.SetParameters(Parameters)
4117 return self.editor.MoveNode(NodeID, x, y, z)
4119 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4121 Find the node closest to a point and moves it to a point location
4124 x: the X coordinate of a point
4125 y: the Y coordinate of a point
4126 z: the Z coordinate of a point
4127 NodeID: if specified (>0), the node with this ID is moved,
4128 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4131 the ID of a moved node
4134 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4135 if hasVars: self.mesh.SetParameters(Parameters)
4136 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4138 def FindNodeClosestTo(self, x, y, z):
4140 Find the node closest to a point
4143 x: the X coordinate of a point
4144 y: the Y coordinate of a point
4145 z: the Z coordinate of a point
4151 #preview = self.mesh.GetMeshEditPreviewer()
4152 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4153 return self.editor.FindNodeClosestTo(x, y, z)
4155 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4157 Find the elements where a point lays IN or ON
4160 x,y,z (float): coordinates of the point
4161 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4162 means elements of any type excluding nodes, discrete and 0D elements.
4163 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4166 list of IDs of found elements
4169 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4171 return self.editor.FindElementsByPoint(x, y, z, elementType)
4173 def GetPointState(self, x, y, z):
4175 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4176 0-IN, 1-OUT, 2-ON, 3-UNKNOWN.
4177 UNKNOWN state means that either mesh is wrong or the analysis fails.
4180 return self.editor.GetPointState(x, y, z)
4182 def IsManifold(self):
4184 Check if a 2D mesh is manifold
4187 return self.editor.IsManifold()
4189 def IsCoherentOrientation2D(self):
4191 Check if orientation of 2D elements is coherent
4194 return self.editor.IsCoherentOrientation2D()
4196 def MeshToPassThroughAPoint(self, x, y, z):
4198 Find the node closest to a point and moves it to a point location
4201 x: the X coordinate of a point
4202 y: the Y coordinate of a point
4203 z: the Z coordinate of a point
4206 the ID of a moved node
4209 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4211 def InverseDiag(self, NodeID1, NodeID2):
4213 Replace two neighbour triangles sharing Node1-Node2 link
4214 with the triangles built on the same 4 nodes but having other common link.
4217 NodeID1: the ID of the first node
4218 NodeID2: the ID of the second node
4221 False if proper faces were not found
4223 return self.editor.InverseDiag(NodeID1, NodeID2)
4225 def DeleteDiag(self, NodeID1, NodeID2):
4227 Replace two neighbour triangles sharing *Node1-Node2* link
4228 with a quadrangle built on the same 4 nodes.
4231 NodeID1: ID of the first node
4232 NodeID2: ID of the second node
4235 False if proper faces were not found
4238 return self.editor.DeleteDiag(NodeID1, NodeID2)
4240 def Reorient(self, IDsOfElements=None):
4242 Reorient elements by ids
4245 IDsOfElements: if undefined reorients all mesh elements
4248 True if succeed else False
4251 if IDsOfElements == None:
4252 IDsOfElements = self.GetElementsId()
4253 return self.editor.Reorient(IDsOfElements)
4255 def ReorientObject(self, theObject):
4257 Reorient all elements of the object
4260 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4263 True if succeed else False
4266 if ( isinstance( theObject, Mesh )):
4267 theObject = theObject.GetMesh()
4268 return self.editor.ReorientObject(theObject)
4270 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4272 Reorient faces contained in *the2DObject*.
4275 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4276 theDirection: is a desired direction of normal of *theFace*.
4277 It can be either a GEOM vector or a list of coordinates [x,y,z].
4278 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4279 compared with theDirection. It can be either ID of face or a point
4280 by which the face will be found. The point can be given as either
4281 a GEOM vertex or a list of point coordinates.
4284 number of reoriented faces
4287 unRegister = genObjUnRegister()
4289 if isinstance( the2DObject, Mesh ):
4290 the2DObject = the2DObject.GetMesh()
4291 if isinstance( the2DObject, list ):
4292 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4293 unRegister.set( the2DObject )
4294 # check theDirection
4295 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4296 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4297 if isinstance( theDirection, list ):
4298 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4299 # prepare theFace and thePoint
4300 theFace = theFaceOrPoint
4301 thePoint = PointStruct(0,0,0)
4302 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4303 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4305 if isinstance( theFaceOrPoint, list ):
4306 thePoint = PointStruct( *theFaceOrPoint )
4308 if isinstance( theFaceOrPoint, PointStruct ):
4309 thePoint = theFaceOrPoint
4311 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4313 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4315 Reorient faces according to adjacent volumes.
4318 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4319 either IDs of faces or face groups.
4320 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4321 theOutsideNormal: to orient faces to have their normals
4322 pointing either *outside* or *inside* the adjacent volumes.
4325 number of reoriented faces.
4328 unRegister = genObjUnRegister()
4330 if not isinstance( the2DObject, list ):
4331 the2DObject = [ the2DObject ]
4332 elif the2DObject and isinstance( the2DObject[0], int ):
4333 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4334 unRegister.set( the2DObject )
4335 the2DObject = [ the2DObject ]
4336 for i,obj2D in enumerate( the2DObject ):
4337 if isinstance( obj2D, Mesh ):
4338 the2DObject[i] = obj2D.GetMesh()
4339 if isinstance( obj2D, list ):
4340 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4341 unRegister.set( the2DObject[i] )
4343 if isinstance( the3DObject, Mesh ):
4344 the3DObject = the3DObject.GetMesh()
4345 if isinstance( the3DObject, list ):
4346 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4347 unRegister.set( the3DObject )
4348 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4350 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4352 Fuse the neighbouring triangles into quadrangles.
4355 IDsOfElements: The triangles to be fused.
4356 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4357 applied to possible quadrangles to choose a neighbour to fuse with.
4358 Note that not all items of :class:`SMESH.FunctorType` corresponds
4359 to numerical functors.
4360 MaxAngle: is the maximum angle between element normals at which the fusion
4361 is still performed; theMaxAngle is measured in radians.
4362 Also it could be a name of variable which defines angle in degrees.
4365 True in case of success, False otherwise.
4368 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4369 self.mesh.SetParameters(Parameters)
4370 if not IDsOfElements:
4371 IDsOfElements = self.GetElementsId()
4372 Functor = self.smeshpyD.GetFunctor(theCriterion)
4373 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4375 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4377 Fuse the neighbouring triangles of the object into quadrangles
4380 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4381 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4382 applied to possible quadrangles to choose a neighbour to fuse with.
4383 Note that not all items of :class:`SMESH.FunctorType` corresponds
4384 to numerical functors.
4385 MaxAngle: a max angle between element normals at which the fusion
4386 is still performed; theMaxAngle is measured in radians.
4389 True in case of success, False otherwise.
4392 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4393 self.mesh.SetParameters(Parameters)
4394 if isinstance( theObject, Mesh ):
4395 theObject = theObject.GetMesh()
4396 Functor = self.smeshpyD.GetFunctor(theCriterion)
4397 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4399 def QuadToTri (self, IDsOfElements, theCriterion = None):
4401 Split quadrangles into triangles.
4404 IDsOfElements: the faces to be splitted.
4405 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4406 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4407 value, then quadrangles will be split by the smallest diagonal.
4408 Note that not all items of :class:`SMESH.FunctorType` corresponds
4409 to numerical functors.
4412 True in case of success, False otherwise.
4414 if IDsOfElements == []:
4415 IDsOfElements = self.GetElementsId()
4416 if theCriterion is None:
4417 theCriterion = FT_MaxElementLength2D
4418 Functor = self.smeshpyD.GetFunctor(theCriterion)
4419 return self.editor.QuadToTri(IDsOfElements, Functor)
4421 def QuadToTriObject (self, theObject, theCriterion = None):
4423 Split quadrangles into triangles.
4426 theObject: the object from which the list of elements is taken,
4427 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4428 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4429 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4430 value, then quadrangles will be split by the smallest diagonal.
4431 Note that not all items of :class:`SMESH.FunctorType` corresponds
4432 to numerical functors.
4435 True in case of success, False otherwise.
4437 if ( isinstance( theObject, Mesh )):
4438 theObject = theObject.GetMesh()
4439 if theCriterion is None:
4440 theCriterion = FT_MaxElementLength2D
4441 Functor = self.smeshpyD.GetFunctor(theCriterion)
4442 return self.editor.QuadToTriObject(theObject, Functor)
4444 def QuadTo4Tri (self, theElements=[]):
4446 Split each of given quadrangles into 4 triangles. A node is added at the center of
4450 theElements: the faces to be splitted. This can be either
4451 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4452 or a list of face IDs. By default all quadrangles are split
4454 unRegister = genObjUnRegister()
4455 if isinstance( theElements, Mesh ):
4456 theElements = theElements.mesh
4457 elif not theElements:
4458 theElements = self.mesh
4459 elif isinstance( theElements, list ):
4460 theElements = self.GetIDSource( theElements, SMESH.FACE )
4461 unRegister.set( theElements )
4462 return self.editor.QuadTo4Tri( theElements )
4464 def SplitQuad (self, IDsOfElements, Diag13):
4466 Split quadrangles into triangles.
4469 IDsOfElements: the faces to be splitted
4470 Diag13: is used to choose a diagonal for splitting.
4473 True in case of success, False otherwise.
4475 if IDsOfElements == []:
4476 IDsOfElements = self.GetElementsId()
4477 return self.editor.SplitQuad(IDsOfElements, Diag13)
4479 def SplitQuadObject (self, theObject, Diag13):
4481 Split quadrangles into triangles.
4484 theObject: the object from which the list of elements is taken,
4485 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4486 Diag13: is used to choose a diagonal for splitting.
4489 True in case of success, False otherwise.
4491 if ( isinstance( theObject, Mesh )):
4492 theObject = theObject.GetMesh()
4493 return self.editor.SplitQuadObject(theObject, Diag13)
4495 def BestSplit (self, IDOfQuad, theCriterion):
4497 Find a better splitting of the given quadrangle.
4500 IDOfQuad: the ID of the quadrangle to be splitted.
4501 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4502 choose a diagonal for splitting.
4503 Note that not all items of :class:`SMESH.FunctorType` corresponds
4504 to numerical functors.
4507 * 1 if 1-3 diagonal is better,
4508 * 2 if 2-4 diagonal is better,
4509 * 0 if error occurs.
4511 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4513 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4515 Split volumic elements into tetrahedrons
4518 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4519 method: flags passing splitting method:
4520 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4521 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4523 unRegister = genObjUnRegister()
4524 if isinstance( elems, Mesh ):
4525 elems = elems.GetMesh()
4526 if ( isinstance( elems, list )):
4527 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4528 unRegister.set( elems )
4529 self.editor.SplitVolumesIntoTetra(elems, method)
4532 def SplitBiQuadraticIntoLinear(self, elems=None):
4534 Split bi-quadratic elements into linear ones without creation of additional nodes:
4536 - bi-quadratic triangle will be split into 3 linear quadrangles;
4537 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4538 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4540 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4541 will be split in order to keep the mesh conformal.
4544 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4545 if None (default), all bi-quadratic elements will be split
4547 unRegister = genObjUnRegister()
4548 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4549 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4550 unRegister.set( elems )
4552 elems = [ self.GetMesh() ]
4553 if isinstance( elems, Mesh ):
4554 elems = [ elems.GetMesh() ]
4555 if not isinstance( elems, list ):
4557 self.editor.SplitBiQuadraticIntoLinear( elems )
4559 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4560 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4562 Split hexahedra into prisms
4565 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4566 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4567 gives a normal vector defining facets to split into triangles.
4568 *startHexPoint* can be either a triple of coordinates or a vertex.
4569 facetNormal: a normal to a facet to split into triangles of a
4570 hexahedron found by *startHexPoint*.
4571 *facetNormal* can be either a triple of coordinates or an edge.
4572 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4573 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4574 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4575 to *startHexPoint* are split, else *startHexPoint*
4576 is used to find the facet to split in all domains present in *elems*.
4579 unRegister = genObjUnRegister()
4580 if isinstance( elems, Mesh ):
4581 elems = elems.GetMesh()
4582 if ( isinstance( elems, list )):
4583 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4584 unRegister.set( elems )
4587 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4588 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4589 elif isinstance( startHexPoint, list ):
4590 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4593 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4594 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4595 elif isinstance( facetNormal, list ):
4596 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4599 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4601 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4603 def SplitQuadsNearTriangularFacets(self):
4605 Split quadrangle faces near triangular facets of volumes
4607 faces_array = self.GetElementsByType(SMESH.FACE)
4608 for face_id in faces_array:
4609 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4610 quad_nodes = self.mesh.GetElemNodes(face_id)
4611 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4612 isVolumeFound = False
4613 for node1_elem in node1_elems:
4614 if not isVolumeFound:
4615 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4616 nb_nodes = self.GetElemNbNodes(node1_elem)
4617 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4618 volume_elem = node1_elem
4619 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4620 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4621 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4622 isVolumeFound = True
4623 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4624 self.SplitQuad([face_id], False) # diagonal 2-4
4625 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4626 isVolumeFound = True
4627 self.SplitQuad([face_id], True) # diagonal 1-3
4628 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4629 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4630 isVolumeFound = True
4631 self.SplitQuad([face_id], True) # diagonal 1-3
4633 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4635 Split hexahedrons into tetrahedrons.
4637 This operation uses :doc:`pattern_mapping` functionality for splitting.
4640 theObject: the object from which the list of hexahedrons is taken;
4641 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4642 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4643 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4644 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4645 key-point will be mapped into *theNode001*-th node of each volume.
4646 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4649 True in case of success, False otherwise.
4657 # (0,0,1) 4.---------.7 * |
4664 # (0,0,0) 0.---------.3
4665 pattern_tetra = "!!! Nb of points: \n 8 \n\
4675 !!! Indices of points of 6 tetras: \n\
4683 pattern = self.smeshpyD.GetPattern()
4684 isDone = pattern.LoadFromFile(pattern_tetra)
4686 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4689 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4690 isDone = pattern.MakeMesh(self.mesh, False, False)
4691 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4693 # split quafrangle faces near triangular facets of volumes
4694 self.SplitQuadsNearTriangularFacets()
4698 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4700 Split hexahedrons into prisms.
4702 Uses the :doc:`pattern_mapping` functionality for splitting.
4705 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4706 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4707 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4708 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4709 will be mapped into the *theNode001* -th node of each volume.
4710 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4713 True in case of success, False otherwise.
4715 # Pattern: 5.---------.6
4720 # (0,0,1) 4.---------.7 |
4727 # (0,0,0) 0.---------.3
4728 pattern_prism = "!!! Nb of points: \n 8 \n\
4738 !!! Indices of points of 2 prisms: \n\
4742 pattern = self.smeshpyD.GetPattern()
4743 isDone = pattern.LoadFromFile(pattern_prism)
4745 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4748 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4749 isDone = pattern.MakeMesh(self.mesh, False, False)
4750 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4752 # Split quafrangle faces near triangular facets of volumes
4753 self.SplitQuadsNearTriangularFacets()
4757 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4758 MaxNbOfIterations, MaxAspectRatio, Method):
4763 IDsOfElements: the list if ids of elements to smooth
4764 IDsOfFixedNodes: the list of ids of fixed nodes.
4765 Note that nodes built on edges and boundary nodes are always fixed.
4766 MaxNbOfIterations: the maximum number of iterations
4767 MaxAspectRatio: varies in range [1.0, inf]
4768 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4769 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4772 True in case of success, False otherwise.
4775 if IDsOfElements == []:
4776 IDsOfElements = self.GetElementsId()
4777 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4778 self.mesh.SetParameters(Parameters)
4779 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4780 MaxNbOfIterations, MaxAspectRatio, Method)
4782 def SmoothObject(self, theObject, IDsOfFixedNodes,
4783 MaxNbOfIterations, MaxAspectRatio, Method):
4785 Smooth elements which belong to the given object
4788 theObject: the object to smooth
4789 IDsOfFixedNodes: the list of ids of fixed nodes.
4790 Note that nodes built on edges and boundary nodes are always fixed.
4791 MaxNbOfIterations: the maximum number of iterations
4792 MaxAspectRatio: varies in range [1.0, inf]
4793 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4794 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4797 True in case of success, False otherwise.
4800 if ( isinstance( theObject, Mesh )):
4801 theObject = theObject.GetMesh()
4802 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4803 MaxNbOfIterations, MaxAspectRatio, Method)
4805 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4806 MaxNbOfIterations, MaxAspectRatio, Method):
4808 Parametrically smooth the given elements
4811 IDsOfElements: the list if ids of elements to smooth
4812 IDsOfFixedNodes: the list of ids of fixed nodes.
4813 Note that nodes built on edges and boundary nodes are always fixed.
4814 MaxNbOfIterations: the maximum number of iterations
4815 MaxAspectRatio: varies in range [1.0, inf]
4816 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4817 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4820 True in case of success, False otherwise.
4823 if IDsOfElements == []:
4824 IDsOfElements = self.GetElementsId()
4825 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4826 self.mesh.SetParameters(Parameters)
4827 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4828 MaxNbOfIterations, MaxAspectRatio, Method)
4830 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4831 MaxNbOfIterations, MaxAspectRatio, Method):
4833 Parametrically smooth the elements which belong to the given object
4836 theObject: the object to smooth
4837 IDsOfFixedNodes: the list of ids of fixed nodes.
4838 Note that nodes built on edges and boundary nodes are always fixed.
4839 MaxNbOfIterations: the maximum number of iterations
4840 MaxAspectRatio: varies in range [1.0, inf]
4841 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4842 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4845 True in case of success, False otherwise.
4848 if ( isinstance( theObject, Mesh )):
4849 theObject = theObject.GetMesh()
4850 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4851 MaxNbOfIterations, MaxAspectRatio, Method)
4853 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4855 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4856 them with quadratic with the same id.
4859 theForce3d: method of new node creation:
4861 * False - the medium node lies at the geometrical entity from which the mesh element is built
4862 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4863 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4864 theToBiQuad: If True, converts the mesh to bi-quadratic
4867 :class:`SMESH.ComputeError` which can hold a warning
4870 If *theSubMesh* is provided, the mesh can become non-conformal
4873 if isinstance( theSubMesh, Mesh ):
4874 theSubMesh = theSubMesh.mesh
4876 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4879 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4881 self.editor.ConvertToQuadratic(theForce3d)
4882 error = self.editor.GetLastError()
4883 if error and error.comment:
4884 print(error.comment)
4887 def ConvertFromQuadratic(self, theSubMesh=None):
4889 Convert the mesh from quadratic to ordinary,
4890 deletes old quadratic elements,
4891 replacing them with ordinary mesh elements with the same id.
4894 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4897 If *theSubMesh* is provided, the mesh can become non-conformal
4901 self.editor.ConvertFromQuadraticObject(theSubMesh)
4903 return self.editor.ConvertFromQuadratic()
4905 def Make2DMeshFrom3D(self):
4907 Create 2D mesh as skin on boundary faces of a 3D mesh
4910 True if operation has been completed successfully, False otherwise
4913 return self.editor.Make2DMeshFrom3D()
4915 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4916 toCopyElements=False, toCopyExistingBondary=False):
4918 Create missing boundary elements
4921 elements: elements whose boundary is to be checked:
4922 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4923 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4924 dimension: defines type of boundary elements to create, either of
4925 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4926 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4927 groupName: a name of group to store created boundary elements in,
4928 "" means not to create the group
4929 meshName: a name of new mesh to store created boundary elements in,
4930 "" means not to create the new mesh
4931 toCopyElements: if True, the checked elements will be copied into
4932 the new mesh else only boundary elements will be copied into the new mesh
4933 toCopyExistingBondary: if True, not only new but also pre-existing
4934 boundary elements will be copied into the new mesh
4937 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4940 unRegister = genObjUnRegister()
4941 if isinstance( elements, Mesh ):
4942 elements = elements.GetMesh()
4943 if ( isinstance( elements, list )):
4944 elemType = SMESH.ALL
4945 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4946 elements = self.editor.MakeIDSource(elements, elemType)
4947 unRegister.set( elements )
4948 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4949 toCopyElements,toCopyExistingBondary)
4950 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4953 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4954 toCopyAll=False, groups=[]):
4956 Create missing boundary elements around either the whole mesh or
4960 dimension: defines type of boundary elements to create, either of
4961 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4962 groupName: a name of group to store all boundary elements in,
4963 "" means not to create the group
4964 meshName: a name of a new mesh, which is a copy of the initial
4965 mesh + created boundary elements; "" means not to create the new mesh
4966 toCopyAll: if True, the whole initial mesh will be copied into
4967 the new mesh else only boundary elements will be copied into the new mesh
4968 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4971 tuple( long, mesh, groups )
4972 - long - number of added boundary elements
4973 - mesh - the :class:`Mesh` where elements were added to
4974 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4977 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4979 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4980 return nb, mesh, group
4982 def RenumberNodes(self):
4984 Renumber mesh nodes to remove unused node IDs
4986 self.editor.RenumberNodes()
4988 def RenumberElements(self):
4990 Renumber mesh elements to remove unused element IDs
4992 self.editor.RenumberElements()
4994 def _getIdSourceList(self, arg, idType, unRegister):
4996 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
4998 if arg and isinstance( arg, list ):
4999 if isinstance( arg[0], int ):
5000 arg = self.GetIDSource( arg, idType )
5001 unRegister.set( arg )
5002 elif isinstance( arg[0], Mesh ):
5003 arg[0] = arg[0].GetMesh()
5004 elif isinstance( arg, Mesh ):
5006 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5010 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5011 MakeGroups=False, TotalAngle=False):
5013 Generate new elements by rotation of the given elements and nodes around the axis
5016 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5017 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5018 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5019 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5020 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5021 which defines angle in degrees
5022 NbOfSteps: the number of steps
5023 Tolerance: tolerance
5024 MakeGroups: forces the generation of new groups from existing ones
5025 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5026 of all steps, else - size of each step
5029 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5032 unRegister = genObjUnRegister()
5033 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5034 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5035 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5037 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5038 Axis = self.smeshpyD.GetAxisStruct( Axis )
5039 if isinstance( Axis, list ):
5040 Axis = SMESH.AxisStruct( *Axis )
5042 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5043 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5044 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5045 self.mesh.SetParameters(Parameters)
5046 if TotalAngle and NbOfSteps:
5047 AngleInRadians /= NbOfSteps
5048 return self.editor.RotationSweepObjects( nodes, edges, faces,
5049 Axis, AngleInRadians,
5050 NbOfSteps, Tolerance, MakeGroups)
5052 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5053 MakeGroups=False, TotalAngle=False):
5055 Generate new elements by rotation of the elements around the axis
5058 IDsOfElements: the list of ids of elements to sweep
5059 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5060 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5061 NbOfSteps: the number of steps
5062 Tolerance: tolerance
5063 MakeGroups: forces the generation of new groups from existing ones
5064 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5065 of all steps, else - size of each step
5068 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5071 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5072 AngleInRadians, NbOfSteps, Tolerance,
5073 MakeGroups, TotalAngle)
5075 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5076 MakeGroups=False, TotalAngle=False):
5078 Generate new elements by rotation of the elements of object around the axis
5079 theObject object which elements should be sweeped.
5080 It can be a mesh, a sub mesh or a group.
5083 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5084 AngleInRadians: the angle of Rotation
5085 NbOfSteps: number of steps
5086 Tolerance: tolerance
5087 MakeGroups: forces the generation of new groups from existing ones
5088 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5089 of all steps, else - size of each step
5092 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5095 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5096 AngleInRadians, NbOfSteps, Tolerance,
5097 MakeGroups, TotalAngle )
5099 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5100 MakeGroups=False, TotalAngle=False):
5102 Generate new elements by rotation of the elements of object around the axis
5103 theObject object which elements should be sweeped.
5104 It can be a mesh, a sub mesh or a group.
5107 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5108 AngleInRadians: the angle of Rotation
5109 NbOfSteps: number of steps
5110 Tolerance: tolerance
5111 MakeGroups: forces the generation of new groups from existing ones
5112 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5113 of all steps, else - size of each step
5116 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5117 empty list otherwise
5120 return self.RotationSweepObjects([],theObject,[], Axis,
5121 AngleInRadians, NbOfSteps, Tolerance,
5122 MakeGroups, TotalAngle)
5124 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5125 MakeGroups=False, TotalAngle=False):
5127 Generate new elements by rotation of the elements of object around the axis
5128 theObject object which elements should be sweeped.
5129 It can be a mesh, a sub mesh or a group.
5132 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5133 AngleInRadians: the angle of Rotation
5134 NbOfSteps: number of steps
5135 Tolerance: tolerance
5136 MakeGroups: forces the generation of new groups from existing ones
5137 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5138 of all steps, else - size of each step
5141 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5144 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5145 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5147 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5148 scaleFactors=[], linearVariation=False, basePoint=[] ):
5150 Generate new elements by extrusion of the given elements and nodes
5153 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5154 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5155 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5156 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5157 the direction and value of extrusion for one step (the total extrusion
5158 length will be NbOfSteps * ||StepVector||)
5159 NbOfSteps: the number of steps
5160 MakeGroups: forces the generation of new groups from existing ones
5161 scaleFactors: optional scale factors to apply during extrusion
5162 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5163 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5164 basePoint: optional scaling center; if not provided, a gravity center of
5165 nodes and elements being extruded is used as the scaling center.
5168 - a list of tree components of the point or
5172 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5174 Example: :ref:`tui_extrusion`
5176 unRegister = genObjUnRegister()
5177 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5178 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5179 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5181 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5182 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5183 if isinstance( StepVector, list ):
5184 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5186 if isinstance( basePoint, int):
5187 xyz = self.GetNodeXYZ( basePoint )
5189 raise RuntimeError("Invalid node ID: %s" % basePoint)
5191 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5192 basePoint = self.geompyD.PointCoordinates( basePoint )
5194 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5195 Parameters = StepVector.PS.parameters + var_separator + Parameters
5196 self.mesh.SetParameters(Parameters)
5198 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5199 StepVector, NbOfSteps,
5200 scaleFactors, linearVariation, basePoint,
5204 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5206 Generate new elements by extrusion of the elements with given ids
5209 IDsOfElements: the list of ids of elements or nodes for extrusion
5210 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5211 the direction and value of extrusion for one step (the total extrusion
5212 length will be NbOfSteps * ||StepVector||)
5213 NbOfSteps: the number of steps
5214 MakeGroups: forces the generation of new groups from existing ones
5215 IsNodes: is True if elements with given ids are nodes
5218 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5220 Example: :ref:`tui_extrusion`
5223 if IsNodes: n = IDsOfElements
5224 else : e,f, = IDsOfElements,IDsOfElements
5225 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5227 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5228 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5230 Generate new elements by extrusion along the normal to a discretized surface or wire
5233 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5234 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5235 StepSize: length of one extrusion step (the total extrusion
5236 length will be *NbOfSteps* *StepSize*).
5237 NbOfSteps: number of extrusion steps.
5238 ByAverageNormal: if True each node is translated by *StepSize*
5239 along the average of the normal vectors to the faces sharing the node;
5240 else each node is translated along the same average normal till
5241 intersection with the plane got by translation of the face sharing
5242 the node along its own normal by *StepSize*.
5243 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5244 for every node of *Elements*.
5245 MakeGroups: forces generation of new groups from existing ones.
5246 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5247 is not yet implemented. This parameter is used if *Elements* contains
5248 both faces and edges, i.e. *Elements* is a Mesh.
5251 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5252 empty list otherwise.
5253 Example: :ref:`tui_extrusion`
5256 unRegister = genObjUnRegister()
5257 if isinstance( Elements, Mesh ):
5258 Elements = [ Elements.GetMesh() ]
5259 if isinstance( Elements, list ):
5261 raise RuntimeError("Elements empty!")
5262 if isinstance( Elements[0], int ):
5263 Elements = self.GetIDSource( Elements, SMESH.ALL )
5264 unRegister.set( Elements )
5265 if not isinstance( Elements, list ):
5266 Elements = [ Elements ]
5267 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5268 self.mesh.SetParameters(Parameters)
5269 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5270 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5272 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5274 Generate new elements by extrusion of the elements or nodes which belong to the object
5277 theObject: the object whose elements or nodes should be processed.
5278 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5279 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5280 the direction and value of extrusion for one step (the total extrusion
5281 length will be NbOfSteps * ||StepVector||)
5282 NbOfSteps: the number of steps
5283 MakeGroups: forces the generation of new groups from existing ones
5284 IsNodes: is True if elements to extrude are nodes
5287 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5288 Example: :ref:`tui_extrusion`
5292 if IsNodes: n = theObject
5293 else : e,f, = theObject,theObject
5294 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5296 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5298 Generate new elements by extrusion of edges which belong to the object
5301 theObject: object whose 1D elements should be processed.
5302 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5303 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5304 the direction and value of extrusion for one step (the total extrusion
5305 length will be NbOfSteps * ||StepVector||)
5306 NbOfSteps: the number of steps
5307 MakeGroups: to generate new groups from existing ones
5310 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5311 Example: :ref:`tui_extrusion`
5314 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5316 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5318 Generate new elements by extrusion of faces which belong to the object
5321 theObject: object whose 2D elements should be processed.
5322 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5323 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5324 the direction and value of extrusion for one step (the total extrusion
5325 length will be NbOfSteps * ||StepVector||)
5326 NbOfSteps: the number of steps
5327 MakeGroups: forces the generation of new groups from existing ones
5330 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5331 Example: :ref:`tui_extrusion`
5334 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5336 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5337 ExtrFlags, SewTolerance, MakeGroups=False):
5339 Generate new elements by extrusion of the elements with given ids
5342 IDsOfElements: is ids of elements
5343 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5344 the direction and value of extrusion for one step (the total extrusion
5345 length will be NbOfSteps * ||StepVector||)
5346 NbOfSteps: the number of steps
5347 ExtrFlags: sets flags for extrusion
5348 SewTolerance: uses for comparing locations of nodes if flag
5349 EXTRUSION_FLAG_SEW is set
5350 MakeGroups: forces the generation of new groups from existing ones
5353 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5356 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5357 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5358 if isinstance( StepVector, list ):
5359 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5360 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5361 ExtrFlags, SewTolerance, MakeGroups)
5363 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5364 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5365 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5367 Generate new elements by extrusion of the given elements and nodes along the path.
5368 The path of extrusion must be a meshed edge.
5371 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5372 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5373 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5374 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5375 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5376 contains not only path segments, else it can be None
5377 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5378 HasAngles: allows the shape to be rotated around the path
5379 to get the resulting mesh in a helical fashion
5380 Angles: list of angles
5381 LinearVariation: forces the computation of rotation angles as linear
5382 variation of the given Angles along path steps
5383 HasRefPoint: allows using the reference point
5384 RefPoint: the reference point around which the shape is rotated (the mass center of the
5385 shape by default). The User can specify any point as the Reference Point.
5386 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5387 MakeGroups: forces the generation of new groups from existing ones
5390 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5391 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5392 Example: :ref:`tui_extrusion_along_path`
5395 unRegister = genObjUnRegister()
5396 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5397 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5398 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5400 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5401 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5402 if isinstance( RefPoint, list ):
5403 if not RefPoint: RefPoint = [0,0,0]
5404 RefPoint = SMESH.PointStruct( *RefPoint )
5405 if isinstance( PathMesh, Mesh ):
5406 PathMesh = PathMesh.GetMesh()
5407 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5408 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5409 self.mesh.SetParameters(Parameters)
5410 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5411 PathMesh, PathShape, NodeStart,
5412 HasAngles, Angles, LinearVariation,
5413 HasRefPoint, RefPoint, MakeGroups)
5415 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5416 HasAngles=False, Angles=[], LinearVariation=False,
5417 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5418 ElemType=SMESH.FACE):
5420 Generate new elements by extrusion of the given elements.
5421 The path of extrusion must be a meshed edge.
5424 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5425 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5426 NodeStart: the start node from Path. Defines the direction of extrusion
5427 HasAngles: allows the shape to be rotated around the path
5428 to get the resulting mesh in a helical fashion
5429 Angles: list of angles in radians
5430 LinearVariation: forces the computation of rotation angles as linear
5431 variation of the given Angles along path steps
5432 HasRefPoint: allows using the reference point
5433 RefPoint: the reference point around which the elements are rotated (the mass
5434 center of the elements by default).
5435 The User can specify any point as the Reference Point.
5436 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5437 MakeGroups: forces the generation of new groups from existing ones
5438 ElemType: type of elements for extrusion (if param Base is a mesh)
5441 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5442 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5443 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5445 Example: :ref:`tui_extrusion_along_path`
5449 if ElemType == SMESH.NODE: n = Base
5450 if ElemType == SMESH.EDGE: e = Base
5451 if ElemType == SMESH.FACE: f = Base
5452 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5453 HasAngles, Angles, LinearVariation,
5454 HasRefPoint, RefPoint, MakeGroups)
5455 if MakeGroups: return gr,er
5458 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5459 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5460 MakeGroups=False, LinearVariation=False):
5462 Generate new elements by extrusion of the given elements.
5463 The path of extrusion must be a meshed edge.
5466 IDsOfElements: ids of elements
5467 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5468 PathShape: shape (edge) defines the sub-mesh for the path
5469 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5470 HasAngles: allows the shape to be rotated around the path
5471 to get the resulting mesh in a helical fashion
5472 Angles: list of angles in radians
5473 HasRefPoint: allows using the reference point
5474 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5475 The User can specify any point as the Reference Point.
5476 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5477 MakeGroups: forces the generation of new groups from existing ones
5478 LinearVariation: forces the computation of rotation angles as linear
5479 variation of the given Angles along path steps
5482 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5483 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5484 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5485 Example: :ref:`tui_extrusion_along_path`
5488 n,e,f = [],IDsOfElements,IDsOfElements
5489 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5490 NodeStart, HasAngles, Angles,
5492 HasRefPoint, RefPoint, MakeGroups)
5493 if MakeGroups: return gr,er
5496 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5497 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5498 MakeGroups=False, LinearVariation=False):
5500 Generate new elements by extrusion of the elements which belong to the object.
5501 The path of extrusion must be a meshed edge.
5504 theObject: the object whose elements should be processed.
5505 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5506 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5507 PathShape: shape (edge) defines the sub-mesh for the path
5508 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5509 HasAngles: allows the shape to be rotated around the path
5510 to get the resulting mesh in a helical fashion
5511 Angles: list of angles
5512 HasRefPoint: allows using the reference point
5513 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5514 The User can specify any point as the Reference Point.
5515 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5516 MakeGroups: forces the generation of new groups from existing ones
5517 LinearVariation: forces the computation of rotation angles as linear
5518 variation of the given Angles along path steps
5521 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5522 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5523 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5524 Example: :ref:`tui_extrusion_along_path`
5527 n,e,f = [],theObject,theObject
5528 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5529 HasAngles, Angles, LinearVariation,
5530 HasRefPoint, RefPoint, MakeGroups)
5531 if MakeGroups: return gr,er
5534 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5535 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5536 MakeGroups=False, LinearVariation=False):
5538 Generate new elements by extrusion of mesh segments which belong to the object.
5539 The path of extrusion must be a meshed edge.
5542 theObject: the object whose 1D elements should be processed.
5543 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5544 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5545 PathShape: shape (edge) defines the sub-mesh for the path
5546 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5547 HasAngles: allows the shape to be rotated around the path
5548 to get the resulting mesh in a helical fashion
5549 Angles: list of angles
5550 HasRefPoint: allows using the reference point
5551 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5552 The User can specify any point as the Reference Point.
5553 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5554 MakeGroups: forces the generation of new groups from existing ones
5555 LinearVariation: forces the computation of rotation angles as linear
5556 variation of the given Angles along path steps
5559 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5560 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5561 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5562 Example: :ref:`tui_extrusion_along_path`
5565 n,e,f = [],theObject,[]
5566 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5567 HasAngles, Angles, LinearVariation,
5568 HasRefPoint, RefPoint, MakeGroups)
5569 if MakeGroups: return gr,er
5572 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5573 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5574 MakeGroups=False, LinearVariation=False):
5576 Generate new elements by extrusion of faces which belong to the object.
5577 The path of extrusion must be a meshed edge.
5580 theObject: the object whose 2D elements should be processed.
5581 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5582 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5583 PathShape: shape (edge) defines the sub-mesh for the path
5584 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5585 HasAngles: allows the shape to be rotated around the path
5586 to get the resulting mesh in a helical fashion
5587 Angles: list of angles
5588 HasRefPoint: allows using the reference point
5589 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5590 The User can specify any point as the Reference Point.
5591 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5592 MakeGroups: forces the generation of new groups from existing ones
5593 LinearVariation: forces the computation of rotation angles as linear
5594 variation of the given Angles along path steps
5597 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5598 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5599 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5600 Example: :ref:`tui_extrusion_along_path`
5603 n,e,f = [],[],theObject
5604 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5605 HasAngles, Angles, LinearVariation,
5606 HasRefPoint, RefPoint, MakeGroups)
5607 if MakeGroups: return gr,er
5610 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5612 Create a symmetrical copy of mesh elements
5615 IDsOfElements: list of elements ids
5616 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5617 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5618 If the *Mirror* is a geom object this parameter is unnecessary
5619 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5620 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5623 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5626 if IDsOfElements == []:
5627 IDsOfElements = self.GetElementsId()
5628 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5629 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5630 theMirrorType = Mirror._mirrorType
5632 self.mesh.SetParameters(Mirror.parameters)
5633 if Copy and MakeGroups:
5634 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5635 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5638 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5640 Create a new mesh by a symmetrical copy of mesh elements
5643 IDsOfElements: the list of elements ids
5644 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5645 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5646 If the *Mirror* is a geom object this parameter is unnecessary
5647 MakeGroups: to generate new groups from existing ones
5648 NewMeshName: a name of the new mesh to create
5651 instance of class :class:`Mesh`
5654 if IDsOfElements == []:
5655 IDsOfElements = self.GetElementsId()
5656 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5657 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5658 theMirrorType = Mirror._mirrorType
5660 self.mesh.SetParameters(Mirror.parameters)
5661 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5662 MakeGroups, NewMeshName)
5663 return Mesh(self.smeshpyD,self.geompyD,mesh)
5665 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5667 Create a symmetrical copy of the object
5670 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5671 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5672 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5673 If the *Mirror* is a geom object this parameter is unnecessary
5674 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5675 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5678 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5681 if ( isinstance( theObject, Mesh )):
5682 theObject = theObject.GetMesh()
5683 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5684 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5685 theMirrorType = Mirror._mirrorType
5687 self.mesh.SetParameters(Mirror.parameters)
5688 if Copy and MakeGroups:
5689 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5690 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5693 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5695 Create a new mesh by a symmetrical copy of the object
5698 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5699 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5700 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5701 If the *Mirror* is a geom object this parameter is unnecessary
5702 MakeGroups: forces the generation of new groups from existing ones
5703 NewMeshName: the name of the new mesh to create
5706 instance of class :class:`Mesh`
5709 if ( isinstance( theObject, Mesh )):
5710 theObject = theObject.GetMesh()
5711 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5712 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5713 theMirrorType = Mirror._mirrorType
5715 self.mesh.SetParameters(Mirror.parameters)
5716 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5717 MakeGroups, NewMeshName)
5718 return Mesh( self.smeshpyD,self.geompyD,mesh )
5720 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5722 Translate the elements
5725 IDsOfElements: list of elements ids
5726 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5727 Copy: allows copying the translated elements
5728 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5731 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5734 if IDsOfElements == []:
5735 IDsOfElements = self.GetElementsId()
5736 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5737 Vector = self.smeshpyD.GetDirStruct(Vector)
5738 if isinstance( Vector, list ):
5739 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5740 self.mesh.SetParameters(Vector.PS.parameters)
5741 if Copy and MakeGroups:
5742 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5743 self.editor.Translate(IDsOfElements, Vector, Copy)
5746 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5748 Create a new mesh of translated elements
5751 IDsOfElements: list of elements ids
5752 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5753 MakeGroups: forces the generation of new groups from existing ones
5754 NewMeshName: the name of the newly created mesh
5757 instance of class :class:`Mesh`
5760 if IDsOfElements == []:
5761 IDsOfElements = self.GetElementsId()
5762 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5763 Vector = self.smeshpyD.GetDirStruct(Vector)
5764 if isinstance( Vector, list ):
5765 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5766 self.mesh.SetParameters(Vector.PS.parameters)
5767 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5768 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5770 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5772 Translate the object
5775 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5776 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5777 Copy: allows copying the translated elements
5778 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5781 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5784 if ( isinstance( theObject, Mesh )):
5785 theObject = theObject.GetMesh()
5786 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5787 Vector = self.smeshpyD.GetDirStruct(Vector)
5788 if isinstance( Vector, list ):
5789 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5790 self.mesh.SetParameters(Vector.PS.parameters)
5791 if Copy and MakeGroups:
5792 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5793 self.editor.TranslateObject(theObject, Vector, Copy)
5796 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5798 Create a new mesh from the translated object
5801 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5802 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5803 MakeGroups: forces the generation of new groups from existing ones
5804 NewMeshName: the name of the newly created mesh
5807 instance of class :class:`Mesh`
5810 if isinstance( theObject, Mesh ):
5811 theObject = theObject.GetMesh()
5812 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5813 Vector = self.smeshpyD.GetDirStruct(Vector)
5814 if isinstance( Vector, list ):
5815 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5816 self.mesh.SetParameters(Vector.PS.parameters)
5817 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5818 return Mesh( self.smeshpyD, self.geompyD, mesh )
5822 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5827 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5828 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5829 theScaleFact: list of 1-3 scale factors for axises
5830 Copy: allows copying the translated elements
5831 MakeGroups: forces the generation of new groups from existing
5835 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5836 empty list otherwise
5838 unRegister = genObjUnRegister()
5839 if ( isinstance( theObject, Mesh )):
5840 theObject = theObject.GetMesh()
5841 if ( isinstance( theObject, list )):
5842 theObject = self.GetIDSource(theObject, SMESH.ALL)
5843 unRegister.set( theObject )
5844 if ( isinstance( thePoint, list )):
5845 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5846 if ( isinstance( theScaleFact, float )):
5847 theScaleFact = [theScaleFact]
5848 if ( isinstance( theScaleFact, int )):
5849 theScaleFact = [ float(theScaleFact)]
5851 self.mesh.SetParameters(thePoint.parameters)
5853 if Copy and MakeGroups:
5854 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5855 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5858 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5860 Create a new mesh from the translated object
5863 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5864 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5865 theScaleFact: list of 1-3 scale factors for axises
5866 MakeGroups: forces the generation of new groups from existing ones
5867 NewMeshName: the name of the newly created mesh
5870 instance of class :class:`Mesh`
5872 unRegister = genObjUnRegister()
5873 if (isinstance(theObject, Mesh)):
5874 theObject = theObject.GetMesh()
5875 if ( isinstance( theObject, list )):
5876 theObject = self.GetIDSource(theObject,SMESH.ALL)
5877 unRegister.set( theObject )
5878 if ( isinstance( thePoint, list )):
5879 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5880 if ( isinstance( theScaleFact, float )):
5881 theScaleFact = [theScaleFact]
5882 if ( isinstance( theScaleFact, int )):
5883 theScaleFact = [ float(theScaleFact)]
5885 self.mesh.SetParameters(thePoint.parameters)
5886 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5887 MakeGroups, NewMeshName)
5888 return Mesh( self.smeshpyD, self.geompyD, mesh )
5892 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5897 IDsOfElements: list of elements ids
5898 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5899 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5900 Copy: allows copying the rotated elements
5901 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5904 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5908 if IDsOfElements == []:
5909 IDsOfElements = self.GetElementsId()
5910 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5911 Axis = self.smeshpyD.GetAxisStruct(Axis)
5912 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5913 Parameters = Axis.parameters + var_separator + Parameters
5914 self.mesh.SetParameters(Parameters)
5915 if Copy and MakeGroups:
5916 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5917 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5920 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5922 Create a new mesh of rotated elements
5925 IDsOfElements: list of element ids
5926 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5927 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5928 MakeGroups: forces the generation of new groups from existing ones
5929 NewMeshName: the name of the newly created mesh
5932 instance of class :class:`Mesh`
5935 if IDsOfElements == []:
5936 IDsOfElements = self.GetElementsId()
5937 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5938 Axis = self.smeshpyD.GetAxisStruct(Axis)
5939 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5940 Parameters = Axis.parameters + var_separator + Parameters
5941 self.mesh.SetParameters(Parameters)
5942 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5943 MakeGroups, NewMeshName)
5944 return Mesh( self.smeshpyD, self.geompyD, mesh )
5946 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5951 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5952 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5953 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5954 Copy: allows copying the rotated elements
5955 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5958 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5961 if (isinstance(theObject, Mesh)):
5962 theObject = theObject.GetMesh()
5963 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5964 Axis = self.smeshpyD.GetAxisStruct(Axis)
5965 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5966 Parameters = Axis.parameters + ":" + Parameters
5967 self.mesh.SetParameters(Parameters)
5968 if Copy and MakeGroups:
5969 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5970 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5973 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5975 Create a new mesh from the rotated object
5978 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5979 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5980 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5981 MakeGroups: forces the generation of new groups from existing ones
5982 NewMeshName: the name of the newly created mesh
5985 instance of class :class:`Mesh`
5988 if (isinstance( theObject, Mesh )):
5989 theObject = theObject.GetMesh()
5990 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5991 Axis = self.smeshpyD.GetAxisStruct(Axis)
5992 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5993 Parameters = Axis.parameters + ":" + Parameters
5994 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
5995 MakeGroups, NewMeshName)
5996 self.mesh.SetParameters(Parameters)
5997 return Mesh( self.smeshpyD, self.geompyD, mesh )
5999 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6001 Create an offset mesh from the given 2D object
6004 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6005 theValue (float): signed offset size
6006 MakeGroups (boolean): forces the generation of new groups from existing ones
6007 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6008 False means to remove original elements.
6009 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6012 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6015 if isinstance( theObject, Mesh ):
6016 theObject = theObject.GetMesh()
6017 theValue,Parameters,hasVars = ParseParameters(Value)
6018 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6019 self.mesh.SetParameters(Parameters)
6020 # if mesh_groups[0]:
6021 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6024 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6026 Find groups of adjacent nodes within Tolerance.
6029 Tolerance (float): the value of tolerance
6030 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6031 corner and medium nodes in separate groups thus preventing
6032 their further merge.
6035 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6038 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6040 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6041 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6043 Find groups of adjacent nodes within Tolerance.
6046 Tolerance: the value of tolerance
6047 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6048 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6049 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6050 corner and medium nodes in separate groups thus preventing
6051 their further merge.
6054 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6057 unRegister = genObjUnRegister()
6058 if (isinstance( SubMeshOrGroup, Mesh )):
6059 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6060 if not isinstance( exceptNodes, list ):
6061 exceptNodes = [ exceptNodes ]
6062 if exceptNodes and isinstance( exceptNodes[0], int ):
6063 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6064 unRegister.set( exceptNodes )
6065 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6066 exceptNodes, SeparateCornerAndMediumNodes)
6068 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6073 GroupsOfNodes: a list of groups of nodes IDs for merging.
6074 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6075 in all elements and groups by nodes 1 and 25 correspondingly
6076 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6077 If *NodesToKeep* does not include a node to keep for some group to merge,
6078 then the first node in the group is kept.
6079 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6082 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6083 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6085 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6087 Find the elements built on the same nodes.
6090 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6093 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6096 if not MeshOrSubMeshOrGroup:
6097 MeshOrSubMeshOrGroup=self.mesh
6098 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6099 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6100 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6102 def MergeElements(self, GroupsOfElementsID):
6104 Merge elements in each given group.
6107 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6108 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6109 replaced in all groups by elements 1 and 25)
6112 self.editor.MergeElements(GroupsOfElementsID)
6114 def MergeEqualElements(self):
6116 Leave one element and remove all other elements built on the same nodes.
6119 self.editor.MergeEqualElements()
6121 def FindFreeBorders(self, ClosedOnly=True):
6123 Returns all or only closed free borders
6126 list of SMESH.FreeBorder's
6129 return self.editor.FindFreeBorders( ClosedOnly )
6131 def FillHole(self, holeNodes):
6133 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6136 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6137 must describe all sequential nodes of the hole border. The first and the last
6138 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6142 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6143 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6144 if not isinstance( holeNodes, SMESH.FreeBorder ):
6145 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6146 self.editor.FillHole( holeNodes )
6148 def FindCoincidentFreeBorders (self, tolerance=0.):
6150 Return groups of FreeBorder's coincident within the given tolerance.
6153 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6154 size of elements adjacent to free borders being compared is used.
6157 SMESH.CoincidentFreeBorders structure
6160 return self.editor.FindCoincidentFreeBorders( tolerance )
6162 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6164 Sew FreeBorder's of each group
6167 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6168 where each enclosed list contains node IDs of a group of coincident free
6169 borders such that each consequent triple of IDs within a group describes
6170 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6171 last node of a border.
6172 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6173 groups of coincident free borders, each group including two borders.
6174 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6175 polygons if a node of opposite border falls on a face edge, else such
6176 faces are split into several ones.
6177 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6178 polyhedra if a node of opposite border falls on a volume edge, else such
6179 volumes, if any, remain intact and the mesh becomes non-conformal.
6182 a number of successfully sewed groups
6185 if freeBorders and isinstance( freeBorders, list ):
6186 # construct SMESH.CoincidentFreeBorders
6187 if isinstance( freeBorders[0], int ):
6188 freeBorders = [freeBorders]
6190 coincidentGroups = []
6191 for nodeList in freeBorders:
6192 if not nodeList or len( nodeList ) % 3:
6193 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6196 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6197 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6198 nodeList = nodeList[3:]
6200 coincidentGroups.append( group )
6202 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6204 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6206 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6207 FirstNodeID2, SecondNodeID2, LastNodeID2,
6208 CreatePolygons, CreatePolyedrs):
6213 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6216 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6217 FirstNodeID2, SecondNodeID2, LastNodeID2,
6218 CreatePolygons, CreatePolyedrs)
6220 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6221 FirstNodeID2, SecondNodeID2):
6223 Sew conform free borders
6226 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6229 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6230 FirstNodeID2, SecondNodeID2)
6232 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6233 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6238 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6241 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6242 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6244 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6245 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6246 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6248 Sew two sides of a mesh. The nodes belonging to Side1 are
6249 merged with the nodes of elements of Side2.
6250 The number of elements in theSide1 and in theSide2 must be
6251 equal and they should have similar nodal connectivity.
6252 The nodes to merge should belong to side borders and
6253 the first node should be linked to the second.
6256 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6259 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6260 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6261 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6263 def ChangeElemNodes(self, ide, newIDs):
6265 Set new nodes for the given element.
6272 False if the number of nodes does not correspond to the type of element
6275 return self.editor.ChangeElemNodes(ide, newIDs)
6277 def GetLastCreatedNodes(self):
6279 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6280 created, this method return the list of their IDs.
6281 If new nodes were not created - return empty list
6284 the list of integer values (can be empty)
6287 return self.editor.GetLastCreatedNodes()
6289 def GetLastCreatedElems(self):
6291 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6292 created this method return the list of their IDs.
6293 If new elements were not created - return empty list
6296 the list of integer values (can be empty)
6299 return self.editor.GetLastCreatedElems()
6301 def ClearLastCreated(self):
6303 Forget what nodes and elements were created by the last mesh edition operation
6306 self.editor.ClearLastCreated()
6308 def DoubleElements(self, theElements, theGroupName=""):
6310 Create duplicates of given elements, i.e. create new elements based on the
6311 same nodes as the given ones.
6314 theElements: container of elements to duplicate. It can be a
6315 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6316 or a list of element IDs. If *theElements* is
6317 a :class:`Mesh`, elements of highest dimension are duplicated
6318 theGroupName: a name of group to contain the generated elements.
6319 If a group with such a name already exists, the new elements
6320 are added to the existing group, else a new group is created.
6321 If *theGroupName* is empty, new elements are not added
6325 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6326 None if *theGroupName* == "".
6329 unRegister = genObjUnRegister()
6330 if isinstance( theElements, Mesh ):
6331 theElements = theElements.mesh
6332 elif isinstance( theElements, list ):
6333 theElements = self.GetIDSource( theElements, SMESH.ALL )
6334 unRegister.set( theElements )
6335 return self.editor.DoubleElements(theElements, theGroupName)
6337 def DoubleNodes(self, theNodes, theModifiedElems):
6339 Create a hole in a mesh by doubling the nodes of some particular elements
6342 theNodes: IDs of nodes to be doubled
6343 theModifiedElems: IDs of elements to be updated by the new (doubled)
6344 nodes. If list of element identifiers is empty then nodes are doubled but
6345 they not assigned to elements
6348 True if operation has been completed successfully, False otherwise
6351 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6353 def DoubleNode(self, theNodeId, theModifiedElems):
6355 Create a hole in a mesh by doubling the nodes of some particular elements.
6356 This method provided for convenience works as :meth:`DoubleNodes`.
6359 theNodeId: IDs of node to double
6360 theModifiedElems: IDs of elements to update
6363 True if operation has been completed successfully, False otherwise
6366 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6368 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6370 Create a hole in a mesh by doubling the nodes of some particular elements.
6371 This method provided for convenience works as :meth:`DoubleNodes`.
6374 theNodes: group of nodes to double.
6375 theModifiedElems: group of elements to update.
6376 theMakeGroup: forces the generation of a group containing new nodes.
6379 True or a created group if operation has been completed successfully,
6380 False or None otherwise
6384 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6385 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6387 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6389 Create a hole in a mesh by doubling the nodes of some particular elements.
6390 This method provided for convenience works as :meth:`DoubleNodes`.
6393 theNodes: list of groups of nodes to double.
6394 theModifiedElems: list of groups of elements to update.
6395 theMakeGroup: forces the generation of a group containing new nodes.
6398 True if operation has been completed successfully, False otherwise
6402 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6403 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6405 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6407 Create a hole in a mesh by doubling the nodes of some particular elements
6410 theElems: the list of elements (edges or faces) to replicate.
6411 The nodes for duplication could be found from these elements
6412 theNodesNot: list of nodes NOT to replicate
6413 theAffectedElems: the list of elements (cells and edges) to which the
6414 replicated nodes should be associated to
6417 True if operation has been completed successfully, False otherwise
6420 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6422 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6424 Create a hole in a mesh by doubling the nodes of some particular elements
6427 theElems: the list of elements (edges or faces) to replicate.
6428 The nodes for duplication could be found from these elements
6429 theNodesNot: list of nodes NOT to replicate
6430 theShape: shape to detect affected elements (element which geometric center
6431 located on or inside shape).
6432 The replicated nodes should be associated to affected elements.
6435 True if operation has been completed successfully, False otherwise
6438 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6440 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6441 theMakeGroup=False, theMakeNodeGroup=False):
6443 Create a hole in a mesh by doubling the nodes of some particular elements.
6444 This method provided for convenience works as :meth:`DoubleNodes`.
6447 theElems: group of of elements (edges or faces) to replicate.
6448 theNodesNot: group of nodes NOT to replicate.
6449 theAffectedElems: group of elements to which the replicated nodes
6450 should be associated to.
6451 theMakeGroup: forces the generation of a group containing new elements.
6452 theMakeNodeGroup: forces the generation of a group containing new nodes.
6455 True or created groups (one or two) if operation has been completed successfully,
6456 False or None otherwise
6459 if theMakeGroup or theMakeNodeGroup:
6460 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6462 theMakeGroup, theMakeNodeGroup)
6463 if theMakeGroup and theMakeNodeGroup:
6466 return twoGroups[ int(theMakeNodeGroup) ]
6467 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6469 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6471 Create a hole in a mesh by doubling the nodes of some particular elements.
6472 This method provided for convenience works as :meth:`DoubleNodes`.
6475 theElems: group of of elements (edges or faces) to replicate
6476 theNodesNot: group of nodes not to replicate
6477 theShape: shape to detect affected elements (element which geometric center
6478 located on or inside shape).
6479 The replicated nodes should be associated to affected elements
6482 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6484 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6485 theMakeGroup=False, theMakeNodeGroup=False):
6487 Create a hole in a mesh by doubling the nodes of some particular elements.
6488 This method provided for convenience works as :meth:`DoubleNodes`.
6491 theElems: list of groups of elements (edges or faces) to replicate
6492 theNodesNot: list of groups of nodes NOT to replicate
6493 theAffectedElems: group of elements to which the replicated nodes
6494 should be associated to
6495 theMakeGroup: forces generation of a group containing new elements.
6496 theMakeNodeGroup: forces generation of a group containing new nodes
6499 True or created groups (one or two) if operation has been completed successfully,
6500 False or None otherwise
6503 if theMakeGroup or theMakeNodeGroup:
6504 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6506 theMakeGroup, theMakeNodeGroup)
6507 if theMakeGroup and theMakeNodeGroup:
6510 return twoGroups[ int(theMakeNodeGroup) ]
6511 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6513 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6515 Create a hole in a mesh by doubling the nodes of some particular elements.
6516 This method provided for convenience works as :meth:`DoubleNodes`.
6519 theElems: list of groups of elements (edges or faces) to replicate
6520 theNodesNot: list of groups of nodes NOT to replicate
6521 theShape: shape to detect affected elements (element which geometric center
6522 located on or inside shape).
6523 The replicated nodes should be associated to affected elements
6526 True if operation has been completed successfully, False otherwise
6529 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6531 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6533 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6534 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6537 theElems: list of groups of nodes or elements (edges or faces) to replicate
6538 theNodesNot: list of groups of nodes NOT to replicate
6539 theShape: shape to detect affected elements (element which geometric center
6540 located on or inside shape).
6541 The replicated nodes should be associated to affected elements
6544 groups of affected elements in order: volumes, faces, edges
6547 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6549 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6552 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6553 The list of groups must describe a partition of the mesh volumes.
6554 The nodes of the internal faces at the boundaries of the groups are doubled.
6555 In option, the internal faces are replaced by flat elements.
6556 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6559 theDomains: list of groups of volumes
6560 createJointElems: if True, create the elements
6561 onAllBoundaries: if True, the nodes and elements are also created on
6562 the boundary between *theDomains* and the rest mesh
6565 True if operation has been completed successfully, False otherwise
6568 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6570 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6572 Double nodes on some external faces and create flat elements.
6573 Flat elements are mainly used by some types of mechanic calculations.
6575 Each group of the list must be constituted of faces.
6576 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6579 theGroupsOfFaces: list of groups of faces
6582 True if operation has been completed successfully, False otherwise
6585 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6587 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6589 Identify all the elements around a geom shape, get the faces delimiting the hole
6591 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6593 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6595 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6596 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6597 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6598 If there are several paths connecting a pair of points, the shortest path is
6599 selected by the module. Position of the cutting plane is defined by the two
6600 points and an optional vector lying on the plane specified by a PolySegment.
6601 By default the vector is defined by Mesh module as following. A middle point
6602 of the two given points is computed. The middle point is projected to the mesh.
6603 The vector goes from the middle point to the projection point. In case of planar
6604 mesh, the vector is normal to the mesh.
6606 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6609 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6610 groupName: optional name of a group where created mesh segments will be added.
6613 editor = self.editor
6615 editor = self.mesh.GetMeshEditPreviewer()
6616 segmentsRes = editor.MakePolyLine( segments, groupName )
6617 for i, seg in enumerate( segmentsRes ):
6618 segments[i].vector = seg.vector
6620 return editor.GetPreviewData()
6623 def GetFunctor(self, funcType ):
6625 Return a cached numerical functor by its type.
6628 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6629 Note that not all items correspond to numerical functors.
6632 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6635 fn = self.functors[ funcType._v ]
6637 fn = self.smeshpyD.GetFunctor(funcType)
6638 fn.SetMesh(self.mesh)
6639 self.functors[ funcType._v ] = fn
6642 def FunctorValue(self, funcType, elemId, isElem=True):
6644 Return value of a functor for a given element
6647 funcType: an item of :class:`SMESH.FunctorType` enum.
6648 elemId: element or node ID
6649 isElem: *elemId* is ID of element or node
6652 the functor value or zero in case of invalid arguments
6655 fn = self.GetFunctor( funcType )
6656 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6657 val = fn.GetValue(elemId)
6662 def GetLength(self, elemId=None):
6664 Get length of 1D element or sum of lengths of all 1D mesh elements
6667 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6670 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6675 length = self.smeshpyD.GetLength(self)
6677 length = self.FunctorValue(SMESH.FT_Length, elemId)
6680 def GetArea(self, elemId=None):
6682 Get area of 2D element or sum of areas of all 2D mesh elements
6683 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6686 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6691 area = self.smeshpyD.GetArea(self)
6693 area = self.FunctorValue(SMESH.FT_Area, elemId)
6696 def GetVolume(self, elemId=None):
6698 Get volume of 3D element or sum of volumes of all 3D mesh elements
6701 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6704 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6709 volume = self.smeshpyD.GetVolume(self)
6711 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6714 def GetMaxElementLength(self, elemId):
6716 Get maximum element length.
6719 elemId: mesh element ID
6722 element's maximum length value
6725 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6726 ftype = SMESH.FT_MaxElementLength3D
6728 ftype = SMESH.FT_MaxElementLength2D
6729 return self.FunctorValue(ftype, elemId)
6731 def GetAspectRatio(self, elemId):
6733 Get aspect ratio of 2D or 3D element.
6736 elemId: mesh element ID
6739 element's aspect ratio value
6742 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6743 ftype = SMESH.FT_AspectRatio3D
6745 ftype = SMESH.FT_AspectRatio
6746 return self.FunctorValue(ftype, elemId)
6748 def GetWarping(self, elemId):
6750 Get warping angle of 2D element.
6753 elemId: mesh element ID
6756 element's warping angle value
6759 return self.FunctorValue(SMESH.FT_Warping, elemId)
6761 def GetMinimumAngle(self, elemId):
6763 Get minimum angle of 2D element.
6766 elemId: mesh element ID
6769 element's minimum angle value
6772 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6774 def GetTaper(self, elemId):
6776 Get taper of 2D element.
6779 elemId: mesh element ID
6782 element's taper value
6785 return self.FunctorValue(SMESH.FT_Taper, elemId)
6787 def GetSkew(self, elemId):
6789 Get skew of 2D element.
6792 elemId: mesh element ID
6795 element's skew value
6798 return self.FunctorValue(SMESH.FT_Skew, elemId)
6800 def GetMinMax(self, funType, meshPart=None):
6802 Return minimal and maximal value of a given functor.
6805 funType (SMESH.FunctorType): a functor type.
6806 Note that not all items of :class:`SMESH.FunctorType` corresponds
6807 to numerical functors.
6808 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6814 unRegister = genObjUnRegister()
6815 if isinstance( meshPart, list ):
6816 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6817 unRegister.set( meshPart )
6818 if isinstance( meshPart, Mesh ):
6819 meshPart = meshPart.mesh
6820 fun = self.GetFunctor( funType )
6823 if hasattr( meshPart, "SetMesh" ):
6824 meshPart.SetMesh( self.mesh ) # set mesh to filter
6825 hist = fun.GetLocalHistogram( 1, False, meshPart )
6827 hist = fun.GetHistogram( 1, False )
6829 return hist[0].min, hist[0].max
6832 pass # end of Mesh class
6835 class meshProxy(SMESH._objref_SMESH_Mesh):
6837 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6838 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6840 def __init__(self,*args):
6841 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6842 def __deepcopy__(self, memo=None):
6843 new = self.__class__(self)
6845 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6846 if len( args ) == 3:
6847 args += SMESH.ALL_NODES, True
6848 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6849 def ExportToMEDX(self, *args): # function removed
6850 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6851 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6852 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6853 def ExportToMED(self, *args): # function removed
6854 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6855 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6856 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6858 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6859 def ExportPartToMED(self, *args): # 'version' parameter removed
6860 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6861 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6862 def ExportMED(self, *args): # signature of method changed
6863 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6864 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6866 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6868 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6871 class submeshProxy(SMESH._objref_SMESH_subMesh):
6874 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6876 def __init__(self,*args):
6877 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6879 def __deepcopy__(self, memo=None):
6880 new = self.__class__(self)
6883 def Compute(self,refresh=False):
6885 Compute the sub-mesh and return the status of the computation
6888 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6893 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6894 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6898 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6900 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6902 if salome.sg.hasDesktop():
6903 smeshgui = salome.ImportComponentGUI("SMESH")
6905 smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
6906 if refresh: salome.sg.updateObjBrowser()
6911 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6914 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6916 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6917 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6920 def __init__(self,*args):
6921 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6923 def __getattr__(self, name ): # method called if an attribute not found
6924 if not self.mesh: # look for name() method in Mesh class
6925 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6926 if hasattr( self.mesh, name ):
6927 return getattr( self.mesh, name )
6928 if name == "ExtrusionAlongPathObjX":
6929 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6930 print("meshEditor: attribute '%s' NOT FOUND" % name)
6932 def __deepcopy__(self, memo=None):
6933 new = self.__class__(self)
6935 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6936 if len( args ) == 1: args += False,
6937 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6938 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6939 if len( args ) == 2: args += False,
6940 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6941 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6942 if len( args ) == 1:
6943 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6944 NodesToKeep = args[1]
6945 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6946 unRegister = genObjUnRegister()
6948 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6949 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6950 if not isinstance( NodesToKeep, list ):
6951 NodesToKeep = [ NodesToKeep ]
6952 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6954 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6956 class Pattern(SMESH._objref_SMESH_Pattern):
6958 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6959 variables in some methods
6962 def LoadFromFile(self, patternTextOrFile ):
6963 text = patternTextOrFile
6964 if os.path.exists( text ):
6965 text = open( patternTextOrFile ).read()
6967 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6969 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6970 decrFun = lambda i: i-1
6971 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6972 theMesh.SetParameters(Parameters)
6973 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6975 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6976 decrFun = lambda i: i-1
6977 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6978 theMesh.SetParameters(Parameters)
6979 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
6981 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
6982 if isinstance( mesh, Mesh ):
6983 mesh = mesh.GetMesh()
6984 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
6986 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
6988 Registering the new proxy for Pattern
6993 Private class used to bind methods creating algorithms to the class Mesh
6996 def __init__(self, method):
6998 self.defaultAlgoType = ""
6999 self.algoTypeToClass = {}
7000 self.method = method
7002 def add(self, algoClass):
7004 Store a python class of algorithm
7006 if inspect.isclass(algoClass) and \
7007 hasattr( algoClass, "algoType"):
7008 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7009 if not self.defaultAlgoType and \
7010 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7011 self.defaultAlgoType = algoClass.algoType
7012 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7014 def copy(self, mesh):
7016 Create a copy of self and assign mesh to the copy
7019 other = algoCreator( self.method )
7020 other.defaultAlgoType = self.defaultAlgoType
7021 other.algoTypeToClass = self.algoTypeToClass
7025 def __call__(self,algo="",geom=0,*args):
7027 Create an instance of algorithm
7031 if isinstance( algo, str ):
7033 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7034 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7039 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7041 elif not algoType and isinstance( geom, str ):
7046 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7048 elif isinstance( arg, str ) and not algoType:
7051 import traceback, sys
7052 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7053 sys.stderr.write( msg + '\n' )
7054 tb = traceback.extract_stack(None,2)
7055 traceback.print_list( [tb[0]] )
7057 algoType = self.defaultAlgoType
7058 if not algoType and self.algoTypeToClass:
7059 algoType = sorted( self.algoTypeToClass.keys() )[0]
7060 if algoType in self.algoTypeToClass:
7061 #print("Create algo",algoType)
7062 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7063 raise RuntimeError( "No class found for algo type %s" % algoType)
7066 class hypMethodWrapper:
7068 Private class used to substitute and store variable parameters of hypotheses.
7071 def __init__(self, hyp, method):
7073 self.method = method
7074 #print("REBIND:", method.__name__)
7077 def __call__(self,*args):
7079 call a method of hypothesis with calling SetVarParameter() before
7083 return self.method( self.hyp, *args ) # hypothesis method with no args
7085 #print("MethWrapper.__call__", self.method.__name__, args)
7087 parsed = ParseParameters(*args) # replace variables with their values
7088 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7089 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7090 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7091 # maybe there is a replaced string arg which is not variable
7092 result = self.method( self.hyp, *args )
7093 except ValueError as detail: # raised by ParseParameters()
7095 result = self.method( self.hyp, *args )
7096 except omniORB.CORBA.BAD_PARAM:
7097 raise ValueError(detail) # wrong variable name
7102 class genObjUnRegister:
7104 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7107 def __init__(self, genObj=None):
7108 self.genObjList = []
7112 def set(self, genObj):
7113 "Store one or a list of of SALOME.GenericObj'es"
7114 if isinstance( genObj, list ):
7115 self.genObjList.extend( genObj )
7117 self.genObjList.append( genObj )
7121 for genObj in self.genObjList:
7122 if genObj and hasattr( genObj, "UnRegister" ):
7125 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7127 Bind methods creating mesher plug-ins to the Mesh class
7130 # print("pluginName: ", pluginName)
7131 pluginBuilderName = pluginName + "Builder"
7133 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7134 except Exception as e:
7135 from salome_utils import verbose
7136 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7138 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7139 plugin = eval( pluginBuilderName )
7140 # print(" plugin:" , str(plugin))
7142 # add methods creating algorithms to Mesh
7143 for k in dir( plugin ):
7144 if k[0] == '_': continue
7145 algo = getattr( plugin, k )
7146 #print(" algo:", str(algo))
7147 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7148 #print(" meshMethod:" , str(algo.meshMethod))
7149 if not hasattr( Mesh, algo.meshMethod ):
7150 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7152 _mmethod = getattr( Mesh, algo.meshMethod )
7153 if hasattr( _mmethod, "add" ):