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 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1420 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1422 :class:`smeshBuilder` instance
1427 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1429 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1434 smeshInst = smeshBuilder()
1435 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1436 smeshInst.init_smesh(instanceGeom)
1440 # Public class: Mesh
1441 # ==================
1444 class Mesh(metaclass = MeshMeta):
1446 This class allows defining and managing a mesh.
1447 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1448 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1449 new nodes and elements and by changing the existing entities), to get information
1450 about a mesh and to export a mesh in different formats.
1457 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1462 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1463 sets the GUI name of this mesh to *name*.
1466 smeshpyD: an instance of smeshBuilder class
1467 geompyD: an instance of geomBuilder class
1468 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1469 name: Study name of the mesh
1472 self.smeshpyD = smeshpyD
1473 self.geompyD = geompyD
1478 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1481 # publish geom of mesh (issue 0021122)
1482 if not self.geom.GetStudyEntry():
1486 geo_name = name + " shape"
1488 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1489 geompyD.addToStudy( self.geom, geo_name )
1490 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1492 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1495 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1497 self.smeshpyD.SetName(self.mesh, name)
1499 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1502 self.geom = self.mesh.GetShapeToMesh()
1504 self.editor = self.mesh.GetMeshEditor()
1505 self.functors = [None] * SMESH.FT_Undefined._v
1507 # set self to algoCreator's
1508 for attrName in dir(self):
1509 attr = getattr( self, attrName )
1510 if isinstance( attr, algoCreator ):
1511 setattr( self, attrName, attr.copy( self ))
1518 Destructor. Clean-up resources
1521 #self.mesh.UnRegister()
1525 def SetMesh(self, theMesh):
1527 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1530 theMesh: a :class:`SMESH.SMESH_Mesh` object
1534 # do not call Register() as this prevents mesh servant deletion at closing study
1535 #if self.mesh: self.mesh.UnRegister()
1538 #self.mesh.Register()
1539 self.geom = self.mesh.GetShapeToMesh()
1544 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1547 a :class:`SMESH.SMESH_Mesh` object
1554 Get the name of the mesh
1557 the name of the mesh as a string
1560 name = GetName(self.GetMesh())
1563 def SetName(self, name):
1565 Set a name to the mesh
1568 name: a new name of the mesh
1571 self.smeshpyD.SetName(self.GetMesh(), name)
1573 def GetSubMesh(self, geom, name):
1575 Get a sub-mesh object associated to a *geom* geometrical object.
1578 geom: a geometrical object (shape)
1579 name: a name for the sub-mesh in the Object Browser
1582 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1583 which lies on the given shape
1586 A sub-mesh is implicitly created when a sub-shape is specified at
1587 creating an algorithm, for example::
1589 algo1D = mesh.Segment(geom=Edge_1)
1591 creates a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1592 The created sub-mesh can be retrieved from the algorithm::
1594 submesh = algo1D.GetSubMesh()
1597 AssureGeomPublished( self, geom, name )
1598 submesh = self.mesh.GetSubMesh( geom, name )
1603 Return the shape associated to the mesh
1611 def SetShape(self, geom):
1613 Associate the given shape to the mesh (entails the recreation of the mesh)
1616 geom: the shape to be meshed (GEOM_Object)
1619 self.mesh = self.smeshpyD.CreateMesh(geom)
1623 Load mesh from the study after opening the study
1627 def IsReadyToCompute(self, theSubObject):
1629 Return true if the hypotheses are defined well
1632 theSubObject: a sub-shape of a mesh shape
1638 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1640 def GetAlgoState(self, theSubObject):
1642 Return errors of hypotheses definition.
1643 The list of errors is empty if everything is OK.
1646 theSubObject: a sub-shape of a mesh shape
1652 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1654 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1656 Return a geometrical object on which the given element was built.
1657 The returned geometrical object, if not nil, is either found in the
1658 study or published by this method with the given name
1661 theElementID: the id of the mesh element
1662 theGeomName: the user-defined name of the geometrical object
1665 GEOM.GEOM_Object instance
1668 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1670 def MeshDimension(self):
1672 Return the mesh dimension depending on the dimension of the underlying shape
1673 or, if the mesh is not based on any shape, basing on deimension of elements
1676 mesh dimension as an integer value [0,3]
1679 if self.mesh.HasShapeToMesh():
1680 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1681 if len( shells ) > 0 :
1683 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1685 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1690 if self.NbVolumes() > 0: return 3
1691 if self.NbFaces() > 0: return 2
1692 if self.NbEdges() > 0: return 1
1695 def Evaluate(self, geom=0):
1697 Evaluate size of prospective mesh on a shape
1700 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1701 To know predicted number of e.g. edges, inquire it this way::
1703 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1706 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1708 geom = self.mesh.GetShapeToMesh()
1711 return self.smeshpyD.Evaluate(self.mesh, geom)
1714 def Compute(self, geom=0, discardModifs=False, refresh=False):
1716 Compute the mesh and return the status of the computation
1719 geom: geomtrical shape on which mesh data should be computed
1720 discardModifs: if True and the mesh has been edited since
1721 a last total re-compute and that may prevent successful partial re-compute,
1722 then the mesh is cleaned before Compute()
1723 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1729 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1731 geom = self.mesh.GetShapeToMesh()
1736 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1738 ok = self.smeshpyD.Compute(self.mesh, geom)
1739 except SALOME.SALOME_Exception as ex:
1740 print("Mesh computation failed, exception caught:")
1741 print(" ", ex.details.text)
1744 print("Mesh computation failed, exception caught:")
1745 traceback.print_exc()
1749 # Treat compute errors
1750 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1752 for err in computeErrors:
1753 if self.mesh.HasShapeToMesh():
1754 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1756 stdErrors = ["OK", #COMPERR_OK
1757 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1758 "std::exception", #COMPERR_STD_EXCEPTION
1759 "OCC exception", #COMPERR_OCC_EXCEPTION
1760 "..", #COMPERR_SLM_EXCEPTION
1761 "Unknown exception", #COMPERR_EXCEPTION
1762 "Memory allocation problem", #COMPERR_MEMORY_PB
1763 "Algorithm failed", #COMPERR_ALGO_FAILED
1764 "Unexpected geometry", #COMPERR_BAD_SHAPE
1765 "Warning", #COMPERR_WARNING
1766 "Computation cancelled",#COMPERR_CANCELED
1767 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1769 if err.code < len(stdErrors): errText = stdErrors[err.code]
1771 errText = "code %s" % -err.code
1772 if errText: errText += ". "
1773 errText += err.comment
1774 if allReasons: allReasons += "\n"
1776 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1778 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1782 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1784 if err.isGlobalAlgo:
1792 reason = '%s %sD algorithm is missing' % (glob, dim)
1793 elif err.state == HYP_MISSING:
1794 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1795 % (glob, dim, name, dim))
1796 elif err.state == HYP_NOTCONFORM:
1797 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1798 elif err.state == HYP_BAD_PARAMETER:
1799 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1800 % ( glob, dim, name ))
1801 elif err.state == HYP_BAD_GEOMETRY:
1802 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1803 'geometry' % ( glob, dim, name ))
1804 elif err.state == HYP_HIDDEN_ALGO:
1805 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1806 'algorithm of upper dimension generating %sD mesh'
1807 % ( glob, dim, name, glob, dim ))
1809 reason = ("For unknown reason. "
1810 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1812 if allReasons: allReasons += "\n"
1813 allReasons += "- " + reason
1815 if not ok or allReasons != "":
1816 msg = '"' + GetName(self.mesh) + '"'
1817 if ok: msg += " has been computed with warnings"
1818 else: msg += " has not been computed"
1819 if allReasons != "": msg += ":"
1824 if salome.sg.hasDesktop():
1825 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1826 smeshgui = salome.ImportComponentGUI("SMESH")
1828 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
1829 if refresh: salome.sg.updateObjBrowser()
1833 def GetComputeErrors(self, shape=0 ):
1835 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1839 shape = self.mesh.GetShapeToMesh()
1840 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1842 def GetSubShapeName(self, subShapeID ):
1844 Return a name of a sub-shape by its ID.
1845 Possible variants (for *subShapeID* == 3):
1847 - **"Face_12"** - published sub-shape
1848 - **FACE #3** - not published sub-shape
1849 - **sub-shape #3** - invalid sub-shape ID
1850 - **#3** - error in this function
1853 subShapeID: a unique ID of a sub-shape
1856 a string describing the sub-shape
1860 if not self.mesh.HasShapeToMesh():
1864 mainIOR = salome.orb.object_to_string( self.GetShape() )
1866 mainSO = s.FindObjectIOR(mainIOR)
1869 shapeText = '"%s"' % mainSO.GetName()
1870 subIt = s.NewChildIterator(mainSO)
1872 subSO = subIt.Value()
1874 obj = subSO.GetObject()
1875 if not obj: continue
1876 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1879 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1882 if ids == subShapeID:
1883 shapeText = '"%s"' % subSO.GetName()
1886 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1888 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1890 shapeText = 'sub-shape #%s' % (subShapeID)
1892 shapeText = "#%s" % (subShapeID)
1895 def GetFailedShapes(self, publish=False):
1897 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1898 error of an algorithm
1901 publish: if *True*, the returned groups will be published in the study
1904 a list of GEOM groups each named after a failed algorithm
1909 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1910 for err in computeErrors:
1911 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1912 if not shape: continue
1913 if err.algoName in algo2shapes:
1914 algo2shapes[ err.algoName ].append( shape )
1916 algo2shapes[ err.algoName ] = [ shape ]
1920 for algoName, shapes in list(algo2shapes.items()):
1922 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1923 otherTypeShapes = []
1925 group = self.geompyD.CreateGroup( self.geom, groupType )
1926 for shape in shapes:
1927 if shape.GetShapeType() == shapes[0].GetShapeType():
1928 sameTypeShapes.append( shape )
1930 otherTypeShapes.append( shape )
1931 self.geompyD.UnionList( group, sameTypeShapes )
1933 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1935 group.SetName( algoName )
1936 groups.append( group )
1937 shapes = otherTypeShapes
1940 for group in groups:
1941 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1944 def GetMeshOrder(self):
1946 Return sub-mesh objects list in meshing order
1949 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1952 return self.mesh.GetMeshOrder()
1954 def SetMeshOrder(self, submeshes):
1956 Set order in which concurrent sub-meshes should be meshed
1959 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
1962 return self.mesh.SetMeshOrder(submeshes)
1964 def Clear(self, refresh=False):
1966 Remove all nodes and elements generated on geometry. Imported elements remain.
1969 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1973 if ( salome.sg.hasDesktop() ):
1974 smeshgui = salome.ImportComponentGUI("SMESH")
1976 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1977 if refresh: salome.sg.updateObjBrowser()
1979 def ClearSubMesh(self, geomId, refresh=False):
1981 Remove all nodes and elements of indicated shape
1984 geomId: the ID of a sub-shape to remove elements on
1985 refresh: if *True*, Object browser is automatically updated (when running in GUI)
1988 self.mesh.ClearSubMesh(geomId)
1989 if salome.sg.hasDesktop():
1990 smeshgui = salome.ImportComponentGUI("SMESH")
1992 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1993 if refresh: salome.sg.updateObjBrowser()
1995 def AutomaticTetrahedralization(self, fineness=0):
1997 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2000 fineness: [0.0,1.0] defines mesh fineness
2006 dim = self.MeshDimension()
2008 self.RemoveGlobalHypotheses()
2009 self.Segment().AutomaticLength(fineness)
2011 self.Triangle().LengthFromEdges()
2016 return self.Compute()
2018 def AutomaticHexahedralization(self, fineness=0):
2020 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2023 fineness: [0.0, 1.0] defines mesh fineness
2029 dim = self.MeshDimension()
2030 # assign the hypotheses
2031 self.RemoveGlobalHypotheses()
2032 self.Segment().AutomaticLength(fineness)
2039 return self.Compute()
2041 def AddHypothesis(self, hyp, geom=0):
2046 hyp: a hypothesis to assign
2047 geom: a subhape of mesh geometry
2050 :class:`SMESH.Hypothesis_Status`
2053 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2054 hyp, geom = geom, hyp
2055 if isinstance( hyp, Mesh_Algorithm ):
2056 hyp = hyp.GetAlgorithm()
2061 geom = self.mesh.GetShapeToMesh()
2064 if self.mesh.HasShapeToMesh():
2065 hyp_type = hyp.GetName()
2066 lib_name = hyp.GetLibName()
2067 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2068 # if checkAll and geom:
2069 # checkAll = geom.GetType() == 37
2071 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2073 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2074 status = self.mesh.AddHypothesis(geom, hyp)
2076 status = HYP_BAD_GEOMETRY, ""
2077 hyp_name = GetName( hyp )
2080 geom_name = geom.GetName()
2081 isAlgo = hyp._narrow( SMESH_Algo )
2082 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2085 def IsUsedHypothesis(self, hyp, geom):
2087 Return True if an algorithm or hypothesis is assigned to a given shape
2090 hyp: an algorithm or hypothesis to check
2091 geom: a subhape of mesh geometry
2097 if not hyp: # or not geom
2099 if isinstance( hyp, Mesh_Algorithm ):
2100 hyp = hyp.GetAlgorithm()
2102 hyps = self.GetHypothesisList(geom)
2104 if h.GetId() == hyp.GetId():
2108 def RemoveHypothesis(self, hyp, geom=0):
2110 Unassign a hypothesis
2113 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2114 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2117 :class:`SMESH.Hypothesis_Status`
2122 if isinstance( hyp, Mesh_Algorithm ):
2123 hyp = hyp.GetAlgorithm()
2129 if self.IsUsedHypothesis( hyp, shape ):
2130 return self.mesh.RemoveHypothesis( shape, hyp )
2131 hypName = GetName( hyp )
2132 geoName = GetName( shape )
2133 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2136 def GetHypothesisList(self, geom):
2138 Get the list of hypotheses added on a geometry
2141 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2144 the sequence of :class:`SMESH.SMESH_Hypothesis`
2147 return self.mesh.GetHypothesisList( geom )
2149 def RemoveGlobalHypotheses(self):
2151 Remove all global hypotheses
2154 current_hyps = self.mesh.GetHypothesisList( self.geom )
2155 for hyp in current_hyps:
2156 self.mesh.RemoveHypothesis( self.geom, hyp )
2159 def ExportMED(self, *args, **kwargs):
2161 Export the mesh in a file in MED format
2162 allowing to overwrite the file if it exists or add the exported data to its contents
2165 fileName: is the file name
2166 auto_groups (boolean): parameter for creating/not creating
2167 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2168 the typical use is auto_groups=False.
2169 overwrite (boolean): parameter for overwriting/not overwriting the file
2170 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2171 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2173 - 1D if all mesh nodes lie on OX coordinate axis, or
2174 - 2D if all mesh nodes lie on XOY coordinate plane, or
2175 - 3D in the rest cases.
2177 If *autoDimension* is *False*, the space dimension is always 3.
2178 fields: list of GEOM fields defined on the shape to mesh.
2179 geomAssocFields: each character of this string means a need to export a
2180 corresponding field; correspondence between fields and characters is following:
2181 - 'v' stands for "_vertices _" field;
2182 - 'e' stands for "_edges _" field;
2183 - 'f' stands for "_faces _" field;
2184 - 's' stands for "_solids _" field.
2186 # process positional arguments
2187 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2189 auto_groups = args[1] if len(args) > 1 else False
2190 overwrite = args[2] if len(args) > 2 else True
2191 meshPart = args[3] if len(args) > 3 else None
2192 autoDimension = args[4] if len(args) > 4 else True
2193 fields = args[5] if len(args) > 5 else []
2194 geomAssocFields = args[6] if len(args) > 6 else ''
2195 # process keywords arguments
2196 auto_groups = kwargs.get("auto_groups", auto_groups)
2197 overwrite = kwargs.get("overwrite", overwrite)
2198 meshPart = kwargs.get("meshPart", meshPart)
2199 autoDimension = kwargs.get("autoDimension", autoDimension)
2200 fields = kwargs.get("fields", fields)
2201 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2202 # invoke engine's function
2203 if meshPart or fields or geomAssocFields:
2204 unRegister = genObjUnRegister()
2205 if isinstance( meshPart, list ):
2206 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2207 unRegister.set( meshPart )
2208 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, overwrite, autoDimension,
2209 fields, geomAssocFields)
2211 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2213 def ExportSAUV(self, f, auto_groups=0):
2215 Export the mesh in a file in SAUV format
2220 auto_groups: boolean parameter for creating/not creating
2221 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2222 the typical use is auto_groups=False.
2225 self.mesh.ExportSAUV(f, auto_groups)
2227 def ExportDAT(self, f, meshPart=None):
2229 Export the mesh in a file in DAT format
2233 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2237 unRegister = genObjUnRegister()
2238 if isinstance( meshPart, list ):
2239 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2240 unRegister.set( meshPart )
2241 self.mesh.ExportPartToDAT( meshPart, f )
2243 self.mesh.ExportDAT(f)
2245 def ExportUNV(self, f, meshPart=None):
2247 Export the mesh in a file in UNV format
2251 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2255 unRegister = genObjUnRegister()
2256 if isinstance( meshPart, list ):
2257 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2258 unRegister.set( meshPart )
2259 self.mesh.ExportPartToUNV( meshPart, f )
2261 self.mesh.ExportUNV(f)
2263 def ExportSTL(self, f, ascii=1, meshPart=None):
2265 Export the mesh in a file in STL format
2269 ascii: defines the file encoding
2270 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2274 unRegister = genObjUnRegister()
2275 if isinstance( meshPart, list ):
2276 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2277 unRegister.set( meshPart )
2278 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2280 self.mesh.ExportSTL(f, ascii)
2282 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2284 Export the mesh in a file in CGNS format
2288 overwrite: boolean parameter for overwriting/not overwriting the file
2289 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2290 groupElemsByType: if True all elements of same entity type are exported at ones,
2291 else elements are exported in order of their IDs which can cause creation
2292 of multiple cgns sections
2295 unRegister = genObjUnRegister()
2296 if isinstance( meshPart, list ):
2297 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2298 unRegister.set( meshPart )
2299 if isinstance( meshPart, Mesh ):
2300 meshPart = meshPart.mesh
2302 meshPart = self.mesh
2303 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2305 def ExportGMF(self, f, meshPart=None):
2307 Export the mesh in a file in GMF format.
2308 GMF files must have .mesh extension for the ASCII format and .meshb for
2309 the bynary format. Other extensions are not allowed.
2313 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2316 unRegister = genObjUnRegister()
2317 if isinstance( meshPart, list ):
2318 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2319 unRegister.set( meshPart )
2320 if isinstance( meshPart, Mesh ):
2321 meshPart = meshPart.mesh
2323 meshPart = self.mesh
2324 self.mesh.ExportGMF(meshPart, f, True)
2326 def ExportToMED(self, *args, **kwargs):
2328 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2329 Export the mesh in a file in MED format
2330 allowing to overwrite the file if it exists or add the exported data to its contents
2333 fileName: the file name
2334 opt (boolean): parameter for creating/not creating
2335 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2336 overwrite: boolean parameter for overwriting/not overwriting the file
2337 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2339 - 1D if all mesh nodes lie on OX coordinate axis, or
2340 - 2D if all mesh nodes lie on XOY coordinate plane, or
2341 - 3D in the rest cases.
2343 If **autoDimension** is *False*, the space dimension is always 3.
2346 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2347 # process positional arguments
2348 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2350 auto_groups = args[1] if len(args) > 1 else False
2351 overwrite = args[2] if len(args) > 2 else True
2352 autoDimension = args[3] if len(args) > 3 else True
2353 # process keywords arguments
2354 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2355 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2356 overwrite = kwargs.get("overwrite", overwrite)
2357 autoDimension = kwargs.get("autoDimension", autoDimension)
2358 # invoke engine's function
2359 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2361 def ExportToMEDX(self, *args, **kwargs):
2363 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2364 Export the mesh in a file in MED format
2367 fileName: the file name
2368 opt (boolean): parameter for creating/not creating
2369 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2370 overwrite: boolean parameter for overwriting/not overwriting the file
2371 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2373 - 1D if all mesh nodes lie on OX coordinate axis, or
2374 - 2D if all mesh nodes lie on XOY coordinate plane, or
2375 - 3D in the rest cases.
2377 If **autoDimension** is *False*, the space dimension is always 3.
2380 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2381 # process positional arguments
2382 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2384 auto_groups = args[1] if len(args) > 1 else False
2385 overwrite = args[2] if len(args) > 2 else True
2386 autoDimension = args[3] if len(args) > 3 else True
2387 # process keywords arguments
2388 auto_groups = kwargs.get("auto_groups", auto_groups)
2389 overwrite = kwargs.get("overwrite", overwrite)
2390 autoDimension = kwargs.get("autoDimension", autoDimension)
2391 # invoke engine's function
2392 self.mesh.ExportMED(fileName, auto_groups, overwrite, autoDimension)
2394 # Operations with groups:
2395 # ----------------------
2396 def CreateEmptyGroup(self, elementType, name):
2398 Create an empty mesh group
2401 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2402 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2403 name: the name of the mesh group
2406 :class:`SMESH.SMESH_Group`
2409 return self.mesh.CreateGroup(elementType, name)
2411 def Group(self, grp, name=""):
2413 Create a mesh group based on the geometric object *grp*
2414 and give it a *name*.
2415 If *name* is not defined the name of the geometric group is used
2418 Works like :meth:`GroupOnGeom`.
2421 grp: a geometric group, a vertex, an edge, a face or a solid
2422 name: the name of the mesh group
2425 :class:`SMESH.SMESH_GroupOnGeom`
2428 return self.GroupOnGeom(grp, name)
2430 def GroupOnGeom(self, grp, name="", typ=None):
2432 Create a mesh group based on the geometrical object *grp*
2434 if *name* is not defined the name of the geometric group is used
2437 grp: a geometrical group, a vertex, an edge, a face or a solid
2438 name: the name of the mesh group
2439 typ: the type of elements in the group; either of
2440 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2441 automatically detected by the type of the geometry
2444 :class:`SMESH.SMESH_GroupOnGeom`
2447 AssureGeomPublished( self, grp, name )
2449 name = grp.GetName()
2451 typ = self._groupTypeFromShape( grp )
2452 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2454 def _groupTypeFromShape( self, shape ):
2456 Pivate method to get a type of group on geometry
2458 tgeo = str(shape.GetShapeType())
2459 if tgeo == "VERTEX":
2461 elif tgeo == "EDGE":
2463 elif tgeo == "FACE" or tgeo == "SHELL":
2465 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2467 elif tgeo == "COMPOUND":
2468 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2470 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2471 return self._groupTypeFromShape( sub[0] )
2473 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2476 def GroupOnFilter(self, typ, name, filter):
2478 Create a mesh group with given *name* based on the *filter* which
2479 is a special type of group dynamically updating it's contents during
2483 typ: the type of elements in the group; either of
2484 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2485 name: the name of the mesh group
2486 filter (SMESH.Filter): the filter defining group contents
2489 :class:`SMESH.SMESH_GroupOnFilter`
2492 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2494 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2496 Create a mesh group by the given ids of elements
2499 groupName: the name of the mesh group
2500 elementType: the type of elements in the group; either of
2501 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2502 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2505 :class:`SMESH.SMESH_Group`
2508 group = self.mesh.CreateGroup(elementType, groupName)
2509 if isinstance( elemIDs, Mesh ):
2510 elemIDs = elemIDs.GetMesh()
2511 if hasattr( elemIDs, "GetIDs" ):
2512 if hasattr( elemIDs, "SetMesh" ):
2513 elemIDs.SetMesh( self.GetMesh() )
2514 group.AddFrom( elemIDs )
2522 CritType=FT_Undefined,
2525 UnaryOp=FT_Undefined,
2528 Create a mesh group by the given conditions
2531 groupName: the name of the mesh group
2532 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2533 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2534 Note that the items starting from FT_LessThan are not suitable for CritType.
2535 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2536 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2537 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2538 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2539 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2542 :class:`SMESH.SMESH_GroupOnFilter`
2545 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2546 group = self.MakeGroupByCriterion(groupName, aCriterion)
2549 def MakeGroupByCriterion(self, groupName, Criterion):
2551 Create a mesh group by the given criterion
2554 groupName: the name of the mesh group
2555 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2558 :class:`SMESH.SMESH_GroupOnFilter`
2561 :meth:`smeshBuilder.GetCriterion`
2564 return self.MakeGroupByCriteria( groupName, [Criterion] )
2566 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2568 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2571 groupName: the name of the mesh group
2572 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2573 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2576 :class:`SMESH.SMESH_GroupOnFilter`
2579 :meth:`smeshBuilder.GetCriterion`
2582 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2583 group = self.MakeGroupByFilter(groupName, aFilter)
2586 def MakeGroupByFilter(self, groupName, theFilter):
2588 Create a mesh group by the given filter
2591 groupName (string): the name of the mesh group
2592 theFilter (SMESH.Filter): the filter
2595 :class:`SMESH.SMESH_GroupOnFilter`
2598 :meth:`smeshBuilder.GetFilter`
2601 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2602 #theFilter.SetMesh( self.mesh )
2603 #group.AddFrom( theFilter )
2604 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2607 def RemoveGroup(self, group):
2612 group (SMESH.SMESH_GroupBase): group to remove
2615 self.mesh.RemoveGroup(group)
2617 def RemoveGroupWithContents(self, group):
2619 Remove a group with its contents
2622 group (SMESH.SMESH_GroupBase): group to remove
2625 self.mesh.RemoveGroupWithContents(group)
2627 def GetGroups(self, elemType = SMESH.ALL):
2629 Get the list of groups existing in the mesh in the order
2630 of creation (starting from the oldest one)
2633 elemType (SMESH.ElementType): type of elements the groups contain;
2634 by default groups of elements of all types are returned
2637 a sequence of :class:`SMESH.SMESH_GroupBase`
2640 groups = self.mesh.GetGroups()
2641 if elemType == SMESH.ALL:
2645 if g.GetType() == elemType:
2646 typedGroups.append( g )
2653 Get the number of groups existing in the mesh
2656 the quantity of groups as an integer value
2659 return self.mesh.NbGroups()
2661 def GetGroupNames(self):
2663 Get the list of names of groups existing in the mesh
2669 groups = self.GetGroups()
2671 for group in groups:
2672 names.append(group.GetName())
2675 def GetGroupByName(self, name, elemType = None):
2677 Find groups by name and type
2680 name (string): name of the group of interest
2681 elemType (SMESH.ElementType): type of elements the groups contain;
2682 by default one group of any type is returned;
2683 if elemType == SMESH.ALL then all groups of any type are returned
2686 a list of :class:`SMESH.SMESH_GroupBase`
2690 for group in self.GetGroups():
2691 if group.GetName() == name:
2692 if elemType is None:
2694 if ( elemType == SMESH.ALL or
2695 group.GetType() == elemType ):
2696 groups.append( group )
2699 def UnionGroups(self, group1, group2, name):
2701 Produce a union of two groups.
2702 A new group is created. All mesh elements that are
2703 present in the initial groups are added to the new one
2706 group1 (SMESH.SMESH_GroupBase): a group
2707 group2 (SMESH.SMESH_GroupBase): another group
2710 instance of :class:`SMESH.SMESH_Group`
2713 return self.mesh.UnionGroups(group1, group2, name)
2715 def UnionListOfGroups(self, groups, name):
2717 Produce a union list of groups.
2718 New group is created. All mesh elements that are present in
2719 initial groups are added to the new one
2722 groups: list of :class:`SMESH.SMESH_GroupBase`
2725 instance of :class:`SMESH.SMESH_Group`
2727 return self.mesh.UnionListOfGroups(groups, name)
2729 def IntersectGroups(self, group1, group2, name):
2731 Prodice an intersection of two groups.
2732 A new group is created. All mesh elements that are common
2733 for the two initial groups are added to the new one.
2736 group1 (SMESH.SMESH_GroupBase): a group
2737 group2 (SMESH.SMESH_GroupBase): another group
2740 instance of :class:`SMESH.SMESH_Group`
2743 return self.mesh.IntersectGroups(group1, group2, name)
2745 def IntersectListOfGroups(self, groups, name):
2747 Produce an intersection of groups.
2748 New group is created. All mesh elements that are present in all
2749 initial groups simultaneously are added to the new one
2752 groups: a list of :class:`SMESH.SMESH_GroupBase`
2755 instance of :class:`SMESH.SMESH_Group`
2757 return self.mesh.IntersectListOfGroups(groups, name)
2759 def CutGroups(self, main_group, tool_group, name):
2761 Produce a cut of two groups.
2762 A new group is created. All mesh elements that are present in
2763 the main group but are not present in the tool group are added to the new one
2766 main_group (SMESH.SMESH_GroupBase): a group to cut from
2767 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2770 an instance of :class:`SMESH.SMESH_Group`
2773 return self.mesh.CutGroups(main_group, tool_group, name)
2775 def CutListOfGroups(self, main_groups, tool_groups, name):
2777 Produce a cut of groups.
2778 A new group is created. All mesh elements that are present in main groups
2779 but do not present in tool groups are added to the new one
2782 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2783 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2786 an instance of :class:`SMESH.SMESH_Group`
2789 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2791 def CreateDimGroup(self, groups, elemType, name,
2792 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2794 Create a standalone group of entities basing on nodes of other groups.
2797 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2798 elemType: a type of elements to include to the new group; either of
2799 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2800 name: a name of the new group.
2801 nbCommonNodes: a criterion of inclusion of an element to the new group
2802 basing on number of element nodes common with reference *groups*.
2803 Meaning of possible values are:
2805 - SMESH.ALL_NODES - include if all nodes are common,
2806 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2807 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2808 - SMEHS.MAJORITY - include if half of nodes or more are common.
2809 underlyingOnly: if *True* (default), an element is included to the
2810 new group provided that it is based on nodes of an element of *groups*;
2811 in this case the reference *groups* are supposed to be of higher dimension
2812 than *elemType*, which can be useful for example to get all faces lying on
2813 volumes of the reference *groups*.
2816 an instance of :class:`SMESH.SMESH_Group`
2819 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2821 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2824 def ConvertToStandalone(self, group):
2826 Convert group on geom into standalone group
2829 return self.mesh.ConvertToStandalone(group)
2831 # Get some info about mesh:
2832 # ------------------------
2834 def GetLog(self, clearAfterGet):
2836 Return the log of nodes and elements added or removed
2837 since the previous clear of the log.
2840 clearAfterGet: log is emptied after Get (safe if concurrents access)
2843 list of SMESH.log_block structures { commandType, number, coords, indexes }
2846 return self.mesh.GetLog(clearAfterGet)
2850 Clear the log of nodes and elements added or removed since the previous
2851 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2854 self.mesh.ClearLog()
2856 def SetAutoColor(self, theAutoColor):
2858 Toggle auto color mode on the object.
2859 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2862 theAutoColor (boolean): the flag which toggles auto color mode.
2865 self.mesh.SetAutoColor(theAutoColor)
2867 def GetAutoColor(self):
2869 Get flag of object auto color mode.
2875 return self.mesh.GetAutoColor()
2882 integer value, which is the internal Id of the mesh
2885 return self.mesh.GetId()
2887 def HasDuplicatedGroupNamesMED(self):
2889 Check the group names for duplications.
2890 Consider the maximum group name length stored in MED file.
2896 return self.mesh.HasDuplicatedGroupNamesMED()
2898 def GetMeshEditor(self):
2900 Obtain the mesh editor tool
2903 an instance of :class:`SMESH.SMESH_MeshEditor`
2908 def GetIDSource(self, ids, elemType = SMESH.ALL):
2910 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2911 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2915 elemType: type of elements; this parameter is used to distinguish
2916 IDs of nodes from IDs of elements; by default ids are treated as
2917 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2920 an instance of :class:`SMESH.SMESH_IDSource`
2923 call UnRegister() for the returned object as soon as it is no more useful::
2925 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2926 mesh.DoSomething( idSrc )
2930 if isinstance( ids, int ):
2932 return self.editor.MakeIDSource(ids, elemType)
2935 # Get information about mesh contents:
2936 # ------------------------------------
2938 def GetMeshInfo(self, obj = None):
2940 Get the mesh statistic.
2941 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2942 an item of :class:`SMESH.EntityType`.
2945 dictionary { :class:`SMESH.EntityType` - "count of elements" }
2948 if not obj: obj = self.mesh
2949 return self.smeshpyD.GetMeshInfo(obj)
2953 Return the number of nodes in the mesh
2959 return self.mesh.NbNodes()
2961 def NbElements(self):
2963 Return the number of elements in the mesh
2969 return self.mesh.NbElements()
2971 def Nb0DElements(self):
2973 Return the number of 0d elements in the mesh
2979 return self.mesh.Nb0DElements()
2983 Return the number of ball discrete elements in the mesh
2989 return self.mesh.NbBalls()
2993 Return the number of edges in the mesh
2999 return self.mesh.NbEdges()
3001 def NbEdgesOfOrder(self, elementOrder):
3003 Return the number of edges with the given order in the mesh
3006 elementOrder: the order of elements
3007 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3013 return self.mesh.NbEdgesOfOrder(elementOrder)
3017 Return the number of faces in the mesh
3023 return self.mesh.NbFaces()
3025 def NbFacesOfOrder(self, elementOrder):
3027 Return the number of faces with the given order in the mesh
3030 elementOrder: the order of elements
3031 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3037 return self.mesh.NbFacesOfOrder(elementOrder)
3039 def NbTriangles(self):
3041 Return the number of triangles in the mesh
3047 return self.mesh.NbTriangles()
3049 def NbTrianglesOfOrder(self, elementOrder):
3051 Return the number of triangles with the given order in the mesh
3054 elementOrder: is the order of elements
3055 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3061 return self.mesh.NbTrianglesOfOrder(elementOrder)
3063 def NbBiQuadTriangles(self):
3065 Return the number of biquadratic triangles in the mesh
3071 return self.mesh.NbBiQuadTriangles()
3073 def NbQuadrangles(self):
3075 Return the number of quadrangles in the mesh
3081 return self.mesh.NbQuadrangles()
3083 def NbQuadranglesOfOrder(self, elementOrder):
3085 Return the number of quadrangles with the given order in the mesh
3088 elementOrder: the order of elements
3089 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3095 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3097 def NbBiQuadQuadrangles(self):
3099 Return the number of biquadratic quadrangles in the mesh
3105 return self.mesh.NbBiQuadQuadrangles()
3107 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3109 Return the number of polygons of given order in the mesh
3112 elementOrder: the order of elements
3113 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3119 return self.mesh.NbPolygonsOfOrder(elementOrder)
3121 def NbVolumes(self):
3123 Return the number of volumes in the mesh
3129 return self.mesh.NbVolumes()
3132 def NbVolumesOfOrder(self, elementOrder):
3134 Return the number of volumes with the given order in the mesh
3137 elementOrder: the order of elements
3138 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3144 return self.mesh.NbVolumesOfOrder(elementOrder)
3148 Return the number of tetrahedrons in the mesh
3154 return self.mesh.NbTetras()
3156 def NbTetrasOfOrder(self, elementOrder):
3158 Return the number of tetrahedrons with the given order in the mesh
3161 elementOrder: the order of elements
3162 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3168 return self.mesh.NbTetrasOfOrder(elementOrder)
3172 Return the number of hexahedrons in the mesh
3178 return self.mesh.NbHexas()
3180 def NbHexasOfOrder(self, elementOrder):
3182 Return the number of hexahedrons with the given order in the mesh
3185 elementOrder: the order of elements
3186 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3192 return self.mesh.NbHexasOfOrder(elementOrder)
3194 def NbTriQuadraticHexas(self):
3196 Return the number of triquadratic hexahedrons in the mesh
3202 return self.mesh.NbTriQuadraticHexas()
3204 def NbPyramids(self):
3206 Return the number of pyramids in the mesh
3212 return self.mesh.NbPyramids()
3214 def NbPyramidsOfOrder(self, elementOrder):
3216 Return the number of pyramids with the given order in the mesh
3219 elementOrder: the order of elements
3220 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3226 return self.mesh.NbPyramidsOfOrder(elementOrder)
3230 Return the number of prisms in the mesh
3236 return self.mesh.NbPrisms()
3238 def NbPrismsOfOrder(self, elementOrder):
3240 Return the number of prisms with the given order in the mesh
3243 elementOrder: the order of elements
3244 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3250 return self.mesh.NbPrismsOfOrder(elementOrder)
3252 def NbHexagonalPrisms(self):
3254 Return the number of hexagonal prisms in the mesh
3260 return self.mesh.NbHexagonalPrisms()
3262 def NbPolyhedrons(self):
3264 Return the number of polyhedrons in the mesh
3270 return self.mesh.NbPolyhedrons()
3272 def NbSubMesh(self):
3274 Return the number of submeshes in the mesh
3280 return self.mesh.NbSubMesh()
3282 def GetElementsId(self):
3284 Return the list of all mesh elements IDs
3287 the list of integer values
3290 :meth:`GetElementsByType`
3293 return self.mesh.GetElementsId()
3295 def GetElementsByType(self, elementType):
3297 Return the list of IDs of mesh elements with the given type
3300 elementType (SMESH.ElementType): the required type of elements
3303 list of integer values
3306 return self.mesh.GetElementsByType(elementType)
3308 def GetNodesId(self):
3310 Return the list of mesh nodes IDs
3313 the list of integer values
3316 return self.mesh.GetNodesId()
3318 # Get the information about mesh elements:
3319 # ------------------------------------
3321 def GetElementType(self, id, iselem=True):
3323 Return the type of mesh element or node
3326 the value from :class:`SMESH.ElementType` enumeration.
3327 Return SMESH.ALL if element or node with the given ID does not exist
3330 return self.mesh.GetElementType(id, iselem)
3332 def GetElementGeomType(self, id):
3334 Return the geometric type of mesh element
3337 the value from :class:`SMESH.EntityType` enumeration.
3340 return self.mesh.GetElementGeomType(id)
3342 def GetElementShape(self, id):
3344 Return the shape type of mesh element
3347 the value from :class:`SMESH.GeometryType` enumeration.
3350 return self.mesh.GetElementShape(id)
3352 def GetSubMeshElementsId(self, Shape):
3354 Return the list of sub-mesh elements IDs
3357 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3358 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3361 list of integer values
3364 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3365 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3368 return self.mesh.GetSubMeshElementsId(ShapeID)
3370 def GetSubMeshNodesId(self, Shape, all):
3372 Return the list of sub-mesh nodes IDs
3375 Shape: a geom object (sub-shape).
3376 *Shape* must be the sub-shape of a :meth:`GetShape`
3377 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3380 list of integer values
3383 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3384 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3387 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3389 def GetSubMeshElementType(self, Shape):
3391 Return type of elements on given shape
3394 Shape: a geom object (sub-shape).
3395 *Shape* must be a sub-shape of a ShapeToMesh()
3398 :class:`SMESH.ElementType`
3401 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3402 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3405 return self.mesh.GetSubMeshElementType(ShapeID)
3409 Get the mesh description
3415 return self.mesh.Dump()
3418 # Get the information about nodes and elements of a mesh by its IDs:
3419 # -----------------------------------------------------------
3421 def GetNodeXYZ(self, id):
3423 Get XYZ coordinates of a node.
3424 If there is no node for the given ID - return an empty list
3427 list of float values
3430 return self.mesh.GetNodeXYZ(id)
3432 def GetNodeInverseElements(self, id):
3434 Return list of IDs of inverse elements for the given node.
3435 If there is no node for the given ID - return an empty list
3438 list of integer values
3441 return self.mesh.GetNodeInverseElements(id)
3443 def GetNodePosition(self,NodeID):
3445 Return the position of a node on the shape
3448 :class:`SMESH.NodePosition`
3451 return self.mesh.GetNodePosition(NodeID)
3453 def GetElementPosition(self,ElemID):
3455 Return the position of an element on the shape
3458 :class:`SMESH.ElementPosition`
3461 return self.mesh.GetElementPosition(ElemID)
3463 def GetShapeID(self, id):
3465 Return the ID of the shape, on which the given node was generated.
3468 an integer value > 0 or -1 if there is no node for the given
3469 ID or the node is not assigned to any geometry
3472 return self.mesh.GetShapeID(id)
3474 def GetShapeIDForElem(self,id):
3476 Return the ID of the shape, on which the given element was generated.
3479 an integer value > 0 or -1 if there is no element for the given
3480 ID or the element is not assigned to any geometry
3483 return self.mesh.GetShapeIDForElem(id)
3485 def GetElemNbNodes(self, id):
3487 Return the number of nodes of the given element
3490 an integer value > 0 or -1 if there is no element for the given ID
3493 return self.mesh.GetElemNbNodes(id)
3495 def GetElemNode(self, id, index):
3497 Return the node ID the given (zero based) index for the given element.
3499 * If there is no element for the given ID - return -1.
3500 * If there is no node for the given index - return -2.
3503 id (int): element ID
3504 index (int): node index within the element
3507 an integer value (ID)
3510 :meth:`GetElemNodes`
3513 return self.mesh.GetElemNode(id, index)
3515 def GetElemNodes(self, id):
3517 Return the IDs of nodes of the given element
3520 a list of integer values
3523 return self.mesh.GetElemNodes(id)
3525 def IsMediumNode(self, elementID, nodeID):
3527 Return true if the given node is the medium node in the given quadratic element
3530 return self.mesh.IsMediumNode(elementID, nodeID)
3532 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3534 Return true if the given node is the medium node in one of quadratic elements
3537 nodeID: ID of the node
3538 elementType: the type of elements to check a state of the node, either of
3539 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3542 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3544 def ElemNbEdges(self, id):
3546 Return the number of edges for the given element
3549 return self.mesh.ElemNbEdges(id)
3551 def ElemNbFaces(self, id):
3553 Return the number of faces for the given element
3556 return self.mesh.ElemNbFaces(id)
3558 def GetElemFaceNodes(self,elemId, faceIndex):
3560 Return nodes of given face (counted from zero) for given volumic element.
3563 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3565 def GetFaceNormal(self, faceId, normalized=False):
3567 Return three components of normal of given mesh face
3568 (or an empty array in KO case)
3571 return self.mesh.GetFaceNormal(faceId,normalized)
3573 def FindElementByNodes(self, nodes):
3575 Return an element based on all given nodes.
3578 return self.mesh.FindElementByNodes(nodes)
3580 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3582 Return elements including all given nodes.
3585 return self.mesh.GetElementsByNodes( nodes, elemType )
3587 def IsPoly(self, id):
3589 Return true if the given element is a polygon
3592 return self.mesh.IsPoly(id)
3594 def IsQuadratic(self, id):
3596 Return true if the given element is quadratic
3599 return self.mesh.IsQuadratic(id)
3601 def GetBallDiameter(self, id):
3603 Return diameter of a ball discrete element or zero in case of an invalid *id*
3606 return self.mesh.GetBallDiameter(id)
3608 def BaryCenter(self, id):
3610 Return XYZ coordinates of the barycenter of the given element.
3611 If there is no element for the given ID - return an empty list
3614 a list of three double values
3617 return self.mesh.BaryCenter(id)
3619 def GetIdsFromFilter(self, theFilter):
3621 Pass mesh elements through the given filter and return IDs of fitting elements
3624 theFilter: :class:`SMESH.Filter`
3630 :meth:`SMESH.Filter.GetIDs`
3633 theFilter.SetMesh( self.mesh )
3634 return theFilter.GetIDs()
3636 # Get mesh measurements information:
3637 # ------------------------------------
3639 def GetFreeBorders(self):
3641 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3642 Return a list of special structures (borders).
3645 a list of :class:`SMESH.FreeEdges.Border`
3648 aFilterMgr = self.smeshpyD.CreateFilterManager()
3649 aPredicate = aFilterMgr.CreateFreeEdges()
3650 aPredicate.SetMesh(self.mesh)
3651 aBorders = aPredicate.GetBorders()
3652 aFilterMgr.UnRegister()
3655 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3657 Get minimum distance between two nodes, elements or distance to the origin
3660 id1: first node/element id
3661 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3662 isElem1: *True* if *id1* is element id, *False* if it is node id
3663 isElem2: *True* if *id2* is element id, *False* if it is node id
3666 minimum distance value **GetMinDistance()**
3669 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3670 return aMeasure.value
3672 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3674 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3677 id1: first node/element id
3678 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3679 isElem1: *True* if *id1* is element id, *False* if it is node id
3680 isElem2: *True* if *id2* is element id, *False* if it is node id
3683 :class:`SMESH.Measure` structure
3689 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3691 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3694 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3696 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3701 aMeasurements = self.smeshpyD.CreateMeasurements()
3702 aMeasure = aMeasurements.MinDistance(id1, id2)
3703 genObjUnRegister([aMeasurements,id1, id2])
3706 def BoundingBox(self, objects=None, isElem=False):
3708 Get bounding box of the specified object(s)
3711 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3712 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3713 *False* specifies that *objects* are nodes
3716 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3719 :meth:`GetBoundingBox()`
3722 result = self.GetBoundingBox(objects, isElem)
3726 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3729 def GetBoundingBox(self, objects=None, isElem=False):
3731 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3734 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3735 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3736 False means that *objects* are nodes
3739 :class:`SMESH.Measure` structure
3742 :meth:`BoundingBox()`
3746 objects = [self.mesh]
3747 elif isinstance(objects, tuple):
3748 objects = list(objects)
3749 if not isinstance(objects, list):
3751 if len(objects) > 0 and isinstance(objects[0], int):
3754 unRegister = genObjUnRegister()
3756 if isinstance(o, Mesh):
3757 srclist.append(o.mesh)
3758 elif hasattr(o, "_narrow"):
3759 src = o._narrow(SMESH.SMESH_IDSource)
3760 if src: srclist.append(src)
3762 elif isinstance(o, list):
3764 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3766 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3767 unRegister.set( srclist[-1] )
3770 aMeasurements = self.smeshpyD.CreateMeasurements()
3771 unRegister.set( aMeasurements )
3772 aMeasure = aMeasurements.BoundingBox(srclist)
3775 # Mesh edition (SMESH_MeshEditor functionality):
3776 # ---------------------------------------------
3778 def RemoveElements(self, IDsOfElements):
3780 Remove the elements from the mesh by ids
3783 IDsOfElements: is a list of ids of elements to remove
3789 return self.editor.RemoveElements(IDsOfElements)
3791 def RemoveNodes(self, IDsOfNodes):
3793 Remove nodes from mesh by ids
3796 IDsOfNodes: is a list of ids of nodes to remove
3802 return self.editor.RemoveNodes(IDsOfNodes)
3804 def RemoveOrphanNodes(self):
3806 Remove all orphan (free) nodes from mesh
3809 number of the removed nodes
3812 return self.editor.RemoveOrphanNodes()
3814 def AddNode(self, x, y, z):
3816 Add a node to the mesh by coordinates
3822 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3823 if hasVars: self.mesh.SetParameters(Parameters)
3824 return self.editor.AddNode( x, y, z)
3826 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3828 Create a 0D element on a node with given number.
3831 IDOfNode: the ID of node for creation of the element.
3832 DuplicateElements: to add one more 0D element to a node or not
3835 ID of the new 0D element
3838 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3840 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3842 Create 0D elements on all nodes of the given elements except those
3843 nodes on which a 0D element already exists.
3846 theObject: an object on whose nodes 0D elements will be created.
3847 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3848 theGroupName: optional name of a group to add 0D elements created
3849 and/or found on nodes of *theObject*.
3850 DuplicateElements: to add one more 0D element to a node or not
3853 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3854 IDs of new and/or found 0D elements. IDs of 0D elements
3855 can be retrieved from the returned object by
3856 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3859 unRegister = genObjUnRegister()
3860 if isinstance( theObject, Mesh ):
3861 theObject = theObject.GetMesh()
3862 elif isinstance( theObject, list ):
3863 theObject = self.GetIDSource( theObject, SMESH.ALL )
3864 unRegister.set( theObject )
3865 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3867 def AddBall(self, IDOfNode, diameter):
3869 Create a ball element on a node with given ID.
3872 IDOfNode: the ID of node for creation of the element.
3873 diameter: the bal diameter.
3876 ID of the new ball element
3879 return self.editor.AddBall( IDOfNode, diameter )
3881 def AddEdge(self, IDsOfNodes):
3883 Create a linear or quadratic edge (this is determined
3884 by the number of given nodes).
3887 IDsOfNodes: list of node IDs for creation of the element.
3888 The order of nodes in this list should correspond to
3889 the :ref:`connectivity convention <connectivity_page>`.
3895 return self.editor.AddEdge(IDsOfNodes)
3897 def AddFace(self, IDsOfNodes):
3899 Create a linear or quadratic face (this is determined
3900 by the number of given nodes).
3903 IDsOfNodes: list of node IDs for creation of the element.
3904 The order of nodes in this list should correspond to
3905 the :ref:`connectivity convention <connectivity_page>`.
3911 return self.editor.AddFace(IDsOfNodes)
3913 def AddPolygonalFace(self, IdsOfNodes):
3915 Add a polygonal face defined by a list of node IDs
3918 IdsOfNodes: the list of node IDs for creation of the element.
3924 return self.editor.AddPolygonalFace(IdsOfNodes)
3926 def AddQuadPolygonalFace(self, IdsOfNodes):
3928 Add a quadratic polygonal face defined by a list of node IDs
3931 IdsOfNodes: the list of node IDs for creation of the element;
3932 corner nodes follow first.
3938 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3940 def AddVolume(self, IDsOfNodes):
3942 Create both simple and quadratic volume (this is determined
3943 by the number of given nodes).
3946 IDsOfNodes: list of node IDs for creation of the element.
3947 The order of nodes in this list should correspond to
3948 the :ref:`connectivity convention <connectivity_page>`.
3951 ID of the new volumic element
3954 return self.editor.AddVolume(IDsOfNodes)
3956 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3958 Create a volume of many faces, giving nodes for each face.
3961 IdsOfNodes: list of node IDs for volume creation, face by face.
3962 Quantities: list of integer values, Quantities[i]
3963 gives the quantity of nodes in face number i.
3966 ID of the new volumic element
3969 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3971 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3973 Create a volume of many faces, giving the IDs of the existing faces.
3976 The created volume will refer only to the nodes
3977 of the given faces, not to the faces themselves.
3980 IdsOfFaces: the list of face IDs for volume creation.
3983 ID of the new volumic element
3986 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
3989 def SetNodeOnVertex(self, NodeID, Vertex):
3991 Binds a node to a vertex
3995 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
3998 True if succeed else raises an exception
4001 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4002 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4006 self.editor.SetNodeOnVertex(NodeID, VertexID)
4007 except SALOME.SALOME_Exception as inst:
4008 raise ValueError(inst.details.text)
4012 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4014 Stores the node position on an edge
4018 Edge: an edge (GEOM.GEOM_Object) or edge ID
4019 paramOnEdge: a parameter on the edge where the node is located
4022 True if succeed else raises an exception
4025 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4026 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4030 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4031 except SALOME.SALOME_Exception as inst:
4032 raise ValueError(inst.details.text)
4035 def SetNodeOnFace(self, NodeID, Face, u, v):
4037 Stores node position on a face
4041 Face: a face (GEOM.GEOM_Object) or face ID
4042 u: U parameter on the face where the node is located
4043 v: V parameter on the face where the node is located
4046 True if succeed else raises an exception
4049 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4050 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4054 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4055 except SALOME.SALOME_Exception as inst:
4056 raise ValueError(inst.details.text)
4059 def SetNodeInVolume(self, NodeID, Solid):
4061 Binds a node to a solid
4065 Solid: a solid (GEOM.GEOM_Object) or solid ID
4068 True if succeed else raises an exception
4071 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4072 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4076 self.editor.SetNodeInVolume(NodeID, SolidID)
4077 except SALOME.SALOME_Exception as inst:
4078 raise ValueError(inst.details.text)
4081 def SetMeshElementOnShape(self, ElementID, Shape):
4083 Bind an element to a shape
4086 ElementID: an element ID
4087 Shape: a shape (GEOM.GEOM_Object) or shape ID
4090 True if succeed else raises an exception
4093 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4094 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4098 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4099 except SALOME.SALOME_Exception as inst:
4100 raise ValueError(inst.details.text)
4104 def MoveNode(self, NodeID, x, y, z):
4106 Move the node with the given id
4109 NodeID: the id of the node
4110 x: a new X coordinate
4111 y: a new Y coordinate
4112 z: a new Z coordinate
4115 True if succeed else False
4118 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4119 if hasVars: self.mesh.SetParameters(Parameters)
4120 return self.editor.MoveNode(NodeID, x, y, z)
4122 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4124 Find the node closest to a point and moves it to a point location
4127 x: the X coordinate of a point
4128 y: the Y coordinate of a point
4129 z: the Z coordinate of a point
4130 NodeID: if specified (>0), the node with this ID is moved,
4131 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4134 the ID of a moved node
4137 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4138 if hasVars: self.mesh.SetParameters(Parameters)
4139 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4141 def FindNodeClosestTo(self, x, y, z):
4143 Find the node closest to a point
4146 x: the X coordinate of a point
4147 y: the Y coordinate of a point
4148 z: the Z coordinate of a point
4154 #preview = self.mesh.GetMeshEditPreviewer()
4155 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4156 return self.editor.FindNodeClosestTo(x, y, z)
4158 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4160 Find the elements where a point lays IN or ON
4163 x,y,z (float): coordinates of the point
4164 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4165 means elements of any type excluding nodes, discrete and 0D elements.
4166 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4169 list of IDs of found elements
4172 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4174 return self.editor.FindElementsByPoint(x, y, z, elementType)
4176 def GetPointState(self, x, y, z):
4178 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4179 0-IN, 1-OUT, 2-ON, 3-UNKNOWN.
4180 UNKNOWN state means that either mesh is wrong or the analysis fails.
4183 return self.editor.GetPointState(x, y, z)
4185 def IsManifold(self):
4187 Check if a 2D mesh is manifold
4190 return self.editor.IsManifold()
4192 def IsCoherentOrientation2D(self):
4194 Check if orientation of 2D elements is coherent
4197 return self.editor.IsCoherentOrientation2D()
4199 def MeshToPassThroughAPoint(self, x, y, z):
4201 Find the node closest to a point and moves it to a point location
4204 x: the X coordinate of a point
4205 y: the Y coordinate of a point
4206 z: the Z coordinate of a point
4209 the ID of a moved node
4212 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4214 def InverseDiag(self, NodeID1, NodeID2):
4216 Replace two neighbour triangles sharing Node1-Node2 link
4217 with the triangles built on the same 4 nodes but having other common link.
4220 NodeID1: the ID of the first node
4221 NodeID2: the ID of the second node
4224 False if proper faces were not found
4226 return self.editor.InverseDiag(NodeID1, NodeID2)
4228 def DeleteDiag(self, NodeID1, NodeID2):
4230 Replace two neighbour triangles sharing *Node1-Node2* link
4231 with a quadrangle built on the same 4 nodes.
4234 NodeID1: ID of the first node
4235 NodeID2: ID of the second node
4238 False if proper faces were not found
4241 return self.editor.DeleteDiag(NodeID1, NodeID2)
4243 def Reorient(self, IDsOfElements=None):
4245 Reorient elements by ids
4248 IDsOfElements: if undefined reorients all mesh elements
4251 True if succeed else False
4254 if IDsOfElements == None:
4255 IDsOfElements = self.GetElementsId()
4256 return self.editor.Reorient(IDsOfElements)
4258 def ReorientObject(self, theObject):
4260 Reorient all elements of the object
4263 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4266 True if succeed else False
4269 if ( isinstance( theObject, Mesh )):
4270 theObject = theObject.GetMesh()
4271 return self.editor.ReorientObject(theObject)
4273 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4275 Reorient faces contained in *the2DObject*.
4278 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4279 theDirection: is a desired direction of normal of *theFace*.
4280 It can be either a GEOM vector or a list of coordinates [x,y,z].
4281 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4282 compared with theDirection. It can be either ID of face or a point
4283 by which the face will be found. The point can be given as either
4284 a GEOM vertex or a list of point coordinates.
4287 number of reoriented faces
4290 unRegister = genObjUnRegister()
4292 if isinstance( the2DObject, Mesh ):
4293 the2DObject = the2DObject.GetMesh()
4294 if isinstance( the2DObject, list ):
4295 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4296 unRegister.set( the2DObject )
4297 # check theDirection
4298 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4299 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4300 if isinstance( theDirection, list ):
4301 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4302 # prepare theFace and thePoint
4303 theFace = theFaceOrPoint
4304 thePoint = PointStruct(0,0,0)
4305 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4306 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4308 if isinstance( theFaceOrPoint, list ):
4309 thePoint = PointStruct( *theFaceOrPoint )
4311 if isinstance( theFaceOrPoint, PointStruct ):
4312 thePoint = theFaceOrPoint
4314 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4316 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4318 Reorient faces according to adjacent volumes.
4321 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4322 either IDs of faces or face groups.
4323 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4324 theOutsideNormal: to orient faces to have their normals
4325 pointing either *outside* or *inside* the adjacent volumes.
4328 number of reoriented faces.
4331 unRegister = genObjUnRegister()
4333 if not isinstance( the2DObject, list ):
4334 the2DObject = [ the2DObject ]
4335 elif the2DObject and isinstance( the2DObject[0], int ):
4336 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4337 unRegister.set( the2DObject )
4338 the2DObject = [ the2DObject ]
4339 for i,obj2D in enumerate( the2DObject ):
4340 if isinstance( obj2D, Mesh ):
4341 the2DObject[i] = obj2D.GetMesh()
4342 if isinstance( obj2D, list ):
4343 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4344 unRegister.set( the2DObject[i] )
4346 if isinstance( the3DObject, Mesh ):
4347 the3DObject = the3DObject.GetMesh()
4348 if isinstance( the3DObject, list ):
4349 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4350 unRegister.set( the3DObject )
4351 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4353 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4355 Fuse the neighbouring triangles into quadrangles.
4358 IDsOfElements: The triangles to be fused.
4359 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4360 applied to possible quadrangles to choose a neighbour to fuse with.
4361 Note that not all items of :class:`SMESH.FunctorType` corresponds
4362 to numerical functors.
4363 MaxAngle: is the maximum angle between element normals at which the fusion
4364 is still performed; theMaxAngle is measured in radians.
4365 Also it could be a name of variable which defines angle in degrees.
4368 True in case of success, False otherwise.
4371 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4372 self.mesh.SetParameters(Parameters)
4373 if not IDsOfElements:
4374 IDsOfElements = self.GetElementsId()
4375 Functor = self.smeshpyD.GetFunctor(theCriterion)
4376 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4378 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4380 Fuse the neighbouring triangles of the object into quadrangles
4383 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4384 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4385 applied to possible quadrangles to choose a neighbour to fuse with.
4386 Note that not all items of :class:`SMESH.FunctorType` corresponds
4387 to numerical functors.
4388 MaxAngle: a max angle between element normals at which the fusion
4389 is still performed; theMaxAngle is measured in radians.
4392 True in case of success, False otherwise.
4395 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4396 self.mesh.SetParameters(Parameters)
4397 if isinstance( theObject, Mesh ):
4398 theObject = theObject.GetMesh()
4399 Functor = self.smeshpyD.GetFunctor(theCriterion)
4400 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4402 def QuadToTri (self, IDsOfElements, theCriterion = None):
4404 Split quadrangles into triangles.
4407 IDsOfElements: the faces to be splitted.
4408 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4409 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4410 value, then quadrangles will be split by the smallest diagonal.
4411 Note that not all items of :class:`SMESH.FunctorType` corresponds
4412 to numerical functors.
4415 True in case of success, False otherwise.
4417 if IDsOfElements == []:
4418 IDsOfElements = self.GetElementsId()
4419 if theCriterion is None:
4420 theCriterion = FT_MaxElementLength2D
4421 Functor = self.smeshpyD.GetFunctor(theCriterion)
4422 return self.editor.QuadToTri(IDsOfElements, Functor)
4424 def QuadToTriObject (self, theObject, theCriterion = None):
4426 Split quadrangles into triangles.
4429 theObject: the object from which the list of elements is taken,
4430 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4431 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4432 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4433 value, then quadrangles will be split by the smallest diagonal.
4434 Note that not all items of :class:`SMESH.FunctorType` corresponds
4435 to numerical functors.
4438 True in case of success, False otherwise.
4440 if ( isinstance( theObject, Mesh )):
4441 theObject = theObject.GetMesh()
4442 if theCriterion is None:
4443 theCriterion = FT_MaxElementLength2D
4444 Functor = self.smeshpyD.GetFunctor(theCriterion)
4445 return self.editor.QuadToTriObject(theObject, Functor)
4447 def QuadTo4Tri (self, theElements=[]):
4449 Split each of given quadrangles into 4 triangles. A node is added at the center of
4453 theElements: the faces to be splitted. This can be either
4454 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4455 or a list of face IDs. By default all quadrangles are split
4457 unRegister = genObjUnRegister()
4458 if isinstance( theElements, Mesh ):
4459 theElements = theElements.mesh
4460 elif not theElements:
4461 theElements = self.mesh
4462 elif isinstance( theElements, list ):
4463 theElements = self.GetIDSource( theElements, SMESH.FACE )
4464 unRegister.set( theElements )
4465 return self.editor.QuadTo4Tri( theElements )
4467 def SplitQuad (self, IDsOfElements, Diag13):
4469 Split quadrangles into triangles.
4472 IDsOfElements: the faces to be splitted
4473 Diag13: is used to choose a diagonal for splitting.
4476 True in case of success, False otherwise.
4478 if IDsOfElements == []:
4479 IDsOfElements = self.GetElementsId()
4480 return self.editor.SplitQuad(IDsOfElements, Diag13)
4482 def SplitQuadObject (self, theObject, Diag13):
4484 Split quadrangles into triangles.
4487 theObject: the object from which the list of elements is taken,
4488 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4489 Diag13: is used to choose a diagonal for splitting.
4492 True in case of success, False otherwise.
4494 if ( isinstance( theObject, Mesh )):
4495 theObject = theObject.GetMesh()
4496 return self.editor.SplitQuadObject(theObject, Diag13)
4498 def BestSplit (self, IDOfQuad, theCriterion):
4500 Find a better splitting of the given quadrangle.
4503 IDOfQuad: the ID of the quadrangle to be splitted.
4504 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4505 choose a diagonal for splitting.
4506 Note that not all items of :class:`SMESH.FunctorType` corresponds
4507 to numerical functors.
4510 * 1 if 1-3 diagonal is better,
4511 * 2 if 2-4 diagonal is better,
4512 * 0 if error occurs.
4514 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4516 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4518 Split volumic elements into tetrahedrons
4521 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4522 method: flags passing splitting method:
4523 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4524 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4526 unRegister = genObjUnRegister()
4527 if isinstance( elems, Mesh ):
4528 elems = elems.GetMesh()
4529 if ( isinstance( elems, list )):
4530 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4531 unRegister.set( elems )
4532 self.editor.SplitVolumesIntoTetra(elems, method)
4535 def SplitBiQuadraticIntoLinear(self, elems=None):
4537 Split bi-quadratic elements into linear ones without creation of additional nodes:
4539 - bi-quadratic triangle will be split into 3 linear quadrangles;
4540 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4541 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4543 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4544 will be split in order to keep the mesh conformal.
4547 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4548 if None (default), all bi-quadratic elements will be split
4550 unRegister = genObjUnRegister()
4551 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4552 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4553 unRegister.set( elems )
4555 elems = [ self.GetMesh() ]
4556 if isinstance( elems, Mesh ):
4557 elems = [ elems.GetMesh() ]
4558 if not isinstance( elems, list ):
4560 self.editor.SplitBiQuadraticIntoLinear( elems )
4562 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4563 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4565 Split hexahedra into prisms
4568 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4569 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4570 gives a normal vector defining facets to split into triangles.
4571 *startHexPoint* can be either a triple of coordinates or a vertex.
4572 facetNormal: a normal to a facet to split into triangles of a
4573 hexahedron found by *startHexPoint*.
4574 *facetNormal* can be either a triple of coordinates or an edge.
4575 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4576 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4577 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4578 to *startHexPoint* are split, else *startHexPoint*
4579 is used to find the facet to split in all domains present in *elems*.
4582 unRegister = genObjUnRegister()
4583 if isinstance( elems, Mesh ):
4584 elems = elems.GetMesh()
4585 if ( isinstance( elems, list )):
4586 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4587 unRegister.set( elems )
4590 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4591 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4592 elif isinstance( startHexPoint, list ):
4593 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4596 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4597 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4598 elif isinstance( facetNormal, list ):
4599 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4602 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4604 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4606 def SplitQuadsNearTriangularFacets(self):
4608 Split quadrangle faces near triangular facets of volumes
4610 faces_array = self.GetElementsByType(SMESH.FACE)
4611 for face_id in faces_array:
4612 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4613 quad_nodes = self.mesh.GetElemNodes(face_id)
4614 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4615 isVolumeFound = False
4616 for node1_elem in node1_elems:
4617 if not isVolumeFound:
4618 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4619 nb_nodes = self.GetElemNbNodes(node1_elem)
4620 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4621 volume_elem = node1_elem
4622 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4623 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4624 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4625 isVolumeFound = True
4626 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4627 self.SplitQuad([face_id], False) # diagonal 2-4
4628 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4629 isVolumeFound = True
4630 self.SplitQuad([face_id], True) # diagonal 1-3
4631 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4632 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4633 isVolumeFound = True
4634 self.SplitQuad([face_id], True) # diagonal 1-3
4636 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4638 Split hexahedrons into tetrahedrons.
4640 This operation uses :doc:`pattern_mapping` functionality for splitting.
4643 theObject: the object from which the list of hexahedrons is taken;
4644 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4645 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4646 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4647 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4648 key-point will be mapped into *theNode001*-th node of each volume.
4649 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4652 True in case of success, False otherwise.
4660 # (0,0,1) 4.---------.7 * |
4667 # (0,0,0) 0.---------.3
4668 pattern_tetra = "!!! Nb of points: \n 8 \n\
4678 !!! Indices of points of 6 tetras: \n\
4686 pattern = self.smeshpyD.GetPattern()
4687 isDone = pattern.LoadFromFile(pattern_tetra)
4689 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4692 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4693 isDone = pattern.MakeMesh(self.mesh, False, False)
4694 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4696 # split quafrangle faces near triangular facets of volumes
4697 self.SplitQuadsNearTriangularFacets()
4701 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4703 Split hexahedrons into prisms.
4705 Uses the :doc:`pattern_mapping` functionality for splitting.
4708 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4709 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4710 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4711 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4712 will be mapped into the *theNode001* -th node of each volume.
4713 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4716 True in case of success, False otherwise.
4718 # Pattern: 5.---------.6
4723 # (0,0,1) 4.---------.7 |
4730 # (0,0,0) 0.---------.3
4731 pattern_prism = "!!! Nb of points: \n 8 \n\
4741 !!! Indices of points of 2 prisms: \n\
4745 pattern = self.smeshpyD.GetPattern()
4746 isDone = pattern.LoadFromFile(pattern_prism)
4748 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4751 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4752 isDone = pattern.MakeMesh(self.mesh, False, False)
4753 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4755 # Split quafrangle faces near triangular facets of volumes
4756 self.SplitQuadsNearTriangularFacets()
4760 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4761 MaxNbOfIterations, MaxAspectRatio, Method):
4766 IDsOfElements: the list if ids of elements to smooth
4767 IDsOfFixedNodes: the list of ids of fixed nodes.
4768 Note that nodes built on edges and boundary nodes are always fixed.
4769 MaxNbOfIterations: the maximum number of iterations
4770 MaxAspectRatio: varies in range [1.0, inf]
4771 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4772 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4775 True in case of success, False otherwise.
4778 if IDsOfElements == []:
4779 IDsOfElements = self.GetElementsId()
4780 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4781 self.mesh.SetParameters(Parameters)
4782 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4783 MaxNbOfIterations, MaxAspectRatio, Method)
4785 def SmoothObject(self, theObject, IDsOfFixedNodes,
4786 MaxNbOfIterations, MaxAspectRatio, Method):
4788 Smooth elements which belong to the given object
4791 theObject: the object to smooth
4792 IDsOfFixedNodes: the list of ids of fixed nodes.
4793 Note that nodes built on edges and boundary nodes are always fixed.
4794 MaxNbOfIterations: the maximum number of iterations
4795 MaxAspectRatio: varies in range [1.0, inf]
4796 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4797 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4800 True in case of success, False otherwise.
4803 if ( isinstance( theObject, Mesh )):
4804 theObject = theObject.GetMesh()
4805 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4806 MaxNbOfIterations, MaxAspectRatio, Method)
4808 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4809 MaxNbOfIterations, MaxAspectRatio, Method):
4811 Parametrically smooth the given elements
4814 IDsOfElements: the list if ids of elements to smooth
4815 IDsOfFixedNodes: the list of ids of fixed nodes.
4816 Note that nodes built on edges and boundary nodes are always fixed.
4817 MaxNbOfIterations: the maximum number of iterations
4818 MaxAspectRatio: varies in range [1.0, inf]
4819 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4820 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4823 True in case of success, False otherwise.
4826 if IDsOfElements == []:
4827 IDsOfElements = self.GetElementsId()
4828 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4829 self.mesh.SetParameters(Parameters)
4830 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4831 MaxNbOfIterations, MaxAspectRatio, Method)
4833 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4834 MaxNbOfIterations, MaxAspectRatio, Method):
4836 Parametrically smooth the elements which belong to the given object
4839 theObject: the object to smooth
4840 IDsOfFixedNodes: the list of ids of fixed nodes.
4841 Note that nodes built on edges and boundary nodes are always fixed.
4842 MaxNbOfIterations: the maximum number of iterations
4843 MaxAspectRatio: varies in range [1.0, inf]
4844 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4845 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4848 True in case of success, False otherwise.
4851 if ( isinstance( theObject, Mesh )):
4852 theObject = theObject.GetMesh()
4853 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4854 MaxNbOfIterations, MaxAspectRatio, Method)
4856 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4858 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4859 them with quadratic with the same id.
4862 theForce3d: method of new node creation:
4864 * False - the medium node lies at the geometrical entity from which the mesh element is built
4865 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4866 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4867 theToBiQuad: If True, converts the mesh to bi-quadratic
4870 :class:`SMESH.ComputeError` which can hold a warning
4873 If *theSubMesh* is provided, the mesh can become non-conformal
4876 if isinstance( theSubMesh, Mesh ):
4877 theSubMesh = theSubMesh.mesh
4879 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4882 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4884 self.editor.ConvertToQuadratic(theForce3d)
4885 error = self.editor.GetLastError()
4886 if error and error.comment:
4887 print(error.comment)
4890 def ConvertFromQuadratic(self, theSubMesh=None):
4892 Convert the mesh from quadratic to ordinary,
4893 deletes old quadratic elements,
4894 replacing them with ordinary mesh elements with the same id.
4897 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4900 If *theSubMesh* is provided, the mesh can become non-conformal
4904 self.editor.ConvertFromQuadraticObject(theSubMesh)
4906 return self.editor.ConvertFromQuadratic()
4908 def Make2DMeshFrom3D(self):
4910 Create 2D mesh as skin on boundary faces of a 3D mesh
4913 True if operation has been completed successfully, False otherwise
4916 return self.editor.Make2DMeshFrom3D()
4918 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4919 toCopyElements=False, toCopyExistingBondary=False):
4921 Create missing boundary elements
4924 elements: elements whose boundary is to be checked:
4925 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4926 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4927 dimension: defines type of boundary elements to create, either of
4928 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4929 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4930 groupName: a name of group to store created boundary elements in,
4931 "" means not to create the group
4932 meshName: a name of new mesh to store created boundary elements in,
4933 "" means not to create the new mesh
4934 toCopyElements: if True, the checked elements will be copied into
4935 the new mesh else only boundary elements will be copied into the new mesh
4936 toCopyExistingBondary: if True, not only new but also pre-existing
4937 boundary elements will be copied into the new mesh
4940 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
4943 unRegister = genObjUnRegister()
4944 if isinstance( elements, Mesh ):
4945 elements = elements.GetMesh()
4946 if ( isinstance( elements, list )):
4947 elemType = SMESH.ALL
4948 if elements: elemType = self.GetElementType( elements[0], iselem=True)
4949 elements = self.editor.MakeIDSource(elements, elemType)
4950 unRegister.set( elements )
4951 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
4952 toCopyElements,toCopyExistingBondary)
4953 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4956 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4957 toCopyAll=False, groups=[]):
4959 Create missing boundary elements around either the whole mesh or
4963 dimension: defines type of boundary elements to create, either of
4964 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
4965 groupName: a name of group to store all boundary elements in,
4966 "" means not to create the group
4967 meshName: a name of a new mesh, which is a copy of the initial
4968 mesh + created boundary elements; "" means not to create the new mesh
4969 toCopyAll: if True, the whole initial mesh will be copied into
4970 the new mesh else only boundary elements will be copied into the new mesh
4971 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
4974 tuple( long, mesh, groups )
4975 - long - number of added boundary elements
4976 - mesh - the :class:`Mesh` where elements were added to
4977 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
4980 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
4982 if mesh: mesh = self.smeshpyD.Mesh(mesh)
4983 return nb, mesh, group
4985 def RenumberNodes(self):
4987 Renumber mesh nodes to remove unused node IDs
4989 self.editor.RenumberNodes()
4991 def RenumberElements(self):
4993 Renumber mesh elements to remove unused element IDs
4995 self.editor.RenumberElements()
4997 def _getIdSourceList(self, arg, idType, unRegister):
4999 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5001 if arg and isinstance( arg, list ):
5002 if isinstance( arg[0], int ):
5003 arg = self.GetIDSource( arg, idType )
5004 unRegister.set( arg )
5005 elif isinstance( arg[0], Mesh ):
5006 arg[0] = arg[0].GetMesh()
5007 elif isinstance( arg, Mesh ):
5009 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5013 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5014 MakeGroups=False, TotalAngle=False):
5016 Generate new elements by rotation of the given elements and nodes around the axis
5019 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5020 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5021 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5022 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5023 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5024 which defines angle in degrees
5025 NbOfSteps: the number of steps
5026 Tolerance: tolerance
5027 MakeGroups: forces the generation of new groups from existing ones
5028 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5029 of all steps, else - size of each step
5032 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5035 unRegister = genObjUnRegister()
5036 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5037 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5038 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5040 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5041 Axis = self.smeshpyD.GetAxisStruct( Axis )
5042 if isinstance( Axis, list ):
5043 Axis = SMESH.AxisStruct( *Axis )
5045 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5046 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5047 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5048 self.mesh.SetParameters(Parameters)
5049 if TotalAngle and NbOfSteps:
5050 AngleInRadians /= NbOfSteps
5051 return self.editor.RotationSweepObjects( nodes, edges, faces,
5052 Axis, AngleInRadians,
5053 NbOfSteps, Tolerance, MakeGroups)
5055 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5056 MakeGroups=False, TotalAngle=False):
5058 Generate new elements by rotation of the elements around the axis
5061 IDsOfElements: the list of ids of elements to sweep
5062 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5063 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5064 NbOfSteps: the number of steps
5065 Tolerance: tolerance
5066 MakeGroups: forces the generation of new groups from existing ones
5067 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5068 of all steps, else - size of each step
5071 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5074 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5075 AngleInRadians, NbOfSteps, Tolerance,
5076 MakeGroups, TotalAngle)
5078 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5079 MakeGroups=False, TotalAngle=False):
5081 Generate new elements by rotation of the elements of object around the axis
5082 theObject object which elements should be sweeped.
5083 It can be a mesh, a sub mesh or a group.
5086 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5087 AngleInRadians: the angle of Rotation
5088 NbOfSteps: number of steps
5089 Tolerance: tolerance
5090 MakeGroups: forces the generation of new groups from existing ones
5091 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5092 of all steps, else - size of each step
5095 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5098 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5099 AngleInRadians, NbOfSteps, Tolerance,
5100 MakeGroups, TotalAngle )
5102 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5103 MakeGroups=False, TotalAngle=False):
5105 Generate new elements by rotation of the elements of object around the axis
5106 theObject object which elements should be sweeped.
5107 It can be a mesh, a sub mesh or a group.
5110 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5111 AngleInRadians: the angle of Rotation
5112 NbOfSteps: number of steps
5113 Tolerance: tolerance
5114 MakeGroups: forces the generation of new groups from existing ones
5115 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5116 of all steps, else - size of each step
5119 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5120 empty list otherwise
5123 return self.RotationSweepObjects([],theObject,[], Axis,
5124 AngleInRadians, NbOfSteps, Tolerance,
5125 MakeGroups, TotalAngle)
5127 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5128 MakeGroups=False, TotalAngle=False):
5130 Generate new elements by rotation of the elements of object around the axis
5131 theObject object which elements should be sweeped.
5132 It can be a mesh, a sub mesh or a group.
5135 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5136 AngleInRadians: the angle of Rotation
5137 NbOfSteps: number of steps
5138 Tolerance: tolerance
5139 MakeGroups: forces the generation of new groups from existing ones
5140 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5141 of all steps, else - size of each step
5144 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5147 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5148 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5150 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5151 scaleFactors=[], linearVariation=False, basePoint=[] ):
5153 Generate new elements by extrusion of the given elements and nodes
5156 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5157 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5158 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5159 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5160 the direction and value of extrusion for one step (the total extrusion
5161 length will be NbOfSteps * ||StepVector||)
5162 NbOfSteps: the number of steps
5163 MakeGroups: forces the generation of new groups from existing ones
5164 scaleFactors: optional scale factors to apply during extrusion
5165 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5166 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5167 basePoint: optional scaling center; if not provided, a gravity center of
5168 nodes and elements being extruded is used as the scaling center.
5171 - a list of tree components of the point or
5175 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5177 Example: :ref:`tui_extrusion`
5179 unRegister = genObjUnRegister()
5180 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5181 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5182 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5184 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5185 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5186 if isinstance( StepVector, list ):
5187 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5189 if isinstance( basePoint, int):
5190 xyz = self.GetNodeXYZ( basePoint )
5192 raise RuntimeError("Invalid node ID: %s" % basePoint)
5194 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5195 basePoint = self.geompyD.PointCoordinates( basePoint )
5197 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5198 Parameters = StepVector.PS.parameters + var_separator + Parameters
5199 self.mesh.SetParameters(Parameters)
5201 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5202 StepVector, NbOfSteps,
5203 scaleFactors, linearVariation, basePoint,
5207 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5209 Generate new elements by extrusion of the elements with given ids
5212 IDsOfElements: the list of ids of elements or nodes for extrusion
5213 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5214 the direction and value of extrusion for one step (the total extrusion
5215 length will be NbOfSteps * ||StepVector||)
5216 NbOfSteps: the number of steps
5217 MakeGroups: forces the generation of new groups from existing ones
5218 IsNodes: is True if elements with given ids are nodes
5221 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5223 Example: :ref:`tui_extrusion`
5226 if IsNodes: n = IDsOfElements
5227 else : e,f, = IDsOfElements,IDsOfElements
5228 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5230 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5231 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5233 Generate new elements by extrusion along the normal to a discretized surface or wire
5236 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5237 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5238 StepSize: length of one extrusion step (the total extrusion
5239 length will be *NbOfSteps* *StepSize*).
5240 NbOfSteps: number of extrusion steps.
5241 ByAverageNormal: if True each node is translated by *StepSize*
5242 along the average of the normal vectors to the faces sharing the node;
5243 else each node is translated along the same average normal till
5244 intersection with the plane got by translation of the face sharing
5245 the node along its own normal by *StepSize*.
5246 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5247 for every node of *Elements*.
5248 MakeGroups: forces generation of new groups from existing ones.
5249 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5250 is not yet implemented. This parameter is used if *Elements* contains
5251 both faces and edges, i.e. *Elements* is a Mesh.
5254 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5255 empty list otherwise.
5256 Example: :ref:`tui_extrusion`
5259 unRegister = genObjUnRegister()
5260 if isinstance( Elements, Mesh ):
5261 Elements = [ Elements.GetMesh() ]
5262 if isinstance( Elements, list ):
5264 raise RuntimeError("Elements empty!")
5265 if isinstance( Elements[0], int ):
5266 Elements = self.GetIDSource( Elements, SMESH.ALL )
5267 unRegister.set( Elements )
5268 if not isinstance( Elements, list ):
5269 Elements = [ Elements ]
5270 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5271 self.mesh.SetParameters(Parameters)
5272 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5273 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5275 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5277 Generate new elements by extrusion of the elements or nodes which belong to the object
5280 theObject: the object whose elements or nodes should be processed.
5281 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5282 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5283 the direction and value of extrusion for one step (the total extrusion
5284 length will be NbOfSteps * ||StepVector||)
5285 NbOfSteps: the number of steps
5286 MakeGroups: forces the generation of new groups from existing ones
5287 IsNodes: is True if elements to extrude are nodes
5290 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5291 Example: :ref:`tui_extrusion`
5295 if IsNodes: n = theObject
5296 else : e,f, = theObject,theObject
5297 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5299 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5301 Generate new elements by extrusion of edges which belong to the object
5304 theObject: object whose 1D elements should be processed.
5305 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5306 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5307 the direction and value of extrusion for one step (the total extrusion
5308 length will be NbOfSteps * ||StepVector||)
5309 NbOfSteps: the number of steps
5310 MakeGroups: to generate new groups from existing ones
5313 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5314 Example: :ref:`tui_extrusion`
5317 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5319 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5321 Generate new elements by extrusion of faces which belong to the object
5324 theObject: object whose 2D elements should be processed.
5325 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5326 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5327 the direction and value of extrusion for one step (the total extrusion
5328 length will be NbOfSteps * ||StepVector||)
5329 NbOfSteps: the number of steps
5330 MakeGroups: forces the generation of new groups from existing ones
5333 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5334 Example: :ref:`tui_extrusion`
5337 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5339 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5340 ExtrFlags, SewTolerance, MakeGroups=False):
5342 Generate new elements by extrusion of the elements with given ids
5345 IDsOfElements: is ids of elements
5346 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5347 the direction and value of extrusion for one step (the total extrusion
5348 length will be NbOfSteps * ||StepVector||)
5349 NbOfSteps: the number of steps
5350 ExtrFlags: sets flags for extrusion
5351 SewTolerance: uses for comparing locations of nodes if flag
5352 EXTRUSION_FLAG_SEW is set
5353 MakeGroups: forces the generation of new groups from existing ones
5356 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5359 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5360 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5361 if isinstance( StepVector, list ):
5362 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5363 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5364 ExtrFlags, SewTolerance, MakeGroups)
5366 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5367 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5368 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5370 Generate new elements by extrusion of the given elements and nodes along the path.
5371 The path of extrusion must be a meshed edge.
5374 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5375 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5376 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5377 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5378 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5379 contains not only path segments, else it can be None
5380 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5381 HasAngles: allows the shape to be rotated around the path
5382 to get the resulting mesh in a helical fashion
5383 Angles: list of angles
5384 LinearVariation: forces the computation of rotation angles as linear
5385 variation of the given Angles along path steps
5386 HasRefPoint: allows using the reference point
5387 RefPoint: the reference point around which the shape is rotated (the mass center of the
5388 shape by default). The User can specify any point as the Reference Point.
5389 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5390 MakeGroups: forces the generation of new groups from existing ones
5393 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5394 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5395 Example: :ref:`tui_extrusion_along_path`
5398 unRegister = genObjUnRegister()
5399 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5400 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5401 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5403 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5404 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5405 if isinstance( RefPoint, list ):
5406 if not RefPoint: RefPoint = [0,0,0]
5407 RefPoint = SMESH.PointStruct( *RefPoint )
5408 if isinstance( PathMesh, Mesh ):
5409 PathMesh = PathMesh.GetMesh()
5410 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5411 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5412 self.mesh.SetParameters(Parameters)
5413 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5414 PathMesh, PathShape, NodeStart,
5415 HasAngles, Angles, LinearVariation,
5416 HasRefPoint, RefPoint, MakeGroups)
5418 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5419 HasAngles=False, Angles=[], LinearVariation=False,
5420 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5421 ElemType=SMESH.FACE):
5423 Generate new elements by extrusion of the given elements.
5424 The path of extrusion must be a meshed edge.
5427 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5428 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5429 NodeStart: the start node from Path. Defines the direction of extrusion
5430 HasAngles: allows the shape to be rotated around the path
5431 to get the resulting mesh in a helical fashion
5432 Angles: list of angles in radians
5433 LinearVariation: forces the computation of rotation angles as linear
5434 variation of the given Angles along path steps
5435 HasRefPoint: allows using the reference point
5436 RefPoint: the reference point around which the elements are rotated (the mass
5437 center of the elements by default).
5438 The User can specify any point as the Reference Point.
5439 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5440 MakeGroups: forces the generation of new groups from existing ones
5441 ElemType: type of elements for extrusion (if param Base is a mesh)
5444 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5445 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5446 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5448 Example: :ref:`tui_extrusion_along_path`
5452 if ElemType == SMESH.NODE: n = Base
5453 if ElemType == SMESH.EDGE: e = Base
5454 if ElemType == SMESH.FACE: f = Base
5455 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5456 HasAngles, Angles, LinearVariation,
5457 HasRefPoint, RefPoint, MakeGroups)
5458 if MakeGroups: return gr,er
5461 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5462 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5463 MakeGroups=False, LinearVariation=False):
5465 Generate new elements by extrusion of the given elements.
5466 The path of extrusion must be a meshed edge.
5469 IDsOfElements: ids of elements
5470 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5471 PathShape: shape (edge) defines the sub-mesh for the path
5472 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5473 HasAngles: allows the shape to be rotated around the path
5474 to get the resulting mesh in a helical fashion
5475 Angles: list of angles in radians
5476 HasRefPoint: allows using the reference point
5477 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5478 The User can specify any point as the Reference Point.
5479 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5480 MakeGroups: forces the generation of new groups from existing ones
5481 LinearVariation: forces the computation of rotation angles as linear
5482 variation of the given Angles along path steps
5485 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5486 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5487 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5488 Example: :ref:`tui_extrusion_along_path`
5491 n,e,f = [],IDsOfElements,IDsOfElements
5492 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5493 NodeStart, HasAngles, Angles,
5495 HasRefPoint, RefPoint, MakeGroups)
5496 if MakeGroups: return gr,er
5499 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5500 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5501 MakeGroups=False, LinearVariation=False):
5503 Generate new elements by extrusion of the elements which belong to the object.
5504 The path of extrusion must be a meshed edge.
5507 theObject: the object whose elements should be processed.
5508 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5509 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5510 PathShape: shape (edge) defines the sub-mesh for the path
5511 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5512 HasAngles: allows the shape to be rotated around the path
5513 to get the resulting mesh in a helical fashion
5514 Angles: list of angles
5515 HasRefPoint: allows using the reference point
5516 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5517 The User can specify any point as the Reference Point.
5518 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5519 MakeGroups: forces the generation of new groups from existing ones
5520 LinearVariation: forces the computation of rotation angles as linear
5521 variation of the given Angles along path steps
5524 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5525 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5526 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5527 Example: :ref:`tui_extrusion_along_path`
5530 n,e,f = [],theObject,theObject
5531 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5532 HasAngles, Angles, LinearVariation,
5533 HasRefPoint, RefPoint, MakeGroups)
5534 if MakeGroups: return gr,er
5537 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5538 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5539 MakeGroups=False, LinearVariation=False):
5541 Generate new elements by extrusion of mesh segments which belong to the object.
5542 The path of extrusion must be a meshed edge.
5545 theObject: the object whose 1D elements should be processed.
5546 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5547 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5548 PathShape: shape (edge) defines the sub-mesh for the path
5549 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5550 HasAngles: allows the shape to be rotated around the path
5551 to get the resulting mesh in a helical fashion
5552 Angles: list of angles
5553 HasRefPoint: allows using the reference point
5554 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5555 The User can specify any point as the Reference Point.
5556 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5557 MakeGroups: forces the generation of new groups from existing ones
5558 LinearVariation: forces the computation of rotation angles as linear
5559 variation of the given Angles along path steps
5562 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5563 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5564 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5565 Example: :ref:`tui_extrusion_along_path`
5568 n,e,f = [],theObject,[]
5569 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5570 HasAngles, Angles, LinearVariation,
5571 HasRefPoint, RefPoint, MakeGroups)
5572 if MakeGroups: return gr,er
5575 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5576 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5577 MakeGroups=False, LinearVariation=False):
5579 Generate new elements by extrusion of faces which belong to the object.
5580 The path of extrusion must be a meshed edge.
5583 theObject: the object whose 2D elements should be processed.
5584 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5585 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5586 PathShape: shape (edge) defines the sub-mesh for the path
5587 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5588 HasAngles: allows the shape to be rotated around the path
5589 to get the resulting mesh in a helical fashion
5590 Angles: list of angles
5591 HasRefPoint: allows using the reference point
5592 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5593 The User can specify any point as the Reference Point.
5594 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5595 MakeGroups: forces the generation of new groups from existing ones
5596 LinearVariation: forces the computation of rotation angles as linear
5597 variation of the given Angles along path steps
5600 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5601 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5602 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5603 Example: :ref:`tui_extrusion_along_path`
5606 n,e,f = [],[],theObject
5607 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5608 HasAngles, Angles, LinearVariation,
5609 HasRefPoint, RefPoint, MakeGroups)
5610 if MakeGroups: return gr,er
5613 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5615 Create a symmetrical copy of mesh elements
5618 IDsOfElements: list of elements ids
5619 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5620 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5621 If the *Mirror* is a geom object this parameter is unnecessary
5622 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5623 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5626 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5629 if IDsOfElements == []:
5630 IDsOfElements = self.GetElementsId()
5631 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5632 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5633 theMirrorType = Mirror._mirrorType
5635 self.mesh.SetParameters(Mirror.parameters)
5636 if Copy and MakeGroups:
5637 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5638 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5641 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5643 Create a new mesh by a symmetrical copy of mesh elements
5646 IDsOfElements: the list of elements ids
5647 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5648 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5649 If the *Mirror* is a geom object this parameter is unnecessary
5650 MakeGroups: to generate new groups from existing ones
5651 NewMeshName: a name of the new mesh to create
5654 instance of class :class:`Mesh`
5657 if IDsOfElements == []:
5658 IDsOfElements = self.GetElementsId()
5659 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5660 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5661 theMirrorType = Mirror._mirrorType
5663 self.mesh.SetParameters(Mirror.parameters)
5664 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5665 MakeGroups, NewMeshName)
5666 return Mesh(self.smeshpyD,self.geompyD,mesh)
5668 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5670 Create a symmetrical copy of the object
5673 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5674 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5675 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5676 If the *Mirror* is a geom object this parameter is unnecessary
5677 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5678 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5681 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5684 if ( isinstance( theObject, Mesh )):
5685 theObject = theObject.GetMesh()
5686 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5687 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5688 theMirrorType = Mirror._mirrorType
5690 self.mesh.SetParameters(Mirror.parameters)
5691 if Copy and MakeGroups:
5692 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5693 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5696 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5698 Create a new mesh by a symmetrical copy of the object
5701 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5702 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5703 theMirrorType: smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE.
5704 If the *Mirror* is a geom object this parameter is unnecessary
5705 MakeGroups: forces the generation of new groups from existing ones
5706 NewMeshName: the name of the new mesh to create
5709 instance of class :class:`Mesh`
5712 if ( isinstance( theObject, Mesh )):
5713 theObject = theObject.GetMesh()
5714 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5715 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5716 theMirrorType = Mirror._mirrorType
5718 self.mesh.SetParameters(Mirror.parameters)
5719 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5720 MakeGroups, NewMeshName)
5721 return Mesh( self.smeshpyD,self.geompyD,mesh )
5723 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5725 Translate the elements
5728 IDsOfElements: list of elements ids
5729 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5730 Copy: allows copying the translated elements
5731 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5734 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5737 if IDsOfElements == []:
5738 IDsOfElements = self.GetElementsId()
5739 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5740 Vector = self.smeshpyD.GetDirStruct(Vector)
5741 if isinstance( Vector, list ):
5742 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5743 self.mesh.SetParameters(Vector.PS.parameters)
5744 if Copy and MakeGroups:
5745 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5746 self.editor.Translate(IDsOfElements, Vector, Copy)
5749 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5751 Create a new mesh of translated elements
5754 IDsOfElements: list of elements ids
5755 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5756 MakeGroups: forces the generation of new groups from existing ones
5757 NewMeshName: the name of the newly created mesh
5760 instance of class :class:`Mesh`
5763 if IDsOfElements == []:
5764 IDsOfElements = self.GetElementsId()
5765 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5766 Vector = self.smeshpyD.GetDirStruct(Vector)
5767 if isinstance( Vector, list ):
5768 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5769 self.mesh.SetParameters(Vector.PS.parameters)
5770 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5771 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5773 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5775 Translate the object
5778 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5779 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5780 Copy: allows copying the translated elements
5781 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5784 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5787 if ( isinstance( theObject, Mesh )):
5788 theObject = theObject.GetMesh()
5789 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5790 Vector = self.smeshpyD.GetDirStruct(Vector)
5791 if isinstance( Vector, list ):
5792 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5793 self.mesh.SetParameters(Vector.PS.parameters)
5794 if Copy and MakeGroups:
5795 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5796 self.editor.TranslateObject(theObject, Vector, Copy)
5799 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5801 Create a new mesh from the translated object
5804 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5805 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5806 MakeGroups: forces the generation of new groups from existing ones
5807 NewMeshName: the name of the newly created mesh
5810 instance of class :class:`Mesh`
5813 if isinstance( theObject, Mesh ):
5814 theObject = theObject.GetMesh()
5815 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5816 Vector = self.smeshpyD.GetDirStruct(Vector)
5817 if isinstance( Vector, list ):
5818 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5819 self.mesh.SetParameters(Vector.PS.parameters)
5820 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5821 return Mesh( self.smeshpyD, self.geompyD, mesh )
5825 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5830 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5831 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5832 theScaleFact: list of 1-3 scale factors for axises
5833 Copy: allows copying the translated elements
5834 MakeGroups: forces the generation of new groups from existing
5838 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5839 empty list otherwise
5841 unRegister = genObjUnRegister()
5842 if ( isinstance( theObject, Mesh )):
5843 theObject = theObject.GetMesh()
5844 if ( isinstance( theObject, list )):
5845 theObject = self.GetIDSource(theObject, SMESH.ALL)
5846 unRegister.set( theObject )
5847 if ( isinstance( thePoint, list )):
5848 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5849 if ( isinstance( theScaleFact, float )):
5850 theScaleFact = [theScaleFact]
5851 if ( isinstance( theScaleFact, int )):
5852 theScaleFact = [ float(theScaleFact)]
5854 self.mesh.SetParameters(thePoint.parameters)
5856 if Copy and MakeGroups:
5857 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5858 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5861 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5863 Create a new mesh from the translated object
5866 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5867 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5868 theScaleFact: list of 1-3 scale factors for axises
5869 MakeGroups: forces the generation of new groups from existing ones
5870 NewMeshName: the name of the newly created mesh
5873 instance of class :class:`Mesh`
5875 unRegister = genObjUnRegister()
5876 if (isinstance(theObject, Mesh)):
5877 theObject = theObject.GetMesh()
5878 if ( isinstance( theObject, list )):
5879 theObject = self.GetIDSource(theObject,SMESH.ALL)
5880 unRegister.set( theObject )
5881 if ( isinstance( thePoint, list )):
5882 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5883 if ( isinstance( theScaleFact, float )):
5884 theScaleFact = [theScaleFact]
5885 if ( isinstance( theScaleFact, int )):
5886 theScaleFact = [ float(theScaleFact)]
5888 self.mesh.SetParameters(thePoint.parameters)
5889 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5890 MakeGroups, NewMeshName)
5891 return Mesh( self.smeshpyD, self.geompyD, mesh )
5895 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5900 IDsOfElements: list of elements ids
5901 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5902 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5903 Copy: allows copying the rotated elements
5904 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5907 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5911 if IDsOfElements == []:
5912 IDsOfElements = self.GetElementsId()
5913 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5914 Axis = self.smeshpyD.GetAxisStruct(Axis)
5915 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5916 Parameters = Axis.parameters + var_separator + Parameters
5917 self.mesh.SetParameters(Parameters)
5918 if Copy and MakeGroups:
5919 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5920 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5923 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5925 Create a new mesh of rotated elements
5928 IDsOfElements: list of element ids
5929 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5930 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5931 MakeGroups: forces the generation of new groups from existing ones
5932 NewMeshName: the name of the newly created mesh
5935 instance of class :class:`Mesh`
5938 if IDsOfElements == []:
5939 IDsOfElements = self.GetElementsId()
5940 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5941 Axis = self.smeshpyD.GetAxisStruct(Axis)
5942 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5943 Parameters = Axis.parameters + var_separator + Parameters
5944 self.mesh.SetParameters(Parameters)
5945 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
5946 MakeGroups, NewMeshName)
5947 return Mesh( self.smeshpyD, self.geompyD, mesh )
5949 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
5954 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5955 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5956 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5957 Copy: allows copying the rotated elements
5958 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5961 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
5964 if (isinstance(theObject, Mesh)):
5965 theObject = theObject.GetMesh()
5966 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5967 Axis = self.smeshpyD.GetAxisStruct(Axis)
5968 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5969 Parameters = Axis.parameters + ":" + Parameters
5970 self.mesh.SetParameters(Parameters)
5971 if Copy and MakeGroups:
5972 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
5973 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
5976 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
5978 Create a new mesh from the rotated object
5981 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5982 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5983 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5984 MakeGroups: forces the generation of new groups from existing ones
5985 NewMeshName: the name of the newly created mesh
5988 instance of class :class:`Mesh`
5991 if (isinstance( theObject, Mesh )):
5992 theObject = theObject.GetMesh()
5993 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5994 Axis = self.smeshpyD.GetAxisStruct(Axis)
5995 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5996 Parameters = Axis.parameters + ":" + Parameters
5997 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
5998 MakeGroups, NewMeshName)
5999 self.mesh.SetParameters(Parameters)
6000 return Mesh( self.smeshpyD, self.geompyD, mesh )
6002 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6004 Create an offset mesh from the given 2D object
6007 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6008 theValue (float): signed offset size
6009 MakeGroups (boolean): forces the generation of new groups from existing ones
6010 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6011 False means to remove original elements.
6012 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6015 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6018 if isinstance( theObject, Mesh ):
6019 theObject = theObject.GetMesh()
6020 theValue,Parameters,hasVars = ParseParameters(Value)
6021 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6022 self.mesh.SetParameters(Parameters)
6023 # if mesh_groups[0]:
6024 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6027 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6029 Find groups of adjacent nodes within Tolerance.
6032 Tolerance (float): the value of tolerance
6033 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6034 corner and medium nodes in separate groups thus preventing
6035 their further merge.
6038 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6041 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6043 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6044 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6046 Find groups of adjacent nodes within Tolerance.
6049 Tolerance: the value of tolerance
6050 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6051 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6052 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6053 corner and medium nodes in separate groups thus preventing
6054 their further merge.
6057 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6060 unRegister = genObjUnRegister()
6061 if (isinstance( SubMeshOrGroup, Mesh )):
6062 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6063 if not isinstance( exceptNodes, list ):
6064 exceptNodes = [ exceptNodes ]
6065 if exceptNodes and isinstance( exceptNodes[0], int ):
6066 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6067 unRegister.set( exceptNodes )
6068 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6069 exceptNodes, SeparateCornerAndMediumNodes)
6071 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6076 GroupsOfNodes: a list of groups of nodes IDs for merging.
6077 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6078 in all elements and groups by nodes 1 and 25 correspondingly
6079 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6080 If *NodesToKeep* does not include a node to keep for some group to merge,
6081 then the first node in the group is kept.
6082 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6085 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6086 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6088 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6090 Find the elements built on the same nodes.
6093 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6096 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6099 if not MeshOrSubMeshOrGroup:
6100 MeshOrSubMeshOrGroup=self.mesh
6101 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6102 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6103 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6105 def MergeElements(self, GroupsOfElementsID):
6107 Merge elements in each given group.
6110 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6111 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6112 replaced in all groups by elements 1 and 25)
6115 self.editor.MergeElements(GroupsOfElementsID)
6117 def MergeEqualElements(self):
6119 Leave one element and remove all other elements built on the same nodes.
6122 self.editor.MergeEqualElements()
6124 def FindFreeBorders(self, ClosedOnly=True):
6126 Returns all or only closed free borders
6129 list of SMESH.FreeBorder's
6132 return self.editor.FindFreeBorders( ClosedOnly )
6134 def FillHole(self, holeNodes):
6136 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6139 FreeBorder: either a SMESH.FreeBorder or a list on node IDs. These nodes
6140 must describe all sequential nodes of the hole border. The first and the last
6141 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6145 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6146 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6147 if not isinstance( holeNodes, SMESH.FreeBorder ):
6148 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6149 self.editor.FillHole( holeNodes )
6151 def FindCoincidentFreeBorders (self, tolerance=0.):
6153 Return groups of FreeBorder's coincident within the given tolerance.
6156 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6157 size of elements adjacent to free borders being compared is used.
6160 SMESH.CoincidentFreeBorders structure
6163 return self.editor.FindCoincidentFreeBorders( tolerance )
6165 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6167 Sew FreeBorder's of each group
6170 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6171 where each enclosed list contains node IDs of a group of coincident free
6172 borders such that each consequent triple of IDs within a group describes
6173 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6174 last node of a border.
6175 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6176 groups of coincident free borders, each group including two borders.
6177 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6178 polygons if a node of opposite border falls on a face edge, else such
6179 faces are split into several ones.
6180 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6181 polyhedra if a node of opposite border falls on a volume edge, else such
6182 volumes, if any, remain intact and the mesh becomes non-conformal.
6185 a number of successfully sewed groups
6188 if freeBorders and isinstance( freeBorders, list ):
6189 # construct SMESH.CoincidentFreeBorders
6190 if isinstance( freeBorders[0], int ):
6191 freeBorders = [freeBorders]
6193 coincidentGroups = []
6194 for nodeList in freeBorders:
6195 if not nodeList or len( nodeList ) % 3:
6196 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6199 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6200 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6201 nodeList = nodeList[3:]
6203 coincidentGroups.append( group )
6205 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6207 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6209 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6210 FirstNodeID2, SecondNodeID2, LastNodeID2,
6211 CreatePolygons, CreatePolyedrs):
6216 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6219 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6220 FirstNodeID2, SecondNodeID2, LastNodeID2,
6221 CreatePolygons, CreatePolyedrs)
6223 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6224 FirstNodeID2, SecondNodeID2):
6226 Sew conform free borders
6229 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6232 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6233 FirstNodeID2, SecondNodeID2)
6235 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6236 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6241 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6244 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6245 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6247 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6248 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6249 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6251 Sew two sides of a mesh. The nodes belonging to Side1 are
6252 merged with the nodes of elements of Side2.
6253 The number of elements in theSide1 and in theSide2 must be
6254 equal and they should have similar nodal connectivity.
6255 The nodes to merge should belong to side borders and
6256 the first node should be linked to the second.
6259 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6262 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6263 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6264 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6266 def ChangeElemNodes(self, ide, newIDs):
6268 Set new nodes for the given element.
6275 False if the number of nodes does not correspond to the type of element
6278 return self.editor.ChangeElemNodes(ide, newIDs)
6280 def GetLastCreatedNodes(self):
6282 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6283 created, this method return the list of their IDs.
6284 If new nodes were not created - return empty list
6287 the list of integer values (can be empty)
6290 return self.editor.GetLastCreatedNodes()
6292 def GetLastCreatedElems(self):
6294 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6295 created this method return the list of their IDs.
6296 If new elements were not created - return empty list
6299 the list of integer values (can be empty)
6302 return self.editor.GetLastCreatedElems()
6304 def ClearLastCreated(self):
6306 Forget what nodes and elements were created by the last mesh edition operation
6309 self.editor.ClearLastCreated()
6311 def DoubleElements(self, theElements, theGroupName=""):
6313 Create duplicates of given elements, i.e. create new elements based on the
6314 same nodes as the given ones.
6317 theElements: container of elements to duplicate. It can be a
6318 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6319 or a list of element IDs. If *theElements* is
6320 a :class:`Mesh`, elements of highest dimension are duplicated
6321 theGroupName: a name of group to contain the generated elements.
6322 If a group with such a name already exists, the new elements
6323 are added to the existing group, else a new group is created.
6324 If *theGroupName* is empty, new elements are not added
6328 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6329 None if *theGroupName* == "".
6332 unRegister = genObjUnRegister()
6333 if isinstance( theElements, Mesh ):
6334 theElements = theElements.mesh
6335 elif isinstance( theElements, list ):
6336 theElements = self.GetIDSource( theElements, SMESH.ALL )
6337 unRegister.set( theElements )
6338 return self.editor.DoubleElements(theElements, theGroupName)
6340 def DoubleNodes(self, theNodes, theModifiedElems):
6342 Create a hole in a mesh by doubling the nodes of some particular elements
6345 theNodes: IDs of nodes to be doubled
6346 theModifiedElems: IDs of elements to be updated by the new (doubled)
6347 nodes. If list of element identifiers is empty then nodes are doubled but
6348 they not assigned to elements
6351 True if operation has been completed successfully, False otherwise
6354 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6356 def DoubleNode(self, theNodeId, theModifiedElems):
6358 Create a hole in a mesh by doubling the nodes of some particular elements.
6359 This method provided for convenience works as :meth:`DoubleNodes`.
6362 theNodeId: IDs of node to double
6363 theModifiedElems: IDs of elements to update
6366 True if operation has been completed successfully, False otherwise
6369 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6371 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6373 Create a hole in a mesh by doubling the nodes of some particular elements.
6374 This method provided for convenience works as :meth:`DoubleNodes`.
6377 theNodes: group of nodes to double.
6378 theModifiedElems: group of elements to update.
6379 theMakeGroup: forces the generation of a group containing new nodes.
6382 True or a created group if operation has been completed successfully,
6383 False or None otherwise
6387 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6388 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6390 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6392 Create a hole in a mesh by doubling the nodes of some particular elements.
6393 This method provided for convenience works as :meth:`DoubleNodes`.
6396 theNodes: list of groups of nodes to double.
6397 theModifiedElems: list of groups of elements to update.
6398 theMakeGroup: forces the generation of a group containing new nodes.
6401 True if operation has been completed successfully, False otherwise
6405 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6406 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6408 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6410 Create a hole in a mesh by doubling the nodes of some particular elements
6413 theElems: the list of elements (edges or faces) to replicate.
6414 The nodes for duplication could be found from these elements
6415 theNodesNot: list of nodes NOT to replicate
6416 theAffectedElems: the list of elements (cells and edges) to which the
6417 replicated nodes should be associated to
6420 True if operation has been completed successfully, False otherwise
6423 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6425 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6427 Create a hole in a mesh by doubling the nodes of some particular elements
6430 theElems: the list of elements (edges or faces) to replicate.
6431 The nodes for duplication could be found from these elements
6432 theNodesNot: list of nodes NOT to replicate
6433 theShape: shape to detect affected elements (element which geometric center
6434 located on or inside shape).
6435 The replicated nodes should be associated to affected elements.
6438 True if operation has been completed successfully, False otherwise
6441 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6443 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6444 theMakeGroup=False, theMakeNodeGroup=False):
6446 Create a hole in a mesh by doubling the nodes of some particular elements.
6447 This method provided for convenience works as :meth:`DoubleNodes`.
6450 theElems: group of of elements (edges or faces) to replicate.
6451 theNodesNot: group of nodes NOT to replicate.
6452 theAffectedElems: group of elements to which the replicated nodes
6453 should be associated to.
6454 theMakeGroup: forces the generation of a group containing new elements.
6455 theMakeNodeGroup: forces the generation of a group containing new nodes.
6458 True or created groups (one or two) if operation has been completed successfully,
6459 False or None otherwise
6462 if theMakeGroup or theMakeNodeGroup:
6463 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6465 theMakeGroup, theMakeNodeGroup)
6466 if theMakeGroup and theMakeNodeGroup:
6469 return twoGroups[ int(theMakeNodeGroup) ]
6470 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6472 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6474 Create a hole in a mesh by doubling the nodes of some particular elements.
6475 This method provided for convenience works as :meth:`DoubleNodes`.
6478 theElems: group of of elements (edges or faces) to replicate
6479 theNodesNot: group of nodes not to replicate
6480 theShape: shape to detect affected elements (element which geometric center
6481 located on or inside shape).
6482 The replicated nodes should be associated to affected elements
6485 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6487 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6488 theMakeGroup=False, theMakeNodeGroup=False):
6490 Create a hole in a mesh by doubling the nodes of some particular elements.
6491 This method provided for convenience works as :meth:`DoubleNodes`.
6494 theElems: list of groups of elements (edges or faces) to replicate
6495 theNodesNot: list of groups of nodes NOT to replicate
6496 theAffectedElems: group of elements to which the replicated nodes
6497 should be associated to
6498 theMakeGroup: forces generation of a group containing new elements.
6499 theMakeNodeGroup: forces generation of a group containing new nodes
6502 True or created groups (one or two) if operation has been completed successfully,
6503 False or None otherwise
6506 if theMakeGroup or theMakeNodeGroup:
6507 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6509 theMakeGroup, theMakeNodeGroup)
6510 if theMakeGroup and theMakeNodeGroup:
6513 return twoGroups[ int(theMakeNodeGroup) ]
6514 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6516 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6518 Create a hole in a mesh by doubling the nodes of some particular elements.
6519 This method provided for convenience works as :meth:`DoubleNodes`.
6522 theElems: list of groups of elements (edges or faces) to replicate
6523 theNodesNot: list of groups of nodes NOT to replicate
6524 theShape: shape to detect affected elements (element which geometric center
6525 located on or inside shape).
6526 The replicated nodes should be associated to affected elements
6529 True if operation has been completed successfully, False otherwise
6532 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6534 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6536 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6537 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6540 theElems: list of groups of nodes or elements (edges or faces) to replicate
6541 theNodesNot: list of groups of nodes NOT to replicate
6542 theShape: shape to detect affected elements (element which geometric center
6543 located on or inside shape).
6544 The replicated nodes should be associated to affected elements
6547 groups of affected elements in order: volumes, faces, edges
6550 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6552 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6555 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6556 The list of groups must describe a partition of the mesh volumes.
6557 The nodes of the internal faces at the boundaries of the groups are doubled.
6558 In option, the internal faces are replaced by flat elements.
6559 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6562 theDomains: list of groups of volumes
6563 createJointElems: if True, create the elements
6564 onAllBoundaries: if True, the nodes and elements are also created on
6565 the boundary between *theDomains* and the rest mesh
6568 True if operation has been completed successfully, False otherwise
6571 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6573 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6575 Double nodes on some external faces and create flat elements.
6576 Flat elements are mainly used by some types of mechanic calculations.
6578 Each group of the list must be constituted of faces.
6579 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6582 theGroupsOfFaces: list of groups of faces
6585 True if operation has been completed successfully, False otherwise
6588 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6590 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6592 Identify all the elements around a geom shape, get the faces delimiting the hole
6594 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6596 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6598 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6599 the initial mesh. Positions of new nodes are found by cutting the mesh by the
6600 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6601 If there are several paths connecting a pair of points, the shortest path is
6602 selected by the module. Position of the cutting plane is defined by the two
6603 points and an optional vector lying on the plane specified by a PolySegment.
6604 By default the vector is defined by Mesh module as following. A middle point
6605 of the two given points is computed. The middle point is projected to the mesh.
6606 The vector goes from the middle point to the projection point. In case of planar
6607 mesh, the vector is normal to the mesh.
6609 *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6612 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6613 groupName: optional name of a group where created mesh segments will be added.
6616 editor = self.editor
6618 editor = self.mesh.GetMeshEditPreviewer()
6619 segmentsRes = editor.MakePolyLine( segments, groupName )
6620 for i, seg in enumerate( segmentsRes ):
6621 segments[i].vector = seg.vector
6623 return editor.GetPreviewData()
6626 def GetFunctor(self, funcType ):
6628 Return a cached numerical functor by its type.
6631 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6632 Note that not all items correspond to numerical functors.
6635 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6638 fn = self.functors[ funcType._v ]
6640 fn = self.smeshpyD.GetFunctor(funcType)
6641 fn.SetMesh(self.mesh)
6642 self.functors[ funcType._v ] = fn
6645 def FunctorValue(self, funcType, elemId, isElem=True):
6647 Return value of a functor for a given element
6650 funcType: an item of :class:`SMESH.FunctorType` enum.
6651 elemId: element or node ID
6652 isElem: *elemId* is ID of element or node
6655 the functor value or zero in case of invalid arguments
6658 fn = self.GetFunctor( funcType )
6659 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6660 val = fn.GetValue(elemId)
6665 def GetLength(self, elemId=None):
6667 Get length of 1D element or sum of lengths of all 1D mesh elements
6670 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6673 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6678 length = self.smeshpyD.GetLength(self)
6680 length = self.FunctorValue(SMESH.FT_Length, elemId)
6683 def GetArea(self, elemId=None):
6685 Get area of 2D element or sum of areas of all 2D mesh elements
6686 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6689 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6694 area = self.smeshpyD.GetArea(self)
6696 area = self.FunctorValue(SMESH.FT_Area, elemId)
6699 def GetVolume(self, elemId=None):
6701 Get volume of 3D element or sum of volumes of all 3D mesh elements
6704 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6707 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6712 volume = self.smeshpyD.GetVolume(self)
6714 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6717 def GetMaxElementLength(self, elemId):
6719 Get maximum element length.
6722 elemId: mesh element ID
6725 element's maximum length value
6728 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6729 ftype = SMESH.FT_MaxElementLength3D
6731 ftype = SMESH.FT_MaxElementLength2D
6732 return self.FunctorValue(ftype, elemId)
6734 def GetAspectRatio(self, elemId):
6736 Get aspect ratio of 2D or 3D element.
6739 elemId: mesh element ID
6742 element's aspect ratio value
6745 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6746 ftype = SMESH.FT_AspectRatio3D
6748 ftype = SMESH.FT_AspectRatio
6749 return self.FunctorValue(ftype, elemId)
6751 def GetWarping(self, elemId):
6753 Get warping angle of 2D element.
6756 elemId: mesh element ID
6759 element's warping angle value
6762 return self.FunctorValue(SMESH.FT_Warping, elemId)
6764 def GetMinimumAngle(self, elemId):
6766 Get minimum angle of 2D element.
6769 elemId: mesh element ID
6772 element's minimum angle value
6775 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6777 def GetTaper(self, elemId):
6779 Get taper of 2D element.
6782 elemId: mesh element ID
6785 element's taper value
6788 return self.FunctorValue(SMESH.FT_Taper, elemId)
6790 def GetSkew(self, elemId):
6792 Get skew of 2D element.
6795 elemId: mesh element ID
6798 element's skew value
6801 return self.FunctorValue(SMESH.FT_Skew, elemId)
6803 def GetMinMax(self, funType, meshPart=None):
6805 Return minimal and maximal value of a given functor.
6808 funType (SMESH.FunctorType): a functor type.
6809 Note that not all items of :class:`SMESH.FunctorType` corresponds
6810 to numerical functors.
6811 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6817 unRegister = genObjUnRegister()
6818 if isinstance( meshPart, list ):
6819 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6820 unRegister.set( meshPart )
6821 if isinstance( meshPart, Mesh ):
6822 meshPart = meshPart.mesh
6823 fun = self.GetFunctor( funType )
6826 if hasattr( meshPart, "SetMesh" ):
6827 meshPart.SetMesh( self.mesh ) # set mesh to filter
6828 hist = fun.GetLocalHistogram( 1, False, meshPart )
6830 hist = fun.GetHistogram( 1, False )
6832 return hist[0].min, hist[0].max
6835 pass # end of Mesh class
6838 class meshProxy(SMESH._objref_SMESH_Mesh):
6840 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6841 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6843 def __init__(self,*args):
6844 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6845 def __deepcopy__(self, memo=None):
6846 new = self.__class__(self)
6848 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6849 if len( args ) == 3:
6850 args += SMESH.ALL_NODES, True
6851 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6852 def ExportToMEDX(self, *args): # function removed
6853 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6854 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6855 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6856 def ExportToMED(self, *args): # function removed
6857 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6858 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6859 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6861 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6862 def ExportPartToMED(self, *args): # 'version' parameter removed
6863 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6864 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6865 def ExportMED(self, *args): # signature of method changed
6866 args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6867 while len(args) < 4: # !!!! nb of parameters for ExportToMED IDL's method
6869 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6871 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6874 class submeshProxy(SMESH._objref_SMESH_subMesh):
6877 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6879 def __init__(self,*args):
6880 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6882 def __deepcopy__(self, memo=None):
6883 new = self.__class__(self)
6886 def Compute(self,refresh=False):
6888 Compute the sub-mesh and return the status of the computation
6891 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6896 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6897 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6901 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6903 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6905 if salome.sg.hasDesktop():
6906 smeshgui = salome.ImportComponentGUI("SMESH")
6908 smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
6909 if refresh: salome.sg.updateObjBrowser()
6914 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6917 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6919 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6920 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6923 def __init__(self,*args):
6924 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6926 def __getattr__(self, name ): # method called if an attribute not found
6927 if not self.mesh: # look for name() method in Mesh class
6928 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6929 if hasattr( self.mesh, name ):
6930 return getattr( self.mesh, name )
6931 if name == "ExtrusionAlongPathObjX":
6932 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
6933 print("meshEditor: attribute '%s' NOT FOUND" % name)
6935 def __deepcopy__(self, memo=None):
6936 new = self.__class__(self)
6938 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
6939 if len( args ) == 1: args += False,
6940 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
6941 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
6942 if len( args ) == 2: args += False,
6943 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
6944 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
6945 if len( args ) == 1:
6946 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
6947 NodesToKeep = args[1]
6948 AvoidMakingHoles = args[2] if len( args ) == 3 else False
6949 unRegister = genObjUnRegister()
6951 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
6952 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
6953 if not isinstance( NodesToKeep, list ):
6954 NodesToKeep = [ NodesToKeep ]
6955 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
6957 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
6959 class Pattern(SMESH._objref_SMESH_Pattern):
6961 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
6962 variables in some methods
6965 def LoadFromFile(self, patternTextOrFile ):
6966 text = patternTextOrFile
6967 if os.path.exists( text ):
6968 text = open( patternTextOrFile ).read()
6970 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
6972 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
6973 decrFun = lambda i: i-1
6974 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
6975 theMesh.SetParameters(Parameters)
6976 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
6978 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
6979 decrFun = lambda i: i-1
6980 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
6981 theMesh.SetParameters(Parameters)
6982 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
6984 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
6985 if isinstance( mesh, Mesh ):
6986 mesh = mesh.GetMesh()
6987 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
6989 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
6991 Registering the new proxy for Pattern
6996 Private class used to bind methods creating algorithms to the class Mesh
6999 def __init__(self, method):
7001 self.defaultAlgoType = ""
7002 self.algoTypeToClass = {}
7003 self.method = method
7005 def add(self, algoClass):
7007 Store a python class of algorithm
7009 if inspect.isclass(algoClass) and \
7010 hasattr( algoClass, "algoType"):
7011 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7012 if not self.defaultAlgoType and \
7013 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7014 self.defaultAlgoType = algoClass.algoType
7015 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7017 def copy(self, mesh):
7019 Create a copy of self and assign mesh to the copy
7022 other = algoCreator( self.method )
7023 other.defaultAlgoType = self.defaultAlgoType
7024 other.algoTypeToClass = self.algoTypeToClass
7028 def __call__(self,algo="",geom=0,*args):
7030 Create an instance of algorithm
7034 if isinstance( algo, str ):
7036 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7037 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7042 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7044 elif not algoType and isinstance( geom, str ):
7049 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7051 elif isinstance( arg, str ) and not algoType:
7054 import traceback, sys
7055 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7056 sys.stderr.write( msg + '\n' )
7057 tb = traceback.extract_stack(None,2)
7058 traceback.print_list( [tb[0]] )
7060 algoType = self.defaultAlgoType
7061 if not algoType and self.algoTypeToClass:
7062 algoType = sorted( self.algoTypeToClass.keys() )[0]
7063 if algoType in self.algoTypeToClass:
7064 #print("Create algo",algoType)
7065 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7066 raise RuntimeError( "No class found for algo type %s" % algoType)
7069 class hypMethodWrapper:
7071 Private class used to substitute and store variable parameters of hypotheses.
7074 def __init__(self, hyp, method):
7076 self.method = method
7077 #print("REBIND:", method.__name__)
7080 def __call__(self,*args):
7082 call a method of hypothesis with calling SetVarParameter() before
7086 return self.method( self.hyp, *args ) # hypothesis method with no args
7088 #print("MethWrapper.__call__", self.method.__name__, args)
7090 parsed = ParseParameters(*args) # replace variables with their values
7091 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7092 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7093 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7094 # maybe there is a replaced string arg which is not variable
7095 result = self.method( self.hyp, *args )
7096 except ValueError as detail: # raised by ParseParameters()
7098 result = self.method( self.hyp, *args )
7099 except omniORB.CORBA.BAD_PARAM:
7100 raise ValueError(detail) # wrong variable name
7105 class genObjUnRegister:
7107 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7110 def __init__(self, genObj=None):
7111 self.genObjList = []
7115 def set(self, genObj):
7116 "Store one or a list of of SALOME.GenericObj'es"
7117 if isinstance( genObj, list ):
7118 self.genObjList.extend( genObj )
7120 self.genObjList.append( genObj )
7124 for genObj in self.genObjList:
7125 if genObj and hasattr( genObj, "UnRegister" ):
7128 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7130 Bind methods creating mesher plug-ins to the Mesh class
7133 # print("pluginName: ", pluginName)
7134 pluginBuilderName = pluginName + "Builder"
7136 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7137 except Exception as e:
7138 from salome_utils import verbose
7139 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7141 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7142 plugin = eval( pluginBuilderName )
7143 # print(" plugin:" , str(plugin))
7145 # add methods creating algorithms to Mesh
7146 for k in dir( plugin ):
7147 if k[0] == '_': continue
7148 algo = getattr( plugin, k )
7149 #print(" algo:", str(algo))
7150 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7151 #print(" meshMethod:" , str(algo.meshMethod))
7152 if not hasattr( Mesh, algo.meshMethod ):
7153 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7155 _mmethod = getattr( Mesh, algo.meshMethod )
7156 if hasattr( _mmethod, "add" ):