1 # Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def RemoveMesh( self, mesh ):
482 if isinstance( mesh, Mesh ):
483 mesh = mesh.GetMesh()
485 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
486 raise TypeError("%s is not a mesh" % mesh )
487 so = salome.ObjectToSObject( mesh )
489 sb = salome.myStudy.NewBuilder()
490 sb.RemoveObjectWithChildren( so )
496 def EnumToLong(self,theItem):
498 Return a long value from enumeration
503 def ColorToString(self,c):
505 Convert SALOMEDS.Color to string.
506 To be used with filters.
509 c: color value (SALOMEDS.Color)
512 a string representation of the color.
516 if isinstance(c, SALOMEDS.Color):
517 val = "%s;%s;%s" % (c.R, c.G, c.B)
518 elif isinstance(c, str):
521 raise ValueError("Color value should be of string or SALOMEDS.Color type")
524 def GetPointStruct(self,theVertex):
526 Get :class:`SMESH.PointStruct` from vertex
529 theVertex (GEOM.GEOM_Object): vertex
532 :class:`SMESH.PointStruct`
535 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
536 return PointStruct(x,y,z)
538 def GetDirStruct(self,theVector):
540 Get :class:`SMESH.DirStruct` from vector
543 theVector (GEOM.GEOM_Object): vector
546 :class:`SMESH.DirStruct`
549 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
550 if(len(vertices) != 2):
551 print("Error: vector object is incorrect.")
553 p1 = self.geompyD.PointCoordinates(vertices[0])
554 p2 = self.geompyD.PointCoordinates(vertices[1])
555 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
556 dirst = DirStruct(pnt)
559 def MakeDirStruct(self,x,y,z):
561 Make :class:`SMESH.DirStruct` from a triplet of floats
564 x,y,z (float): vector components
567 :class:`SMESH.DirStruct`
570 pnt = PointStruct(x,y,z)
571 return DirStruct(pnt)
573 def GetAxisStruct(self,theObj):
575 Get :class:`SMESH.AxisStruct` from a geometrical object
578 theObj (GEOM.GEOM_Object): line or plane
581 :class:`SMESH.AxisStruct`
584 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
587 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
589 vertex1 = self.geompyD.PointCoordinates(vertex1)
590 vertex2 = self.geompyD.PointCoordinates(vertex2)
591 vertex3 = self.geompyD.PointCoordinates(vertex3)
592 vertex4 = self.geompyD.PointCoordinates(vertex4)
593 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
594 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
595 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] ]
596 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
597 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
598 elif len(edges) == 1:
599 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
600 p1 = self.geompyD.PointCoordinates( vertex1 )
601 p2 = self.geompyD.PointCoordinates( vertex2 )
602 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
603 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
604 elif theObj.GetShapeType() == GEOM.VERTEX:
605 x,y,z = self.geompyD.PointCoordinates( theObj )
606 axis = AxisStruct( x,y,z, 1,0,0,)
607 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
610 # From SMESH_Gen interface:
611 # ------------------------
613 def SetName(self, obj, name):
615 Set the given name to an object
618 obj: the object to rename
619 name: a new object name
622 if isinstance( obj, Mesh ):
624 elif isinstance( obj, Mesh_Algorithm ):
625 obj = obj.GetAlgorithm()
626 ior = salome.orb.object_to_string(obj)
627 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
629 def SetEmbeddedMode( self,theMode ):
634 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
636 def IsEmbeddedMode(self):
641 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
643 def UpdateStudy( self, geompyD = None ):
645 Update the current study. Calling UpdateStudy() allows to
646 update meshes at switching GEOM->SMESH
650 from salome.geom import geomBuilder
651 geompyD = geomBuilder.geom
653 geompyD = geomBuilder.New()
656 self.SetGeomEngine(geompyD)
657 SMESH._objref_SMESH_Gen.UpdateStudy(self)
658 sb = salome.myStudy.NewBuilder()
659 sc = salome.myStudy.FindComponent("SMESH")
661 sb.LoadWith(sc, self)
664 def SetEnablePublish( self, theIsEnablePublish ):
666 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
667 switch **off** publishing in the Study of mesh objects.
669 #self.SetEnablePublish(theIsEnablePublish)
670 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
672 notebook = salome_notebook.NoteBook( theIsEnablePublish )
675 def CreateMeshesFromUNV( self,theFileName ):
677 Create a Mesh object importing data from the given UNV file
680 an instance of class :class:`Mesh`
683 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
684 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
687 def CreateMeshesFromMED( self,theFileName ):
689 Create a Mesh object(s) importing data from the given MED file
692 a tuple ( list of class :class:`Mesh` instances,
693 :class:`SMESH.DriverMED_ReadStatus` )
696 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
697 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
698 return aMeshes, aStatus
700 def CreateMeshesFromSAUV( self,theFileName ):
702 Create a Mesh object(s) importing data from the given SAUV file
705 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
708 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
709 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710 return aMeshes, aStatus
712 def CreateMeshesFromSTL( self, theFileName ):
714 Create a Mesh object importing data from the given STL file
717 an instance of class :class:`Mesh`
720 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
721 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
724 def CreateMeshesFromCGNS( self, theFileName ):
726 Create Mesh objects importing data from the given CGNS file
729 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
732 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
733 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
734 return aMeshes, aStatus
736 def CreateMeshesFromGMF( self, theFileName ):
738 Create a Mesh object importing data from the given GMF file.
739 GMF files must have .mesh extension for the ASCII format and .meshb for
743 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
746 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
749 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
750 return Mesh(self, self.geompyD, aSmeshMesh), error
752 def Concatenate( self, meshes, uniteIdenticalGroups,
753 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
754 name = "", meshToAppendTo = None):
756 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
757 All groups of input meshes will be present in the new mesh.
760 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
761 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
762 mergeNodesAndElements: if True, equal nodes and elements are merged
763 mergeTolerance: tolerance for merging nodes
764 allGroups: forces creation of groups corresponding to every input mesh
765 name: name of a new mesh
766 meshToAppendTo: a mesh to append all given meshes
769 an instance of class :class:`Mesh`
775 if not meshes: return None
776 if not isinstance( meshes, list ):
778 for i,m in enumerate( meshes ):
779 if isinstance( m, Mesh ):
780 meshes[i] = m.GetMesh()
781 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
782 if hasattr(meshes[0], "SetParameters"):
783 meshes[0].SetParameters( Parameters )
785 meshes[0].GetMesh().SetParameters( Parameters )
786 if isinstance( meshToAppendTo, Mesh ):
787 meshToAppendTo = meshToAppendTo.GetMesh()
789 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
790 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
791 mergeTolerance,meshToAppendTo )
793 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
794 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
795 mergeTolerance,meshToAppendTo )
797 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
800 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
802 Create a mesh by copying a part of another mesh.
805 meshPart: a part of mesh to copy, either
806 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
807 To copy nodes or elements not forming any mesh object,
808 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
809 meshName: a name of the new mesh
810 toCopyGroups: to create in the new mesh groups the copied elements belongs to
811 toKeepIDs: to preserve order of the copied elements or not
814 an instance of class :class:`Mesh`
817 if isinstance( meshPart, Mesh ):
818 meshPart = meshPart.GetMesh()
819 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
820 return Mesh(self, self.geompyD, mesh)
822 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
823 toReuseHypotheses=True, toCopyElements=True):
825 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
826 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
827 To facilitate and speed up the operation, consider using
828 "Set presentation parameters and sub-shapes from arguments" option in
829 a dialog of geometrical operation used to create the new geometry.
832 sourceMesh: the mesh to copy definition of.
833 newGeom: the new geometry.
834 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
835 toCopyGroups: to create groups in the new mesh.
836 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
837 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
840 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
841 *invalidEntries* are study entries of objects whose
842 counterparts are not found in the *newGeom*, followed by entries
843 of mesh sub-objects that are invalid because they depend on a not found
846 if isinstance( sourceMesh, Mesh ):
847 sourceMesh = sourceMesh.GetMesh()
849 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
850 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
854 return ( ok, Mesh(self, self.geompyD, newMesh),
855 newGroups, newSubMeshes, newHypotheses, invalidEntries )
857 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
859 Return IDs of sub-shapes
862 theMainObject (GEOM.GEOM_Object): a shape
863 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
865 the list of integer values
868 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
870 def GetPattern(self):
872 Create a pattern mapper.
875 an instance of :class:`SMESH.SMESH_Pattern`
877 :ref:`Example of Patterns usage <tui_pattern_mapping>`
880 return SMESH._objref_SMESH_Gen.GetPattern(self)
882 def SetBoundaryBoxSegmentation(self, nbSegments):
884 Set number of segments per diagonal of boundary box of geometry, by which
885 default segment length of appropriate 1D hypotheses is defined in GUI.
889 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
891 # Filtering. Auxiliary functions:
892 # ------------------------------
894 def GetEmptyCriterion(self):
896 Create an empty criterion
899 :class:`SMESH.Filter.Criterion`
902 Type = self.EnumToLong(FT_Undefined)
903 Compare = self.EnumToLong(FT_Undefined)
907 UnaryOp = self.EnumToLong(FT_Undefined)
908 BinaryOp = self.EnumToLong(FT_Undefined)
911 Precision = -1 ##@1e-07
912 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
913 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
915 def GetCriterion(self,elementType,
917 Compare = FT_EqualTo,
919 UnaryOp=FT_Undefined,
920 BinaryOp=FT_Undefined,
923 Create a criterion by the given parameters
924 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
927 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
928 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
929 Note that the items starting from FT_LessThan are not suitable for *CritType*.
930 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
931 Threshold: the threshold value (range of ids as string, shape, numeric)
932 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
933 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
935 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
936 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
939 :class:`SMESH.Filter.Criterion`
941 Example: :ref:`combining_filters`
944 if not CritType in SMESH.FunctorType._items:
945 raise TypeError("CritType should be of SMESH.FunctorType")
946 aCriterion = self.GetEmptyCriterion()
947 aCriterion.TypeOfElement = elementType
948 aCriterion.Type = self.EnumToLong(CritType)
949 aCriterion.Tolerance = Tolerance
951 aThreshold = Threshold
953 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
954 aCriterion.Compare = self.EnumToLong(Compare)
955 elif Compare == "=" or Compare == "==":
956 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
958 aCriterion.Compare = self.EnumToLong(FT_LessThan)
960 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
961 elif Compare != FT_Undefined:
962 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
965 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
966 FT_BelongToCylinder, FT_LyingOnGeom]:
967 # Check that Threshold is GEOM object
968 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
969 aCriterion.ThresholdStr = GetName(aThreshold)
970 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
971 if not aCriterion.ThresholdID:
972 name = aCriterion.ThresholdStr
974 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
975 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
976 # or a name of GEOM object
977 elif isinstance( aThreshold, str ):
978 aCriterion.ThresholdStr = aThreshold
980 raise TypeError("The Threshold should be a shape.")
981 if isinstance(UnaryOp,float):
982 aCriterion.Tolerance = UnaryOp
983 UnaryOp = FT_Undefined
985 elif CritType == FT_BelongToMeshGroup:
986 # Check that Threshold is a group
987 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
988 if aThreshold.GetType() != elementType:
989 raise ValueError("Group type mismatches Element type")
990 aCriterion.ThresholdStr = aThreshold.GetName()
991 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
992 study = salome.myStudy
994 so = study.FindObjectIOR( aCriterion.ThresholdID )
998 aCriterion.ThresholdID = entry
1000 raise TypeError("The Threshold should be a Mesh Group")
1001 elif CritType == FT_RangeOfIds:
1002 # Check that Threshold is string
1003 if isinstance(aThreshold, str):
1004 aCriterion.ThresholdStr = aThreshold
1006 raise TypeError("The Threshold should be a string.")
1007 elif CritType == FT_CoplanarFaces:
1008 # Check the Threshold
1009 if isinstance(aThreshold, int):
1010 aCriterion.ThresholdID = str(aThreshold)
1011 elif isinstance(aThreshold, str):
1012 ID = int(aThreshold)
1014 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1015 aCriterion.ThresholdID = aThreshold
1017 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1018 elif CritType == FT_ConnectedElements:
1019 # Check the Threshold
1020 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1021 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1022 if not aCriterion.ThresholdID:
1023 name = aThreshold.GetName()
1025 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1026 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1027 elif isinstance(aThreshold, int): # node id
1028 aCriterion.Threshold = aThreshold
1029 elif isinstance(aThreshold, list): # 3 point coordinates
1030 if len( aThreshold ) < 3:
1031 raise ValueError("too few point coordinates, must be 3")
1032 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1033 elif isinstance(aThreshold, str):
1034 if aThreshold.isdigit():
1035 aCriterion.Threshold = aThreshold # node id
1037 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1039 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1040 "or a list of point coordinates and not '%s'"%aThreshold)
1041 elif CritType == FT_ElemGeomType:
1042 # Check the Threshold
1044 aCriterion.Threshold = self.EnumToLong(aThreshold)
1045 assert( aThreshold in SMESH.GeometryType._items )
1047 if isinstance(aThreshold, int):
1048 aCriterion.Threshold = aThreshold
1050 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1053 elif CritType == FT_EntityType:
1054 # Check the Threshold
1056 aCriterion.Threshold = self.EnumToLong(aThreshold)
1057 assert( aThreshold in SMESH.EntityType._items )
1059 if isinstance(aThreshold, int):
1060 aCriterion.Threshold = aThreshold
1062 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1066 elif CritType == FT_GroupColor:
1067 # Check the Threshold
1069 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1071 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1073 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1074 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1075 FT_BareBorderFace, FT_BareBorderVolume,
1076 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1077 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1078 # At this point the Threshold is unnecessary
1079 if aThreshold == FT_LogicalNOT:
1080 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1081 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1082 aCriterion.BinaryOp = aThreshold
1086 aThreshold = float(aThreshold)
1087 aCriterion.Threshold = aThreshold
1089 raise TypeError("The Threshold should be a number.")
1092 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1093 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1095 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1096 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1098 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1099 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1101 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1102 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1106 def GetFilter(self,elementType,
1107 CritType=FT_Undefined,
1110 UnaryOp=FT_Undefined,
1114 Create a filter with the given parameters
1117 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1118 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1119 Note that the items starting from FT_LessThan are not suitable for CritType.
1120 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1121 Threshold: the threshold value (range of ids as string, shape, numeric)
1122 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1123 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1124 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1125 mesh: the mesh to initialize the filter with
1128 :class:`SMESH.Filter`
1131 See :doc:`Filters usage examples <tui_filters>`
1134 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1135 aFilterMgr = self.CreateFilterManager()
1136 aFilter = aFilterMgr.CreateFilter()
1138 aCriteria.append(aCriterion)
1139 aFilter.SetCriteria(aCriteria)
1141 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1142 else : aFilter.SetMesh( mesh )
1143 aFilterMgr.UnRegister()
1146 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1148 Create a filter from criteria
1151 criteria: a list of :class:`SMESH.Filter.Criterion`
1152 binOp: binary operator used when binary operator of criteria is undefined
1155 :class:`SMESH.Filter`
1158 See :doc:`Filters usage examples <tui_filters>`
1161 for i in range( len( criteria ) - 1 ):
1162 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1163 criteria[i].BinaryOp = self.EnumToLong( binOp )
1164 aFilterMgr = self.CreateFilterManager()
1165 aFilter = aFilterMgr.CreateFilter()
1166 aFilter.SetCriteria(criteria)
1167 aFilterMgr.UnRegister()
1170 def GetFunctor(self,theCriterion):
1172 Create a numerical functor by its type
1175 theCriterion (SMESH.FunctorType): functor type.
1176 Note that not all items correspond to numerical functors.
1179 :class:`SMESH.NumericalFunctor`
1182 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1184 aFilterMgr = self.CreateFilterManager()
1186 if theCriterion == FT_AspectRatio:
1187 functor = aFilterMgr.CreateAspectRatio()
1188 elif theCriterion == FT_AspectRatio3D:
1189 functor = aFilterMgr.CreateAspectRatio3D()
1190 elif theCriterion == FT_Warping:
1191 functor = aFilterMgr.CreateWarping()
1192 elif theCriterion == FT_MinimumAngle:
1193 functor = aFilterMgr.CreateMinimumAngle()
1194 elif theCriterion == FT_Taper:
1195 functor = aFilterMgr.CreateTaper()
1196 elif theCriterion == FT_Skew:
1197 functor = aFilterMgr.CreateSkew()
1198 elif theCriterion == FT_Area:
1199 functor = aFilterMgr.CreateArea()
1200 elif theCriterion == FT_Volume3D:
1201 functor = aFilterMgr.CreateVolume3D()
1202 elif theCriterion == FT_MaxElementLength2D:
1203 functor = aFilterMgr.CreateMaxElementLength2D()
1204 elif theCriterion == FT_MaxElementLength3D:
1205 functor = aFilterMgr.CreateMaxElementLength3D()
1206 elif theCriterion == FT_MultiConnection:
1207 functor = aFilterMgr.CreateMultiConnection()
1208 elif theCriterion == FT_MultiConnection2D:
1209 functor = aFilterMgr.CreateMultiConnection2D()
1210 elif theCriterion == FT_Length:
1211 functor = aFilterMgr.CreateLength()
1212 elif theCriterion == FT_Length2D:
1213 functor = aFilterMgr.CreateLength2D()
1214 elif theCriterion == FT_Length3D:
1215 functor = aFilterMgr.CreateLength3D()
1216 elif theCriterion == FT_Deflection2D:
1217 functor = aFilterMgr.CreateDeflection2D()
1218 elif theCriterion == FT_NodeConnectivityNumber:
1219 functor = aFilterMgr.CreateNodeConnectivityNumber()
1220 elif theCriterion == FT_BallDiameter:
1221 functor = aFilterMgr.CreateBallDiameter()
1223 print("Error: given parameter is not numerical functor type.")
1224 aFilterMgr.UnRegister()
1227 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1232 theHType (string): mesh hypothesis type
1233 theLibName (string): mesh plug-in library name
1236 created hypothesis instance
1238 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1240 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1243 # wrap hypothesis methods
1244 for meth_name in dir( hyp.__class__ ):
1245 if not meth_name.startswith("Get") and \
1246 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1247 method = getattr ( hyp.__class__, meth_name )
1248 if callable(method):
1249 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1253 def GetMeshInfo(self, obj):
1255 Get the mesh statistic.
1258 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1261 if isinstance( obj, Mesh ):
1264 if hasattr(obj, "GetMeshInfo"):
1265 values = obj.GetMeshInfo()
1266 for i in range(SMESH.Entity_Last._v):
1267 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1271 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1273 Get minimum distance between two objects
1275 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1276 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1279 src1 (SMESH.SMESH_IDSource): first source object
1280 src2 (SMESH.SMESH_IDSource): second source object
1281 id1 (int): node/element id from the first source
1282 id2 (int): node/element id from the second (or first) source
1283 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1284 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1287 minimum distance value
1290 :meth:`GetMinDistance`
1293 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1297 result = result.value
1300 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1302 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1304 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1305 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1308 src1 (SMESH.SMESH_IDSource): first source object
1309 src2 (SMESH.SMESH_IDSource): second source object
1310 id1 (int): node/element id from the first source
1311 id2 (int): node/element id from the second (or first) source
1312 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1313 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1316 :class:`SMESH.Measure` structure or None if input data is invalid
1321 if isinstance(src1, Mesh): src1 = src1.mesh
1322 if isinstance(src2, Mesh): src2 = src2.mesh
1323 if src2 is None and id2 != 0: src2 = src1
1324 if not hasattr(src1, "_narrow"): return None
1325 src1 = src1._narrow(SMESH.SMESH_IDSource)
1326 if not src1: return None
1327 unRegister = genObjUnRegister()
1330 e = m.GetMeshEditor()
1332 src1 = e.MakeIDSource([id1], SMESH.FACE)
1334 src1 = e.MakeIDSource([id1], SMESH.NODE)
1335 unRegister.set( src1 )
1337 if hasattr(src2, "_narrow"):
1338 src2 = src2._narrow(SMESH.SMESH_IDSource)
1339 if src2 and id2 != 0:
1341 e = m.GetMeshEditor()
1343 src2 = e.MakeIDSource([id2], SMESH.FACE)
1345 src2 = e.MakeIDSource([id2], SMESH.NODE)
1346 unRegister.set( src2 )
1349 aMeasurements = self.CreateMeasurements()
1350 unRegister.set( aMeasurements )
1351 result = aMeasurements.MinDistance(src1, src2)
1354 def BoundingBox(self, objects):
1356 Get bounding box of the specified object(s)
1359 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1362 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1365 :meth:`GetBoundingBox`
1368 result = self.GetBoundingBox(objects)
1372 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1375 def GetBoundingBox(self, objects):
1377 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1380 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1383 :class:`SMESH.Measure` structure
1389 if isinstance(objects, tuple):
1390 objects = list(objects)
1391 if not isinstance(objects, list):
1395 if isinstance(o, Mesh):
1396 srclist.append(o.mesh)
1397 elif hasattr(o, "_narrow"):
1398 src = o._narrow(SMESH.SMESH_IDSource)
1399 if src: srclist.append(src)
1402 aMeasurements = self.CreateMeasurements()
1403 result = aMeasurements.BoundingBox(srclist)
1404 aMeasurements.UnRegister()
1407 def GetLength(self, obj):
1409 Get sum of lengths of all 1D elements in the mesh object.
1412 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1415 sum of lengths of all 1D elements
1418 if isinstance(obj, Mesh): obj = obj.mesh
1419 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1420 aMeasurements = self.CreateMeasurements()
1421 value = aMeasurements.Length(obj)
1422 aMeasurements.UnRegister()
1425 def GetArea(self, obj):
1427 Get sum of areas of all 2D elements in the mesh object.
1430 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1433 sum of areas of all 2D elements
1436 if isinstance(obj, Mesh): obj = obj.mesh
1437 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438 aMeasurements = self.CreateMeasurements()
1439 value = aMeasurements.Area(obj)
1440 aMeasurements.UnRegister()
1443 def GetVolume(self, obj):
1445 Get sum of volumes of all 3D elements in the mesh object.
1448 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1451 sum of volumes of all 3D elements
1454 if isinstance(obj, Mesh): obj = obj.mesh
1455 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1456 aMeasurements = self.CreateMeasurements()
1457 value = aMeasurements.Volume(obj)
1458 aMeasurements.UnRegister()
1461 def GetGravityCenter(self, obj):
1463 Get gravity center of all nodes of a mesh object.
1466 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1469 Three components of the gravity center (x,y,z)
1472 :meth:`Mesh.BaryCenter`
1474 if isinstance(obj, Mesh): obj = obj.mesh
1475 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476 aMeasurements = self.CreateMeasurements()
1477 pointStruct = aMeasurements.GravityCenter(obj)
1478 aMeasurements.UnRegister()
1479 return pointStruct.x, pointStruct.y, pointStruct.z
1481 def GetAngle(self, p1, p2, p3 ):
1483 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1486 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1492 if isinstance( p1, list ): p1 = PointStruct(*p1)
1493 if isinstance( p2, list ): p2 = PointStruct(*p2)
1494 if isinstance( p3, list ): p3 = PointStruct(*p3)
1496 aMeasurements = self.CreateMeasurements()
1497 angle = aMeasurements.Angle(p1,p2,p3)
1498 aMeasurements.UnRegister()
1503 pass # end of class smeshBuilder
1506 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1507 """Registering the new proxy for SMESH.SMESH_Gen"""
1510 def New( instance=None, instanceGeom=None):
1512 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1513 interface to create or load meshes.
1518 salome.salome_init()
1519 from salome.smesh import smeshBuilder
1520 smesh = smeshBuilder.New()
1523 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1524 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1526 :class:`smeshBuilder` instance
1531 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1533 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1538 smeshInst = smeshBuilder()
1539 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1540 smeshInst.init_smesh(instanceGeom)
1544 # Public class: Mesh
1545 # ==================
1548 class Mesh(metaclass = MeshMeta):
1550 This class allows defining and managing a mesh.
1551 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1552 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1553 new nodes and elements and by changing the existing entities), to get information
1554 about a mesh and to export a mesh in different formats.
1561 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1566 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1567 sets the GUI name of this mesh to *name*.
1570 smeshpyD: an instance of smeshBuilder class
1571 geompyD: an instance of geomBuilder class
1572 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1573 name: Study name of the mesh
1576 self.smeshpyD = smeshpyD
1577 self.geompyD = geompyD
1582 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1585 # publish geom of mesh (issue 0021122)
1586 if not self.geom.GetStudyEntry():
1590 geo_name = name + " shape"
1592 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1593 geompyD.addToStudy( self.geom, geo_name )
1594 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1596 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1599 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1601 self.smeshpyD.SetName(self.mesh, name)
1603 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1606 self.geom = self.mesh.GetShapeToMesh()
1608 self.editor = self.mesh.GetMeshEditor()
1609 self.functors = [None] * SMESH.FT_Undefined._v
1611 # set self to algoCreator's
1612 for attrName in dir(self):
1613 attr = getattr( self, attrName )
1614 if isinstance( attr, algoCreator ):
1615 setattr( self, attrName, attr.copy( self ))
1622 Destructor. Clean-up resources
1625 #self.mesh.UnRegister()
1629 def SetMesh(self, theMesh):
1631 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1634 theMesh: a :class:`SMESH.SMESH_Mesh` object
1638 # do not call Register() as this prevents mesh servant deletion at closing study
1639 #if self.mesh: self.mesh.UnRegister()
1642 #self.mesh.Register()
1643 self.geom = self.mesh.GetShapeToMesh()
1648 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1651 a :class:`SMESH.SMESH_Mesh` object
1656 def GetEngine(self):
1658 Return a smeshBuilder instance created this mesh
1660 return self.smeshpyD
1662 def GetGeomEngine(self):
1664 Return a geomBuilder instance
1670 Get the name of the mesh
1673 the name of the mesh as a string
1676 name = GetName(self.GetMesh())
1679 def SetName(self, name):
1681 Set a name to the mesh
1684 name: a new name of the mesh
1687 self.smeshpyD.SetName(self.GetMesh(), name)
1689 def GetSubMesh(self, geom, name):
1691 Get a sub-mesh object associated to a *geom* geometrical object.
1694 geom: a geometrical object (shape)
1695 name: a name for the sub-mesh in the Object Browser
1698 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1699 which lies on the given shape
1702 A sub-mesh is implicitly created when a sub-shape is specified at
1703 creating an algorithm, for example::
1705 algo1D = mesh.Segment(geom=Edge_1)
1707 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1708 The created sub-mesh can be retrieved from the algorithm::
1710 submesh = algo1D.GetSubMesh()
1713 AssureGeomPublished( self, geom, name )
1714 submesh = self.mesh.GetSubMesh( geom, name )
1719 Return the shape associated to the mesh
1727 def SetShape(self, geom):
1729 Associate the given shape to the mesh (entails the recreation of the mesh)
1732 geom: the shape to be meshed (GEOM_Object)
1735 self.mesh = self.smeshpyD.CreateMesh(geom)
1737 def HasShapeToMesh(self):
1739 Return ``True`` if this mesh is based on geometry
1741 return self.mesh.HasShapeToMesh()
1745 Load mesh from the study after opening the study
1749 def IsReadyToCompute(self, theSubObject):
1751 Return true if the hypotheses are defined well
1754 theSubObject: a sub-shape of a mesh shape
1760 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1762 def GetAlgoState(self, theSubObject):
1764 Return errors of hypotheses definition.
1765 The list of errors is empty if everything is OK.
1768 theSubObject: a sub-shape of a mesh shape
1774 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1776 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1778 Return a geometrical object on which the given element was built.
1779 The returned geometrical object, if not nil, is either found in the
1780 study or published by this method with the given name
1783 theElementID: the id of the mesh element
1784 theGeomName: the user-defined name of the geometrical object
1787 GEOM.GEOM_Object instance
1790 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1792 def MeshDimension(self):
1794 Return the mesh dimension depending on the dimension of the underlying shape
1795 or, if the mesh is not based on any shape, basing on deimension of elements
1798 mesh dimension as an integer value [0,3]
1801 if self.mesh.HasShapeToMesh():
1802 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1803 if len( shells ) > 0 :
1805 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1807 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1812 if self.NbVolumes() > 0: return 3
1813 if self.NbFaces() > 0: return 2
1814 if self.NbEdges() > 0: return 1
1817 def Evaluate(self, geom=0):
1819 Evaluate size of prospective mesh on a shape
1822 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1823 To know predicted number of e.g. edges, inquire it this way::
1825 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1828 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1830 geom = self.mesh.GetShapeToMesh()
1833 return self.smeshpyD.Evaluate(self.mesh, geom)
1836 def Compute(self, geom=0, discardModifs=False, refresh=False):
1838 Compute the mesh and return the status of the computation
1841 geom: geomtrical shape on which mesh data should be computed
1842 discardModifs: if True and the mesh has been edited since
1843 a last total re-compute and that may prevent successful partial re-compute,
1844 then the mesh is cleaned before Compute()
1845 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1851 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1853 geom = self.mesh.GetShapeToMesh()
1858 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1860 ok = self.smeshpyD.Compute(self.mesh, geom)
1861 except SALOME.SALOME_Exception as ex:
1862 print("Mesh computation failed, exception caught:")
1863 print(" ", ex.details.text)
1866 print("Mesh computation failed, exception caught:")
1867 traceback.print_exc()
1871 # Treat compute errors
1872 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1874 for err in computeErrors:
1875 if self.mesh.HasShapeToMesh():
1876 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1878 stdErrors = ["OK", #COMPERR_OK
1879 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1880 "std::exception", #COMPERR_STD_EXCEPTION
1881 "OCC exception", #COMPERR_OCC_EXCEPTION
1882 "..", #COMPERR_SLM_EXCEPTION
1883 "Unknown exception", #COMPERR_EXCEPTION
1884 "Memory allocation problem", #COMPERR_MEMORY_PB
1885 "Algorithm failed", #COMPERR_ALGO_FAILED
1886 "Unexpected geometry", #COMPERR_BAD_SHAPE
1887 "Warning", #COMPERR_WARNING
1888 "Computation cancelled",#COMPERR_CANCELED
1889 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1891 if err.code < len(stdErrors): errText = stdErrors[err.code]
1893 errText = "code %s" % -err.code
1894 if errText: errText += ". "
1895 errText += err.comment
1896 if allReasons: allReasons += "\n"
1898 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1900 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1904 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1906 if err.isGlobalAlgo:
1914 reason = '%s %sD algorithm is missing' % (glob, dim)
1915 elif err.state == HYP_MISSING:
1916 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1917 % (glob, dim, name, dim))
1918 elif err.state == HYP_NOTCONFORM:
1919 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1920 elif err.state == HYP_BAD_PARAMETER:
1921 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1922 % ( glob, dim, name ))
1923 elif err.state == HYP_BAD_GEOMETRY:
1924 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1925 'geometry' % ( glob, dim, name ))
1926 elif err.state == HYP_HIDDEN_ALGO:
1927 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1928 'algorithm of upper dimension generating %sD mesh'
1929 % ( glob, dim, name, glob, dim ))
1931 reason = ("For unknown reason. "
1932 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1934 if allReasons: allReasons += "\n"
1935 allReasons += "- " + reason
1937 if not ok or allReasons != "":
1938 msg = '"' + GetName(self.mesh) + '"'
1939 if ok: msg += " has been computed with warnings"
1940 else: msg += " has not been computed"
1941 if allReasons != "": msg += ":"
1946 if salome.sg.hasDesktop():
1947 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1948 if refresh: salome.sg.updateObjBrowser()
1952 def GetComputeErrors(self, shape=0 ):
1954 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1958 shape = self.mesh.GetShapeToMesh()
1959 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1961 def GetSubShapeName(self, subShapeID ):
1963 Return a name of a sub-shape by its ID.
1964 Possible variants (for *subShapeID* == 3):
1966 - **"Face_12"** - published sub-shape
1967 - **FACE #3** - not published sub-shape
1968 - **sub-shape #3** - invalid sub-shape ID
1969 - **#3** - error in this function
1972 subShapeID: a unique ID of a sub-shape
1975 a string describing the sub-shape
1979 if not self.mesh.HasShapeToMesh():
1983 mainIOR = salome.orb.object_to_string( self.GetShape() )
1985 mainSO = s.FindObjectIOR(mainIOR)
1988 shapeText = '"%s"' % mainSO.GetName()
1989 subIt = s.NewChildIterator(mainSO)
1991 subSO = subIt.Value()
1993 obj = subSO.GetObject()
1994 if not obj: continue
1995 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1998 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2001 if ids == subShapeID:
2002 shapeText = '"%s"' % subSO.GetName()
2005 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2007 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2009 shapeText = 'sub-shape #%s' % (subShapeID)
2011 shapeText = "#%s" % (subShapeID)
2014 def GetFailedShapes(self, publish=False):
2016 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2017 error of an algorithm
2020 publish: if *True*, the returned groups will be published in the study
2023 a list of GEOM groups each named after a failed algorithm
2028 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2029 for err in computeErrors:
2030 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2031 if not shape: continue
2032 if err.algoName in algo2shapes:
2033 algo2shapes[ err.algoName ].append( shape )
2035 algo2shapes[ err.algoName ] = [ shape ]
2039 for algoName, shapes in list(algo2shapes.items()):
2041 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2042 otherTypeShapes = []
2044 group = self.geompyD.CreateGroup( self.geom, groupType )
2045 for shape in shapes:
2046 if shape.GetShapeType() == shapes[0].GetShapeType():
2047 sameTypeShapes.append( shape )
2049 otherTypeShapes.append( shape )
2050 self.geompyD.UnionList( group, sameTypeShapes )
2052 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2054 group.SetName( algoName )
2055 groups.append( group )
2056 shapes = otherTypeShapes
2059 for group in groups:
2060 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2063 def GetMeshOrder(self):
2065 Return sub-mesh objects list in meshing order
2068 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2071 return self.mesh.GetMeshOrder()
2073 def SetMeshOrder(self, submeshes):
2075 Set priority of sub-meshes. It works in two ways:
2077 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2078 *several dimensions*, it sets the order in which the sub-meshes are computed.
2079 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2080 when looking for meshing parameters to apply to a sub-shape. To impose the
2081 order in which sub-meshes with uni-dimensional algorithms are computed,
2082 call **submesh.Compute()** in a desired order.
2085 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2088 return self.mesh.SetMeshOrder(submeshes)
2090 def Clear(self, refresh=False):
2092 Remove all nodes and elements generated on geometry. Imported elements remain.
2095 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2099 if ( salome.sg.hasDesktop() ):
2100 if refresh: salome.sg.updateObjBrowser()
2102 def ClearSubMesh(self, geomId, refresh=False):
2104 Remove all nodes and elements of indicated shape
2107 geomId: the ID of a sub-shape to remove elements on
2108 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2111 self.mesh.ClearSubMesh(geomId)
2112 if salome.sg.hasDesktop():
2113 if refresh: salome.sg.updateObjBrowser()
2115 def AutomaticTetrahedralization(self, fineness=0):
2117 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2120 fineness: [0.0,1.0] defines mesh fineness
2126 dim = self.MeshDimension()
2128 self.RemoveGlobalHypotheses()
2129 self.Segment().AutomaticLength(fineness)
2131 self.Triangle().LengthFromEdges()
2136 return self.Compute()
2138 def AutomaticHexahedralization(self, fineness=0):
2140 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2143 fineness: [0.0, 1.0] defines mesh fineness
2149 dim = self.MeshDimension()
2150 # assign the hypotheses
2151 self.RemoveGlobalHypotheses()
2152 self.Segment().AutomaticLength(fineness)
2159 return self.Compute()
2161 def AddHypothesis(self, hyp, geom=0):
2166 hyp: a hypothesis to assign
2167 geom: a subhape of mesh geometry
2170 :class:`SMESH.Hypothesis_Status`
2173 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2174 hyp, geom = geom, hyp
2175 if isinstance( hyp, Mesh_Algorithm ):
2176 hyp = hyp.GetAlgorithm()
2181 geom = self.mesh.GetShapeToMesh()
2184 if self.mesh.HasShapeToMesh():
2185 hyp_type = hyp.GetName()
2186 lib_name = hyp.GetLibName()
2187 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2188 # if checkAll and geom:
2189 # checkAll = geom.GetType() == 37
2191 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2193 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2194 status = self.mesh.AddHypothesis(geom, hyp)
2196 status = HYP_BAD_GEOMETRY, ""
2197 hyp_name = GetName( hyp )
2200 geom_name = geom.GetName()
2201 isAlgo = hyp._narrow( SMESH_Algo )
2202 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2205 def IsUsedHypothesis(self, hyp, geom):
2207 Return True if an algorithm or hypothesis is assigned to a given shape
2210 hyp: an algorithm or hypothesis to check
2211 geom: a subhape of mesh geometry
2217 if not hyp: # or not geom
2219 if isinstance( hyp, Mesh_Algorithm ):
2220 hyp = hyp.GetAlgorithm()
2222 hyps = self.GetHypothesisList(geom)
2224 if h.GetId() == hyp.GetId():
2228 def RemoveHypothesis(self, hyp, geom=0):
2230 Unassign a hypothesis
2233 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2234 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2237 :class:`SMESH.Hypothesis_Status`
2242 if isinstance( hyp, Mesh_Algorithm ):
2243 hyp = hyp.GetAlgorithm()
2249 if self.IsUsedHypothesis( hyp, shape ):
2250 return self.mesh.RemoveHypothesis( shape, hyp )
2251 hypName = GetName( hyp )
2252 geoName = GetName( shape )
2253 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2256 def GetHypothesisList(self, geom):
2258 Get the list of hypotheses added on a geometry
2261 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2264 the sequence of :class:`SMESH.SMESH_Hypothesis`
2267 return self.mesh.GetHypothesisList( geom )
2269 def RemoveGlobalHypotheses(self):
2271 Remove all global hypotheses
2274 current_hyps = self.mesh.GetHypothesisList( self.geom )
2275 for hyp in current_hyps:
2276 self.mesh.RemoveHypothesis( self.geom, hyp )
2279 def ExportMED(self, *args, **kwargs):
2281 Export the mesh in a file in MED format
2282 allowing to overwrite the file if it exists or add the exported data to its contents
2285 fileName: is the file name
2286 auto_groups (boolean): parameter for creating/not creating
2287 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2288 the typical use is auto_groups=False.
2289 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2290 The minor must be between 0 and the current minor version of MED file library.
2291 If minor is equal to -1, the minor version is not changed (default).
2292 The major version (x, where version is x.y.z) cannot be changed.
2293 overwrite (boolean): parameter for overwriting/not overwriting the file
2294 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2295 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2297 - 1D if all mesh nodes lie on OX coordinate axis, or
2298 - 2D if all mesh nodes lie on XOY coordinate plane, or
2299 - 3D in the rest cases.
2301 If *autoDimension* is *False*, the space dimension is always 3.
2302 fields: list of GEOM fields defined on the shape to mesh.
2303 geomAssocFields: each character of this string means a need to export a
2304 corresponding field; correspondence between fields and characters
2307 - 'v' stands for "_vertices_" field;
2308 - 'e' stands for "_edges_" field;
2309 - 'f' stands for "_faces_" field;
2310 - 's' stands for "_solids_" field.
2312 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2313 close to zero within a given tolerance, the coordinate is set to zero.
2314 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2316 # process positional arguments
2317 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2319 auto_groups = args[1] if len(args) > 1 else False
2320 minor = args[2] if len(args) > 2 else -1
2321 overwrite = args[3] if len(args) > 3 else True
2322 meshPart = args[4] if len(args) > 4 else None
2323 autoDimension = args[5] if len(args) > 5 else True
2324 fields = args[6] if len(args) > 6 else []
2325 geomAssocFields = args[7] if len(args) > 7 else ''
2326 z_tolerance = args[8] if len(args) > 8 else -1.
2327 # process keywords arguments
2328 auto_groups = kwargs.get("auto_groups", auto_groups)
2329 minor = kwargs.get("minor", minor)
2330 overwrite = kwargs.get("overwrite", overwrite)
2331 meshPart = kwargs.get("meshPart", meshPart)
2332 autoDimension = kwargs.get("autoDimension", autoDimension)
2333 fields = kwargs.get("fields", fields)
2334 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2335 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2337 # invoke engine's function
2338 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2339 unRegister = genObjUnRegister()
2340 if isinstance( meshPart, list ):
2341 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2342 unRegister.set( meshPart )
2344 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2345 self.mesh.SetParameters(Parameters)
2347 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2348 fields, geomAssocFields, z_tolerance)
2350 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2352 def ExportSAUV(self, f, auto_groups=0):
2354 Export the mesh in a file in SAUV format
2359 auto_groups: boolean parameter for creating/not creating
2360 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2361 the typical use is auto_groups=False.
2364 self.mesh.ExportSAUV(f, auto_groups)
2366 def ExportDAT(self, f, meshPart=None):
2368 Export the mesh in a file in DAT format
2372 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2376 unRegister = genObjUnRegister()
2377 if isinstance( meshPart, list ):
2378 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2379 unRegister.set( meshPart )
2380 self.mesh.ExportPartToDAT( meshPart, f )
2382 self.mesh.ExportDAT(f)
2384 def ExportUNV(self, f, meshPart=None):
2386 Export the mesh in a file in UNV format
2390 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2394 unRegister = genObjUnRegister()
2395 if isinstance( meshPart, list ):
2396 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2397 unRegister.set( meshPart )
2398 self.mesh.ExportPartToUNV( meshPart, f )
2400 self.mesh.ExportUNV(f)
2402 def ExportSTL(self, f, ascii=1, meshPart=None):
2404 Export the mesh in a file in STL format
2408 ascii: defines the file encoding
2409 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2413 unRegister = genObjUnRegister()
2414 if isinstance( meshPart, list ):
2415 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2416 unRegister.set( meshPart )
2417 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2419 self.mesh.ExportSTL(f, ascii)
2421 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2423 Export the mesh in a file in CGNS format
2427 overwrite: boolean parameter for overwriting/not overwriting the file
2428 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2429 groupElemsByType: if True all elements of same entity type are exported at ones,
2430 else elements are exported in order of their IDs which can cause creation
2431 of multiple cgns sections
2434 unRegister = genObjUnRegister()
2435 if isinstance( meshPart, list ):
2436 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2437 unRegister.set( meshPart )
2438 if isinstance( meshPart, Mesh ):
2439 meshPart = meshPart.mesh
2441 meshPart = self.mesh
2442 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2444 def ExportGMF(self, f, meshPart=None):
2446 Export the mesh in a file in GMF format.
2447 GMF files must have .mesh extension for the ASCII format and .meshb for
2448 the bynary format. Other extensions are not allowed.
2452 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2455 unRegister = genObjUnRegister()
2456 if isinstance( meshPart, list ):
2457 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2458 unRegister.set( meshPart )
2459 if isinstance( meshPart, Mesh ):
2460 meshPart = meshPart.mesh
2462 meshPart = self.mesh
2463 self.mesh.ExportGMF(meshPart, f, True)
2465 def ExportToMED(self, *args, **kwargs):
2467 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2468 Export the mesh in a file in MED format
2469 allowing to overwrite the file if it exists or add the exported data to its contents
2472 fileName: the file name
2473 opt (boolean): parameter for creating/not creating
2474 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2475 overwrite: boolean parameter for overwriting/not overwriting the file
2476 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2478 - 1D if all mesh nodes lie on OX coordinate axis, or
2479 - 2D if all mesh nodes lie on XOY coordinate plane, or
2480 - 3D in the rest cases.
2482 If **autoDimension** is *False*, the space dimension is always 3.
2485 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2486 # process positional arguments
2487 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2489 auto_groups = args[1] if len(args) > 1 else False
2490 overwrite = args[2] if len(args) > 2 else True
2491 autoDimension = args[3] if len(args) > 3 else True
2492 # process keywords arguments
2493 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2494 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2495 overwrite = kwargs.get("overwrite", overwrite)
2496 autoDimension = kwargs.get("autoDimension", autoDimension)
2498 # invoke engine's function
2499 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2501 def ExportToMEDX(self, *args, **kwargs):
2503 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2504 Export the mesh in a file in MED format
2507 fileName: the file name
2508 opt (boolean): parameter for creating/not creating
2509 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2510 overwrite: boolean parameter for overwriting/not overwriting the file
2511 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2513 - 1D if all mesh nodes lie on OX coordinate axis, or
2514 - 2D if all mesh nodes lie on XOY coordinate plane, or
2515 - 3D in the rest cases.
2517 If **autoDimension** is *False*, the space dimension is always 3.
2520 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2521 # process positional arguments
2522 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2524 auto_groups = args[1] if len(args) > 1 else False
2525 overwrite = args[2] if len(args) > 2 else True
2526 autoDimension = args[3] if len(args) > 3 else True
2527 # process keywords arguments
2528 auto_groups = kwargs.get("auto_groups", auto_groups)
2529 overwrite = kwargs.get("overwrite", overwrite)
2530 autoDimension = kwargs.get("autoDimension", autoDimension)
2532 # invoke engine's function
2533 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2537 def Append(self, meshes, uniteIdenticalGroups = True,
2538 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2540 Append given meshes into this mesh.
2541 All groups of input meshes will be created in this mesh.
2544 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2545 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2546 mergeNodesAndElements: if True, equal nodes and elements are merged
2547 mergeTolerance: tolerance for merging nodes
2548 allGroups: forces creation of groups corresponding to every input mesh
2550 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2551 mergeNodesAndElements, mergeTolerance, allGroups,
2552 meshToAppendTo = self.GetMesh() )
2554 # Operations with groups:
2555 # ----------------------
2556 def CreateEmptyGroup(self, elementType, name):
2558 Create an empty standalone mesh group
2561 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2562 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2563 name: the name of the mesh group
2566 :class:`SMESH.SMESH_Group`
2569 return self.mesh.CreateGroup(elementType, name)
2571 def Group(self, grp, name=""):
2573 Create a mesh group based on the geometric object *grp*
2574 and give it a *name*.
2575 If *name* is not defined the name of the geometric group is used
2578 Works like :meth:`GroupOnGeom`.
2581 grp: a geometric group, a vertex, an edge, a face or a solid
2582 name: the name of the mesh group
2585 :class:`SMESH.SMESH_GroupOnGeom`
2588 return self.GroupOnGeom(grp, name)
2590 def GroupOnGeom(self, grp, name="", typ=None):
2592 Create a mesh group based on the geometrical object *grp*
2593 and give it a *name*.
2594 if *name* is not defined the name of the geometric group is used
2597 grp: a geometrical group, a vertex, an edge, a face or a solid
2598 name: the name of the mesh group
2599 typ: the type of elements in the group; either of
2600 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2601 automatically detected by the type of the geometry
2604 :class:`SMESH.SMESH_GroupOnGeom`
2607 AssureGeomPublished( self, grp, name )
2609 name = grp.GetName()
2611 typ = self._groupTypeFromShape( grp )
2612 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2614 def _groupTypeFromShape( self, shape ):
2616 Pivate method to get a type of group on geometry
2618 tgeo = str(shape.GetShapeType())
2619 if tgeo == "VERTEX":
2621 elif tgeo == "EDGE":
2623 elif tgeo == "FACE" or tgeo == "SHELL":
2625 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2627 elif tgeo == "COMPOUND":
2628 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2630 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2631 return self._groupTypeFromShape( sub[0] )
2633 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2636 def GroupOnFilter(self, typ, name, filter):
2638 Create a mesh group with given *name* based on the *filter*.
2639 It is a special type of group dynamically updating it's contents during
2643 typ: the type of elements in the group; either of
2644 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2645 name: the name of the mesh group
2646 filter (SMESH.Filter): the filter defining group contents
2649 :class:`SMESH.SMESH_GroupOnFilter`
2652 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2654 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2656 Create a mesh group by the given ids of elements
2659 groupName: the name of the mesh group
2660 elementType: the type of elements in the group; either of
2661 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2662 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2665 :class:`SMESH.SMESH_Group`
2668 group = self.mesh.CreateGroup(elementType, groupName)
2669 if isinstance( elemIDs, Mesh ):
2670 elemIDs = elemIDs.GetMesh()
2671 if hasattr( elemIDs, "GetIDs" ):
2672 if hasattr( elemIDs, "SetMesh" ):
2673 elemIDs.SetMesh( self.GetMesh() )
2674 group.AddFrom( elemIDs )
2682 CritType=FT_Undefined,
2685 UnaryOp=FT_Undefined,
2688 Create a mesh group by the given conditions
2691 groupName: the name of the mesh group
2692 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2693 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2694 Note that the items starting from FT_LessThan are not suitable for CritType.
2695 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2696 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2697 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2698 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2699 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2702 :class:`SMESH.SMESH_GroupOnFilter`
2705 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2706 group = self.MakeGroupByCriterion(groupName, aCriterion)
2709 def MakeGroupByCriterion(self, groupName, Criterion):
2711 Create a mesh group by the given criterion
2714 groupName: the name of the mesh group
2715 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2718 :class:`SMESH.SMESH_GroupOnFilter`
2721 :meth:`smeshBuilder.GetCriterion`
2724 return self.MakeGroupByCriteria( groupName, [Criterion] )
2726 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2728 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2731 groupName: the name of the mesh group
2732 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2733 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2736 :class:`SMESH.SMESH_GroupOnFilter`
2739 :meth:`smeshBuilder.GetCriterion`
2742 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2743 group = self.MakeGroupByFilter(groupName, aFilter)
2746 def MakeGroupByFilter(self, groupName, theFilter):
2748 Create a mesh group by the given filter
2751 groupName (string): the name of the mesh group
2752 theFilter (SMESH.Filter): the filter
2755 :class:`SMESH.SMESH_GroupOnFilter`
2758 :meth:`smeshBuilder.GetFilter`
2761 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2762 #theFilter.SetMesh( self.mesh )
2763 #group.AddFrom( theFilter )
2764 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2767 def RemoveGroup(self, group):
2772 group (SMESH.SMESH_GroupBase): group to remove
2775 self.mesh.RemoveGroup(group)
2777 def RemoveGroupWithContents(self, group):
2779 Remove a group with its contents
2782 group (SMESH.SMESH_GroupBase): group to remove
2785 This operation can create gaps in numeration of nodes or elements.
2786 Call :meth:`RenumberElements` to remove the gaps.
2789 self.mesh.RemoveGroupWithContents(group)
2791 def GetGroups(self, elemType = SMESH.ALL):
2793 Get the list of groups existing in the mesh in the order of creation
2794 (starting from the oldest one)
2797 elemType (SMESH.ElementType): type of elements the groups contain;
2798 by default groups of elements of all types are returned
2801 a list of :class:`SMESH.SMESH_GroupBase`
2804 groups = self.mesh.GetGroups()
2805 if elemType == SMESH.ALL:
2809 if g.GetType() == elemType:
2810 typedGroups.append( g )
2817 Get the number of groups existing in the mesh
2820 the quantity of groups as an integer value
2823 return self.mesh.NbGroups()
2825 def GetGroupNames(self):
2827 Get the list of names of groups existing in the mesh
2833 groups = self.GetGroups()
2835 for group in groups:
2836 names.append(group.GetName())
2839 def GetGroupByName(self, name, elemType = None):
2841 Find groups by name and type
2844 name (string): name of the group of interest
2845 elemType (SMESH.ElementType): type of elements the groups contain;
2846 by default one group of any type is returned;
2847 if elemType == SMESH.ALL then all groups of any type are returned
2850 a list of :class:`SMESH.SMESH_GroupBase`
2854 for group in self.GetGroups():
2855 if group.GetName() == name:
2856 if elemType is None:
2858 if ( elemType == SMESH.ALL or
2859 group.GetType() == elemType ):
2860 groups.append( group )
2863 def UnionGroups(self, group1, group2, name):
2865 Produce a union of two groups.
2866 A new group is created. All mesh elements that are
2867 present in the initial groups are added to the new one
2870 group1 (SMESH.SMESH_GroupBase): a group
2871 group2 (SMESH.SMESH_GroupBase): another group
2874 instance of :class:`SMESH.SMESH_Group`
2877 return self.mesh.UnionGroups(group1, group2, name)
2879 def UnionListOfGroups(self, groups, name):
2881 Produce a union list of groups.
2882 New group is created. All mesh elements that are present in
2883 initial groups are added to the new one
2886 groups: list of :class:`SMESH.SMESH_GroupBase`
2889 instance of :class:`SMESH.SMESH_Group`
2891 return self.mesh.UnionListOfGroups(groups, name)
2893 def IntersectGroups(self, group1, group2, name):
2895 Prodice an intersection of two groups.
2896 A new group is created. All mesh elements that are common
2897 for the two initial groups are added to the new one.
2900 group1 (SMESH.SMESH_GroupBase): a group
2901 group2 (SMESH.SMESH_GroupBase): another group
2904 instance of :class:`SMESH.SMESH_Group`
2907 return self.mesh.IntersectGroups(group1, group2, name)
2909 def IntersectListOfGroups(self, groups, name):
2911 Produce an intersection of groups.
2912 New group is created. All mesh elements that are present in all
2913 initial groups simultaneously are added to the new one
2916 groups: a list of :class:`SMESH.SMESH_GroupBase`
2919 instance of :class:`SMESH.SMESH_Group`
2921 return self.mesh.IntersectListOfGroups(groups, name)
2923 def CutGroups(self, main_group, tool_group, name):
2925 Produce a cut of two groups.
2926 A new group is created. All mesh elements that are present in
2927 the main group but are not present in the tool group are added to the new one
2930 main_group (SMESH.SMESH_GroupBase): a group to cut from
2931 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2934 an instance of :class:`SMESH.SMESH_Group`
2937 return self.mesh.CutGroups(main_group, tool_group, name)
2939 def CutListOfGroups(self, main_groups, tool_groups, name):
2941 Produce a cut of groups.
2942 A new group is created. All mesh elements that are present in main groups
2943 but do not present in tool groups are added to the new one
2946 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2947 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2950 an instance of :class:`SMESH.SMESH_Group`
2953 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2955 def CreateDimGroup(self, groups, elemType, name,
2956 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2958 Create a standalone group of entities basing on nodes of other groups.
2961 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2962 elemType: a type of elements to include to the new group; either of
2963 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2964 name: a name of the new group.
2965 nbCommonNodes: a criterion of inclusion of an element to the new group
2966 basing on number of element nodes common with reference *groups*.
2967 Meaning of possible values are:
2969 - SMESH.ALL_NODES - include if all nodes are common,
2970 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2971 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2972 - SMEHS.MAJORITY - include if half of nodes or more are common.
2973 underlyingOnly: if *True* (default), an element is included to the
2974 new group provided that it is based on nodes of an element of *groups*;
2975 in this case the reference *groups* are supposed to be of higher dimension
2976 than *elemType*, which can be useful for example to get all faces lying on
2977 volumes of the reference *groups*.
2980 an instance of :class:`SMESH.SMESH_Group`
2983 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2985 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2987 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2989 Distribute all faces of the mesh among groups using sharp edges and optionally
2990 existing 1D elements as group boundaries.
2993 sharpAngle: edge is considered sharp if an angle between normals of
2994 adjacent faces is more than \a sharpAngle in degrees.
2995 createEdges (boolean): to create 1D elements for detected sharp edges.
2996 useExistingEdges (boolean): to use existing edges as group boundaries
2998 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3000 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3001 self.mesh.SetParameters(Parameters)
3002 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3004 def ConvertToStandalone(self, group):
3006 Convert group on geom into standalone group
3009 return self.mesh.ConvertToStandalone(group)
3011 # Get some info about mesh:
3012 # ------------------------
3014 def GetLog(self, clearAfterGet):
3016 Return the log of nodes and elements added or removed
3017 since the previous clear of the log.
3020 clearAfterGet: log is emptied after Get (safe if concurrents access)
3023 list of SMESH.log_block structures { commandType, number, coords, indexes }
3026 return self.mesh.GetLog(clearAfterGet)
3030 Clear the log of nodes and elements added or removed since the previous
3031 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3034 self.mesh.ClearLog()
3036 def SetAutoColor(self, theAutoColor):
3038 Toggle auto color mode on the object.
3039 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3042 theAutoColor (boolean): the flag which toggles auto color mode.
3045 self.mesh.SetAutoColor(theAutoColor)
3047 def GetAutoColor(self):
3049 Get flag of object auto color mode.
3055 return self.mesh.GetAutoColor()
3062 integer value, which is the internal Id of the mesh
3065 return self.mesh.GetId()
3067 def HasDuplicatedGroupNamesMED(self):
3069 Check the group names for duplications.
3070 Consider the maximum group name length stored in MED file.
3076 return self.mesh.HasDuplicatedGroupNamesMED()
3078 def GetMeshEditor(self):
3080 Obtain the mesh editor tool
3083 an instance of :class:`SMESH.SMESH_MeshEditor`
3088 def GetIDSource(self, ids, elemType = SMESH.ALL):
3090 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3091 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3095 elemType: type of elements; this parameter is used to distinguish
3096 IDs of nodes from IDs of elements; by default ids are treated as
3097 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3100 an instance of :class:`SMESH.SMESH_IDSource`
3103 call UnRegister() for the returned object as soon as it is no more useful::
3105 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3106 mesh.DoSomething( idSrc )
3110 if isinstance( ids, int ):
3112 return self.editor.MakeIDSource(ids, elemType)
3115 # Get information about mesh contents:
3116 # ------------------------------------
3118 def GetMeshInfo(self, obj = None):
3120 Get the mesh statistic.
3123 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3126 if not obj: obj = self.mesh
3127 return self.smeshpyD.GetMeshInfo(obj)
3131 Return the number of nodes in the mesh
3137 return self.mesh.NbNodes()
3139 def NbElements(self):
3141 Return the number of elements in the mesh
3147 return self.mesh.NbElements()
3149 def Nb0DElements(self):
3151 Return the number of 0d elements in the mesh
3157 return self.mesh.Nb0DElements()
3161 Return the number of ball discrete elements in the mesh
3167 return self.mesh.NbBalls()
3171 Return the number of edges in the mesh
3177 return self.mesh.NbEdges()
3179 def NbEdgesOfOrder(self, elementOrder):
3181 Return the number of edges with the given order in the mesh
3184 elementOrder: the order of elements
3185 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3191 return self.mesh.NbEdgesOfOrder(elementOrder)
3195 Return the number of faces in the mesh
3201 return self.mesh.NbFaces()
3203 def NbFacesOfOrder(self, elementOrder):
3205 Return the number of faces with the given order in the mesh
3208 elementOrder: the order of elements
3209 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3215 return self.mesh.NbFacesOfOrder(elementOrder)
3217 def NbTriangles(self):
3219 Return the number of triangles in the mesh
3225 return self.mesh.NbTriangles()
3227 def NbTrianglesOfOrder(self, elementOrder):
3229 Return the number of triangles with the given order in the mesh
3232 elementOrder: is the order of elements
3233 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3239 return self.mesh.NbTrianglesOfOrder(elementOrder)
3241 def NbBiQuadTriangles(self):
3243 Return the number of biquadratic triangles in the mesh
3249 return self.mesh.NbBiQuadTriangles()
3251 def NbQuadrangles(self):
3253 Return the number of quadrangles in the mesh
3259 return self.mesh.NbQuadrangles()
3261 def NbQuadranglesOfOrder(self, elementOrder):
3263 Return the number of quadrangles with the given order in the mesh
3266 elementOrder: the order of elements
3267 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3273 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3275 def NbBiQuadQuadrangles(self):
3277 Return the number of biquadratic quadrangles in the mesh
3283 return self.mesh.NbBiQuadQuadrangles()
3285 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3287 Return the number of polygons of given order in the mesh
3290 elementOrder: the order of elements
3291 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3297 return self.mesh.NbPolygonsOfOrder(elementOrder)
3299 def NbVolumes(self):
3301 Return the number of volumes in the mesh
3307 return self.mesh.NbVolumes()
3310 def NbVolumesOfOrder(self, elementOrder):
3312 Return the number of volumes with the given order in the mesh
3315 elementOrder: the order of elements
3316 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322 return self.mesh.NbVolumesOfOrder(elementOrder)
3326 Return the number of tetrahedrons in the mesh
3332 return self.mesh.NbTetras()
3334 def NbTetrasOfOrder(self, elementOrder):
3336 Return the number of tetrahedrons with the given order in the mesh
3339 elementOrder: the order of elements
3340 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346 return self.mesh.NbTetrasOfOrder(elementOrder)
3350 Return the number of hexahedrons in the mesh
3356 return self.mesh.NbHexas()
3358 def NbHexasOfOrder(self, elementOrder):
3360 Return the number of hexahedrons with the given order in the mesh
3363 elementOrder: the order of elements
3364 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370 return self.mesh.NbHexasOfOrder(elementOrder)
3372 def NbTriQuadraticHexas(self):
3374 Return the number of triquadratic hexahedrons in the mesh
3380 return self.mesh.NbTriQuadraticHexas()
3382 def NbPyramids(self):
3384 Return the number of pyramids in the mesh
3390 return self.mesh.NbPyramids()
3392 def NbPyramidsOfOrder(self, elementOrder):
3394 Return the number of pyramids with the given order in the mesh
3397 elementOrder: the order of elements
3398 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3404 return self.mesh.NbPyramidsOfOrder(elementOrder)
3408 Return the number of prisms in the mesh
3414 return self.mesh.NbPrisms()
3416 def NbPrismsOfOrder(self, elementOrder):
3418 Return the number of prisms with the given order in the mesh
3421 elementOrder: the order of elements
3422 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428 return self.mesh.NbPrismsOfOrder(elementOrder)
3430 def NbHexagonalPrisms(self):
3432 Return the number of hexagonal prisms in the mesh
3438 return self.mesh.NbHexagonalPrisms()
3440 def NbPolyhedrons(self):
3442 Return the number of polyhedrons in the mesh
3448 return self.mesh.NbPolyhedrons()
3450 def NbSubMesh(self):
3452 Return the number of submeshes in the mesh
3458 return self.mesh.NbSubMesh()
3460 def GetElementsId(self):
3462 Return the list of all mesh elements IDs
3465 the list of integer values
3468 :meth:`GetElementsByType`
3471 return self.mesh.GetElementsId()
3473 def GetElementsByType(self, elementType):
3475 Return the list of IDs of mesh elements with the given type
3478 elementType (SMESH.ElementType): the required type of elements
3481 list of integer values
3484 return self.mesh.GetElementsByType(elementType)
3486 def GetNodesId(self):
3488 Return the list of mesh nodes IDs
3491 the list of integer values
3494 return self.mesh.GetNodesId()
3496 # Get the information about mesh elements:
3497 # ------------------------------------
3499 def GetElementType(self, id, iselem=True):
3501 Return the type of mesh element or node
3504 the value from :class:`SMESH.ElementType` enumeration.
3505 Return SMESH.ALL if element or node with the given ID does not exist
3508 return self.mesh.GetElementType(id, iselem)
3510 def GetElementGeomType(self, id):
3512 Return the geometric type of mesh element
3515 the value from :class:`SMESH.EntityType` enumeration.
3518 return self.mesh.GetElementGeomType(id)
3520 def GetElementShape(self, id):
3522 Return the shape type of mesh element
3525 the value from :class:`SMESH.GeometryType` enumeration.
3528 return self.mesh.GetElementShape(id)
3530 def GetSubMeshElementsId(self, Shape):
3532 Return the list of sub-mesh elements IDs
3535 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3536 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3539 list of integer values
3542 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3543 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3546 return self.mesh.GetSubMeshElementsId(ShapeID)
3548 def GetSubMeshNodesId(self, Shape, all):
3550 Return the list of sub-mesh nodes IDs
3553 Shape: a geom object (sub-shape).
3554 *Shape* must be the sub-shape of a :meth:`GetShape`
3555 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3558 list of integer values
3561 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3562 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3565 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3567 def GetSubMeshElementType(self, Shape):
3569 Return type of elements on given shape
3572 Shape: a geom object (sub-shape).
3573 *Shape* must be a sub-shape of a ShapeToMesh()
3576 :class:`SMESH.ElementType`
3579 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3580 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3583 return self.mesh.GetSubMeshElementType(ShapeID)
3587 Get the mesh description
3593 return self.mesh.Dump()
3596 # Get the information about nodes and elements of a mesh by its IDs:
3597 # -----------------------------------------------------------
3599 def GetNodeXYZ(self, id):
3601 Get XYZ coordinates of a node.
3602 If there is no node for the given ID - return an empty list
3605 list of float values
3608 return self.mesh.GetNodeXYZ(id)
3610 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3612 Return list of IDs of inverse elements for the given node.
3613 If there is no node for the given ID - return an empty list
3617 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3620 list of integer values
3623 return self.mesh.GetNodeInverseElements(id,elemType)
3625 def GetNodePosition(self,NodeID):
3627 Return the position of a node on the shape
3630 :class:`SMESH.NodePosition`
3633 return self.mesh.GetNodePosition(NodeID)
3635 def GetElementPosition(self,ElemID):
3637 Return the position of an element on the shape
3640 :class:`SMESH.ElementPosition`
3643 return self.mesh.GetElementPosition(ElemID)
3645 def GetShapeID(self, id):
3647 Return the ID of the shape, on which the given node was generated.
3650 an integer value > 0 or -1 if there is no node for the given
3651 ID or the node is not assigned to any geometry
3654 return self.mesh.GetShapeID(id)
3656 def GetShapeIDForElem(self,id):
3658 Return the ID of the shape, on which the given element was generated.
3661 an integer value > 0 or -1 if there is no element for the given
3662 ID or the element is not assigned to any geometry
3665 return self.mesh.GetShapeIDForElem(id)
3667 def GetElemNbNodes(self, id):
3669 Return the number of nodes of the given element
3672 an integer value > 0 or -1 if there is no element for the given ID
3675 return self.mesh.GetElemNbNodes(id)
3677 def GetElemNode(self, id, index):
3679 Return the node ID the given (zero based) index for the given element.
3681 * If there is no element for the given ID - return -1.
3682 * If there is no node for the given index - return -2.
3685 id (int): element ID
3686 index (int): node index within the element
3689 an integer value (ID)
3692 :meth:`GetElemNodes`
3695 return self.mesh.GetElemNode(id, index)
3697 def GetElemNodes(self, id):
3699 Return the IDs of nodes of the given element
3702 a list of integer values
3705 return self.mesh.GetElemNodes(id)
3707 def IsMediumNode(self, elementID, nodeID):
3709 Return true if the given node is the medium node in the given quadratic element
3712 return self.mesh.IsMediumNode(elementID, nodeID)
3714 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3716 Return true if the given node is the medium node in one of quadratic elements
3719 nodeID: ID of the node
3720 elementType: the type of elements to check a state of the node, either of
3721 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3724 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3726 def ElemNbEdges(self, id):
3728 Return the number of edges for the given element
3731 return self.mesh.ElemNbEdges(id)
3733 def ElemNbFaces(self, id):
3735 Return the number of faces for the given element
3738 return self.mesh.ElemNbFaces(id)
3740 def GetElemFaceNodes(self,elemId, faceIndex):
3742 Return nodes of given face (counted from zero) for given volumic element.
3745 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3747 def GetFaceNormal(self, faceId, normalized=False):
3749 Return three components of normal of given mesh face
3750 (or an empty array in KO case)
3753 return self.mesh.GetFaceNormal(faceId,normalized)
3755 def FindElementByNodes(self, nodes):
3757 Return an element based on all given nodes.
3760 return self.mesh.FindElementByNodes(nodes)
3762 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3764 Return elements including all given nodes.
3767 return self.mesh.GetElementsByNodes( nodes, elemType )
3769 def IsPoly(self, id):
3771 Return true if the given element is a polygon
3774 return self.mesh.IsPoly(id)
3776 def IsQuadratic(self, id):
3778 Return true if the given element is quadratic
3781 return self.mesh.IsQuadratic(id)
3783 def GetBallDiameter(self, id):
3785 Return diameter of a ball discrete element or zero in case of an invalid *id*
3788 return self.mesh.GetBallDiameter(id)
3790 def BaryCenter(self, id):
3792 Return XYZ coordinates of the barycenter of the given element.
3793 If there is no element for the given ID - return an empty list
3796 a list of three double values
3799 :meth:`smeshBuilder.GetGravityCenter`
3802 return self.mesh.BaryCenter(id)
3804 def GetIdsFromFilter(self, filter, meshParts=[] ):
3806 Pass mesh elements through the given filter and return IDs of fitting elements
3809 filter: :class:`SMESH.Filter`
3810 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3816 :meth:`SMESH.Filter.GetIDs`
3817 :meth:`SMESH.Filter.GetElementsIdFromParts`
3820 filter.SetMesh( self.mesh )
3823 if isinstance( meshParts, Mesh ):
3824 filter.SetMesh( meshParts.GetMesh() )
3825 return theFilter.GetIDs()
3826 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3827 meshParts = [ meshParts ]
3828 return filter.GetElementsIdFromParts( meshParts )
3830 return filter.GetIDs()
3832 # Get mesh measurements information:
3833 # ------------------------------------
3835 def GetFreeBorders(self):
3837 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3838 Return a list of special structures (borders).
3841 a list of :class:`SMESH.FreeEdges.Border`
3844 aFilterMgr = self.smeshpyD.CreateFilterManager()
3845 aPredicate = aFilterMgr.CreateFreeEdges()
3846 aPredicate.SetMesh(self.mesh)
3847 aBorders = aPredicate.GetBorders()
3848 aFilterMgr.UnRegister()
3851 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3853 Get minimum distance between two nodes, elements or distance to the origin
3856 id1: first node/element id
3857 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3858 isElem1: *True* if *id1* is element id, *False* if it is node id
3859 isElem2: *True* if *id2* is element id, *False* if it is node id
3862 minimum distance value
3864 :meth:`GetMinDistance`
3867 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3868 return aMeasure.value
3870 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3872 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3875 id1: first node/element id
3876 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3877 isElem1: *True* if *id1* is element id, *False* if it is node id
3878 isElem2: *True* if *id2* is element id, *False* if it is node id
3881 :class:`SMESH.Measure` structure
3887 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3889 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3892 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3894 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3899 aMeasurements = self.smeshpyD.CreateMeasurements()
3900 aMeasure = aMeasurements.MinDistance(id1, id2)
3901 genObjUnRegister([aMeasurements,id1, id2])
3904 def BoundingBox(self, objects=None, isElem=False):
3906 Get bounding box of the specified object(s)
3909 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3910 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3911 *False* specifies that *objects* are nodes
3914 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3917 :meth:`GetBoundingBox()`
3920 result = self.GetBoundingBox(objects, isElem)
3924 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3927 def GetBoundingBox(self, objects=None, isElem=False):
3929 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3932 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3933 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3934 False means that *objects* are nodes
3937 :class:`SMESH.Measure` structure
3940 :meth:`BoundingBox()`
3944 objects = [self.mesh]
3945 elif isinstance(objects, tuple):
3946 objects = list(objects)
3947 if not isinstance(objects, list):
3949 if len(objects) > 0 and isinstance(objects[0], int):
3952 unRegister = genObjUnRegister()
3954 if isinstance(o, Mesh):
3955 srclist.append(o.mesh)
3956 elif hasattr(o, "_narrow"):
3957 src = o._narrow(SMESH.SMESH_IDSource)
3958 if src: srclist.append(src)
3960 elif isinstance(o, list):
3962 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3964 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3965 unRegister.set( srclist[-1] )
3968 aMeasurements = self.smeshpyD.CreateMeasurements()
3969 unRegister.set( aMeasurements )
3970 aMeasure = aMeasurements.BoundingBox(srclist)
3973 # Mesh edition (SMESH_MeshEditor functionality):
3974 # ---------------------------------------------
3976 def RemoveElements(self, IDsOfElements):
3978 Remove the elements from the mesh by ids
3981 IDsOfElements: is a list of ids of elements to remove
3987 This operation can create gaps in numeration of elements.
3988 Call :meth:`RenumberElements` to remove the gaps.
3991 return self.editor.RemoveElements(IDsOfElements)
3993 def RemoveNodes(self, IDsOfNodes):
3995 Remove nodes from mesh by ids
3998 IDsOfNodes: is a list of ids of nodes to remove
4004 This operation can create gaps in numeration of nodes.
4005 Call :meth:`RenumberElements` to remove the gaps.
4008 return self.editor.RemoveNodes(IDsOfNodes)
4010 def RemoveOrphanNodes(self):
4012 Remove all orphan (free) nodes from mesh
4015 number of the removed nodes
4018 This operation can create gaps in numeration of nodes.
4019 Call :meth:`RenumberElements` to remove the gaps.
4022 return self.editor.RemoveOrphanNodes()
4024 def AddNode(self, x, y, z):
4026 Add a node to the mesh by coordinates
4032 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4033 if hasVars: self.mesh.SetParameters(Parameters)
4034 return self.editor.AddNode( x, y, z)
4036 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4038 Create a 0D element on a node with given number.
4041 IDOfNode: the ID of node for creation of the element.
4042 DuplicateElements: to add one more 0D element to a node or not
4045 ID of the new 0D element
4048 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4050 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4052 Create 0D elements on all nodes of the given elements except those
4053 nodes on which a 0D element already exists.
4056 theObject: an object on whose nodes 0D elements will be created.
4057 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4058 theGroupName: optional name of a group to add 0D elements created
4059 and/or found on nodes of *theObject*.
4060 DuplicateElements: to add one more 0D element to a node or not
4063 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4064 IDs of new and/or found 0D elements. IDs of 0D elements
4065 can be retrieved from the returned object by
4066 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4069 unRegister = genObjUnRegister()
4070 if isinstance( theObject, Mesh ):
4071 theObject = theObject.GetMesh()
4072 elif isinstance( theObject, list ):
4073 theObject = self.GetIDSource( theObject, SMESH.ALL )
4074 unRegister.set( theObject )
4075 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4077 def AddBall(self, IDOfNode, diameter):
4079 Create a ball element on a node with given ID.
4082 IDOfNode: the ID of node for creation of the element.
4083 diameter: the bal diameter.
4086 ID of the new ball element
4089 return self.editor.AddBall( IDOfNode, diameter )
4091 def AddEdge(self, IDsOfNodes):
4093 Create a linear or quadratic edge (this is determined
4094 by the number of given nodes).
4097 IDsOfNodes: list of node IDs for creation of the element.
4098 The order of nodes in this list should correspond to
4099 the :ref:`connectivity convention <connectivity_page>`.
4105 return self.editor.AddEdge(IDsOfNodes)
4107 def AddFace(self, IDsOfNodes):
4109 Create a linear or quadratic face (this is determined
4110 by the number of given nodes).
4113 IDsOfNodes: list of node IDs for creation of the element.
4114 The order of nodes in this list should correspond to
4115 the :ref:`connectivity convention <connectivity_page>`.
4121 return self.editor.AddFace(IDsOfNodes)
4123 def AddPolygonalFace(self, IdsOfNodes):
4125 Add a polygonal face defined by a list of node IDs
4128 IdsOfNodes: the list of node IDs for creation of the element.
4134 return self.editor.AddPolygonalFace(IdsOfNodes)
4136 def AddQuadPolygonalFace(self, IdsOfNodes):
4138 Add a quadratic polygonal face defined by a list of node IDs
4141 IdsOfNodes: the list of node IDs for creation of the element;
4142 corner nodes follow first.
4148 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4150 def AddVolume(self, IDsOfNodes):
4152 Create both simple and quadratic volume (this is determined
4153 by the number of given nodes).
4156 IDsOfNodes: list of node IDs for creation of the element.
4157 The order of nodes in this list should correspond to
4158 the :ref:`connectivity convention <connectivity_page>`.
4161 ID of the new volumic element
4164 return self.editor.AddVolume(IDsOfNodes)
4166 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4168 Create a volume of many faces, giving nodes for each face.
4171 IdsOfNodes: list of node IDs for volume creation, face by face.
4172 Quantities: list of integer values, Quantities[i]
4173 gives the quantity of nodes in face number i.
4176 ID of the new volumic element
4179 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4181 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4183 Create a volume of many faces, giving the IDs of the existing faces.
4186 The created volume will refer only to the nodes
4187 of the given faces, not to the faces themselves.
4190 IdsOfFaces: the list of face IDs for volume creation.
4193 ID of the new volumic element
4196 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4199 def SetNodeOnVertex(self, NodeID, Vertex):
4201 Bind a node to a vertex
4205 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4208 True if succeed else raises an exception
4211 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4212 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4216 self.editor.SetNodeOnVertex(NodeID, VertexID)
4217 except SALOME.SALOME_Exception as inst:
4218 raise ValueError(inst.details.text)
4222 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4224 Store the node position on an edge
4228 Edge: an edge (GEOM.GEOM_Object) or edge ID
4229 paramOnEdge: a parameter on the edge where the node is located
4232 True if succeed else raises an exception
4235 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4236 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4240 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4241 except SALOME.SALOME_Exception as inst:
4242 raise ValueError(inst.details.text)
4245 def SetNodeOnFace(self, NodeID, Face, u, v):
4247 Store node position on a face
4251 Face: a face (GEOM.GEOM_Object) or face ID
4252 u: U parameter on the face where the node is located
4253 v: V parameter on the face where the node is located
4256 True if succeed else raises an exception
4259 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4260 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4264 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4265 except SALOME.SALOME_Exception as inst:
4266 raise ValueError(inst.details.text)
4269 def SetNodeInVolume(self, NodeID, Solid):
4271 Bind a node to a solid
4275 Solid: a solid (GEOM.GEOM_Object) or solid ID
4278 True if succeed else raises an exception
4281 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4282 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4286 self.editor.SetNodeInVolume(NodeID, SolidID)
4287 except SALOME.SALOME_Exception as inst:
4288 raise ValueError(inst.details.text)
4291 def SetMeshElementOnShape(self, ElementID, Shape):
4293 Bind an element to a shape
4296 ElementID: an element ID
4297 Shape: a shape (GEOM.GEOM_Object) or shape ID
4300 True if succeed else raises an exception
4303 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4304 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4308 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4309 except SALOME.SALOME_Exception as inst:
4310 raise ValueError(inst.details.text)
4314 def MoveNode(self, NodeID, x, y, z):
4316 Move the node with the given id
4319 NodeID: the id of the node
4320 x: a new X coordinate
4321 y: a new Y coordinate
4322 z: a new Z coordinate
4325 True if succeed else False
4328 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4329 if hasVars: self.mesh.SetParameters(Parameters)
4330 return self.editor.MoveNode(NodeID, x, y, z)
4332 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4334 Find the node closest to a point and moves it to a point location
4337 x: the X coordinate of a point
4338 y: the Y coordinate of a point
4339 z: the Z coordinate of a point
4340 NodeID: if specified (>0), the node with this ID is moved,
4341 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4344 the ID of a moved node
4347 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4348 if hasVars: self.mesh.SetParameters(Parameters)
4349 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4351 def FindNodeClosestTo(self, x, y, z):
4353 Find the node closest to a point
4356 x: the X coordinate of a point
4357 y: the Y coordinate of a point
4358 z: the Z coordinate of a point
4364 return self.editor.FindNodeClosestTo(x, y, z)
4366 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4368 Find the elements where a point lays IN or ON
4371 x,y,z (float): coordinates of the point
4372 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4373 means elements of any type excluding nodes, discrete and 0D elements.
4374 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4377 list of IDs of found elements
4380 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4382 return self.editor.FindElementsByPoint(x, y, z, elementType)
4384 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4386 Project a point to a mesh object.
4387 Return ID of an element of given type where the given point is projected
4388 and coordinates of the projection point.
4389 In the case if nothing found, return -1 and []
4391 if isinstance( meshObject, Mesh ):
4392 meshObject = meshObject.GetMesh()
4394 meshObject = self.GetMesh()
4395 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4397 def GetPointState(self, x, y, z):
4399 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4400 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4401 UNKNOWN state means that either mesh is wrong or the analysis fails.
4404 return self.editor.GetPointState(x, y, z)
4406 def IsManifold(self):
4408 Check if a 2D mesh is manifold
4411 return self.editor.IsManifold()
4413 def IsCoherentOrientation2D(self):
4415 Check if orientation of 2D elements is coherent
4418 return self.editor.IsCoherentOrientation2D()
4420 def Get1DBranches( self, edges, startNode = 0 ):
4422 Partition given 1D elements into groups of contiguous edges.
4423 A node where number of meeting edges != 2 is a group end.
4424 An optional startNode is used to orient groups it belongs to.
4427 A list of edge groups and a list of corresponding node groups,
4428 where the group is a list of IDs of edges or elements, like follows
4429 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4430 If a group is closed, the first and last nodes of the group are same.
4432 if isinstance( edges, Mesh ):
4433 edges = edges.GetMesh()
4434 unRegister = genObjUnRegister()
4435 if isinstance( edges, list ):
4436 edges = self.GetIDSource( edges, SMESH.EDGE )
4437 unRegister.set( edges )
4438 return self.editor.Get1DBranches( edges, startNode )
4440 def FindSharpEdges( self, angle, addExisting=False ):
4442 Return sharp edges of faces and non-manifold ones.
4443 Optionally add existing edges.
4446 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4447 addExisting: to return existing edges (1D elements) as well
4450 list of FaceEdge structures
4452 angle = ParseParameters( angle )[0]
4453 return self.editor.FindSharpEdges( angle, addExisting )
4455 def MeshToPassThroughAPoint(self, x, y, z):
4457 Find the node closest to a point and moves it to a point location
4460 x: the X coordinate of a point
4461 y: the Y coordinate of a point
4462 z: the Z coordinate of a point
4465 the ID of a moved node
4468 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4470 def InverseDiag(self, NodeID1, NodeID2):
4472 Replace two neighbour triangles sharing Node1-Node2 link
4473 with the triangles built on the same 4 nodes but having other common link.
4476 NodeID1: the ID of the first node
4477 NodeID2: the ID of the second node
4480 False if proper faces were not found
4482 return self.editor.InverseDiag(NodeID1, NodeID2)
4484 def DeleteDiag(self, NodeID1, NodeID2):
4486 Replace two neighbour triangles sharing *Node1-Node2* link
4487 with a quadrangle built on the same 4 nodes.
4490 NodeID1: ID of the first node
4491 NodeID2: ID of the second node
4494 False if proper faces were not found
4497 This operation can create gaps in numeration of elements.
4498 Call :meth:`RenumberElements` to remove the gaps.
4501 return self.editor.DeleteDiag(NodeID1, NodeID2)
4503 def Reorient(self, IDsOfElements=None):
4505 Reorient elements by ids
4508 IDsOfElements: if undefined reorients all mesh elements
4511 True if succeed else False
4514 if IDsOfElements == None:
4515 IDsOfElements = self.GetElementsId()
4516 return self.editor.Reorient(IDsOfElements)
4518 def ReorientObject(self, theObject):
4520 Reorient all elements of the object
4523 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4526 True if succeed else False
4529 if ( isinstance( theObject, Mesh )):
4530 theObject = theObject.GetMesh()
4531 return self.editor.ReorientObject(theObject)
4533 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4535 Reorient faces contained in *the2DObject*.
4538 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4539 theDirection: a desired direction of normal of *theFace*.
4540 It can be either a GEOM vector or a list of coordinates [x,y,z].
4541 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4542 compared with theDirection. It can be either ID of face or a point
4543 by which the face will be found. The point can be given as either
4544 a GEOM vertex or a list of point coordinates.
4547 number of reoriented faces
4550 unRegister = genObjUnRegister()
4552 if isinstance( the2DObject, Mesh ):
4553 the2DObject = the2DObject.GetMesh()
4554 if isinstance( the2DObject, list ):
4555 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4556 unRegister.set( the2DObject )
4557 # check theDirection
4558 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4559 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4560 if isinstance( theDirection, list ):
4561 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4562 # prepare theFace and thePoint
4563 theFace = theFaceOrPoint
4564 thePoint = PointStruct(0,0,0)
4565 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4566 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4568 if isinstance( theFaceOrPoint, list ):
4569 thePoint = PointStruct( *theFaceOrPoint )
4571 if isinstance( theFaceOrPoint, PointStruct ):
4572 thePoint = theFaceOrPoint
4574 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4576 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4578 Reorient faces according to adjacent volumes.
4581 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4582 either IDs of faces or face groups.
4583 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4584 theOutsideNormal: to orient faces to have their normals
4585 pointing either *outside* or *inside* the adjacent volumes.
4588 number of reoriented faces.
4591 unRegister = genObjUnRegister()
4593 if not isinstance( the2DObject, list ):
4594 the2DObject = [ the2DObject ]
4595 elif the2DObject and isinstance( the2DObject[0], int ):
4596 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4597 unRegister.set( the2DObject )
4598 the2DObject = [ the2DObject ]
4599 for i,obj2D in enumerate( the2DObject ):
4600 if isinstance( obj2D, Mesh ):
4601 the2DObject[i] = obj2D.GetMesh()
4602 if isinstance( obj2D, list ):
4603 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4604 unRegister.set( the2DObject[i] )
4606 if isinstance( the3DObject, Mesh ):
4607 the3DObject = the3DObject.GetMesh()
4608 if isinstance( the3DObject, list ):
4609 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4610 unRegister.set( the3DObject )
4611 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4613 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4615 Fuse the neighbouring triangles into quadrangles.
4618 IDsOfElements: The triangles to be fused.
4619 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4620 applied to possible quadrangles to choose a neighbour to fuse with.
4621 Note that not all items of :class:`SMESH.FunctorType` corresponds
4622 to numerical functors.
4623 MaxAngle: is the maximum angle between element normals at which the fusion
4624 is still performed; theMaxAngle is measured in radians.
4625 Also it could be a name of variable which defines angle in degrees.
4628 True in case of success, False otherwise.
4631 This operation can create gaps in numeration of elements.
4632 Call :meth:`RenumberElements` to remove the gaps.
4635 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4636 self.mesh.SetParameters(Parameters)
4637 if not IDsOfElements:
4638 IDsOfElements = self.GetElementsId()
4639 Functor = self.smeshpyD.GetFunctor(theCriterion)
4640 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4642 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4644 Fuse the neighbouring triangles of the object into quadrangles
4647 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4648 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4649 applied to possible quadrangles to choose a neighbour to fuse with.
4650 Note that not all items of :class:`SMESH.FunctorType` corresponds
4651 to numerical functors.
4652 MaxAngle: a max angle between element normals at which the fusion
4653 is still performed; theMaxAngle is measured in radians.
4656 True in case of success, False otherwise.
4659 This operation can create gaps in numeration of elements.
4660 Call :meth:`RenumberElements` to remove the gaps.
4663 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4664 self.mesh.SetParameters(Parameters)
4665 if isinstance( theObject, Mesh ):
4666 theObject = theObject.GetMesh()
4667 Functor = self.smeshpyD.GetFunctor(theCriterion)
4668 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4670 def QuadToTri (self, IDsOfElements, theCriterion = None):
4672 Split quadrangles into triangles.
4675 IDsOfElements: the faces to be splitted.
4676 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4677 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4678 value, then quadrangles will be split by the smallest diagonal.
4679 Note that not all items of :class:`SMESH.FunctorType` corresponds
4680 to numerical functors.
4683 True in case of success, False otherwise.
4686 This operation can create gaps in numeration of elements.
4687 Call :meth:`RenumberElements` to remove the gaps.
4689 if IDsOfElements == []:
4690 IDsOfElements = self.GetElementsId()
4691 if theCriterion is None:
4692 theCriterion = FT_MaxElementLength2D
4693 Functor = self.smeshpyD.GetFunctor(theCriterion)
4694 return self.editor.QuadToTri(IDsOfElements, Functor)
4696 def QuadToTriObject (self, theObject, theCriterion = None):
4698 Split quadrangles into triangles.
4701 theObject: the object from which the list of elements is taken,
4702 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4703 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4704 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4705 value, then quadrangles will be split by the smallest diagonal.
4706 Note that not all items of :class:`SMESH.FunctorType` corresponds
4707 to numerical functors.
4710 True in case of success, False otherwise.
4713 This operation can create gaps in numeration of elements.
4714 Call :meth:`RenumberElements` to remove the gaps.
4716 if ( isinstance( theObject, Mesh )):
4717 theObject = theObject.GetMesh()
4718 if theCriterion is None:
4719 theCriterion = FT_MaxElementLength2D
4720 Functor = self.smeshpyD.GetFunctor(theCriterion)
4721 return self.editor.QuadToTriObject(theObject, Functor)
4723 def QuadTo4Tri (self, theElements=[]):
4725 Split each of given quadrangles into 4 triangles. A node is added at the center of
4729 theElements: the faces to be splitted. This can be either
4730 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4731 or a list of face IDs. By default all quadrangles are split
4734 This operation can create gaps in numeration of elements.
4735 Call :meth:`RenumberElements` to remove the gaps.
4737 unRegister = genObjUnRegister()
4738 if isinstance( theElements, Mesh ):
4739 theElements = theElements.mesh
4740 elif not theElements:
4741 theElements = self.mesh
4742 elif isinstance( theElements, list ):
4743 theElements = self.GetIDSource( theElements, SMESH.FACE )
4744 unRegister.set( theElements )
4745 return self.editor.QuadTo4Tri( theElements )
4747 def SplitQuad (self, IDsOfElements, Diag13):
4749 Split quadrangles into triangles.
4752 IDsOfElements: the faces to be splitted
4753 Diag13 (boolean): is used to choose a diagonal for splitting.
4756 True in case of success, False otherwise.
4759 This operation can create gaps in numeration of elements.
4760 Call :meth:`RenumberElements` to remove the gaps.
4762 if IDsOfElements == []:
4763 IDsOfElements = self.GetElementsId()
4764 return self.editor.SplitQuad(IDsOfElements, Diag13)
4766 def SplitQuadObject (self, theObject, Diag13):
4768 Split quadrangles into triangles.
4771 theObject: the object from which the list of elements is taken,
4772 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4773 Diag13 (boolean): is used to choose a diagonal for splitting.
4776 True in case of success, False otherwise.
4779 This operation can create gaps in numeration of elements.
4780 Call :meth:`RenumberElements` to remove the gaps.
4782 if ( isinstance( theObject, Mesh )):
4783 theObject = theObject.GetMesh()
4784 return self.editor.SplitQuadObject(theObject, Diag13)
4786 def BestSplit (self, IDOfQuad, theCriterion):
4788 Find a better splitting of the given quadrangle.
4791 IDOfQuad: the ID of the quadrangle to be splitted.
4792 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4793 choose a diagonal for splitting.
4794 Note that not all items of :class:`SMESH.FunctorType` corresponds
4795 to numerical functors.
4798 * 1 if 1-3 diagonal is better,
4799 * 2 if 2-4 diagonal is better,
4800 * 0 if error occurs.
4803 This operation can create gaps in numeration of elements.
4804 Call :meth:`RenumberElements` to remove the gaps.
4806 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4808 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4810 Split volumic elements into tetrahedrons
4813 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4814 method: flags passing splitting method:
4815 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4816 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4819 This operation can create gaps in numeration of elements.
4820 Call :meth:`RenumberElements` to remove the gaps.
4822 unRegister = genObjUnRegister()
4823 if isinstance( elems, Mesh ):
4824 elems = elems.GetMesh()
4825 if ( isinstance( elems, list )):
4826 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4827 unRegister.set( elems )
4828 self.editor.SplitVolumesIntoTetra(elems, method)
4831 def SplitBiQuadraticIntoLinear(self, elems=None):
4833 Split bi-quadratic elements into linear ones without creation of additional nodes:
4835 - bi-quadratic triangle will be split into 3 linear quadrangles;
4836 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4837 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4839 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4840 will be split in order to keep the mesh conformal.
4843 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4844 if None (default), all bi-quadratic elements will be split
4847 This operation can create gaps in numeration of elements.
4848 Call :meth:`RenumberElements` to remove the gaps.
4850 unRegister = genObjUnRegister()
4851 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4852 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4853 unRegister.set( elems )
4855 elems = [ self.GetMesh() ]
4856 if isinstance( elems, Mesh ):
4857 elems = [ elems.GetMesh() ]
4858 if not isinstance( elems, list ):
4860 self.editor.SplitBiQuadraticIntoLinear( elems )
4862 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4863 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4865 Split hexahedra into prisms
4868 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4869 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4870 gives a normal vector defining facets to split into triangles.
4871 *startHexPoint* can be either a triple of coordinates or a vertex.
4872 facetNormal: a normal to a facet to split into triangles of a
4873 hexahedron found by *startHexPoint*.
4874 *facetNormal* can be either a triple of coordinates or an edge.
4875 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4876 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4877 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4878 to *startHexPoint* are split, else *startHexPoint*
4879 is used to find the facet to split in all domains present in *elems*.
4882 This operation can create gaps in numeration of elements.
4883 Call :meth:`RenumberElements` to remove the gaps.
4886 unRegister = genObjUnRegister()
4887 if isinstance( elems, Mesh ):
4888 elems = elems.GetMesh()
4889 if ( isinstance( elems, list )):
4890 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4891 unRegister.set( elems )
4894 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4895 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4896 elif isinstance( startHexPoint, list ):
4897 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4900 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4901 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4902 elif isinstance( facetNormal, list ):
4903 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4906 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4908 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4910 def SplitQuadsNearTriangularFacets(self):
4912 Split quadrangle faces near triangular facets of volumes
4915 This operation can create gaps in numeration of elements.
4916 Call :meth:`RenumberElements` to remove the gaps.
4918 faces_array = self.GetElementsByType(SMESH.FACE)
4919 for face_id in faces_array:
4920 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4921 quad_nodes = self.mesh.GetElemNodes(face_id)
4922 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4923 isVolumeFound = False
4924 for node1_elem in node1_elems:
4925 if not isVolumeFound:
4926 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4927 nb_nodes = self.GetElemNbNodes(node1_elem)
4928 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4929 volume_elem = node1_elem
4930 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4931 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4932 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4933 isVolumeFound = True
4934 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4935 self.SplitQuad([face_id], False) # diagonal 2-4
4936 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4937 isVolumeFound = True
4938 self.SplitQuad([face_id], True) # diagonal 1-3
4939 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4940 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4941 isVolumeFound = True
4942 self.SplitQuad([face_id], True) # diagonal 1-3
4944 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4946 Split hexahedrons into tetrahedrons.
4948 This operation uses :doc:`pattern_mapping` functionality for splitting.
4951 theObject: the object from which the list of hexahedrons is taken;
4952 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4953 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4954 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4955 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4956 key-point will be mapped into *theNode001*-th node of each volume.
4957 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4960 True in case of success, False otherwise.
4963 This operation can create gaps in numeration of elements.
4964 Call :meth:`RenumberElements` to remove the gaps.
4972 # (0,0,1) 4.---------.7 * |
4979 # (0,0,0) 0.---------.3
4980 pattern_tetra = "!!! Nb of points: \n 8 \n\
4990 !!! Indices of points of 6 tetras: \n\
4998 pattern = self.smeshpyD.GetPattern()
4999 isDone = pattern.LoadFromFile(pattern_tetra)
5001 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5004 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5005 isDone = pattern.MakeMesh(self.mesh, False, False)
5006 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5008 # split quafrangle faces near triangular facets of volumes
5009 self.SplitQuadsNearTriangularFacets()
5013 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5015 Split hexahedrons into prisms.
5017 Uses the :doc:`pattern_mapping` functionality for splitting.
5020 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5021 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5022 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5023 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5024 will be mapped into the *theNode001* -th node of each volume.
5025 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5028 True in case of success, False otherwise.
5031 This operation can create gaps in numeration of elements.
5032 Call :meth:`RenumberElements` to remove the gaps.
5034 # Pattern: 5.---------.6
5039 # (0,0,1) 4.---------.7 |
5046 # (0,0,0) 0.---------.3
5047 pattern_prism = "!!! Nb of points: \n 8 \n\
5057 !!! Indices of points of 2 prisms: \n\
5061 pattern = self.smeshpyD.GetPattern()
5062 isDone = pattern.LoadFromFile(pattern_prism)
5064 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5067 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5068 isDone = pattern.MakeMesh(self.mesh, False, False)
5069 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5071 # Split quafrangle faces near triangular facets of volumes
5072 self.SplitQuadsNearTriangularFacets()
5076 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5077 MaxNbOfIterations, MaxAspectRatio, Method):
5082 IDsOfElements: the list if ids of elements to smooth
5083 IDsOfFixedNodes: the list of ids of fixed nodes.
5084 Note that nodes built on edges and boundary nodes are always fixed.
5085 MaxNbOfIterations: the maximum number of iterations
5086 MaxAspectRatio: varies in range [1.0, inf]
5087 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5088 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5091 True in case of success, False otherwise.
5094 if IDsOfElements == []:
5095 IDsOfElements = self.GetElementsId()
5096 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5097 self.mesh.SetParameters(Parameters)
5098 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5099 MaxNbOfIterations, MaxAspectRatio, Method)
5101 def SmoothObject(self, theObject, IDsOfFixedNodes,
5102 MaxNbOfIterations, MaxAspectRatio, Method):
5104 Smooth elements which belong to the given object
5107 theObject: the object to smooth
5108 IDsOfFixedNodes: the list of ids of fixed nodes.
5109 Note that nodes built on edges and boundary nodes are always fixed.
5110 MaxNbOfIterations: the maximum number of iterations
5111 MaxAspectRatio: varies in range [1.0, inf]
5112 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5113 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5116 True in case of success, False otherwise.
5119 if ( isinstance( theObject, Mesh )):
5120 theObject = theObject.GetMesh()
5121 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5122 MaxNbOfIterations, MaxAspectRatio, Method)
5124 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5125 MaxNbOfIterations, MaxAspectRatio, Method):
5127 Parametrically smooth the given elements
5130 IDsOfElements: the list if ids of elements to smooth
5131 IDsOfFixedNodes: the list of ids of fixed nodes.
5132 Note that nodes built on edges and boundary nodes are always fixed.
5133 MaxNbOfIterations: the maximum number of iterations
5134 MaxAspectRatio: varies in range [1.0, inf]
5135 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5136 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5139 True in case of success, False otherwise.
5142 if IDsOfElements == []:
5143 IDsOfElements = self.GetElementsId()
5144 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5145 self.mesh.SetParameters(Parameters)
5146 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5147 MaxNbOfIterations, MaxAspectRatio, Method)
5149 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5150 MaxNbOfIterations, MaxAspectRatio, Method):
5152 Parametrically smooth the elements which belong to the given object
5155 theObject: the object to smooth
5156 IDsOfFixedNodes: the list of ids of fixed nodes.
5157 Note that nodes built on edges and boundary nodes are always fixed.
5158 MaxNbOfIterations: the maximum number of iterations
5159 MaxAspectRatio: varies in range [1.0, inf]
5160 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5161 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5164 True in case of success, False otherwise.
5167 if ( isinstance( theObject, Mesh )):
5168 theObject = theObject.GetMesh()
5169 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5170 MaxNbOfIterations, MaxAspectRatio, Method)
5172 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5174 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5175 them with quadratic with the same id.
5178 theForce3d: method of new node creation:
5180 * False - the medium node lies at the geometrical entity from which the mesh element is built
5181 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5182 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5183 theToBiQuad: If True, converts the mesh to bi-quadratic
5186 :class:`SMESH.ComputeError` which can hold a warning
5189 If *theSubMesh* is provided, the mesh can become non-conformal
5192 This operation can create gaps in numeration of nodes or elements.
5193 Call :meth:`RenumberElements` to remove the gaps.
5196 if isinstance( theSubMesh, Mesh ):
5197 theSubMesh = theSubMesh.mesh
5199 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5202 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5204 self.editor.ConvertToQuadratic(theForce3d)
5205 error = self.editor.GetLastError()
5206 if error and error.comment:
5207 print(error.comment)
5210 def ConvertFromQuadratic(self, theSubMesh=None):
5212 Convert the mesh from quadratic to ordinary,
5213 deletes old quadratic elements,
5214 replacing them with ordinary mesh elements with the same id.
5217 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5220 If *theSubMesh* is provided, the mesh can become non-conformal
5223 This operation can create gaps in numeration of nodes or elements.
5224 Call :meth:`RenumberElements` to remove the gaps.
5228 self.editor.ConvertFromQuadraticObject(theSubMesh)
5230 return self.editor.ConvertFromQuadratic()
5232 def Make2DMeshFrom3D(self):
5234 Create 2D mesh as skin on boundary faces of a 3D mesh
5237 True if operation has been completed successfully, False otherwise
5240 return self.editor.Make2DMeshFrom3D()
5242 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5243 toCopyElements=False, toCopyExistingBondary=False):
5245 Create missing boundary elements
5248 elements: elements whose boundary is to be checked:
5249 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5250 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5251 dimension: defines type of boundary elements to create, either of
5252 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5253 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5254 groupName: a name of group to store created boundary elements in,
5255 "" means not to create the group
5256 meshName: a name of new mesh to store created boundary elements in,
5257 "" means not to create the new mesh
5258 toCopyElements: if True, the checked elements will be copied into
5259 the new mesh else only boundary elements will be copied into the new mesh
5260 toCopyExistingBondary: if True, not only new but also pre-existing
5261 boundary elements will be copied into the new mesh
5264 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5267 unRegister = genObjUnRegister()
5268 if isinstance( elements, Mesh ):
5269 elements = elements.GetMesh()
5270 if ( isinstance( elements, list )):
5271 elemType = SMESH.ALL
5272 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5273 elements = self.editor.MakeIDSource(elements, elemType)
5274 unRegister.set( elements )
5275 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5276 toCopyElements,toCopyExistingBondary)
5277 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5280 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5281 toCopyAll=False, groups=[]):
5283 Create missing boundary elements around either the whole mesh or
5287 dimension: defines type of boundary elements to create, either of
5288 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5289 groupName: a name of group to store all boundary elements in,
5290 "" means not to create the group
5291 meshName: a name of a new mesh, which is a copy of the initial
5292 mesh + created boundary elements; "" means not to create the new mesh
5293 toCopyAll: if True, the whole initial mesh will be copied into
5294 the new mesh else only boundary elements will be copied into the new mesh
5295 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5298 tuple( long, mesh, group )
5299 - long - number of added boundary elements
5300 - mesh - the :class:`Mesh` where elements were added to
5301 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5304 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5306 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5307 return nb, mesh, group
5309 def RenumberNodes(self):
5311 Renumber mesh nodes to remove unused node IDs
5313 self.editor.RenumberNodes()
5315 def RenumberElements(self):
5317 Renumber mesh elements to remove unused element IDs
5319 self.editor.RenumberElements()
5321 def _getIdSourceList(self, arg, idType, unRegister):
5323 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5325 if arg and isinstance( arg, list ):
5326 if isinstance( arg[0], int ):
5327 arg = self.GetIDSource( arg, idType )
5328 unRegister.set( arg )
5329 elif isinstance( arg[0], Mesh ):
5330 arg[0] = arg[0].GetMesh()
5331 elif isinstance( arg, Mesh ):
5333 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5337 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5338 MakeGroups=False, TotalAngle=False):
5340 Generate new elements by rotation of the given elements and nodes around the axis
5343 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5344 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5345 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5346 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5347 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5348 which defines angle in degrees
5349 NbOfSteps: the number of steps
5350 Tolerance: tolerance
5351 MakeGroups: forces the generation of new groups from existing ones
5352 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5353 of all steps, else - size of each step
5356 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5359 unRegister = genObjUnRegister()
5360 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5361 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5362 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5364 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5365 Axis = self.smeshpyD.GetAxisStruct( Axis )
5366 if isinstance( Axis, list ):
5367 Axis = SMESH.AxisStruct( *Axis )
5369 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5370 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5371 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5372 self.mesh.SetParameters(Parameters)
5373 if TotalAngle and NbOfSteps:
5374 AngleInRadians /= NbOfSteps
5375 return self.editor.RotationSweepObjects( nodes, edges, faces,
5376 Axis, AngleInRadians,
5377 NbOfSteps, Tolerance, MakeGroups)
5379 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5380 MakeGroups=False, TotalAngle=False):
5382 Generate new elements by rotation of the elements around the axis
5385 IDsOfElements: the list of ids of elements to sweep
5386 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5387 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5388 NbOfSteps: the number of steps
5389 Tolerance: tolerance
5390 MakeGroups: forces the generation of new groups from existing ones
5391 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5392 of all steps, else - size of each step
5395 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5398 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5399 AngleInRadians, NbOfSteps, Tolerance,
5400 MakeGroups, TotalAngle)
5402 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5403 MakeGroups=False, TotalAngle=False):
5405 Generate new elements by rotation of the elements of object around the axis
5406 theObject object which elements should be sweeped.
5407 It can be a mesh, a sub mesh or a group.
5410 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5411 AngleInRadians: the angle of Rotation
5412 NbOfSteps: number of steps
5413 Tolerance: tolerance
5414 MakeGroups: forces the generation of new groups from existing ones
5415 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5416 of all steps, else - size of each step
5419 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5422 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5423 AngleInRadians, NbOfSteps, Tolerance,
5424 MakeGroups, TotalAngle )
5426 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5427 MakeGroups=False, TotalAngle=False):
5429 Generate new elements by rotation of the elements of object around the axis
5430 theObject object which elements should be sweeped.
5431 It can be a mesh, a sub mesh or a group.
5434 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5435 AngleInRadians: the angle of Rotation
5436 NbOfSteps: number of steps
5437 Tolerance: tolerance
5438 MakeGroups: forces the generation of new groups from existing ones
5439 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5440 of all steps, else - size of each step
5443 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5444 empty list otherwise
5447 return self.RotationSweepObjects([],theObject,[], Axis,
5448 AngleInRadians, NbOfSteps, Tolerance,
5449 MakeGroups, TotalAngle)
5451 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5452 MakeGroups=False, TotalAngle=False):
5454 Generate new elements by rotation of the elements of object around the axis
5455 theObject object which elements should be sweeped.
5456 It can be a mesh, a sub mesh or a group.
5459 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5460 AngleInRadians: the angle of Rotation
5461 NbOfSteps: number of steps
5462 Tolerance: tolerance
5463 MakeGroups: forces the generation of new groups from existing ones
5464 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5465 of all steps, else - size of each step
5468 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5471 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5472 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5474 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5475 scaleFactors=[], linearVariation=False, basePoint=[],
5476 angles=[], anglesVariation=False):
5478 Generate new elements by extrusion of the given elements and nodes
5481 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5482 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5483 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5484 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5485 the direction and value of extrusion for one step (the total extrusion
5486 length will be NbOfSteps * ||StepVector||)
5487 NbOfSteps: the number of steps
5488 MakeGroups: forces the generation of new groups from existing ones
5489 scaleFactors: optional scale factors to apply during extrusion
5490 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5491 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5492 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5493 nodes and elements being extruded is used as the scaling center.
5496 - a list of tree components of the point or
5499 angles: list of angles in radians. Nodes at each extrusion step are rotated
5500 around *basePoint*, additionally to previous steps.
5501 anglesVariation: forces the computation of rotation angles as linear
5502 variation of the given *angles* along path steps
5504 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5506 Example: :ref:`tui_extrusion`
5508 unRegister = genObjUnRegister()
5509 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5510 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5511 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5513 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5514 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5515 if isinstance( StepVector, list ):
5516 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5518 if isinstance( basePoint, int):
5519 xyz = self.GetNodeXYZ( basePoint )
5521 raise RuntimeError("Invalid node ID: %s" % basePoint)
5523 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5524 basePoint = self.geompyD.PointCoordinates( basePoint )
5526 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5527 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5528 angles,angleParameters,hasVars = ParseAngles(angles)
5529 Parameters = StepVector.PS.parameters + var_separator + \
5530 Parameters + var_separator + \
5531 scaleParameters + var_separator + angleParameters
5532 self.mesh.SetParameters(Parameters)
5534 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5535 StepVector, NbOfSteps, MakeGroups,
5536 scaleFactors, linearVariation, basePoint,
5537 angles, anglesVariation )
5540 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5542 Generate new elements by extrusion of the elements with given ids
5545 IDsOfElements: the list of ids of elements or nodes for extrusion
5546 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5547 the direction and value of extrusion for one step (the total extrusion
5548 length will be NbOfSteps * ||StepVector||)
5549 NbOfSteps: the number of steps
5550 MakeGroups: forces the generation of new groups from existing ones
5551 IsNodes: is True if elements with given ids are nodes
5554 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5556 Example: :ref:`tui_extrusion`
5559 if IsNodes: n = IDsOfElements
5560 else : e,f, = IDsOfElements,IDsOfElements
5561 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5563 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5564 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5566 Generate new elements by extrusion along the normal to a discretized surface or wire
5569 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5570 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5571 StepSize: length of one extrusion step (the total extrusion
5572 length will be *NbOfSteps* *StepSize*).
5573 NbOfSteps: number of extrusion steps.
5574 ByAverageNormal: if True each node is translated by *StepSize*
5575 along the average of the normal vectors to the faces sharing the node;
5576 else each node is translated along the same average normal till
5577 intersection with the plane got by translation of the face sharing
5578 the node along its own normal by *StepSize*.
5579 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5580 for every node of *Elements*.
5581 MakeGroups: forces generation of new groups from existing ones.
5582 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5583 is not yet implemented. This parameter is used if *Elements* contains
5584 both faces and edges, i.e. *Elements* is a Mesh.
5587 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5588 empty list otherwise.
5589 Example: :ref:`tui_extrusion`
5592 unRegister = genObjUnRegister()
5593 if isinstance( Elements, Mesh ):
5594 Elements = [ Elements.GetMesh() ]
5595 if isinstance( Elements, list ):
5597 raise RuntimeError("Elements empty!")
5598 if isinstance( Elements[0], Mesh ):
5599 Elements = [ Elements[0].GetMesh() ]
5600 if isinstance( Elements[0], int ):
5601 Elements = self.GetIDSource( Elements, SMESH.ALL )
5602 unRegister.set( Elements )
5603 if not isinstance( Elements, list ):
5604 Elements = [ Elements ]
5605 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5606 self.mesh.SetParameters(Parameters)
5607 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5608 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5610 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5612 Generate new elements by extrusion of the elements or nodes which belong to the object
5615 theObject: the object whose elements or nodes should be processed.
5616 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5617 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5618 the direction and value of extrusion for one step (the total extrusion
5619 length will be NbOfSteps * ||StepVector||)
5620 NbOfSteps: the number of steps
5621 MakeGroups: forces the generation of new groups from existing ones
5622 IsNodes: is True if elements to extrude are nodes
5625 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5626 Example: :ref:`tui_extrusion`
5630 if IsNodes: n = theObject
5631 else : e,f, = theObject,theObject
5632 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5634 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5636 Generate new elements by extrusion of edges which belong to the object
5639 theObject: object whose 1D elements should be processed.
5640 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5641 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5642 the direction and value of extrusion for one step (the total extrusion
5643 length will be NbOfSteps * ||StepVector||)
5644 NbOfSteps: the number of steps
5645 MakeGroups: to generate new groups from existing ones
5648 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5649 Example: :ref:`tui_extrusion`
5652 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5654 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5656 Generate new elements by extrusion of faces which belong to the object
5659 theObject: object whose 2D elements should be processed.
5660 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5661 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5662 the direction and value of extrusion for one step (the total extrusion
5663 length will be NbOfSteps * ||StepVector||)
5664 NbOfSteps: the number of steps
5665 MakeGroups: forces the generation of new groups from existing ones
5668 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5669 Example: :ref:`tui_extrusion`
5672 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5674 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5675 ExtrFlags, SewTolerance, MakeGroups=False):
5677 Generate new elements by extrusion of the elements with given ids
5680 IDsOfElements: is ids of elements
5681 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5682 the direction and value of extrusion for one step (the total extrusion
5683 length will be NbOfSteps * ||StepVector||)
5684 NbOfSteps: the number of steps
5685 ExtrFlags: sets flags for extrusion
5686 SewTolerance: uses for comparing locations of nodes if flag
5687 EXTRUSION_FLAG_SEW is set
5688 MakeGroups: forces the generation of new groups from existing ones
5691 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5694 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5695 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5696 if isinstance( StepVector, list ):
5697 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5698 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5699 ExtrFlags, SewTolerance, MakeGroups)
5701 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5702 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5703 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5704 ScaleFactors=[], ScalesVariation=False):
5706 Generate new elements by extrusion of the given elements and nodes along the path.
5707 The path of extrusion must be a meshed edge.
5710 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5711 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5712 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5713 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5714 PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None
5715 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5716 HasAngles: not used obsolete
5717 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5718 around *basePoint*, additionally to previous steps.
5719 LinearVariation: forces the computation of rotation angles as linear
5720 variation of the given Angles along path steps
5721 HasRefPoint: allows using the reference point
5722 RefPoint: optional scaling and rotation center (mass center of the extruded
5723 elements by default). The User can specify any point as the Reference Point.
5724 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5725 MakeGroups: forces the generation of new groups from existing ones
5726 ScaleFactors: optional scale factors to apply during extrusion
5727 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5728 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5731 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5732 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5733 Example: :ref:`tui_extrusion_along_path`
5736 unRegister = genObjUnRegister()
5737 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5738 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5739 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5741 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5742 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5743 if isinstance( RefPoint, list ):
5744 if not RefPoint: RefPoint = [0,0,0]
5745 RefPoint = SMESH.PointStruct( *RefPoint )
5746 if isinstance( PathObject, Mesh ):
5747 PathObject = PathObject.GetMesh()
5748 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5749 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5750 Parameters = AnglesParameters + var_separator + \
5751 RefPoint.parameters + var_separator + ScalesParameters
5752 self.mesh.SetParameters(Parameters)
5753 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5754 PathObject, PathShape, NodeStart,
5755 HasAngles, Angles, LinearVariation,
5756 HasRefPoint, RefPoint, MakeGroups,
5757 ScaleFactors, ScalesVariation)
5759 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5760 HasAngles=False, Angles=[], LinearVariation=False,
5761 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5762 ElemType=SMESH.FACE):
5764 Generate new elements by extrusion of the given elements.
5765 The path of extrusion must be a meshed edge.
5768 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5769 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5770 NodeStart: the start node from Path. Defines the direction of extrusion
5771 HasAngles: not used obsolete
5772 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5773 around *basePoint*, additionally to previous steps.
5774 LinearVariation: forces the computation of rotation angles as linear
5775 variation of the given Angles along path steps
5776 HasRefPoint: allows using the reference point
5777 RefPoint: the reference point around which the elements are rotated (the mass
5778 center of the elements by default).
5779 The User can specify any point as the Reference Point.
5780 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5781 MakeGroups: forces the generation of new groups from existing ones
5782 ElemType: type of elements for extrusion (if param Base is a mesh)
5785 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5786 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5787 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5789 Example: :ref:`tui_extrusion_along_path`
5793 if ElemType == SMESH.NODE: n = Base
5794 if ElemType == SMESH.EDGE: e = Base
5795 if ElemType == SMESH.FACE: f = Base
5796 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5797 HasAngles, Angles, LinearVariation,
5798 HasRefPoint, RefPoint, MakeGroups)
5799 if MakeGroups: return gr,er
5802 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5803 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5804 MakeGroups=False, LinearVariation=False):
5806 Generate new elements by extrusion of the given elements.
5807 The path of extrusion must be a meshed edge.
5810 IDsOfElements: ids of elements
5811 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5812 PathShape: shape (edge) defines the sub-mesh for the path
5813 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5814 HasAngles: not used obsolete
5815 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5816 around *basePoint*, additionally to previous steps.
5817 HasRefPoint: allows using the reference point
5818 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5819 The User can specify any point as the Reference Point.
5820 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5821 MakeGroups: forces the generation of new groups from existing ones
5822 LinearVariation: forces the computation of rotation angles as linear
5823 variation of the given Angles along path steps
5826 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5827 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5828 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5829 Example: :ref:`tui_extrusion_along_path`
5832 if not IDsOfElements:
5833 IDsOfElements = [ self.GetMesh() ]
5834 n,e,f = [],IDsOfElements,IDsOfElements
5835 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5836 NodeStart, HasAngles, Angles,
5838 HasRefPoint, RefPoint, MakeGroups)
5839 if MakeGroups: return gr,er
5842 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5843 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5844 MakeGroups=False, LinearVariation=False):
5846 Generate new elements by extrusion of the elements which belong to the object.
5847 The path of extrusion must be a meshed edge.
5850 theObject: the object whose elements should be processed.
5851 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5852 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5853 PathShape: shape (edge) defines the sub-mesh for the path
5854 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5855 HasAngles: not used obsolete
5856 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5857 around *basePoint*, additionally to previous steps.
5858 HasRefPoint: allows using the reference point
5859 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5860 The User can specify any point as the Reference Point.
5861 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5862 MakeGroups: forces the generation of new groups from existing ones
5863 LinearVariation: forces the computation of rotation angles as linear
5864 variation of the given Angles along path steps
5867 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5868 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5869 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5870 Example: :ref:`tui_extrusion_along_path`
5873 n,e,f = [],theObject,theObject
5874 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5875 HasAngles, Angles, LinearVariation,
5876 HasRefPoint, RefPoint, MakeGroups)
5877 if MakeGroups: return gr,er
5880 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5881 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5882 MakeGroups=False, LinearVariation=False):
5884 Generate new elements by extrusion of mesh segments which belong to the object.
5885 The path of extrusion must be a meshed edge.
5888 theObject: the object whose 1D elements should be processed.
5889 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5890 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5891 PathShape: shape (edge) defines the sub-mesh for the path
5892 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5893 HasAngles: not used obsolete
5894 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5895 around *basePoint*, additionally to previous steps.
5896 HasRefPoint: allows using the reference point
5897 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5898 The User can specify any point as the Reference Point.
5899 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5900 MakeGroups: forces the generation of new groups from existing ones
5901 LinearVariation: forces the computation of rotation angles as linear
5902 variation of the given Angles along path steps
5905 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5906 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5907 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5908 Example: :ref:`tui_extrusion_along_path`
5911 n,e,f = [],theObject,[]
5912 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5913 HasAngles, Angles, LinearVariation,
5914 HasRefPoint, RefPoint, MakeGroups)
5915 if MakeGroups: return gr,er
5918 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5919 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5920 MakeGroups=False, LinearVariation=False):
5922 Generate new elements by extrusion of faces which belong to the object.
5923 The path of extrusion must be a meshed edge.
5926 theObject: the object whose 2D elements should be processed.
5927 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5928 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5929 PathShape: shape (edge) defines the sub-mesh for the path
5930 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5931 HasAngles: not used obsolete
5932 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5933 around *basePoint*, additionally to previous steps.
5934 HasRefPoint: allows using the reference point
5935 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5936 The User can specify any point as the Reference Point.
5937 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5938 MakeGroups: forces the generation of new groups from existing ones
5939 LinearVariation: forces the computation of rotation angles as linear
5940 variation of the given Angles along path steps
5943 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5944 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5945 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5946 Example: :ref:`tui_extrusion_along_path`
5949 n,e,f = [],[],theObject
5950 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5951 HasAngles, Angles, LinearVariation,
5952 HasRefPoint, RefPoint, MakeGroups)
5953 if MakeGroups: return gr,er
5956 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5958 Create a symmetrical copy of mesh elements
5961 IDsOfElements: list of elements ids
5962 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5963 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5964 If the *Mirror* is a geom object this parameter is unnecessary
5965 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5966 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5969 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5972 if IDsOfElements == []:
5973 IDsOfElements = self.GetElementsId()
5974 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5975 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5976 theMirrorType = Mirror._mirrorType
5978 self.mesh.SetParameters(Mirror.parameters)
5979 if Copy and MakeGroups:
5980 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5981 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5984 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5986 Create a new mesh by a symmetrical copy of mesh elements
5989 IDsOfElements: the list of elements ids
5990 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5991 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5992 If the *Mirror* is a geom object this parameter is unnecessary
5993 MakeGroups: to generate new groups from existing ones
5994 NewMeshName: a name of the new mesh to create
5997 instance of class :class:`Mesh`
6000 if IDsOfElements == []:
6001 IDsOfElements = self.GetElementsId()
6002 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6003 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6004 theMirrorType = Mirror._mirrorType
6006 self.mesh.SetParameters(Mirror.parameters)
6007 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6008 MakeGroups, NewMeshName)
6009 return Mesh(self.smeshpyD,self.geompyD,mesh)
6011 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6013 Create a symmetrical copy of the object
6016 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6017 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6018 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6019 If the *Mirror* is a geom object this parameter is unnecessary
6020 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6021 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6024 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6027 if ( isinstance( theObject, Mesh )):
6028 theObject = theObject.GetMesh()
6029 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6030 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6031 theMirrorType = Mirror._mirrorType
6033 self.mesh.SetParameters(Mirror.parameters)
6034 if Copy and MakeGroups:
6035 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6036 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6039 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6041 Create a new mesh by a symmetrical copy of the object
6044 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6045 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6046 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6047 If the *Mirror* is a geom object this parameter is unnecessary
6048 MakeGroups: forces the generation of new groups from existing ones
6049 NewMeshName: the name of the new mesh to create
6052 instance of class :class:`Mesh`
6055 if ( isinstance( theObject, Mesh )):
6056 theObject = theObject.GetMesh()
6057 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6058 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6059 theMirrorType = Mirror._mirrorType
6061 self.mesh.SetParameters(Mirror.parameters)
6062 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6063 MakeGroups, NewMeshName)
6064 return Mesh( self.smeshpyD,self.geompyD,mesh )
6066 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6068 Translate the elements
6071 IDsOfElements: list of elements ids
6072 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6073 Copy: allows copying the translated elements
6074 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6077 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6080 if IDsOfElements == []:
6081 IDsOfElements = self.GetElementsId()
6082 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6083 Vector = self.smeshpyD.GetDirStruct(Vector)
6084 if isinstance( Vector, list ):
6085 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6086 self.mesh.SetParameters(Vector.PS.parameters)
6087 if Copy and MakeGroups:
6088 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6089 self.editor.Translate(IDsOfElements, Vector, Copy)
6092 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6094 Create a new mesh of translated elements
6097 IDsOfElements: list of elements ids
6098 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6099 MakeGroups: forces the generation of new groups from existing ones
6100 NewMeshName: the name of the newly created mesh
6103 instance of class :class:`Mesh`
6106 if IDsOfElements == []:
6107 IDsOfElements = self.GetElementsId()
6108 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6109 Vector = self.smeshpyD.GetDirStruct(Vector)
6110 if isinstance( Vector, list ):
6111 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6112 self.mesh.SetParameters(Vector.PS.parameters)
6113 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6114 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6116 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6118 Translate the object
6121 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6122 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6123 Copy: allows copying the translated elements
6124 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6127 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6130 if ( isinstance( theObject, Mesh )):
6131 theObject = theObject.GetMesh()
6132 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6133 Vector = self.smeshpyD.GetDirStruct(Vector)
6134 if isinstance( Vector, list ):
6135 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6136 self.mesh.SetParameters(Vector.PS.parameters)
6137 if Copy and MakeGroups:
6138 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6139 self.editor.TranslateObject(theObject, Vector, Copy)
6142 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6144 Create a new mesh from the translated object
6147 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6148 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6149 MakeGroups: forces the generation of new groups from existing ones
6150 NewMeshName: the name of the newly created mesh
6153 instance of class :class:`Mesh`
6156 if isinstance( theObject, Mesh ):
6157 theObject = theObject.GetMesh()
6158 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6159 Vector = self.smeshpyD.GetDirStruct(Vector)
6160 if isinstance( Vector, list ):
6161 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6162 self.mesh.SetParameters(Vector.PS.parameters)
6163 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6164 return Mesh( self.smeshpyD, self.geompyD, mesh )
6168 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6173 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6174 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6175 theScaleFact: list of 1-3 scale factors for axises
6176 Copy: allows copying the translated elements
6177 MakeGroups: forces the generation of new groups from existing
6181 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6182 empty list otherwise
6184 unRegister = genObjUnRegister()
6185 if ( isinstance( theObject, Mesh )):
6186 theObject = theObject.GetMesh()
6187 if ( isinstance( theObject, list )):
6188 theObject = self.GetIDSource(theObject, SMESH.ALL)
6189 unRegister.set( theObject )
6190 if ( isinstance( thePoint, list )):
6191 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6192 if ( isinstance( theScaleFact, float )):
6193 theScaleFact = [theScaleFact]
6194 if ( isinstance( theScaleFact, int )):
6195 theScaleFact = [ float(theScaleFact)]
6197 self.mesh.SetParameters(thePoint.parameters)
6199 if Copy and MakeGroups:
6200 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6201 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6204 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6206 Create a new mesh from the translated object
6209 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6210 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6211 theScaleFact: list of 1-3 scale factors for axises
6212 MakeGroups: forces the generation of new groups from existing ones
6213 NewMeshName: the name of the newly created mesh
6216 instance of class :class:`Mesh`
6218 unRegister = genObjUnRegister()
6219 if (isinstance(theObject, Mesh)):
6220 theObject = theObject.GetMesh()
6221 if ( isinstance( theObject, list )):
6222 theObject = self.GetIDSource(theObject,SMESH.ALL)
6223 unRegister.set( theObject )
6224 if ( isinstance( thePoint, list )):
6225 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6226 if ( isinstance( theScaleFact, float )):
6227 theScaleFact = [theScaleFact]
6228 if ( isinstance( theScaleFact, int )):
6229 theScaleFact = [ float(theScaleFact)]
6231 self.mesh.SetParameters(thePoint.parameters)
6232 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6233 MakeGroups, NewMeshName)
6234 return Mesh( self.smeshpyD, self.geompyD, mesh )
6238 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6243 IDsOfElements: list of elements ids
6244 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6245 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6246 Copy: allows copying the rotated elements
6247 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6250 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6254 if IDsOfElements == []:
6255 IDsOfElements = self.GetElementsId()
6256 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6257 Axis = self.smeshpyD.GetAxisStruct(Axis)
6258 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6259 Parameters = Axis.parameters + var_separator + Parameters
6260 self.mesh.SetParameters(Parameters)
6261 if Copy and MakeGroups:
6262 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6263 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6266 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6268 Create a new mesh of rotated elements
6271 IDsOfElements: list of element ids
6272 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6273 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6274 MakeGroups: forces the generation of new groups from existing ones
6275 NewMeshName: the name of the newly created mesh
6278 instance of class :class:`Mesh`
6281 if IDsOfElements == []:
6282 IDsOfElements = self.GetElementsId()
6283 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6284 Axis = self.smeshpyD.GetAxisStruct(Axis)
6285 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6286 Parameters = Axis.parameters + var_separator + Parameters
6287 self.mesh.SetParameters(Parameters)
6288 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6289 MakeGroups, NewMeshName)
6290 return Mesh( self.smeshpyD, self.geompyD, mesh )
6292 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6297 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6298 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6299 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6300 Copy: allows copying the rotated elements
6301 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6304 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6307 if (isinstance(theObject, Mesh)):
6308 theObject = theObject.GetMesh()
6309 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6310 Axis = self.smeshpyD.GetAxisStruct(Axis)
6311 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6312 Parameters = Axis.parameters + ":" + Parameters
6313 self.mesh.SetParameters(Parameters)
6314 if Copy and MakeGroups:
6315 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6316 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6319 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6321 Create a new mesh from the rotated object
6324 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6325 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6326 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6327 MakeGroups: forces the generation of new groups from existing ones
6328 NewMeshName: the name of the newly created mesh
6331 instance of class :class:`Mesh`
6334 if (isinstance( theObject, Mesh )):
6335 theObject = theObject.GetMesh()
6336 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6337 Axis = self.smeshpyD.GetAxisStruct(Axis)
6338 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6339 Parameters = Axis.parameters + ":" + Parameters
6340 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6341 MakeGroups, NewMeshName)
6342 self.mesh.SetParameters(Parameters)
6343 return Mesh( self.smeshpyD, self.geompyD, mesh )
6345 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6347 Create an offset mesh from the given 2D object
6350 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6351 theValue (float): signed offset size
6352 MakeGroups (boolean): forces the generation of new groups from existing ones
6353 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6354 False means to remove original elements.
6355 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6358 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6361 if isinstance( theObject, Mesh ):
6362 theObject = theObject.GetMesh()
6363 theValue,Parameters,hasVars = ParseParameters(Value)
6364 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6365 self.mesh.SetParameters(Parameters)
6366 # if mesh_groups[0]:
6367 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6370 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6372 Find groups of adjacent nodes within Tolerance.
6375 Tolerance (float): the value of tolerance
6376 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6377 corner and medium nodes in separate groups thus preventing
6378 their further merge.
6381 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6384 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6386 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6387 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6389 Find groups of adjacent nodes within Tolerance.
6392 Tolerance: the value of tolerance
6393 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6394 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6395 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6396 corner and medium nodes in separate groups thus preventing
6397 their further merge.
6400 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6403 unRegister = genObjUnRegister()
6404 if not isinstance( SubMeshOrGroup, list ):
6405 SubMeshOrGroup = [ SubMeshOrGroup ]
6406 for i,obj in enumerate( SubMeshOrGroup ):
6407 if isinstance( obj, Mesh ):
6408 SubMeshOrGroup = [ obj.GetMesh() ]
6410 if isinstance( obj, int ):
6411 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6412 unRegister.set( SubMeshOrGroup )
6415 if not isinstance( exceptNodes, list ):
6416 exceptNodes = [ exceptNodes ]
6417 if exceptNodes and isinstance( exceptNodes[0], int ):
6418 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6419 unRegister.set( exceptNodes )
6421 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6422 exceptNodes, SeparateCornerAndMediumNodes)
6424 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6429 GroupsOfNodes: a list of groups of nodes IDs for merging.
6430 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6431 in all elements and mesh groups by nodes 1 and 25 correspondingly
6432 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6433 If *NodesToKeep* does not include a node to keep for some group to merge,
6434 then the first node in the group is kept.
6435 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6439 This operation can create gaps in numeration of nodes or elements.
6440 Call :meth:`RenumberElements` to remove the gaps.
6442 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6444 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6446 Find the elements built on the same nodes.
6449 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6450 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6454 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6457 unRegister = genObjUnRegister()
6458 if MeshOrSubMeshOrGroup is None:
6459 MeshOrSubMeshOrGroup = [ self.mesh ]
6460 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6461 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6462 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6463 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6464 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6465 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6466 unRegister.set( MeshOrSubMeshOrGroup )
6467 for item in MeshOrSubMeshOrGroup:
6468 if isinstance( item, Mesh ):
6469 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6471 if not isinstance( exceptElements, list ):
6472 exceptElements = [ exceptElements ]
6473 if exceptElements and isinstance( exceptElements[0], int ):
6474 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6475 unRegister.set( exceptElements )
6477 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6479 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6481 Merge elements in each given group.
6484 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6485 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6486 replaced in all mesh groups by elements 1 and 25)
6487 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6488 If *ElementsToKeep* does not include an element to keep for some group to merge,
6489 then the first element in the group is kept.
6492 This operation can create gaps in numeration of elements.
6493 Call :meth:`RenumberElements` to remove the gaps.
6496 unRegister = genObjUnRegister()
6498 if not isinstance( ElementsToKeep, list ):
6499 ElementsToKeep = [ ElementsToKeep ]
6500 if isinstance( ElementsToKeep[0], int ):
6501 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6502 unRegister.set( ElementsToKeep )
6504 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6506 def MergeEqualElements(self):
6508 Leave one element and remove all other elements built on the same nodes.
6511 This operation can create gaps in numeration of elements.
6512 Call :meth:`RenumberElements` to remove the gaps.
6515 self.editor.MergeEqualElements()
6517 def FindFreeBorders(self, ClosedOnly=True):
6519 Returns all or only closed free borders
6522 list of SMESH.FreeBorder's
6525 return self.editor.FindFreeBorders( ClosedOnly )
6527 def FillHole(self, holeNodes, groupName=""):
6529 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6532 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6533 must describe all sequential nodes of the hole border. The first and the last
6534 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6535 groupName (string): name of a group to add new faces
6537 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6541 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6542 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6543 if not isinstance( holeNodes, SMESH.FreeBorder ):
6544 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6545 return self.editor.FillHole( holeNodes, groupName )
6547 def FindCoincidentFreeBorders (self, tolerance=0.):
6549 Return groups of FreeBorder's coincident within the given tolerance.
6552 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6553 size of elements adjacent to free borders being compared is used.
6556 SMESH.CoincidentFreeBorders structure
6559 return self.editor.FindCoincidentFreeBorders( tolerance )
6561 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6563 Sew FreeBorder's of each group
6566 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6567 where each enclosed list contains node IDs of a group of coincident free
6568 borders such that each consequent triple of IDs within a group describes
6569 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6570 last node of a border.
6571 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6572 groups of coincident free borders, each group including two borders.
6573 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6574 polygons if a node of opposite border falls on a face edge, else such
6575 faces are split into several ones.
6576 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6577 polyhedra if a node of opposite border falls on a volume edge, else such
6578 volumes, if any, remain intact and the mesh becomes non-conformal.
6581 a number of successfully sewed groups
6584 This operation can create gaps in numeration of nodes or elements.
6585 Call :meth:`RenumberElements` to remove the gaps.
6588 if freeBorders and isinstance( freeBorders, list ):
6589 # construct SMESH.CoincidentFreeBorders
6590 if isinstance( freeBorders[0], int ):
6591 freeBorders = [freeBorders]
6593 coincidentGroups = []
6594 for nodeList in freeBorders:
6595 if not nodeList or len( nodeList ) % 3:
6596 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6599 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6600 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6601 nodeList = nodeList[3:]
6603 coincidentGroups.append( group )
6605 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6607 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6609 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6610 FirstNodeID2, SecondNodeID2, LastNodeID2,
6611 CreatePolygons, CreatePolyedrs):
6616 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6619 This operation can create gaps in numeration of nodes or elements.
6620 Call :meth:`RenumberElements` to remove the gaps.
6623 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6624 FirstNodeID2, SecondNodeID2, LastNodeID2,
6625 CreatePolygons, CreatePolyedrs)
6627 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6628 FirstNodeID2, SecondNodeID2):
6630 Sew conform free borders
6633 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6636 This operation can create gaps in numeration of elements.
6637 Call :meth:`RenumberElements` to remove the gaps.
6640 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6641 FirstNodeID2, SecondNodeID2)
6643 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6644 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6649 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6652 This operation can create gaps in numeration of elements.
6653 Call :meth:`RenumberElements` to remove the gaps.
6656 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6657 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6659 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6660 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6661 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6663 Sew two sides of a mesh. The nodes belonging to Side1 are
6664 merged with the nodes of elements of Side2.
6665 The number of elements in theSide1 and in theSide2 must be
6666 equal and they should have similar nodal connectivity.
6667 The nodes to merge should belong to side borders and
6668 the first node should be linked to the second.
6671 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6674 This operation can create gaps in numeration of nodes.
6675 Call :meth:`RenumberElements` to remove the gaps.
6678 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6679 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6680 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6682 def ChangeElemNodes(self, ide, newIDs):
6684 Set new nodes for the given element. Number of nodes should be kept.
6691 False if the number of nodes does not correspond to the type of element
6694 return self.editor.ChangeElemNodes(ide, newIDs)
6696 def GetLastCreatedNodes(self):
6698 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6699 created, this method return the list of their IDs.
6700 If new nodes were not created - return empty list
6703 the list of integer values (can be empty)
6706 return self.editor.GetLastCreatedNodes()
6708 def GetLastCreatedElems(self):
6710 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6711 created this method return the list of their IDs.
6712 If new elements were not created - return empty list
6715 the list of integer values (can be empty)
6718 return self.editor.GetLastCreatedElems()
6720 def ClearLastCreated(self):
6722 Forget what nodes and elements were created by the last mesh edition operation
6725 self.editor.ClearLastCreated()
6727 def DoubleElements(self, theElements, theGroupName=""):
6729 Create duplicates of given elements, i.e. create new elements based on the
6730 same nodes as the given ones.
6733 theElements: container of elements to duplicate. It can be a
6734 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6735 or a list of element IDs. If *theElements* is
6736 a :class:`Mesh`, elements of highest dimension are duplicated
6737 theGroupName: a name of group to contain the generated elements.
6738 If a group with such a name already exists, the new elements
6739 are added to the existing group, else a new group is created.
6740 If *theGroupName* is empty, new elements are not added
6744 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6745 None if *theGroupName* == "".
6748 unRegister = genObjUnRegister()
6749 if isinstance( theElements, Mesh ):
6750 theElements = theElements.mesh
6751 elif isinstance( theElements, list ):
6752 theElements = self.GetIDSource( theElements, SMESH.ALL )
6753 unRegister.set( theElements )
6754 return self.editor.DoubleElements(theElements, theGroupName)
6756 def DoubleNodes(self, theNodes, theModifiedElems):
6758 Create a hole in a mesh by doubling the nodes of some particular elements
6761 theNodes: IDs of nodes to be doubled
6762 theModifiedElems: IDs of elements to be updated by the new (doubled)
6763 nodes. If list of element identifiers is empty then nodes are doubled but
6764 they not assigned to elements
6767 True if operation has been completed successfully, False otherwise
6770 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6772 def DoubleNode(self, theNodeId, theModifiedElems):
6774 Create a hole in a mesh by doubling the nodes of some particular elements.
6775 This method provided for convenience works as :meth:`DoubleNodes`.
6778 theNodeId: IDs of node to double
6779 theModifiedElems: IDs of elements to update
6782 True if operation has been completed successfully, False otherwise
6785 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6787 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6789 Create a hole in a mesh by doubling the nodes of some particular elements.
6790 This method provided for convenience works as :meth:`DoubleNodes`.
6793 theNodes: group of nodes to double.
6794 theModifiedElems: group of elements to update.
6795 theMakeGroup: forces the generation of a group containing new nodes.
6798 True or a created group if operation has been completed successfully,
6799 False or None otherwise
6803 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6804 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6806 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6808 Create a hole in a mesh by doubling the nodes of some particular elements.
6809 This method provided for convenience works as :meth:`DoubleNodes`.
6812 theNodes: list of groups of nodes to double.
6813 theModifiedElems: list of groups of elements to update.
6814 theMakeGroup: forces the generation of a group containing new nodes.
6817 True if operation has been completed successfully, False otherwise
6821 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6822 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6824 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6826 Create a hole in a mesh by doubling the nodes of some particular elements
6829 theElems: the list of elements (edges or faces) to replicate.
6830 The nodes for duplication could be found from these elements
6831 theNodesNot: list of nodes NOT to replicate
6832 theAffectedElems: the list of elements (cells and edges) to which the
6833 replicated nodes should be associated to
6836 True if operation has been completed successfully, False otherwise
6839 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6841 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6843 Create a hole in a mesh by doubling the nodes of some particular elements
6846 theElems: the list of elements (edges or faces) to replicate.
6847 The nodes for duplication could be found from these elements
6848 theNodesNot: list of nodes NOT to replicate
6849 theShape: shape to detect affected elements (element which geometric center
6850 located on or inside shape).
6851 The replicated nodes should be associated to affected elements.
6854 True if operation has been completed successfully, False otherwise
6857 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6859 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6860 theMakeGroup=False, theMakeNodeGroup=False):
6862 Create a hole in a mesh by doubling the nodes of some particular elements.
6863 This method provided for convenience works as :meth:`DoubleNodes`.
6866 theElems: group of of elements (edges or faces) to replicate.
6867 theNodesNot: group of nodes NOT to replicate.
6868 theAffectedElems: group of elements to which the replicated nodes
6869 should be associated to.
6870 theMakeGroup: forces the generation of a group containing new elements.
6871 theMakeNodeGroup: forces the generation of a group containing new nodes.
6874 True or created groups (one or two) if operation has been completed successfully,
6875 False or None otherwise
6878 if theMakeGroup or theMakeNodeGroup:
6879 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6881 theMakeGroup, theMakeNodeGroup)
6882 if theMakeGroup and theMakeNodeGroup:
6885 return twoGroups[ int(theMakeNodeGroup) ]
6886 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6888 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6890 Create a hole in a mesh by doubling the nodes of some particular elements.
6891 This method provided for convenience works as :meth:`DoubleNodes`.
6894 theElems: group of of elements (edges or faces) to replicate
6895 theNodesNot: group of nodes not to replicate
6896 theShape: shape to detect affected elements (element which geometric center
6897 located on or inside shape).
6898 The replicated nodes should be associated to affected elements
6901 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6903 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6904 theMakeGroup=False, theMakeNodeGroup=False):
6906 Create a hole in a mesh by doubling the nodes of some particular elements.
6907 This method provided for convenience works as :meth:`DoubleNodes`.
6910 theElems: list of groups of elements (edges or faces) to replicate
6911 theNodesNot: list of groups of nodes NOT to replicate
6912 theAffectedElems: group of elements to which the replicated nodes
6913 should be associated to
6914 theMakeGroup: forces generation of a group containing new elements.
6915 theMakeNodeGroup: forces generation of a group containing new nodes
6918 True or created groups (one or two) if operation has been completed successfully,
6919 False or None otherwise
6922 if theMakeGroup or theMakeNodeGroup:
6923 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6925 theMakeGroup, theMakeNodeGroup)
6926 if theMakeGroup and theMakeNodeGroup:
6929 return twoGroups[ int(theMakeNodeGroup) ]
6930 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6932 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6934 Create a hole in a mesh by doubling the nodes of some particular elements.
6935 This method provided for convenience works as :meth:`DoubleNodes`.
6938 theElems: list of groups of elements (edges or faces) to replicate
6939 theNodesNot: list of groups of nodes NOT to replicate
6940 theShape: shape to detect affected elements (element which geometric center
6941 located on or inside shape).
6942 The replicated nodes should be associated to affected elements
6945 True if operation has been completed successfully, False otherwise
6948 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6950 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6952 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6953 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6956 theElems: list of groups of nodes or elements (edges or faces) to replicate
6957 theNodesNot: list of groups of nodes NOT to replicate
6958 theShape: shape to detect affected elements (element which geometric center
6959 located on or inside shape).
6960 The replicated nodes should be associated to affected elements
6963 groups of affected elements in order: volumes, faces, edges
6966 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6968 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6971 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6972 The list of groups must describe a partition of the mesh volumes.
6973 The nodes of the internal faces at the boundaries of the groups are doubled.
6974 In option, the internal faces are replaced by flat elements.
6975 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6978 theDomains: list of groups of volumes
6979 createJointElems: if True, create the elements
6980 onAllBoundaries: if True, the nodes and elements are also created on
6981 the boundary between *theDomains* and the rest mesh
6984 True if operation has been completed successfully, False otherwise
6987 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6989 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6991 Double nodes on some external faces and create flat elements.
6992 Flat elements are mainly used by some types of mechanic calculations.
6994 Each group of the list must be constituted of faces.
6995 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6998 theGroupsOfFaces: list of groups of faces
7001 True if operation has been completed successfully, False otherwise
7004 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7006 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7008 Identify all the elements around a geom shape, get the faces delimiting the hole
7010 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7012 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7014 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7015 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7016 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7017 If there are several paths connecting a pair of points, the shortest path is
7018 selected by the module. Position of the cutting plane is defined by the two
7019 points and an optional vector lying on the plane specified by a PolySegment.
7020 By default the vector is defined by Mesh module as following. A middle point
7021 of the two given points is computed. The middle point is projected to the mesh.
7022 The vector goes from the middle point to the projection point. In case of planar
7023 mesh, the vector is normal to the mesh.
7025 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7028 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7029 groupName: optional name of a group where created mesh segments will be added.
7032 editor = self.editor
7034 editor = self.mesh.GetMeshEditPreviewer()
7035 segmentsRes = editor.MakePolyLine( segments, groupName )
7036 for i, seg in enumerate( segmentsRes ):
7037 segments[i].vector = seg.vector
7039 return editor.GetPreviewData()
7042 def MakeSlot(self, segmentGroup, width ):
7044 Create a slot of given width around given 1D elements lying on a triangle mesh.
7045 The slot is constructed by cutting faces by cylindrical surfaces made
7046 around each segment. Segments are expected to be created by MakePolyLine().
7049 FaceEdge's located at the slot boundary
7051 return self.editor.MakeSlot( segmentGroup, width )
7053 def GetFunctor(self, funcType ):
7055 Return a cached numerical functor by its type.
7058 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7059 Note that not all items correspond to numerical functors.
7062 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7065 fn = self.functors[ funcType._v ]
7067 fn = self.smeshpyD.GetFunctor(funcType)
7068 fn.SetMesh(self.mesh)
7069 self.functors[ funcType._v ] = fn
7072 def FunctorValue(self, funcType, elemId, isElem=True):
7074 Return value of a functor for a given element
7077 funcType: an item of :class:`SMESH.FunctorType` enum.
7078 elemId: element or node ID
7079 isElem: *elemId* is ID of element or node
7082 the functor value or zero in case of invalid arguments
7085 fn = self.GetFunctor( funcType )
7086 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7087 val = fn.GetValue(elemId)
7092 def GetLength(self, elemId=None):
7094 Get length of given 1D elements or of all 1D mesh elements
7097 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
7100 Sum of lengths of given elements
7105 length = self.smeshpyD.GetLength(self)
7106 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7107 length = self.smeshpyD.GetLength(elemId)
7110 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7112 length += self.smeshpyD.GetLength(obj)
7113 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7114 unRegister = genObjUnRegister()
7115 obj = self.GetIDSource( elemId )
7116 unRegister.set( obj )
7117 length = self.smeshpyD.GetLength( obj )
7119 length = self.FunctorValue(SMESH.FT_Length, elemId)
7122 def GetArea(self, elemId=None):
7124 Get area of given 2D elements or of all 2D mesh elements
7127 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
7130 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7135 area = self.smeshpyD.GetArea(self)
7136 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7137 area = self.smeshpyD.GetArea(elemId)
7140 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7142 area += self.smeshpyD.GetArea(obj)
7143 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7144 unRegister = genObjUnRegister()
7145 obj = self.GetIDSource( elemId )
7146 unRegister.set( obj )
7147 area = self.smeshpyD.GetArea( obj )
7149 area = self.FunctorValue(SMESH.FT_Area, elemId)
7152 def GetVolume(self, elemId=None):
7154 Get volume of given 3D elements or of all 3D mesh elements
7157 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
7160 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7165 volume= self.smeshpyD.GetVolume(self)
7166 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7167 volume= self.smeshpyD.GetVolume(elemId)
7170 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7172 volume+= self.smeshpyD.GetVolume(obj)
7173 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7174 unRegister = genObjUnRegister()
7175 obj = self.GetIDSource( elemId )
7176 unRegister.set( obj )
7177 volume= self.smeshpyD.GetVolume( obj )
7179 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7182 def GetAngle(self, node1, node2, node3 ):
7184 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7187 node1,node2,node3: IDs of the three nodes
7190 Angle in radians [0,PI]. -1 if failure case.
7192 p1 = self.GetNodeXYZ( node1 )
7193 p2 = self.GetNodeXYZ( node2 )
7194 p3 = self.GetNodeXYZ( node3 )
7195 if p1 and p2 and p3:
7196 return self.smeshpyD.GetAngle( p1,p2,p3 )
7200 def GetMaxElementLength(self, elemId):
7202 Get maximum element length.
7205 elemId: mesh element ID
7208 element's maximum length value
7211 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7212 ftype = SMESH.FT_MaxElementLength3D
7214 ftype = SMESH.FT_MaxElementLength2D
7215 return self.FunctorValue(ftype, elemId)
7217 def GetAspectRatio(self, elemId):
7219 Get aspect ratio of 2D or 3D element.
7222 elemId: mesh element ID
7225 element's aspect ratio value
7228 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7229 ftype = SMESH.FT_AspectRatio3D
7231 ftype = SMESH.FT_AspectRatio
7232 return self.FunctorValue(ftype, elemId)
7234 def GetWarping(self, elemId):
7236 Get warping angle of 2D element.
7239 elemId: mesh element ID
7242 element's warping angle value
7245 return self.FunctorValue(SMESH.FT_Warping, elemId)
7247 def GetMinimumAngle(self, elemId):
7249 Get minimum angle of 2D element.
7252 elemId: mesh element ID
7255 element's minimum angle value
7258 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7260 def GetTaper(self, elemId):
7262 Get taper of 2D element.
7265 elemId: mesh element ID
7268 element's taper value
7271 return self.FunctorValue(SMESH.FT_Taper, elemId)
7273 def GetSkew(self, elemId):
7275 Get skew of 2D element.
7278 elemId: mesh element ID
7281 element's skew value
7284 return self.FunctorValue(SMESH.FT_Skew, elemId)
7286 def GetMinMax(self, funType, meshPart=None):
7288 Return minimal and maximal value of a given functor.
7291 funType (SMESH.FunctorType): a functor type.
7292 Note that not all items of :class:`SMESH.FunctorType` corresponds
7293 to numerical functors.
7294 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7300 unRegister = genObjUnRegister()
7301 if isinstance( meshPart, list ):
7302 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7303 unRegister.set( meshPart )
7304 if isinstance( meshPart, Mesh ):
7305 meshPart = meshPart.mesh
7306 fun = self.GetFunctor( funType )
7309 if hasattr( meshPart, "SetMesh" ):
7310 meshPart.SetMesh( self.mesh ) # set mesh to filter
7311 hist = fun.GetLocalHistogram( 1, False, meshPart )
7313 hist = fun.GetHistogram( 1, False )
7315 return hist[0].min, hist[0].max
7318 pass # end of Mesh class
7321 class meshProxy(SMESH._objref_SMESH_Mesh):
7323 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7324 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7326 def __init__(self,*args):
7327 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7328 def __deepcopy__(self, memo=None):
7329 new = self.__class__(self)
7331 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7332 if len( args ) == 3:
7333 args += SMESH.ALL_NODES, True
7334 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7335 def ExportToMEDX(self, *args): # function removed
7336 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7337 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7338 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7339 def ExportToMED(self, *args): # function removed
7340 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7341 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7343 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7345 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7346 def ExportPartToMED(self, *args): # 'version' parameter removed
7347 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7348 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7349 def ExportMED(self, *args): # signature of method changed
7350 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7352 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7354 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7356 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7359 class submeshProxy(SMESH._objref_SMESH_subMesh):
7362 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7364 def __init__(self,*args):
7365 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7367 def __deepcopy__(self, memo=None):
7368 new = self.__class__(self)
7371 def Compute(self,refresh=False):
7373 Compute the sub-mesh and return the status of the computation
7376 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7381 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7382 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7386 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7388 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7390 if salome.sg.hasDesktop():
7391 if refresh: salome.sg.updateObjBrowser()
7396 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7399 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7401 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7402 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7405 def __init__(self,*args):
7406 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7408 def __getattr__(self, name ): # method called if an attribute not found
7409 if not self.mesh: # look for name() method in Mesh class
7410 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7411 if hasattr( self.mesh, name ):
7412 return getattr( self.mesh, name )
7413 if name == "ExtrusionAlongPathObjX":
7414 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7415 print("meshEditor: attribute '%s' NOT FOUND" % name)
7417 def __deepcopy__(self, memo=None):
7418 new = self.__class__(self)
7420 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7421 if len( args ) == 1: args += False,
7422 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7423 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7424 if len( args ) == 2: args += False,
7425 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7426 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7427 if len( args ) == 1:
7428 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7429 NodesToKeep = args[1]
7430 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7431 unRegister = genObjUnRegister()
7433 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7434 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7435 if not isinstance( NodesToKeep, list ):
7436 NodesToKeep = [ NodesToKeep ]
7437 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7439 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7441 class Pattern(SMESH._objref_SMESH_Pattern):
7443 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7444 variables in some methods
7447 def LoadFromFile(self, patternTextOrFile ):
7448 text = patternTextOrFile
7449 if os.path.exists( text ):
7450 text = open( patternTextOrFile ).read()
7452 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7454 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7455 decrFun = lambda i: i-1
7456 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7457 theMesh.SetParameters(Parameters)
7458 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7460 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7461 decrFun = lambda i: i-1
7462 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7463 theMesh.SetParameters(Parameters)
7464 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7466 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7467 if isinstance( mesh, Mesh ):
7468 mesh = mesh.GetMesh()
7469 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7471 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7473 Registering the new proxy for Pattern
7478 Private class used to bind methods creating algorithms to the class Mesh
7481 def __init__(self, method):
7483 self.defaultAlgoType = ""
7484 self.algoTypeToClass = {}
7485 self.method = method
7487 def add(self, algoClass):
7489 Store a python class of algorithm
7491 if inspect.isclass(algoClass) and \
7492 hasattr( algoClass, "algoType"):
7493 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7494 if not self.defaultAlgoType and \
7495 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7496 self.defaultAlgoType = algoClass.algoType
7497 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7499 def copy(self, mesh):
7501 Create a copy of self and assign mesh to the copy
7504 other = algoCreator( self.method )
7505 other.defaultAlgoType = self.defaultAlgoType
7506 other.algoTypeToClass = self.algoTypeToClass
7510 def __call__(self,algo="",geom=0,*args):
7512 Create an instance of algorithm
7516 if isinstance( algo, str ):
7518 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7519 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7524 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7526 elif not algoType and isinstance( geom, str ):
7531 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7533 elif isinstance( arg, str ) and not algoType:
7536 import traceback, sys
7537 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7538 sys.stderr.write( msg + '\n' )
7539 tb = traceback.extract_stack(None,2)
7540 traceback.print_list( [tb[0]] )
7542 algoType = self.defaultAlgoType
7543 if not algoType and self.algoTypeToClass:
7544 algoType = sorted( self.algoTypeToClass.keys() )[0]
7545 if algoType in self.algoTypeToClass:
7546 #print("Create algo",algoType)
7547 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7548 raise RuntimeError( "No class found for algo type %s" % algoType)
7551 class hypMethodWrapper:
7553 Private class used to substitute and store variable parameters of hypotheses.
7556 def __init__(self, hyp, method):
7558 self.method = method
7559 #print("REBIND:", method.__name__)
7562 def __call__(self,*args):
7564 call a method of hypothesis with calling SetVarParameter() before
7568 return self.method( self.hyp, *args ) # hypothesis method with no args
7570 #print("MethWrapper.__call__", self.method.__name__, args)
7572 parsed = ParseParameters(*args) # replace variables with their values
7573 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7574 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7575 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7576 # maybe there is a replaced string arg which is not variable
7577 result = self.method( self.hyp, *args )
7578 except ValueError as detail: # raised by ParseParameters()
7580 result = self.method( self.hyp, *args )
7581 except omniORB.CORBA.BAD_PARAM:
7582 raise ValueError(detail) # wrong variable name
7587 class genObjUnRegister:
7589 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7592 def __init__(self, genObj=None):
7593 self.genObjList = []
7597 def set(self, genObj):
7598 "Store one or a list of of SALOME.GenericObj'es"
7599 if isinstance( genObj, list ):
7600 self.genObjList.extend( genObj )
7602 self.genObjList.append( genObj )
7606 for genObj in self.genObjList:
7607 if genObj and hasattr( genObj, "UnRegister" ):
7610 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7612 Bind methods creating mesher plug-ins to the Mesh class
7615 # print("pluginName: ", pluginName)
7616 pluginBuilderName = pluginName + "Builder"
7618 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7619 except Exception as e:
7620 from salome_utils import verbose
7621 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7623 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7624 plugin = eval( pluginBuilderName )
7625 # print(" plugin:" , str(plugin))
7627 # add methods creating algorithms to Mesh
7628 for k in dir( plugin ):
7629 if k[0] == '_': continue
7630 algo = getattr( plugin, k )
7631 #print(" algo:", str(algo))
7632 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7633 #print(" meshMethod:" , str(algo.meshMethod))
7634 if not hasattr( Mesh, algo.meshMethod ):
7635 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7637 _mmethod = getattr( Mesh, algo.meshMethod )
7638 if hasattr( _mmethod, "add" ):