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 order in which concurrent sub-meshes should be meshed
2078 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2081 return self.mesh.SetMeshOrder(submeshes)
2083 def Clear(self, refresh=False):
2085 Remove all nodes and elements generated on geometry. Imported elements remain.
2088 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2092 if ( salome.sg.hasDesktop() ):
2093 if refresh: salome.sg.updateObjBrowser()
2095 def ClearSubMesh(self, geomId, refresh=False):
2097 Remove all nodes and elements of indicated shape
2100 geomId: the ID of a sub-shape to remove elements on
2101 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2104 self.mesh.ClearSubMesh(geomId)
2105 if salome.sg.hasDesktop():
2106 if refresh: salome.sg.updateObjBrowser()
2108 def AutomaticTetrahedralization(self, fineness=0):
2110 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2113 fineness: [0.0,1.0] defines mesh fineness
2119 dim = self.MeshDimension()
2121 self.RemoveGlobalHypotheses()
2122 self.Segment().AutomaticLength(fineness)
2124 self.Triangle().LengthFromEdges()
2129 return self.Compute()
2131 def AutomaticHexahedralization(self, fineness=0):
2133 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2136 fineness: [0.0, 1.0] defines mesh fineness
2142 dim = self.MeshDimension()
2143 # assign the hypotheses
2144 self.RemoveGlobalHypotheses()
2145 self.Segment().AutomaticLength(fineness)
2152 return self.Compute()
2154 def AddHypothesis(self, hyp, geom=0):
2159 hyp: a hypothesis to assign
2160 geom: a subhape of mesh geometry
2163 :class:`SMESH.Hypothesis_Status`
2166 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2167 hyp, geom = geom, hyp
2168 if isinstance( hyp, Mesh_Algorithm ):
2169 hyp = hyp.GetAlgorithm()
2174 geom = self.mesh.GetShapeToMesh()
2177 if self.mesh.HasShapeToMesh():
2178 hyp_type = hyp.GetName()
2179 lib_name = hyp.GetLibName()
2180 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2181 # if checkAll and geom:
2182 # checkAll = geom.GetType() == 37
2184 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2186 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2187 status = self.mesh.AddHypothesis(geom, hyp)
2189 status = HYP_BAD_GEOMETRY, ""
2190 hyp_name = GetName( hyp )
2193 geom_name = geom.GetName()
2194 isAlgo = hyp._narrow( SMESH_Algo )
2195 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2198 def IsUsedHypothesis(self, hyp, geom):
2200 Return True if an algorithm or hypothesis is assigned to a given shape
2203 hyp: an algorithm or hypothesis to check
2204 geom: a subhape of mesh geometry
2210 if not hyp: # or not geom
2212 if isinstance( hyp, Mesh_Algorithm ):
2213 hyp = hyp.GetAlgorithm()
2215 hyps = self.GetHypothesisList(geom)
2217 if h.GetId() == hyp.GetId():
2221 def RemoveHypothesis(self, hyp, geom=0):
2223 Unassign a hypothesis
2226 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2227 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2230 :class:`SMESH.Hypothesis_Status`
2235 if isinstance( hyp, Mesh_Algorithm ):
2236 hyp = hyp.GetAlgorithm()
2242 if self.IsUsedHypothesis( hyp, shape ):
2243 return self.mesh.RemoveHypothesis( shape, hyp )
2244 hypName = GetName( hyp )
2245 geoName = GetName( shape )
2246 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2249 def GetHypothesisList(self, geom):
2251 Get the list of hypotheses added on a geometry
2254 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2257 the sequence of :class:`SMESH.SMESH_Hypothesis`
2260 return self.mesh.GetHypothesisList( geom )
2262 def RemoveGlobalHypotheses(self):
2264 Remove all global hypotheses
2267 current_hyps = self.mesh.GetHypothesisList( self.geom )
2268 for hyp in current_hyps:
2269 self.mesh.RemoveHypothesis( self.geom, hyp )
2272 def ExportMED(self, *args, **kwargs):
2274 Export the mesh in a file in MED format
2275 allowing to overwrite the file if it exists or add the exported data to its contents
2278 fileName: is the file name
2279 auto_groups (boolean): parameter for creating/not creating
2280 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2281 the typical use is auto_groups=False.
2282 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2283 The minor must be between 0 and the current minor version of MED file library.
2284 If minor is equal to -1, the minor version is not changed (default).
2285 The major version (x, where version is x.y.z) cannot be changed.
2286 overwrite (boolean): parameter for overwriting/not overwriting the file
2287 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2288 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2290 - 1D if all mesh nodes lie on OX coordinate axis, or
2291 - 2D if all mesh nodes lie on XOY coordinate plane, or
2292 - 3D in the rest cases.
2294 If *autoDimension* is *False*, the space dimension is always 3.
2295 fields: list of GEOM fields defined on the shape to mesh.
2296 geomAssocFields: each character of this string means a need to export a
2297 corresponding field; correspondence between fields and characters
2300 - 'v' stands for "_vertices_" field;
2301 - 'e' stands for "_edges_" field;
2302 - 'f' stands for "_faces_" field;
2303 - 's' stands for "_solids_" field.
2305 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2306 close to zero within a given tolerance, the coordinate is set to zero.
2307 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2309 # process positional arguments
2310 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2312 auto_groups = args[1] if len(args) > 1 else False
2313 minor = args[2] if len(args) > 2 else -1
2314 overwrite = args[3] if len(args) > 3 else True
2315 meshPart = args[4] if len(args) > 4 else None
2316 autoDimension = args[5] if len(args) > 5 else True
2317 fields = args[6] if len(args) > 6 else []
2318 geomAssocFields = args[7] if len(args) > 7 else ''
2319 z_tolerance = args[8] if len(args) > 8 else -1.
2320 # process keywords arguments
2321 auto_groups = kwargs.get("auto_groups", auto_groups)
2322 minor = kwargs.get("minor", minor)
2323 overwrite = kwargs.get("overwrite", overwrite)
2324 meshPart = kwargs.get("meshPart", meshPart)
2325 autoDimension = kwargs.get("autoDimension", autoDimension)
2326 fields = kwargs.get("fields", fields)
2327 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2328 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2330 # invoke engine's function
2331 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2332 unRegister = genObjUnRegister()
2333 if isinstance( meshPart, list ):
2334 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2335 unRegister.set( meshPart )
2337 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2338 self.mesh.SetParameters(Parameters)
2340 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2341 fields, geomAssocFields, z_tolerance)
2343 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2345 def ExportSAUV(self, f, auto_groups=0):
2347 Export the mesh in a file in SAUV format
2352 auto_groups: boolean parameter for creating/not creating
2353 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2354 the typical use is auto_groups=False.
2357 self.mesh.ExportSAUV(f, auto_groups)
2359 def ExportDAT(self, f, meshPart=None):
2361 Export the mesh in a file in DAT format
2365 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2369 unRegister = genObjUnRegister()
2370 if isinstance( meshPart, list ):
2371 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2372 unRegister.set( meshPart )
2373 self.mesh.ExportPartToDAT( meshPart, f )
2375 self.mesh.ExportDAT(f)
2377 def ExportUNV(self, f, meshPart=None):
2379 Export the mesh in a file in UNV format
2383 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2387 unRegister = genObjUnRegister()
2388 if isinstance( meshPart, list ):
2389 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2390 unRegister.set( meshPart )
2391 self.mesh.ExportPartToUNV( meshPart, f )
2393 self.mesh.ExportUNV(f)
2395 def ExportSTL(self, f, ascii=1, meshPart=None):
2397 Export the mesh in a file in STL format
2401 ascii: defines the file encoding
2402 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2406 unRegister = genObjUnRegister()
2407 if isinstance( meshPart, list ):
2408 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2409 unRegister.set( meshPart )
2410 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2412 self.mesh.ExportSTL(f, ascii)
2414 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2416 Export the mesh in a file in CGNS format
2420 overwrite: boolean parameter for overwriting/not overwriting the file
2421 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2422 groupElemsByType: if True all elements of same entity type are exported at ones,
2423 else elements are exported in order of their IDs which can cause creation
2424 of multiple cgns sections
2427 unRegister = genObjUnRegister()
2428 if isinstance( meshPart, list ):
2429 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2430 unRegister.set( meshPart )
2431 if isinstance( meshPart, Mesh ):
2432 meshPart = meshPart.mesh
2434 meshPart = self.mesh
2435 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2437 def ExportGMF(self, f, meshPart=None):
2439 Export the mesh in a file in GMF format.
2440 GMF files must have .mesh extension for the ASCII format and .meshb for
2441 the bynary format. Other extensions are not allowed.
2445 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2448 unRegister = genObjUnRegister()
2449 if isinstance( meshPart, list ):
2450 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2451 unRegister.set( meshPart )
2452 if isinstance( meshPart, Mesh ):
2453 meshPart = meshPart.mesh
2455 meshPart = self.mesh
2456 self.mesh.ExportGMF(meshPart, f, True)
2458 def ExportToMED(self, *args, **kwargs):
2460 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2461 Export the mesh in a file in MED format
2462 allowing to overwrite the file if it exists or add the exported data to its contents
2465 fileName: the file name
2466 opt (boolean): parameter for creating/not creating
2467 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2468 overwrite: boolean parameter for overwriting/not overwriting the file
2469 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2471 - 1D if all mesh nodes lie on OX coordinate axis, or
2472 - 2D if all mesh nodes lie on XOY coordinate plane, or
2473 - 3D in the rest cases.
2475 If **autoDimension** is *False*, the space dimension is always 3.
2478 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2479 # process positional arguments
2480 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2482 auto_groups = args[1] if len(args) > 1 else False
2483 overwrite = args[2] if len(args) > 2 else True
2484 autoDimension = args[3] if len(args) > 3 else True
2485 # process keywords arguments
2486 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2487 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2488 overwrite = kwargs.get("overwrite", overwrite)
2489 autoDimension = kwargs.get("autoDimension", autoDimension)
2491 # invoke engine's function
2492 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2494 def ExportToMEDX(self, *args, **kwargs):
2496 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2497 Export the mesh in a file in MED format
2500 fileName: the file name
2501 opt (boolean): parameter for creating/not creating
2502 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2503 overwrite: boolean parameter for overwriting/not overwriting the file
2504 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2506 - 1D if all mesh nodes lie on OX coordinate axis, or
2507 - 2D if all mesh nodes lie on XOY coordinate plane, or
2508 - 3D in the rest cases.
2510 If **autoDimension** is *False*, the space dimension is always 3.
2513 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2514 # process positional arguments
2515 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2517 auto_groups = args[1] if len(args) > 1 else False
2518 overwrite = args[2] if len(args) > 2 else True
2519 autoDimension = args[3] if len(args) > 3 else True
2520 # process keywords arguments
2521 auto_groups = kwargs.get("auto_groups", auto_groups)
2522 overwrite = kwargs.get("overwrite", overwrite)
2523 autoDimension = kwargs.get("autoDimension", autoDimension)
2525 # invoke engine's function
2526 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2530 def Append(self, meshes, uniteIdenticalGroups = True,
2531 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2533 Append given meshes into this mesh.
2534 All groups of input meshes will be created in this mesh.
2537 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2538 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2539 mergeNodesAndElements: if True, equal nodes and elements are merged
2540 mergeTolerance: tolerance for merging nodes
2541 allGroups: forces creation of groups corresponding to every input mesh
2543 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2544 mergeNodesAndElements, mergeTolerance, allGroups,
2545 meshToAppendTo = self.GetMesh() )
2547 # Operations with groups:
2548 # ----------------------
2549 def CreateEmptyGroup(self, elementType, name):
2551 Create an empty standalone mesh group
2554 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2555 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2556 name: the name of the mesh group
2559 :class:`SMESH.SMESH_Group`
2562 return self.mesh.CreateGroup(elementType, name)
2564 def Group(self, grp, name=""):
2566 Create a mesh group based on the geometric object *grp*
2567 and give it a *name*.
2568 If *name* is not defined the name of the geometric group is used
2571 Works like :meth:`GroupOnGeom`.
2574 grp: a geometric group, a vertex, an edge, a face or a solid
2575 name: the name of the mesh group
2578 :class:`SMESH.SMESH_GroupOnGeom`
2581 return self.GroupOnGeom(grp, name)
2583 def GroupOnGeom(self, grp, name="", typ=None):
2585 Create a mesh group based on the geometrical object *grp*
2586 and give it a *name*.
2587 if *name* is not defined the name of the geometric group is used
2590 grp: a geometrical group, a vertex, an edge, a face or a solid
2591 name: the name of the mesh group
2592 typ: the type of elements in the group; either of
2593 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2594 automatically detected by the type of the geometry
2597 :class:`SMESH.SMESH_GroupOnGeom`
2600 AssureGeomPublished( self, grp, name )
2602 name = grp.GetName()
2604 typ = self._groupTypeFromShape( grp )
2605 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2607 def _groupTypeFromShape( self, shape ):
2609 Pivate method to get a type of group on geometry
2611 tgeo = str(shape.GetShapeType())
2612 if tgeo == "VERTEX":
2614 elif tgeo == "EDGE":
2616 elif tgeo == "FACE" or tgeo == "SHELL":
2618 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2620 elif tgeo == "COMPOUND":
2621 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2623 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2624 return self._groupTypeFromShape( sub[0] )
2626 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2629 def GroupOnFilter(self, typ, name, filter):
2631 Create a mesh group with given *name* based on the *filter*.
2632 It is a special type of group dynamically updating it's contents during
2636 typ: the type of elements in the group; either of
2637 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2638 name: the name of the mesh group
2639 filter (SMESH.Filter): the filter defining group contents
2642 :class:`SMESH.SMESH_GroupOnFilter`
2645 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2647 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2649 Create a mesh group by the given ids of elements
2652 groupName: the name of the mesh group
2653 elementType: the type of elements in the group; either of
2654 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2655 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2658 :class:`SMESH.SMESH_Group`
2661 group = self.mesh.CreateGroup(elementType, groupName)
2662 if isinstance( elemIDs, Mesh ):
2663 elemIDs = elemIDs.GetMesh()
2664 if hasattr( elemIDs, "GetIDs" ):
2665 if hasattr( elemIDs, "SetMesh" ):
2666 elemIDs.SetMesh( self.GetMesh() )
2667 group.AddFrom( elemIDs )
2675 CritType=FT_Undefined,
2678 UnaryOp=FT_Undefined,
2681 Create a mesh group by the given conditions
2684 groupName: the name of the mesh group
2685 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2686 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2687 Note that the items starting from FT_LessThan are not suitable for CritType.
2688 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2689 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2690 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2691 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2692 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2695 :class:`SMESH.SMESH_GroupOnFilter`
2698 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2699 group = self.MakeGroupByCriterion(groupName, aCriterion)
2702 def MakeGroupByCriterion(self, groupName, Criterion):
2704 Create a mesh group by the given criterion
2707 groupName: the name of the mesh group
2708 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2711 :class:`SMESH.SMESH_GroupOnFilter`
2714 :meth:`smeshBuilder.GetCriterion`
2717 return self.MakeGroupByCriteria( groupName, [Criterion] )
2719 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2721 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2724 groupName: the name of the mesh group
2725 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2726 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2729 :class:`SMESH.SMESH_GroupOnFilter`
2732 :meth:`smeshBuilder.GetCriterion`
2735 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2736 group = self.MakeGroupByFilter(groupName, aFilter)
2739 def MakeGroupByFilter(self, groupName, theFilter):
2741 Create a mesh group by the given filter
2744 groupName (string): the name of the mesh group
2745 theFilter (SMESH.Filter): the filter
2748 :class:`SMESH.SMESH_GroupOnFilter`
2751 :meth:`smeshBuilder.GetFilter`
2754 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2755 #theFilter.SetMesh( self.mesh )
2756 #group.AddFrom( theFilter )
2757 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2760 def RemoveGroup(self, group):
2765 group (SMESH.SMESH_GroupBase): group to remove
2768 self.mesh.RemoveGroup(group)
2770 def RemoveGroupWithContents(self, group):
2772 Remove a group with its contents
2775 group (SMESH.SMESH_GroupBase): group to remove
2778 This operation can create gaps in numeration of nodes or elements.
2779 Call :meth:`RenumberElements` to remove the gaps.
2782 self.mesh.RemoveGroupWithContents(group)
2784 def GetGroups(self, elemType = SMESH.ALL):
2786 Get the list of groups existing in the mesh in the order of creation
2787 (starting from the oldest one)
2790 elemType (SMESH.ElementType): type of elements the groups contain;
2791 by default groups of elements of all types are returned
2794 a list of :class:`SMESH.SMESH_GroupBase`
2797 groups = self.mesh.GetGroups()
2798 if elemType == SMESH.ALL:
2802 if g.GetType() == elemType:
2803 typedGroups.append( g )
2810 Get the number of groups existing in the mesh
2813 the quantity of groups as an integer value
2816 return self.mesh.NbGroups()
2818 def GetGroupNames(self):
2820 Get the list of names of groups existing in the mesh
2826 groups = self.GetGroups()
2828 for group in groups:
2829 names.append(group.GetName())
2832 def GetGroupByName(self, name, elemType = None):
2834 Find groups by name and type
2837 name (string): name of the group of interest
2838 elemType (SMESH.ElementType): type of elements the groups contain;
2839 by default one group of any type is returned;
2840 if elemType == SMESH.ALL then all groups of any type are returned
2843 a list of :class:`SMESH.SMESH_GroupBase`
2847 for group in self.GetGroups():
2848 if group.GetName() == name:
2849 if elemType is None:
2851 if ( elemType == SMESH.ALL or
2852 group.GetType() == elemType ):
2853 groups.append( group )
2856 def UnionGroups(self, group1, group2, name):
2858 Produce a union of two groups.
2859 A new group is created. All mesh elements that are
2860 present in the initial groups are added to the new one
2863 group1 (SMESH.SMESH_GroupBase): a group
2864 group2 (SMESH.SMESH_GroupBase): another group
2867 instance of :class:`SMESH.SMESH_Group`
2870 return self.mesh.UnionGroups(group1, group2, name)
2872 def UnionListOfGroups(self, groups, name):
2874 Produce a union list of groups.
2875 New group is created. All mesh elements that are present in
2876 initial groups are added to the new one
2879 groups: list of :class:`SMESH.SMESH_GroupBase`
2882 instance of :class:`SMESH.SMESH_Group`
2884 return self.mesh.UnionListOfGroups(groups, name)
2886 def IntersectGroups(self, group1, group2, name):
2888 Prodice an intersection of two groups.
2889 A new group is created. All mesh elements that are common
2890 for the two initial groups are added to the new one.
2893 group1 (SMESH.SMESH_GroupBase): a group
2894 group2 (SMESH.SMESH_GroupBase): another group
2897 instance of :class:`SMESH.SMESH_Group`
2900 return self.mesh.IntersectGroups(group1, group2, name)
2902 def IntersectListOfGroups(self, groups, name):
2904 Produce an intersection of groups.
2905 New group is created. All mesh elements that are present in all
2906 initial groups simultaneously are added to the new one
2909 groups: a list of :class:`SMESH.SMESH_GroupBase`
2912 instance of :class:`SMESH.SMESH_Group`
2914 return self.mesh.IntersectListOfGroups(groups, name)
2916 def CutGroups(self, main_group, tool_group, name):
2918 Produce a cut of two groups.
2919 A new group is created. All mesh elements that are present in
2920 the main group but are not present in the tool group are added to the new one
2923 main_group (SMESH.SMESH_GroupBase): a group to cut from
2924 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2927 an instance of :class:`SMESH.SMESH_Group`
2930 return self.mesh.CutGroups(main_group, tool_group, name)
2932 def CutListOfGroups(self, main_groups, tool_groups, name):
2934 Produce a cut of groups.
2935 A new group is created. All mesh elements that are present in main groups
2936 but do not present in tool groups are added to the new one
2939 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2940 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2943 an instance of :class:`SMESH.SMESH_Group`
2946 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2948 def CreateDimGroup(self, groups, elemType, name,
2949 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2951 Create a standalone group of entities basing on nodes of other groups.
2954 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2955 elemType: a type of elements to include to the new group; either of
2956 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2957 name: a name of the new group.
2958 nbCommonNodes: a criterion of inclusion of an element to the new group
2959 basing on number of element nodes common with reference *groups*.
2960 Meaning of possible values are:
2962 - SMESH.ALL_NODES - include if all nodes are common,
2963 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2964 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2965 - SMEHS.MAJORITY - include if half of nodes or more are common.
2966 underlyingOnly: if *True* (default), an element is included to the
2967 new group provided that it is based on nodes of an element of *groups*;
2968 in this case the reference *groups* are supposed to be of higher dimension
2969 than *elemType*, which can be useful for example to get all faces lying on
2970 volumes of the reference *groups*.
2973 an instance of :class:`SMESH.SMESH_Group`
2976 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2978 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2980 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2982 Distribute all faces of the mesh among groups using sharp edges and optionally
2983 existing 1D elements as group boundaries.
2986 sharpAngle: edge is considered sharp if an angle between normals of
2987 adjacent faces is more than \a sharpAngle in degrees.
2988 createEdges (boolean): to create 1D elements for detected sharp edges.
2989 useExistingEdges (boolean): to use existing edges as group boundaries
2991 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2993 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2994 self.mesh.SetParameters(Parameters)
2995 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2997 def ConvertToStandalone(self, group):
2999 Convert group on geom into standalone group
3002 return self.mesh.ConvertToStandalone(group)
3004 # Get some info about mesh:
3005 # ------------------------
3007 def GetLog(self, clearAfterGet):
3009 Return the log of nodes and elements added or removed
3010 since the previous clear of the log.
3013 clearAfterGet: log is emptied after Get (safe if concurrents access)
3016 list of SMESH.log_block structures { commandType, number, coords, indexes }
3019 return self.mesh.GetLog(clearAfterGet)
3023 Clear the log of nodes and elements added or removed since the previous
3024 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3027 self.mesh.ClearLog()
3029 def SetAutoColor(self, theAutoColor):
3031 Toggle auto color mode on the object.
3032 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3035 theAutoColor (boolean): the flag which toggles auto color mode.
3038 self.mesh.SetAutoColor(theAutoColor)
3040 def GetAutoColor(self):
3042 Get flag of object auto color mode.
3048 return self.mesh.GetAutoColor()
3055 integer value, which is the internal Id of the mesh
3058 return self.mesh.GetId()
3060 def HasDuplicatedGroupNamesMED(self):
3062 Check the group names for duplications.
3063 Consider the maximum group name length stored in MED file.
3069 return self.mesh.HasDuplicatedGroupNamesMED()
3071 def GetMeshEditor(self):
3073 Obtain the mesh editor tool
3076 an instance of :class:`SMESH.SMESH_MeshEditor`
3081 def GetIDSource(self, ids, elemType = SMESH.ALL):
3083 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3084 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3088 elemType: type of elements; this parameter is used to distinguish
3089 IDs of nodes from IDs of elements; by default ids are treated as
3090 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3093 an instance of :class:`SMESH.SMESH_IDSource`
3096 call UnRegister() for the returned object as soon as it is no more useful::
3098 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3099 mesh.DoSomething( idSrc )
3103 if isinstance( ids, int ):
3105 return self.editor.MakeIDSource(ids, elemType)
3108 # Get information about mesh contents:
3109 # ------------------------------------
3111 def GetMeshInfo(self, obj = None):
3113 Get the mesh statistic.
3116 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3119 if not obj: obj = self.mesh
3120 return self.smeshpyD.GetMeshInfo(obj)
3124 Return the number of nodes in the mesh
3130 return self.mesh.NbNodes()
3132 def NbElements(self):
3134 Return the number of elements in the mesh
3140 return self.mesh.NbElements()
3142 def Nb0DElements(self):
3144 Return the number of 0d elements in the mesh
3150 return self.mesh.Nb0DElements()
3154 Return the number of ball discrete elements in the mesh
3160 return self.mesh.NbBalls()
3164 Return the number of edges in the mesh
3170 return self.mesh.NbEdges()
3172 def NbEdgesOfOrder(self, elementOrder):
3174 Return the number of edges with the given order in the mesh
3177 elementOrder: the order of elements
3178 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3184 return self.mesh.NbEdgesOfOrder(elementOrder)
3188 Return the number of faces in the mesh
3194 return self.mesh.NbFaces()
3196 def NbFacesOfOrder(self, elementOrder):
3198 Return the number of faces with the given order in the mesh
3201 elementOrder: the order of elements
3202 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3208 return self.mesh.NbFacesOfOrder(elementOrder)
3210 def NbTriangles(self):
3212 Return the number of triangles in the mesh
3218 return self.mesh.NbTriangles()
3220 def NbTrianglesOfOrder(self, elementOrder):
3222 Return the number of triangles with the given order in the mesh
3225 elementOrder: is the order of elements
3226 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3232 return self.mesh.NbTrianglesOfOrder(elementOrder)
3234 def NbBiQuadTriangles(self):
3236 Return the number of biquadratic triangles in the mesh
3242 return self.mesh.NbBiQuadTriangles()
3244 def NbQuadrangles(self):
3246 Return the number of quadrangles in the mesh
3252 return self.mesh.NbQuadrangles()
3254 def NbQuadranglesOfOrder(self, elementOrder):
3256 Return the number of quadrangles with the given order in the mesh
3259 elementOrder: the order of elements
3260 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3266 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3268 def NbBiQuadQuadrangles(self):
3270 Return the number of biquadratic quadrangles in the mesh
3276 return self.mesh.NbBiQuadQuadrangles()
3278 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3280 Return the number of polygons of given order in the mesh
3283 elementOrder: the order of elements
3284 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3290 return self.mesh.NbPolygonsOfOrder(elementOrder)
3292 def NbVolumes(self):
3294 Return the number of volumes in the mesh
3300 return self.mesh.NbVolumes()
3303 def NbVolumesOfOrder(self, elementOrder):
3305 Return the number of volumes with the given order in the mesh
3308 elementOrder: the order of elements
3309 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3315 return self.mesh.NbVolumesOfOrder(elementOrder)
3319 Return the number of tetrahedrons in the mesh
3325 return self.mesh.NbTetras()
3327 def NbTetrasOfOrder(self, elementOrder):
3329 Return the number of tetrahedrons with the given order in the mesh
3332 elementOrder: the order of elements
3333 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3339 return self.mesh.NbTetrasOfOrder(elementOrder)
3343 Return the number of hexahedrons in the mesh
3349 return self.mesh.NbHexas()
3351 def NbHexasOfOrder(self, elementOrder):
3353 Return the number of hexahedrons with the given order in the mesh
3356 elementOrder: the order of elements
3357 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3363 return self.mesh.NbHexasOfOrder(elementOrder)
3365 def NbTriQuadraticHexas(self):
3367 Return the number of triquadratic hexahedrons in the mesh
3373 return self.mesh.NbTriQuadraticHexas()
3375 def NbPyramids(self):
3377 Return the number of pyramids in the mesh
3383 return self.mesh.NbPyramids()
3385 def NbPyramidsOfOrder(self, elementOrder):
3387 Return the number of pyramids with the given order in the mesh
3390 elementOrder: the order of elements
3391 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3397 return self.mesh.NbPyramidsOfOrder(elementOrder)
3401 Return the number of prisms in the mesh
3407 return self.mesh.NbPrisms()
3409 def NbPrismsOfOrder(self, elementOrder):
3411 Return the number of prisms with the given order in the mesh
3414 elementOrder: the order of elements
3415 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3421 return self.mesh.NbPrismsOfOrder(elementOrder)
3423 def NbHexagonalPrisms(self):
3425 Return the number of hexagonal prisms in the mesh
3431 return self.mesh.NbHexagonalPrisms()
3433 def NbPolyhedrons(self):
3435 Return the number of polyhedrons in the mesh
3441 return self.mesh.NbPolyhedrons()
3443 def NbSubMesh(self):
3445 Return the number of submeshes in the mesh
3451 return self.mesh.NbSubMesh()
3453 def GetElementsId(self):
3455 Return the list of all mesh elements IDs
3458 the list of integer values
3461 :meth:`GetElementsByType`
3464 return self.mesh.GetElementsId()
3466 def GetElementsByType(self, elementType):
3468 Return the list of IDs of mesh elements with the given type
3471 elementType (SMESH.ElementType): the required type of elements
3474 list of integer values
3477 return self.mesh.GetElementsByType(elementType)
3479 def GetNodesId(self):
3481 Return the list of mesh nodes IDs
3484 the list of integer values
3487 return self.mesh.GetNodesId()
3489 # Get the information about mesh elements:
3490 # ------------------------------------
3492 def GetElementType(self, id, iselem=True):
3494 Return the type of mesh element or node
3497 the value from :class:`SMESH.ElementType` enumeration.
3498 Return SMESH.ALL if element or node with the given ID does not exist
3501 return self.mesh.GetElementType(id, iselem)
3503 def GetElementGeomType(self, id):
3505 Return the geometric type of mesh element
3508 the value from :class:`SMESH.EntityType` enumeration.
3511 return self.mesh.GetElementGeomType(id)
3513 def GetElementShape(self, id):
3515 Return the shape type of mesh element
3518 the value from :class:`SMESH.GeometryType` enumeration.
3521 return self.mesh.GetElementShape(id)
3523 def GetSubMeshElementsId(self, Shape):
3525 Return the list of sub-mesh elements IDs
3528 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3529 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3532 list of integer values
3535 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3536 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3539 return self.mesh.GetSubMeshElementsId(ShapeID)
3541 def GetSubMeshNodesId(self, Shape, all):
3543 Return the list of sub-mesh nodes IDs
3546 Shape: a geom object (sub-shape).
3547 *Shape* must be the sub-shape of a :meth:`GetShape`
3548 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3551 list of integer values
3554 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3555 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3558 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3560 def GetSubMeshElementType(self, Shape):
3562 Return type of elements on given shape
3565 Shape: a geom object (sub-shape).
3566 *Shape* must be a sub-shape of a ShapeToMesh()
3569 :class:`SMESH.ElementType`
3572 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3573 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3576 return self.mesh.GetSubMeshElementType(ShapeID)
3580 Get the mesh description
3586 return self.mesh.Dump()
3589 # Get the information about nodes and elements of a mesh by its IDs:
3590 # -----------------------------------------------------------
3592 def GetNodeXYZ(self, id):
3594 Get XYZ coordinates of a node.
3595 If there is no node for the given ID - return an empty list
3598 list of float values
3601 return self.mesh.GetNodeXYZ(id)
3603 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3605 Return list of IDs of inverse elements for the given node.
3606 If there is no node for the given ID - return an empty list
3610 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3613 list of integer values
3616 return self.mesh.GetNodeInverseElements(id,elemType)
3618 def GetNodePosition(self,NodeID):
3620 Return the position of a node on the shape
3623 :class:`SMESH.NodePosition`
3626 return self.mesh.GetNodePosition(NodeID)
3628 def GetElementPosition(self,ElemID):
3630 Return the position of an element on the shape
3633 :class:`SMESH.ElementPosition`
3636 return self.mesh.GetElementPosition(ElemID)
3638 def GetShapeID(self, id):
3640 Return the ID of the shape, on which the given node was generated.
3643 an integer value > 0 or -1 if there is no node for the given
3644 ID or the node is not assigned to any geometry
3647 return self.mesh.GetShapeID(id)
3649 def GetShapeIDForElem(self,id):
3651 Return the ID of the shape, on which the given element was generated.
3654 an integer value > 0 or -1 if there is no element for the given
3655 ID or the element is not assigned to any geometry
3658 return self.mesh.GetShapeIDForElem(id)
3660 def GetElemNbNodes(self, id):
3662 Return the number of nodes of the given element
3665 an integer value > 0 or -1 if there is no element for the given ID
3668 return self.mesh.GetElemNbNodes(id)
3670 def GetElemNode(self, id, index):
3672 Return the node ID the given (zero based) index for the given element.
3674 * If there is no element for the given ID - return -1.
3675 * If there is no node for the given index - return -2.
3678 id (int): element ID
3679 index (int): node index within the element
3682 an integer value (ID)
3685 :meth:`GetElemNodes`
3688 return self.mesh.GetElemNode(id, index)
3690 def GetElemNodes(self, id):
3692 Return the IDs of nodes of the given element
3695 a list of integer values
3698 return self.mesh.GetElemNodes(id)
3700 def IsMediumNode(self, elementID, nodeID):
3702 Return true if the given node is the medium node in the given quadratic element
3705 return self.mesh.IsMediumNode(elementID, nodeID)
3707 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3709 Return true if the given node is the medium node in one of quadratic elements
3712 nodeID: ID of the node
3713 elementType: the type of elements to check a state of the node, either of
3714 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3717 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3719 def ElemNbEdges(self, id):
3721 Return the number of edges for the given element
3724 return self.mesh.ElemNbEdges(id)
3726 def ElemNbFaces(self, id):
3728 Return the number of faces for the given element
3731 return self.mesh.ElemNbFaces(id)
3733 def GetElemFaceNodes(self,elemId, faceIndex):
3735 Return nodes of given face (counted from zero) for given volumic element.
3738 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3740 def GetFaceNormal(self, faceId, normalized=False):
3742 Return three components of normal of given mesh face
3743 (or an empty array in KO case)
3746 return self.mesh.GetFaceNormal(faceId,normalized)
3748 def FindElementByNodes(self, nodes):
3750 Return an element based on all given nodes.
3753 return self.mesh.FindElementByNodes(nodes)
3755 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3757 Return elements including all given nodes.
3760 return self.mesh.GetElementsByNodes( nodes, elemType )
3762 def IsPoly(self, id):
3764 Return true if the given element is a polygon
3767 return self.mesh.IsPoly(id)
3769 def IsQuadratic(self, id):
3771 Return true if the given element is quadratic
3774 return self.mesh.IsQuadratic(id)
3776 def GetBallDiameter(self, id):
3778 Return diameter of a ball discrete element or zero in case of an invalid *id*
3781 return self.mesh.GetBallDiameter(id)
3783 def BaryCenter(self, id):
3785 Return XYZ coordinates of the barycenter of the given element.
3786 If there is no element for the given ID - return an empty list
3789 a list of three double values
3792 :meth:`smeshBuilder.GetGravityCenter`
3795 return self.mesh.BaryCenter(id)
3797 def GetIdsFromFilter(self, filter, meshParts=[] ):
3799 Pass mesh elements through the given filter and return IDs of fitting elements
3802 filter: :class:`SMESH.Filter`
3803 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3809 :meth:`SMESH.Filter.GetIDs`
3810 :meth:`SMESH.Filter.GetElementsIdFromParts`
3813 filter.SetMesh( self.mesh )
3816 if isinstance( meshParts, Mesh ):
3817 filter.SetMesh( meshParts.GetMesh() )
3818 return theFilter.GetIDs()
3819 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3820 meshParts = [ meshParts ]
3821 return filter.GetElementsIdFromParts( meshParts )
3823 return filter.GetIDs()
3825 # Get mesh measurements information:
3826 # ------------------------------------
3828 def GetFreeBorders(self):
3830 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3831 Return a list of special structures (borders).
3834 a list of :class:`SMESH.FreeEdges.Border`
3837 aFilterMgr = self.smeshpyD.CreateFilterManager()
3838 aPredicate = aFilterMgr.CreateFreeEdges()
3839 aPredicate.SetMesh(self.mesh)
3840 aBorders = aPredicate.GetBorders()
3841 aFilterMgr.UnRegister()
3844 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3846 Get minimum distance between two nodes, elements or distance to the origin
3849 id1: first node/element id
3850 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3851 isElem1: *True* if *id1* is element id, *False* if it is node id
3852 isElem2: *True* if *id2* is element id, *False* if it is node id
3855 minimum distance value
3857 :meth:`GetMinDistance`
3860 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3861 return aMeasure.value
3863 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3865 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3868 id1: first node/element id
3869 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3870 isElem1: *True* if *id1* is element id, *False* if it is node id
3871 isElem2: *True* if *id2* is element id, *False* if it is node id
3874 :class:`SMESH.Measure` structure
3880 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3882 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3885 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3887 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3892 aMeasurements = self.smeshpyD.CreateMeasurements()
3893 aMeasure = aMeasurements.MinDistance(id1, id2)
3894 genObjUnRegister([aMeasurements,id1, id2])
3897 def BoundingBox(self, objects=None, isElem=False):
3899 Get bounding box of the specified object(s)
3902 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3903 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3904 *False* specifies that *objects* are nodes
3907 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3910 :meth:`GetBoundingBox()`
3913 result = self.GetBoundingBox(objects, isElem)
3917 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3920 def GetBoundingBox(self, objects=None, isElem=False):
3922 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3925 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3926 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3927 False means that *objects* are nodes
3930 :class:`SMESH.Measure` structure
3933 :meth:`BoundingBox()`
3937 objects = [self.mesh]
3938 elif isinstance(objects, tuple):
3939 objects = list(objects)
3940 if not isinstance(objects, list):
3942 if len(objects) > 0 and isinstance(objects[0], int):
3945 unRegister = genObjUnRegister()
3947 if isinstance(o, Mesh):
3948 srclist.append(o.mesh)
3949 elif hasattr(o, "_narrow"):
3950 src = o._narrow(SMESH.SMESH_IDSource)
3951 if src: srclist.append(src)
3953 elif isinstance(o, list):
3955 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3957 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3958 unRegister.set( srclist[-1] )
3961 aMeasurements = self.smeshpyD.CreateMeasurements()
3962 unRegister.set( aMeasurements )
3963 aMeasure = aMeasurements.BoundingBox(srclist)
3966 # Mesh edition (SMESH_MeshEditor functionality):
3967 # ---------------------------------------------
3969 def RemoveElements(self, IDsOfElements):
3971 Remove the elements from the mesh by ids
3974 IDsOfElements: is a list of ids of elements to remove
3980 This operation can create gaps in numeration of elements.
3981 Call :meth:`RenumberElements` to remove the gaps.
3984 return self.editor.RemoveElements(IDsOfElements)
3986 def RemoveNodes(self, IDsOfNodes):
3988 Remove nodes from mesh by ids
3991 IDsOfNodes: is a list of ids of nodes to remove
3997 This operation can create gaps in numeration of nodes.
3998 Call :meth:`RenumberElements` to remove the gaps.
4001 return self.editor.RemoveNodes(IDsOfNodes)
4003 def RemoveOrphanNodes(self):
4005 Remove all orphan (free) nodes from mesh
4008 number of the removed nodes
4011 This operation can create gaps in numeration of nodes.
4012 Call :meth:`RenumberElements` to remove the gaps.
4015 return self.editor.RemoveOrphanNodes()
4017 def AddNode(self, x, y, z):
4019 Add a node to the mesh by coordinates
4025 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4026 if hasVars: self.mesh.SetParameters(Parameters)
4027 return self.editor.AddNode( x, y, z)
4029 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4031 Create a 0D element on a node with given number.
4034 IDOfNode: the ID of node for creation of the element.
4035 DuplicateElements: to add one more 0D element to a node or not
4038 ID of the new 0D element
4041 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4043 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4045 Create 0D elements on all nodes of the given elements except those
4046 nodes on which a 0D element already exists.
4049 theObject: an object on whose nodes 0D elements will be created.
4050 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4051 theGroupName: optional name of a group to add 0D elements created
4052 and/or found on nodes of *theObject*.
4053 DuplicateElements: to add one more 0D element to a node or not
4056 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4057 IDs of new and/or found 0D elements. IDs of 0D elements
4058 can be retrieved from the returned object by
4059 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4062 unRegister = genObjUnRegister()
4063 if isinstance( theObject, Mesh ):
4064 theObject = theObject.GetMesh()
4065 elif isinstance( theObject, list ):
4066 theObject = self.GetIDSource( theObject, SMESH.ALL )
4067 unRegister.set( theObject )
4068 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4070 def AddBall(self, IDOfNode, diameter):
4072 Create a ball element on a node with given ID.
4075 IDOfNode: the ID of node for creation of the element.
4076 diameter: the bal diameter.
4079 ID of the new ball element
4082 return self.editor.AddBall( IDOfNode, diameter )
4084 def AddEdge(self, IDsOfNodes):
4086 Create a linear or quadratic edge (this is determined
4087 by the number of given nodes).
4090 IDsOfNodes: list of node IDs for creation of the element.
4091 The order of nodes in this list should correspond to
4092 the :ref:`connectivity convention <connectivity_page>`.
4098 return self.editor.AddEdge(IDsOfNodes)
4100 def AddFace(self, IDsOfNodes):
4102 Create a linear or quadratic face (this is determined
4103 by the number of given nodes).
4106 IDsOfNodes: list of node IDs for creation of the element.
4107 The order of nodes in this list should correspond to
4108 the :ref:`connectivity convention <connectivity_page>`.
4114 return self.editor.AddFace(IDsOfNodes)
4116 def AddPolygonalFace(self, IdsOfNodes):
4118 Add a polygonal face defined by a list of node IDs
4121 IdsOfNodes: the list of node IDs for creation of the element.
4127 return self.editor.AddPolygonalFace(IdsOfNodes)
4129 def AddQuadPolygonalFace(self, IdsOfNodes):
4131 Add a quadratic polygonal face defined by a list of node IDs
4134 IdsOfNodes: the list of node IDs for creation of the element;
4135 corner nodes follow first.
4141 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4143 def AddVolume(self, IDsOfNodes):
4145 Create both simple and quadratic volume (this is determined
4146 by the number of given nodes).
4149 IDsOfNodes: list of node IDs for creation of the element.
4150 The order of nodes in this list should correspond to
4151 the :ref:`connectivity convention <connectivity_page>`.
4154 ID of the new volumic element
4157 return self.editor.AddVolume(IDsOfNodes)
4159 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4161 Create a volume of many faces, giving nodes for each face.
4164 IdsOfNodes: list of node IDs for volume creation, face by face.
4165 Quantities: list of integer values, Quantities[i]
4166 gives the quantity of nodes in face number i.
4169 ID of the new volumic element
4172 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4174 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4176 Create a volume of many faces, giving the IDs of the existing faces.
4179 The created volume will refer only to the nodes
4180 of the given faces, not to the faces themselves.
4183 IdsOfFaces: the list of face IDs for volume creation.
4186 ID of the new volumic element
4189 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4192 def SetNodeOnVertex(self, NodeID, Vertex):
4194 Bind a node to a vertex
4198 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4201 True if succeed else raises an exception
4204 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4205 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4209 self.editor.SetNodeOnVertex(NodeID, VertexID)
4210 except SALOME.SALOME_Exception as inst:
4211 raise ValueError(inst.details.text)
4215 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4217 Store the node position on an edge
4221 Edge: an edge (GEOM.GEOM_Object) or edge ID
4222 paramOnEdge: a parameter on the edge where the node is located
4225 True if succeed else raises an exception
4228 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4229 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4233 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4234 except SALOME.SALOME_Exception as inst:
4235 raise ValueError(inst.details.text)
4238 def SetNodeOnFace(self, NodeID, Face, u, v):
4240 Store node position on a face
4244 Face: a face (GEOM.GEOM_Object) or face ID
4245 u: U parameter on the face where the node is located
4246 v: V parameter on the face where the node is located
4249 True if succeed else raises an exception
4252 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4253 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4257 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4258 except SALOME.SALOME_Exception as inst:
4259 raise ValueError(inst.details.text)
4262 def SetNodeInVolume(self, NodeID, Solid):
4264 Bind a node to a solid
4268 Solid: a solid (GEOM.GEOM_Object) or solid ID
4271 True if succeed else raises an exception
4274 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4275 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4279 self.editor.SetNodeInVolume(NodeID, SolidID)
4280 except SALOME.SALOME_Exception as inst:
4281 raise ValueError(inst.details.text)
4284 def SetMeshElementOnShape(self, ElementID, Shape):
4286 Bind an element to a shape
4289 ElementID: an element ID
4290 Shape: a shape (GEOM.GEOM_Object) or shape ID
4293 True if succeed else raises an exception
4296 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4297 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4301 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4302 except SALOME.SALOME_Exception as inst:
4303 raise ValueError(inst.details.text)
4307 def MoveNode(self, NodeID, x, y, z):
4309 Move the node with the given id
4312 NodeID: the id of the node
4313 x: a new X coordinate
4314 y: a new Y coordinate
4315 z: a new Z coordinate
4318 True if succeed else False
4321 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4322 if hasVars: self.mesh.SetParameters(Parameters)
4323 return self.editor.MoveNode(NodeID, x, y, z)
4325 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4327 Find the node closest to a point and moves it to a point location
4330 x: the X coordinate of a point
4331 y: the Y coordinate of a point
4332 z: the Z coordinate of a point
4333 NodeID: if specified (>0), the node with this ID is moved,
4334 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4337 the ID of a moved node
4340 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4341 if hasVars: self.mesh.SetParameters(Parameters)
4342 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4344 def FindNodeClosestTo(self, x, y, z):
4346 Find the node closest to a point
4349 x: the X coordinate of a point
4350 y: the Y coordinate of a point
4351 z: the Z coordinate of a point
4357 return self.editor.FindNodeClosestTo(x, y, z)
4359 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4361 Find the elements where a point lays IN or ON
4364 x,y,z (float): coordinates of the point
4365 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4366 means elements of any type excluding nodes, discrete and 0D elements.
4367 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4370 list of IDs of found elements
4373 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4375 return self.editor.FindElementsByPoint(x, y, z, elementType)
4377 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4379 Project a point to a mesh object.
4380 Return ID of an element of given type where the given point is projected
4381 and coordinates of the projection point.
4382 In the case if nothing found, return -1 and []
4384 if isinstance( meshObject, Mesh ):
4385 meshObject = meshObject.GetMesh()
4387 meshObject = self.GetMesh()
4388 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4390 def GetPointState(self, x, y, z):
4392 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4393 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4394 UNKNOWN state means that either mesh is wrong or the analysis fails.
4397 return self.editor.GetPointState(x, y, z)
4399 def IsManifold(self):
4401 Check if a 2D mesh is manifold
4404 return self.editor.IsManifold()
4406 def IsCoherentOrientation2D(self):
4408 Check if orientation of 2D elements is coherent
4411 return self.editor.IsCoherentOrientation2D()
4413 def Get1DBranches( self, edges, startNode = 0 ):
4415 Partition given 1D elements into groups of contiguous edges.
4416 A node where number of meeting edges != 2 is a group end.
4417 An optional startNode is used to orient groups it belongs to.
4420 A list of edge groups and a list of corresponding node groups,
4421 where the group is a list of IDs of edges or elements, like follows
4422 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4423 If a group is closed, the first and last nodes of the group are same.
4425 if isinstance( edges, Mesh ):
4426 edges = edges.GetMesh()
4427 unRegister = genObjUnRegister()
4428 if isinstance( edges, list ):
4429 edges = self.GetIDSource( edges, SMESH.EDGE )
4430 unRegister.set( edges )
4431 return self.editor.Get1DBranches( edges, startNode )
4433 def FindSharpEdges( self, angle, addExisting=False ):
4435 Return sharp edges of faces and non-manifold ones.
4436 Optionally add existing edges.
4439 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4440 addExisting: to return existing edges (1D elements) as well
4443 list of FaceEdge structures
4445 angle = ParseParameters( angle )[0]
4446 return self.editor.FindSharpEdges( angle, addExisting )
4448 def MeshToPassThroughAPoint(self, x, y, z):
4450 Find the node closest to a point and moves it to a point location
4453 x: the X coordinate of a point
4454 y: the Y coordinate of a point
4455 z: the Z coordinate of a point
4458 the ID of a moved node
4461 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4463 def InverseDiag(self, NodeID1, NodeID2):
4465 Replace two neighbour triangles sharing Node1-Node2 link
4466 with the triangles built on the same 4 nodes but having other common link.
4469 NodeID1: the ID of the first node
4470 NodeID2: the ID of the second node
4473 False if proper faces were not found
4475 return self.editor.InverseDiag(NodeID1, NodeID2)
4477 def DeleteDiag(self, NodeID1, NodeID2):
4479 Replace two neighbour triangles sharing *Node1-Node2* link
4480 with a quadrangle built on the same 4 nodes.
4483 NodeID1: ID of the first node
4484 NodeID2: ID of the second node
4487 False if proper faces were not found
4490 This operation can create gaps in numeration of elements.
4491 Call :meth:`RenumberElements` to remove the gaps.
4494 return self.editor.DeleteDiag(NodeID1, NodeID2)
4496 def Reorient(self, IDsOfElements=None):
4498 Reorient elements by ids
4501 IDsOfElements: if undefined reorients all mesh elements
4504 True if succeed else False
4507 if IDsOfElements == None:
4508 IDsOfElements = self.GetElementsId()
4509 return self.editor.Reorient(IDsOfElements)
4511 def ReorientObject(self, theObject):
4513 Reorient all elements of the object
4516 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4519 True if succeed else False
4522 if ( isinstance( theObject, Mesh )):
4523 theObject = theObject.GetMesh()
4524 return self.editor.ReorientObject(theObject)
4526 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4528 Reorient faces contained in *the2DObject*.
4531 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4532 theDirection: a desired direction of normal of *theFace*.
4533 It can be either a GEOM vector or a list of coordinates [x,y,z].
4534 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4535 compared with theDirection. It can be either ID of face or a point
4536 by which the face will be found. The point can be given as either
4537 a GEOM vertex or a list of point coordinates.
4540 number of reoriented faces
4543 unRegister = genObjUnRegister()
4545 if isinstance( the2DObject, Mesh ):
4546 the2DObject = the2DObject.GetMesh()
4547 if isinstance( the2DObject, list ):
4548 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4549 unRegister.set( the2DObject )
4550 # check theDirection
4551 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4552 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4553 if isinstance( theDirection, list ):
4554 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4555 # prepare theFace and thePoint
4556 theFace = theFaceOrPoint
4557 thePoint = PointStruct(0,0,0)
4558 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4559 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4561 if isinstance( theFaceOrPoint, list ):
4562 thePoint = PointStruct( *theFaceOrPoint )
4564 if isinstance( theFaceOrPoint, PointStruct ):
4565 thePoint = theFaceOrPoint
4567 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4569 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4571 Reorient faces according to adjacent volumes.
4574 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4575 either IDs of faces or face groups.
4576 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4577 theOutsideNormal: to orient faces to have their normals
4578 pointing either *outside* or *inside* the adjacent volumes.
4581 number of reoriented faces.
4584 unRegister = genObjUnRegister()
4586 if not isinstance( the2DObject, list ):
4587 the2DObject = [ the2DObject ]
4588 elif the2DObject and isinstance( the2DObject[0], int ):
4589 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4590 unRegister.set( the2DObject )
4591 the2DObject = [ the2DObject ]
4592 for i,obj2D in enumerate( the2DObject ):
4593 if isinstance( obj2D, Mesh ):
4594 the2DObject[i] = obj2D.GetMesh()
4595 if isinstance( obj2D, list ):
4596 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4597 unRegister.set( the2DObject[i] )
4599 if isinstance( the3DObject, Mesh ):
4600 the3DObject = the3DObject.GetMesh()
4601 if isinstance( the3DObject, list ):
4602 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4603 unRegister.set( the3DObject )
4604 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4606 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4608 Fuse the neighbouring triangles into quadrangles.
4611 IDsOfElements: The triangles to be fused.
4612 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4613 applied to possible quadrangles to choose a neighbour to fuse with.
4614 Note that not all items of :class:`SMESH.FunctorType` corresponds
4615 to numerical functors.
4616 MaxAngle: is the maximum angle between element normals at which the fusion
4617 is still performed; theMaxAngle is measured in radians.
4618 Also it could be a name of variable which defines angle in degrees.
4621 True in case of success, False otherwise.
4624 This operation can create gaps in numeration of elements.
4625 Call :meth:`RenumberElements` to remove the gaps.
4628 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4629 self.mesh.SetParameters(Parameters)
4630 if not IDsOfElements:
4631 IDsOfElements = self.GetElementsId()
4632 Functor = self.smeshpyD.GetFunctor(theCriterion)
4633 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4635 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4637 Fuse the neighbouring triangles of the object into quadrangles
4640 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4641 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4642 applied to possible quadrangles to choose a neighbour to fuse with.
4643 Note that not all items of :class:`SMESH.FunctorType` corresponds
4644 to numerical functors.
4645 MaxAngle: a max angle between element normals at which the fusion
4646 is still performed; theMaxAngle is measured in radians.
4649 True in case of success, False otherwise.
4652 This operation can create gaps in numeration of elements.
4653 Call :meth:`RenumberElements` to remove the gaps.
4656 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4657 self.mesh.SetParameters(Parameters)
4658 if isinstance( theObject, Mesh ):
4659 theObject = theObject.GetMesh()
4660 Functor = self.smeshpyD.GetFunctor(theCriterion)
4661 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4663 def QuadToTri (self, IDsOfElements, theCriterion = None):
4665 Split quadrangles into triangles.
4668 IDsOfElements: the faces to be splitted.
4669 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4670 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4671 value, then quadrangles will be split by the smallest diagonal.
4672 Note that not all items of :class:`SMESH.FunctorType` corresponds
4673 to numerical functors.
4676 True in case of success, False otherwise.
4679 This operation can create gaps in numeration of elements.
4680 Call :meth:`RenumberElements` to remove the gaps.
4682 if IDsOfElements == []:
4683 IDsOfElements = self.GetElementsId()
4684 if theCriterion is None:
4685 theCriterion = FT_MaxElementLength2D
4686 Functor = self.smeshpyD.GetFunctor(theCriterion)
4687 return self.editor.QuadToTri(IDsOfElements, Functor)
4689 def QuadToTriObject (self, theObject, theCriterion = None):
4691 Split quadrangles into triangles.
4694 theObject: the object from which the list of elements is taken,
4695 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4696 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4697 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4698 value, then quadrangles will be split by the smallest diagonal.
4699 Note that not all items of :class:`SMESH.FunctorType` corresponds
4700 to numerical functors.
4703 True in case of success, False otherwise.
4706 This operation can create gaps in numeration of elements.
4707 Call :meth:`RenumberElements` to remove the gaps.
4709 if ( isinstance( theObject, Mesh )):
4710 theObject = theObject.GetMesh()
4711 if theCriterion is None:
4712 theCriterion = FT_MaxElementLength2D
4713 Functor = self.smeshpyD.GetFunctor(theCriterion)
4714 return self.editor.QuadToTriObject(theObject, Functor)
4716 def QuadTo4Tri (self, theElements=[]):
4718 Split each of given quadrangles into 4 triangles. A node is added at the center of
4722 theElements: the faces to be splitted. This can be either
4723 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4724 or a list of face IDs. By default all quadrangles are split
4727 This operation can create gaps in numeration of elements.
4728 Call :meth:`RenumberElements` to remove the gaps.
4730 unRegister = genObjUnRegister()
4731 if isinstance( theElements, Mesh ):
4732 theElements = theElements.mesh
4733 elif not theElements:
4734 theElements = self.mesh
4735 elif isinstance( theElements, list ):
4736 theElements = self.GetIDSource( theElements, SMESH.FACE )
4737 unRegister.set( theElements )
4738 return self.editor.QuadTo4Tri( theElements )
4740 def SplitQuad (self, IDsOfElements, Diag13):
4742 Split quadrangles into triangles.
4745 IDsOfElements: the faces to be splitted
4746 Diag13 (boolean): is used to choose a diagonal for splitting.
4749 True in case of success, False otherwise.
4752 This operation can create gaps in numeration of elements.
4753 Call :meth:`RenumberElements` to remove the gaps.
4755 if IDsOfElements == []:
4756 IDsOfElements = self.GetElementsId()
4757 return self.editor.SplitQuad(IDsOfElements, Diag13)
4759 def SplitQuadObject (self, theObject, Diag13):
4761 Split quadrangles into triangles.
4764 theObject: the object from which the list of elements is taken,
4765 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4766 Diag13 (boolean): is used to choose a diagonal for splitting.
4769 True in case of success, False otherwise.
4772 This operation can create gaps in numeration of elements.
4773 Call :meth:`RenumberElements` to remove the gaps.
4775 if ( isinstance( theObject, Mesh )):
4776 theObject = theObject.GetMesh()
4777 return self.editor.SplitQuadObject(theObject, Diag13)
4779 def BestSplit (self, IDOfQuad, theCriterion):
4781 Find a better splitting of the given quadrangle.
4784 IDOfQuad: the ID of the quadrangle to be splitted.
4785 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4786 choose a diagonal for splitting.
4787 Note that not all items of :class:`SMESH.FunctorType` corresponds
4788 to numerical functors.
4791 * 1 if 1-3 diagonal is better,
4792 * 2 if 2-4 diagonal is better,
4793 * 0 if error occurs.
4796 This operation can create gaps in numeration of elements.
4797 Call :meth:`RenumberElements` to remove the gaps.
4799 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4801 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4803 Split volumic elements into tetrahedrons
4806 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4807 method: flags passing splitting method:
4808 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4809 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4812 This operation can create gaps in numeration of elements.
4813 Call :meth:`RenumberElements` to remove the gaps.
4815 unRegister = genObjUnRegister()
4816 if isinstance( elems, Mesh ):
4817 elems = elems.GetMesh()
4818 if ( isinstance( elems, list )):
4819 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4820 unRegister.set( elems )
4821 self.editor.SplitVolumesIntoTetra(elems, method)
4824 def SplitBiQuadraticIntoLinear(self, elems=None):
4826 Split bi-quadratic elements into linear ones without creation of additional nodes:
4828 - bi-quadratic triangle will be split into 3 linear quadrangles;
4829 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4830 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4832 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4833 will be split in order to keep the mesh conformal.
4836 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4837 if None (default), all bi-quadratic elements will be split
4840 This operation can create gaps in numeration of elements.
4841 Call :meth:`RenumberElements` to remove the gaps.
4843 unRegister = genObjUnRegister()
4844 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4845 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4846 unRegister.set( elems )
4848 elems = [ self.GetMesh() ]
4849 if isinstance( elems, Mesh ):
4850 elems = [ elems.GetMesh() ]
4851 if not isinstance( elems, list ):
4853 self.editor.SplitBiQuadraticIntoLinear( elems )
4855 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4856 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4858 Split hexahedra into prisms
4861 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4862 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4863 gives a normal vector defining facets to split into triangles.
4864 *startHexPoint* can be either a triple of coordinates or a vertex.
4865 facetNormal: a normal to a facet to split into triangles of a
4866 hexahedron found by *startHexPoint*.
4867 *facetNormal* can be either a triple of coordinates or an edge.
4868 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4869 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4870 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4871 to *startHexPoint* are split, else *startHexPoint*
4872 is used to find the facet to split in all domains present in *elems*.
4875 This operation can create gaps in numeration of elements.
4876 Call :meth:`RenumberElements` to remove the gaps.
4879 unRegister = genObjUnRegister()
4880 if isinstance( elems, Mesh ):
4881 elems = elems.GetMesh()
4882 if ( isinstance( elems, list )):
4883 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4884 unRegister.set( elems )
4887 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4888 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4889 elif isinstance( startHexPoint, list ):
4890 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4893 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4894 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4895 elif isinstance( facetNormal, list ):
4896 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4899 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4901 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4903 def SplitQuadsNearTriangularFacets(self):
4905 Split quadrangle faces near triangular facets of volumes
4908 This operation can create gaps in numeration of elements.
4909 Call :meth:`RenumberElements` to remove the gaps.
4911 faces_array = self.GetElementsByType(SMESH.FACE)
4912 for face_id in faces_array:
4913 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4914 quad_nodes = self.mesh.GetElemNodes(face_id)
4915 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4916 isVolumeFound = False
4917 for node1_elem in node1_elems:
4918 if not isVolumeFound:
4919 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4920 nb_nodes = self.GetElemNbNodes(node1_elem)
4921 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4922 volume_elem = node1_elem
4923 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4924 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4925 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4926 isVolumeFound = True
4927 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4928 self.SplitQuad([face_id], False) # diagonal 2-4
4929 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4930 isVolumeFound = True
4931 self.SplitQuad([face_id], True) # diagonal 1-3
4932 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4933 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4934 isVolumeFound = True
4935 self.SplitQuad([face_id], True) # diagonal 1-3
4937 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4939 Split hexahedrons into tetrahedrons.
4941 This operation uses :doc:`pattern_mapping` functionality for splitting.
4944 theObject: the object from which the list of hexahedrons is taken;
4945 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4946 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4947 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4948 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4949 key-point will be mapped into *theNode001*-th node of each volume.
4950 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4953 True in case of success, False otherwise.
4956 This operation can create gaps in numeration of elements.
4957 Call :meth:`RenumberElements` to remove the gaps.
4965 # (0,0,1) 4.---------.7 * |
4972 # (0,0,0) 0.---------.3
4973 pattern_tetra = "!!! Nb of points: \n 8 \n\
4983 !!! Indices of points of 6 tetras: \n\
4991 pattern = self.smeshpyD.GetPattern()
4992 isDone = pattern.LoadFromFile(pattern_tetra)
4994 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4997 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4998 isDone = pattern.MakeMesh(self.mesh, False, False)
4999 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5001 # split quafrangle faces near triangular facets of volumes
5002 self.SplitQuadsNearTriangularFacets()
5006 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5008 Split hexahedrons into prisms.
5010 Uses the :doc:`pattern_mapping` functionality for splitting.
5013 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5014 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5015 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5016 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5017 will be mapped into the *theNode001* -th node of each volume.
5018 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5021 True in case of success, False otherwise.
5024 This operation can create gaps in numeration of elements.
5025 Call :meth:`RenumberElements` to remove the gaps.
5027 # Pattern: 5.---------.6
5032 # (0,0,1) 4.---------.7 |
5039 # (0,0,0) 0.---------.3
5040 pattern_prism = "!!! Nb of points: \n 8 \n\
5050 !!! Indices of points of 2 prisms: \n\
5054 pattern = self.smeshpyD.GetPattern()
5055 isDone = pattern.LoadFromFile(pattern_prism)
5057 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5060 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5061 isDone = pattern.MakeMesh(self.mesh, False, False)
5062 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5064 # Split quafrangle faces near triangular facets of volumes
5065 self.SplitQuadsNearTriangularFacets()
5069 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5070 MaxNbOfIterations, MaxAspectRatio, Method):
5075 IDsOfElements: the list if ids of elements to smooth
5076 IDsOfFixedNodes: the list of ids of fixed nodes.
5077 Note that nodes built on edges and boundary nodes are always fixed.
5078 MaxNbOfIterations: the maximum number of iterations
5079 MaxAspectRatio: varies in range [1.0, inf]
5080 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5081 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5084 True in case of success, False otherwise.
5087 if IDsOfElements == []:
5088 IDsOfElements = self.GetElementsId()
5089 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5090 self.mesh.SetParameters(Parameters)
5091 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5092 MaxNbOfIterations, MaxAspectRatio, Method)
5094 def SmoothObject(self, theObject, IDsOfFixedNodes,
5095 MaxNbOfIterations, MaxAspectRatio, Method):
5097 Smooth elements which belong to the given object
5100 theObject: the object to smooth
5101 IDsOfFixedNodes: the list of ids of fixed nodes.
5102 Note that nodes built on edges and boundary nodes are always fixed.
5103 MaxNbOfIterations: the maximum number of iterations
5104 MaxAspectRatio: varies in range [1.0, inf]
5105 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5106 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5109 True in case of success, False otherwise.
5112 if ( isinstance( theObject, Mesh )):
5113 theObject = theObject.GetMesh()
5114 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5115 MaxNbOfIterations, MaxAspectRatio, Method)
5117 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5118 MaxNbOfIterations, MaxAspectRatio, Method):
5120 Parametrically smooth the given elements
5123 IDsOfElements: the list if ids of elements to smooth
5124 IDsOfFixedNodes: the list of ids of fixed nodes.
5125 Note that nodes built on edges and boundary nodes are always fixed.
5126 MaxNbOfIterations: the maximum number of iterations
5127 MaxAspectRatio: varies in range [1.0, inf]
5128 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5129 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5132 True in case of success, False otherwise.
5135 if IDsOfElements == []:
5136 IDsOfElements = self.GetElementsId()
5137 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5138 self.mesh.SetParameters(Parameters)
5139 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5140 MaxNbOfIterations, MaxAspectRatio, Method)
5142 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5143 MaxNbOfIterations, MaxAspectRatio, Method):
5145 Parametrically smooth the elements which belong to the given object
5148 theObject: the object to smooth
5149 IDsOfFixedNodes: the list of ids of fixed nodes.
5150 Note that nodes built on edges and boundary nodes are always fixed.
5151 MaxNbOfIterations: the maximum number of iterations
5152 MaxAspectRatio: varies in range [1.0, inf]
5153 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5154 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5157 True in case of success, False otherwise.
5160 if ( isinstance( theObject, Mesh )):
5161 theObject = theObject.GetMesh()
5162 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5163 MaxNbOfIterations, MaxAspectRatio, Method)
5165 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5167 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5168 them with quadratic with the same id.
5171 theForce3d: method of new node creation:
5173 * False - the medium node lies at the geometrical entity from which the mesh element is built
5174 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5175 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5176 theToBiQuad: If True, converts the mesh to bi-quadratic
5179 :class:`SMESH.ComputeError` which can hold a warning
5182 If *theSubMesh* is provided, the mesh can become non-conformal
5185 This operation can create gaps in numeration of nodes or elements.
5186 Call :meth:`RenumberElements` to remove the gaps.
5189 if isinstance( theSubMesh, Mesh ):
5190 theSubMesh = theSubMesh.mesh
5192 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5195 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5197 self.editor.ConvertToQuadratic(theForce3d)
5198 error = self.editor.GetLastError()
5199 if error and error.comment:
5200 print(error.comment)
5203 def ConvertFromQuadratic(self, theSubMesh=None):
5205 Convert the mesh from quadratic to ordinary,
5206 deletes old quadratic elements,
5207 replacing them with ordinary mesh elements with the same id.
5210 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5213 If *theSubMesh* is provided, the mesh can become non-conformal
5216 This operation can create gaps in numeration of nodes or elements.
5217 Call :meth:`RenumberElements` to remove the gaps.
5221 self.editor.ConvertFromQuadraticObject(theSubMesh)
5223 return self.editor.ConvertFromQuadratic()
5225 def Make2DMeshFrom3D(self):
5227 Create 2D mesh as skin on boundary faces of a 3D mesh
5230 True if operation has been completed successfully, False otherwise
5233 return self.editor.Make2DMeshFrom3D()
5235 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5236 toCopyElements=False, toCopyExistingBondary=False):
5238 Create missing boundary elements
5241 elements: elements whose boundary is to be checked:
5242 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5243 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5244 dimension: defines type of boundary elements to create, either of
5245 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5246 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5247 groupName: a name of group to store created boundary elements in,
5248 "" means not to create the group
5249 meshName: a name of new mesh to store created boundary elements in,
5250 "" means not to create the new mesh
5251 toCopyElements: if True, the checked elements will be copied into
5252 the new mesh else only boundary elements will be copied into the new mesh
5253 toCopyExistingBondary: if True, not only new but also pre-existing
5254 boundary elements will be copied into the new mesh
5257 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5260 unRegister = genObjUnRegister()
5261 if isinstance( elements, Mesh ):
5262 elements = elements.GetMesh()
5263 if ( isinstance( elements, list )):
5264 elemType = SMESH.ALL
5265 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5266 elements = self.editor.MakeIDSource(elements, elemType)
5267 unRegister.set( elements )
5268 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5269 toCopyElements,toCopyExistingBondary)
5270 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5273 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5274 toCopyAll=False, groups=[]):
5276 Create missing boundary elements around either the whole mesh or
5280 dimension: defines type of boundary elements to create, either of
5281 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5282 groupName: a name of group to store all boundary elements in,
5283 "" means not to create the group
5284 meshName: a name of a new mesh, which is a copy of the initial
5285 mesh + created boundary elements; "" means not to create the new mesh
5286 toCopyAll: if True, the whole initial mesh will be copied into
5287 the new mesh else only boundary elements will be copied into the new mesh
5288 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5291 tuple( long, mesh, group )
5292 - long - number of added boundary elements
5293 - mesh - the :class:`Mesh` where elements were added to
5294 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5297 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5299 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5300 return nb, mesh, group
5302 def RenumberNodes(self):
5304 Renumber mesh nodes to remove unused node IDs
5306 self.editor.RenumberNodes()
5308 def RenumberElements(self):
5310 Renumber mesh elements to remove unused element IDs
5312 self.editor.RenumberElements()
5314 def _getIdSourceList(self, arg, idType, unRegister):
5316 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5318 if arg and isinstance( arg, list ):
5319 if isinstance( arg[0], int ):
5320 arg = self.GetIDSource( arg, idType )
5321 unRegister.set( arg )
5322 elif isinstance( arg[0], Mesh ):
5323 arg[0] = arg[0].GetMesh()
5324 elif isinstance( arg, Mesh ):
5326 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5330 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5331 MakeGroups=False, TotalAngle=False):
5333 Generate new elements by rotation of the given elements and nodes around the axis
5336 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5337 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5338 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5339 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5340 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5341 which defines angle in degrees
5342 NbOfSteps: the number of steps
5343 Tolerance: tolerance
5344 MakeGroups: forces the generation of new groups from existing ones
5345 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5346 of all steps, else - size of each step
5349 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5352 unRegister = genObjUnRegister()
5353 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5354 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5355 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5357 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5358 Axis = self.smeshpyD.GetAxisStruct( Axis )
5359 if isinstance( Axis, list ):
5360 Axis = SMESH.AxisStruct( *Axis )
5362 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5363 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5364 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5365 self.mesh.SetParameters(Parameters)
5366 if TotalAngle and NbOfSteps:
5367 AngleInRadians /= NbOfSteps
5368 return self.editor.RotationSweepObjects( nodes, edges, faces,
5369 Axis, AngleInRadians,
5370 NbOfSteps, Tolerance, MakeGroups)
5372 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5373 MakeGroups=False, TotalAngle=False):
5375 Generate new elements by rotation of the elements around the axis
5378 IDsOfElements: the list of ids of elements to sweep
5379 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5380 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5381 NbOfSteps: the number of steps
5382 Tolerance: tolerance
5383 MakeGroups: forces the generation of new groups from existing ones
5384 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5385 of all steps, else - size of each step
5388 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5391 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5392 AngleInRadians, NbOfSteps, Tolerance,
5393 MakeGroups, TotalAngle)
5395 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5396 MakeGroups=False, TotalAngle=False):
5398 Generate new elements by rotation of the elements of object around the axis
5399 theObject object which elements should be sweeped.
5400 It can be a mesh, a sub mesh or a group.
5403 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5404 AngleInRadians: the angle of Rotation
5405 NbOfSteps: number of steps
5406 Tolerance: tolerance
5407 MakeGroups: forces the generation of new groups from existing ones
5408 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5409 of all steps, else - size of each step
5412 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5415 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5416 AngleInRadians, NbOfSteps, Tolerance,
5417 MakeGroups, TotalAngle )
5419 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5420 MakeGroups=False, TotalAngle=False):
5422 Generate new elements by rotation of the elements of object around the axis
5423 theObject object which elements should be sweeped.
5424 It can be a mesh, a sub mesh or a group.
5427 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5428 AngleInRadians: the angle of Rotation
5429 NbOfSteps: number of steps
5430 Tolerance: tolerance
5431 MakeGroups: forces the generation of new groups from existing ones
5432 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5433 of all steps, else - size of each step
5436 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5437 empty list otherwise
5440 return self.RotationSweepObjects([],theObject,[], Axis,
5441 AngleInRadians, NbOfSteps, Tolerance,
5442 MakeGroups, TotalAngle)
5444 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5445 MakeGroups=False, TotalAngle=False):
5447 Generate new elements by rotation of the elements of object around the axis
5448 theObject object which elements should be sweeped.
5449 It can be a mesh, a sub mesh or a group.
5452 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5453 AngleInRadians: the angle of Rotation
5454 NbOfSteps: number of steps
5455 Tolerance: tolerance
5456 MakeGroups: forces the generation of new groups from existing ones
5457 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5458 of all steps, else - size of each step
5461 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5464 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5465 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5467 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5468 scaleFactors=[], linearVariation=False, basePoint=[],
5469 angles=[], anglesVariation=False):
5471 Generate new elements by extrusion of the given elements and nodes
5474 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5475 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5476 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5477 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5478 the direction and value of extrusion for one step (the total extrusion
5479 length will be NbOfSteps * ||StepVector||)
5480 NbOfSteps: the number of steps
5481 MakeGroups: forces the generation of new groups from existing ones
5482 scaleFactors: optional scale factors to apply during extrusion
5483 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5484 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5485 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5486 nodes and elements being extruded is used as the scaling center.
5489 - a list of tree components of the point or
5492 angles: list of angles in radians. Nodes at each extrusion step are rotated
5493 around *basePoint*, additionally to previous steps.
5494 anglesVariation: forces the computation of rotation angles as linear
5495 variation of the given *angles* along path steps
5497 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5499 Example: :ref:`tui_extrusion`
5501 unRegister = genObjUnRegister()
5502 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5503 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5504 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5506 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5507 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5508 if isinstance( StepVector, list ):
5509 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5511 if isinstance( basePoint, int):
5512 xyz = self.GetNodeXYZ( basePoint )
5514 raise RuntimeError("Invalid node ID: %s" % basePoint)
5516 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5517 basePoint = self.geompyD.PointCoordinates( basePoint )
5519 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5520 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5521 angles,angleParameters,hasVars = ParseAngles(angles)
5522 Parameters = StepVector.PS.parameters + var_separator + \
5523 Parameters + var_separator + \
5524 scaleParameters + var_separator + angleParameters
5525 self.mesh.SetParameters(Parameters)
5527 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5528 StepVector, NbOfSteps, MakeGroups,
5529 scaleFactors, linearVariation, basePoint,
5530 angles, anglesVariation )
5533 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5535 Generate new elements by extrusion of the elements with given ids
5538 IDsOfElements: the list of ids of elements or nodes for extrusion
5539 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5540 the direction and value of extrusion for one step (the total extrusion
5541 length will be NbOfSteps * ||StepVector||)
5542 NbOfSteps: the number of steps
5543 MakeGroups: forces the generation of new groups from existing ones
5544 IsNodes: is True if elements with given ids are nodes
5547 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5549 Example: :ref:`tui_extrusion`
5552 if IsNodes: n = IDsOfElements
5553 else : e,f, = IDsOfElements,IDsOfElements
5554 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5556 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5557 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5559 Generate new elements by extrusion along the normal to a discretized surface or wire
5562 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5563 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5564 StepSize: length of one extrusion step (the total extrusion
5565 length will be *NbOfSteps* *StepSize*).
5566 NbOfSteps: number of extrusion steps.
5567 ByAverageNormal: if True each node is translated by *StepSize*
5568 along the average of the normal vectors to the faces sharing the node;
5569 else each node is translated along the same average normal till
5570 intersection with the plane got by translation of the face sharing
5571 the node along its own normal by *StepSize*.
5572 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5573 for every node of *Elements*.
5574 MakeGroups: forces generation of new groups from existing ones.
5575 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5576 is not yet implemented. This parameter is used if *Elements* contains
5577 both faces and edges, i.e. *Elements* is a Mesh.
5580 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5581 empty list otherwise.
5582 Example: :ref:`tui_extrusion`
5585 unRegister = genObjUnRegister()
5586 if isinstance( Elements, Mesh ):
5587 Elements = [ Elements.GetMesh() ]
5588 if isinstance( Elements, list ):
5590 raise RuntimeError("Elements empty!")
5591 if isinstance( Elements[0], int ):
5592 Elements = self.GetIDSource( Elements, SMESH.ALL )
5593 unRegister.set( Elements )
5594 if not isinstance( Elements, list ):
5595 Elements = [ Elements ]
5596 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5597 self.mesh.SetParameters(Parameters)
5598 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5599 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5601 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5603 Generate new elements by extrusion of the elements or nodes which belong to the object
5606 theObject: the object whose elements or nodes should be processed.
5607 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5608 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5609 the direction and value of extrusion for one step (the total extrusion
5610 length will be NbOfSteps * ||StepVector||)
5611 NbOfSteps: the number of steps
5612 MakeGroups: forces the generation of new groups from existing ones
5613 IsNodes: is True if elements to extrude are nodes
5616 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5617 Example: :ref:`tui_extrusion`
5621 if IsNodes: n = theObject
5622 else : e,f, = theObject,theObject
5623 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5625 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5627 Generate new elements by extrusion of edges which belong to the object
5630 theObject: object whose 1D elements should be processed.
5631 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5632 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5633 the direction and value of extrusion for one step (the total extrusion
5634 length will be NbOfSteps * ||StepVector||)
5635 NbOfSteps: the number of steps
5636 MakeGroups: to generate new groups from existing ones
5639 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5640 Example: :ref:`tui_extrusion`
5643 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5645 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5647 Generate new elements by extrusion of faces which belong to the object
5650 theObject: object whose 2D elements should be processed.
5651 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5652 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5653 the direction and value of extrusion for one step (the total extrusion
5654 length will be NbOfSteps * ||StepVector||)
5655 NbOfSteps: the number of steps
5656 MakeGroups: forces the generation of new groups from existing ones
5659 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5660 Example: :ref:`tui_extrusion`
5663 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5665 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5666 ExtrFlags, SewTolerance, MakeGroups=False):
5668 Generate new elements by extrusion of the elements with given ids
5671 IDsOfElements: is ids of elements
5672 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5673 the direction and value of extrusion for one step (the total extrusion
5674 length will be NbOfSteps * ||StepVector||)
5675 NbOfSteps: the number of steps
5676 ExtrFlags: sets flags for extrusion
5677 SewTolerance: uses for comparing locations of nodes if flag
5678 EXTRUSION_FLAG_SEW is set
5679 MakeGroups: forces the generation of new groups from existing ones
5682 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5685 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5686 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5687 if isinstance( StepVector, list ):
5688 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5689 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5690 ExtrFlags, SewTolerance, MakeGroups)
5692 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5693 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5694 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5695 ScaleFactors=[], ScalesVariation=False):
5697 Generate new elements by extrusion of the given elements and nodes along the path.
5698 The path of extrusion must be a meshed edge.
5701 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5702 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5703 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5704 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5705 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
5706 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5707 HasAngles: not used obsolete
5708 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5709 around *basePoint*, additionally to previous steps.
5710 LinearVariation: forces the computation of rotation angles as linear
5711 variation of the given Angles along path steps
5712 HasRefPoint: allows using the reference point
5713 RefPoint: optional scaling and rotation center (mass center of the extruded
5714 elements by default). The User can specify any point as the Reference Point.
5715 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5716 MakeGroups: forces the generation of new groups from existing ones
5717 ScaleFactors: optional scale factors to apply during extrusion
5718 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5719 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5722 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5723 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5724 Example: :ref:`tui_extrusion_along_path`
5727 unRegister = genObjUnRegister()
5728 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5729 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5730 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5732 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5733 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5734 if isinstance( RefPoint, list ):
5735 if not RefPoint: RefPoint = [0,0,0]
5736 RefPoint = SMESH.PointStruct( *RefPoint )
5737 if isinstance( PathObject, Mesh ):
5738 PathObject = PathObject.GetMesh()
5739 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5740 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5741 Parameters = AnglesParameters + var_separator + \
5742 RefPoint.parameters + var_separator + ScalesParameters
5743 self.mesh.SetParameters(Parameters)
5744 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5745 PathObject, PathShape, NodeStart,
5746 HasAngles, Angles, LinearVariation,
5747 HasRefPoint, RefPoint, MakeGroups,
5748 ScaleFactors, ScalesVariation)
5750 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5751 HasAngles=False, Angles=[], LinearVariation=False,
5752 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5753 ElemType=SMESH.FACE):
5755 Generate new elements by extrusion of the given elements.
5756 The path of extrusion must be a meshed edge.
5759 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5760 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5761 NodeStart: the start node from Path. Defines the direction of extrusion
5762 HasAngles: not used obsolete
5763 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5764 around *basePoint*, additionally to previous steps.
5765 LinearVariation: forces the computation of rotation angles as linear
5766 variation of the given Angles along path steps
5767 HasRefPoint: allows using the reference point
5768 RefPoint: the reference point around which the elements are rotated (the mass
5769 center of the elements by default).
5770 The User can specify any point as the Reference Point.
5771 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5772 MakeGroups: forces the generation of new groups from existing ones
5773 ElemType: type of elements for extrusion (if param Base is a mesh)
5776 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5777 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5778 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5780 Example: :ref:`tui_extrusion_along_path`
5784 if ElemType == SMESH.NODE: n = Base
5785 if ElemType == SMESH.EDGE: e = Base
5786 if ElemType == SMESH.FACE: f = Base
5787 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5788 HasAngles, Angles, LinearVariation,
5789 HasRefPoint, RefPoint, MakeGroups)
5790 if MakeGroups: return gr,er
5793 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5794 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5795 MakeGroups=False, LinearVariation=False):
5797 Generate new elements by extrusion of the given elements.
5798 The path of extrusion must be a meshed edge.
5801 IDsOfElements: ids of elements
5802 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5803 PathShape: shape (edge) defines the sub-mesh for the path
5804 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5805 HasAngles: not used obsolete
5806 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5807 around *basePoint*, additionally to previous steps.
5808 HasRefPoint: allows using the reference point
5809 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5810 The User can specify any point as the Reference Point.
5811 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5812 MakeGroups: forces the generation of new groups from existing ones
5813 LinearVariation: forces the computation of rotation angles as linear
5814 variation of the given Angles along path steps
5817 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5818 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5819 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5820 Example: :ref:`tui_extrusion_along_path`
5823 if not IDsOfElements:
5824 IDsOfElements = [ self.GetMesh() ]
5825 n,e,f = [],IDsOfElements,IDsOfElements
5826 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5827 NodeStart, HasAngles, Angles,
5829 HasRefPoint, RefPoint, MakeGroups)
5830 if MakeGroups: return gr,er
5833 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5834 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5835 MakeGroups=False, LinearVariation=False):
5837 Generate new elements by extrusion of the elements which belong to the object.
5838 The path of extrusion must be a meshed edge.
5841 theObject: the object whose elements should be processed.
5842 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5843 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5844 PathShape: shape (edge) defines the sub-mesh for the path
5845 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5846 HasAngles: not used obsolete
5847 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5848 around *basePoint*, additionally to previous steps.
5849 HasRefPoint: allows using the reference point
5850 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5851 The User can specify any point as the Reference Point.
5852 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5853 MakeGroups: forces the generation of new groups from existing ones
5854 LinearVariation: forces the computation of rotation angles as linear
5855 variation of the given Angles along path steps
5858 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5859 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5860 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5861 Example: :ref:`tui_extrusion_along_path`
5864 n,e,f = [],theObject,theObject
5865 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5866 HasAngles, Angles, LinearVariation,
5867 HasRefPoint, RefPoint, MakeGroups)
5868 if MakeGroups: return gr,er
5871 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5872 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5873 MakeGroups=False, LinearVariation=False):
5875 Generate new elements by extrusion of mesh segments which belong to the object.
5876 The path of extrusion must be a meshed edge.
5879 theObject: the object whose 1D elements should be processed.
5880 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5881 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5882 PathShape: shape (edge) defines the sub-mesh for the path
5883 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5884 HasAngles: not used obsolete
5885 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5886 around *basePoint*, additionally to previous steps.
5887 HasRefPoint: allows using the reference point
5888 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5889 The User can specify any point as the Reference Point.
5890 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5891 MakeGroups: forces the generation of new groups from existing ones
5892 LinearVariation: forces the computation of rotation angles as linear
5893 variation of the given Angles along path steps
5896 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5897 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5898 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5899 Example: :ref:`tui_extrusion_along_path`
5902 n,e,f = [],theObject,[]
5903 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5904 HasAngles, Angles, LinearVariation,
5905 HasRefPoint, RefPoint, MakeGroups)
5906 if MakeGroups: return gr,er
5909 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5910 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5911 MakeGroups=False, LinearVariation=False):
5913 Generate new elements by extrusion of faces which belong to the object.
5914 The path of extrusion must be a meshed edge.
5917 theObject: the object whose 2D elements should be processed.
5918 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5919 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5920 PathShape: shape (edge) defines the sub-mesh for the path
5921 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5922 HasAngles: not used obsolete
5923 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5924 around *basePoint*, additionally to previous steps.
5925 HasRefPoint: allows using the reference point
5926 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5927 The User can specify any point as the Reference Point.
5928 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5929 MakeGroups: forces the generation of new groups from existing ones
5930 LinearVariation: forces the computation of rotation angles as linear
5931 variation of the given Angles along path steps
5934 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5935 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5936 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5937 Example: :ref:`tui_extrusion_along_path`
5940 n,e,f = [],[],theObject
5941 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5942 HasAngles, Angles, LinearVariation,
5943 HasRefPoint, RefPoint, MakeGroups)
5944 if MakeGroups: return gr,er
5947 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5949 Create a symmetrical copy of mesh elements
5952 IDsOfElements: list of elements ids
5953 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5954 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5955 If the *Mirror* is a geom object this parameter is unnecessary
5956 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5957 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5960 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5963 if IDsOfElements == []:
5964 IDsOfElements = self.GetElementsId()
5965 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5966 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5967 theMirrorType = Mirror._mirrorType
5969 self.mesh.SetParameters(Mirror.parameters)
5970 if Copy and MakeGroups:
5971 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5972 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5975 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5977 Create a new mesh by a symmetrical copy of mesh elements
5980 IDsOfElements: the list of elements ids
5981 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5982 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5983 If the *Mirror* is a geom object this parameter is unnecessary
5984 MakeGroups: to generate new groups from existing ones
5985 NewMeshName: a name of the new mesh to create
5988 instance of class :class:`Mesh`
5991 if IDsOfElements == []:
5992 IDsOfElements = self.GetElementsId()
5993 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5994 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5995 theMirrorType = Mirror._mirrorType
5997 self.mesh.SetParameters(Mirror.parameters)
5998 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5999 MakeGroups, NewMeshName)
6000 return Mesh(self.smeshpyD,self.geompyD,mesh)
6002 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6004 Create a symmetrical copy of the object
6007 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6008 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6009 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6010 If the *Mirror* is a geom object this parameter is unnecessary
6011 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6012 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6015 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6018 if ( isinstance( theObject, Mesh )):
6019 theObject = theObject.GetMesh()
6020 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6021 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6022 theMirrorType = Mirror._mirrorType
6024 self.mesh.SetParameters(Mirror.parameters)
6025 if Copy and MakeGroups:
6026 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6027 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6030 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6032 Create a new mesh by a symmetrical copy of the object
6035 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6036 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6037 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6038 If the *Mirror* is a geom object this parameter is unnecessary
6039 MakeGroups: forces the generation of new groups from existing ones
6040 NewMeshName: the name of the new mesh to create
6043 instance of class :class:`Mesh`
6046 if ( isinstance( theObject, Mesh )):
6047 theObject = theObject.GetMesh()
6048 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6049 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6050 theMirrorType = Mirror._mirrorType
6052 self.mesh.SetParameters(Mirror.parameters)
6053 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6054 MakeGroups, NewMeshName)
6055 return Mesh( self.smeshpyD,self.geompyD,mesh )
6057 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6059 Translate the elements
6062 IDsOfElements: list of elements ids
6063 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6064 Copy: allows copying the translated elements
6065 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6068 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6071 if IDsOfElements == []:
6072 IDsOfElements = self.GetElementsId()
6073 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6074 Vector = self.smeshpyD.GetDirStruct(Vector)
6075 if isinstance( Vector, list ):
6076 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6077 self.mesh.SetParameters(Vector.PS.parameters)
6078 if Copy and MakeGroups:
6079 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6080 self.editor.Translate(IDsOfElements, Vector, Copy)
6083 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6085 Create a new mesh of translated elements
6088 IDsOfElements: list of elements ids
6089 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6090 MakeGroups: forces the generation of new groups from existing ones
6091 NewMeshName: the name of the newly created mesh
6094 instance of class :class:`Mesh`
6097 if IDsOfElements == []:
6098 IDsOfElements = self.GetElementsId()
6099 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6100 Vector = self.smeshpyD.GetDirStruct(Vector)
6101 if isinstance( Vector, list ):
6102 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6103 self.mesh.SetParameters(Vector.PS.parameters)
6104 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6105 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6107 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6109 Translate the object
6112 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6113 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6114 Copy: allows copying the translated elements
6115 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6118 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6121 if ( isinstance( theObject, Mesh )):
6122 theObject = theObject.GetMesh()
6123 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6124 Vector = self.smeshpyD.GetDirStruct(Vector)
6125 if isinstance( Vector, list ):
6126 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6127 self.mesh.SetParameters(Vector.PS.parameters)
6128 if Copy and MakeGroups:
6129 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6130 self.editor.TranslateObject(theObject, Vector, Copy)
6133 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6135 Create a new mesh from the translated object
6138 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6139 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6140 MakeGroups: forces the generation of new groups from existing ones
6141 NewMeshName: the name of the newly created mesh
6144 instance of class :class:`Mesh`
6147 if isinstance( theObject, Mesh ):
6148 theObject = theObject.GetMesh()
6149 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6150 Vector = self.smeshpyD.GetDirStruct(Vector)
6151 if isinstance( Vector, list ):
6152 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6153 self.mesh.SetParameters(Vector.PS.parameters)
6154 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6155 return Mesh( self.smeshpyD, self.geompyD, mesh )
6159 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6164 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6165 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6166 theScaleFact: list of 1-3 scale factors for axises
6167 Copy: allows copying the translated elements
6168 MakeGroups: forces the generation of new groups from existing
6172 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6173 empty list otherwise
6175 unRegister = genObjUnRegister()
6176 if ( isinstance( theObject, Mesh )):
6177 theObject = theObject.GetMesh()
6178 if ( isinstance( theObject, list )):
6179 theObject = self.GetIDSource(theObject, SMESH.ALL)
6180 unRegister.set( theObject )
6181 if ( isinstance( thePoint, list )):
6182 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6183 if ( isinstance( theScaleFact, float )):
6184 theScaleFact = [theScaleFact]
6185 if ( isinstance( theScaleFact, int )):
6186 theScaleFact = [ float(theScaleFact)]
6188 self.mesh.SetParameters(thePoint.parameters)
6190 if Copy and MakeGroups:
6191 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6192 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6195 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6197 Create a new mesh from the translated object
6200 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6201 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6202 theScaleFact: list of 1-3 scale factors for axises
6203 MakeGroups: forces the generation of new groups from existing ones
6204 NewMeshName: the name of the newly created mesh
6207 instance of class :class:`Mesh`
6209 unRegister = genObjUnRegister()
6210 if (isinstance(theObject, Mesh)):
6211 theObject = theObject.GetMesh()
6212 if ( isinstance( theObject, list )):
6213 theObject = self.GetIDSource(theObject,SMESH.ALL)
6214 unRegister.set( theObject )
6215 if ( isinstance( thePoint, list )):
6216 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6217 if ( isinstance( theScaleFact, float )):
6218 theScaleFact = [theScaleFact]
6219 if ( isinstance( theScaleFact, int )):
6220 theScaleFact = [ float(theScaleFact)]
6222 self.mesh.SetParameters(thePoint.parameters)
6223 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6224 MakeGroups, NewMeshName)
6225 return Mesh( self.smeshpyD, self.geompyD, mesh )
6229 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6234 IDsOfElements: list of elements ids
6235 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6236 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6237 Copy: allows copying the rotated elements
6238 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6241 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6245 if IDsOfElements == []:
6246 IDsOfElements = self.GetElementsId()
6247 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6248 Axis = self.smeshpyD.GetAxisStruct(Axis)
6249 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6250 Parameters = Axis.parameters + var_separator + Parameters
6251 self.mesh.SetParameters(Parameters)
6252 if Copy and MakeGroups:
6253 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6254 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6257 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6259 Create a new mesh of rotated elements
6262 IDsOfElements: list of element ids
6263 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6264 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6265 MakeGroups: forces the generation of new groups from existing ones
6266 NewMeshName: the name of the newly created mesh
6269 instance of class :class:`Mesh`
6272 if IDsOfElements == []:
6273 IDsOfElements = self.GetElementsId()
6274 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6275 Axis = self.smeshpyD.GetAxisStruct(Axis)
6276 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6277 Parameters = Axis.parameters + var_separator + Parameters
6278 self.mesh.SetParameters(Parameters)
6279 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6280 MakeGroups, NewMeshName)
6281 return Mesh( self.smeshpyD, self.geompyD, mesh )
6283 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6288 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6289 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6290 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6291 Copy: allows copying the rotated elements
6292 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6295 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6298 if (isinstance(theObject, Mesh)):
6299 theObject = theObject.GetMesh()
6300 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6301 Axis = self.smeshpyD.GetAxisStruct(Axis)
6302 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6303 Parameters = Axis.parameters + ":" + Parameters
6304 self.mesh.SetParameters(Parameters)
6305 if Copy and MakeGroups:
6306 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6307 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6310 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6312 Create a new mesh from the rotated object
6315 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6316 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6317 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6318 MakeGroups: forces the generation of new groups from existing ones
6319 NewMeshName: the name of the newly created mesh
6322 instance of class :class:`Mesh`
6325 if (isinstance( theObject, Mesh )):
6326 theObject = theObject.GetMesh()
6327 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6328 Axis = self.smeshpyD.GetAxisStruct(Axis)
6329 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6330 Parameters = Axis.parameters + ":" + Parameters
6331 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6332 MakeGroups, NewMeshName)
6333 self.mesh.SetParameters(Parameters)
6334 return Mesh( self.smeshpyD, self.geompyD, mesh )
6336 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6338 Create an offset mesh from the given 2D object
6341 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6342 theValue (float): signed offset size
6343 MakeGroups (boolean): forces the generation of new groups from existing ones
6344 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6345 False means to remove original elements.
6346 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6349 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6352 if isinstance( theObject, Mesh ):
6353 theObject = theObject.GetMesh()
6354 theValue,Parameters,hasVars = ParseParameters(Value)
6355 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6356 self.mesh.SetParameters(Parameters)
6357 # if mesh_groups[0]:
6358 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6361 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6363 Find groups of adjacent nodes within Tolerance.
6366 Tolerance (float): the value of tolerance
6367 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6368 corner and medium nodes in separate groups thus preventing
6369 their further merge.
6372 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6375 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6377 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6378 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6380 Find groups of adjacent nodes within Tolerance.
6383 Tolerance: the value of tolerance
6384 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6385 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6386 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6387 corner and medium nodes in separate groups thus preventing
6388 their further merge.
6391 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6394 unRegister = genObjUnRegister()
6395 if not isinstance( SubMeshOrGroup, list ):
6396 SubMeshOrGroup = [ SubMeshOrGroup ]
6397 for i,obj in enumerate( SubMeshOrGroup ):
6398 if isinstance( obj, Mesh ):
6399 SubMeshOrGroup = [ obj.GetMesh() ]
6401 if isinstance( obj, int ):
6402 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6403 unRegister.set( SubMeshOrGroup )
6406 if not isinstance( exceptNodes, list ):
6407 exceptNodes = [ exceptNodes ]
6408 if exceptNodes and isinstance( exceptNodes[0], int ):
6409 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6410 unRegister.set( exceptNodes )
6412 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6413 exceptNodes, SeparateCornerAndMediumNodes)
6415 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6420 GroupsOfNodes: a list of groups of nodes IDs for merging.
6421 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6422 in all elements and mesh groups by nodes 1 and 25 correspondingly
6423 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6424 If *NodesToKeep* does not include a node to keep for some group to merge,
6425 then the first node in the group is kept.
6426 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6430 This operation can create gaps in numeration of nodes or elements.
6431 Call :meth:`RenumberElements` to remove the gaps.
6433 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6435 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6437 Find the elements built on the same nodes.
6440 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6441 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6445 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6448 unRegister = genObjUnRegister()
6449 if MeshOrSubMeshOrGroup is None:
6450 MeshOrSubMeshOrGroup = [ self.mesh ]
6451 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6452 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6453 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6454 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6455 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6456 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6457 unRegister.set( MeshOrSubMeshOrGroup )
6458 for item in MeshOrSubMeshOrGroup:
6459 if isinstance( item, Mesh ):
6460 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6462 if not isinstance( exceptElements, list ):
6463 exceptElements = [ exceptElements ]
6464 if exceptElements and isinstance( exceptElements[0], int ):
6465 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6466 unRegister.set( exceptElements )
6468 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6470 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6472 Merge elements in each given group.
6475 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6476 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6477 replaced in all mesh groups by elements 1 and 25)
6478 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6479 If *ElementsToKeep* does not include an element to keep for some group to merge,
6480 then the first element in the group is kept.
6483 This operation can create gaps in numeration of elements.
6484 Call :meth:`RenumberElements` to remove the gaps.
6487 unRegister = genObjUnRegister()
6489 if not isinstance( ElementsToKeep, list ):
6490 ElementsToKeep = [ ElementsToKeep ]
6491 if isinstance( ElementsToKeep[0], int ):
6492 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6493 unRegister.set( ElementsToKeep )
6495 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6497 def MergeEqualElements(self):
6499 Leave one element and remove all other elements built on the same nodes.
6502 This operation can create gaps in numeration of elements.
6503 Call :meth:`RenumberElements` to remove the gaps.
6506 self.editor.MergeEqualElements()
6508 def FindFreeBorders(self, ClosedOnly=True):
6510 Returns all or only closed free borders
6513 list of SMESH.FreeBorder's
6516 return self.editor.FindFreeBorders( ClosedOnly )
6518 def FillHole(self, holeNodes, groupName=""):
6520 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6523 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6524 must describe all sequential nodes of the hole border. The first and the last
6525 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6526 groupName (string): name of a group to add new faces
6528 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6532 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6533 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6534 if not isinstance( holeNodes, SMESH.FreeBorder ):
6535 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6536 return self.editor.FillHole( holeNodes, groupName )
6538 def FindCoincidentFreeBorders (self, tolerance=0.):
6540 Return groups of FreeBorder's coincident within the given tolerance.
6543 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6544 size of elements adjacent to free borders being compared is used.
6547 SMESH.CoincidentFreeBorders structure
6550 return self.editor.FindCoincidentFreeBorders( tolerance )
6552 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6554 Sew FreeBorder's of each group
6557 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6558 where each enclosed list contains node IDs of a group of coincident free
6559 borders such that each consequent triple of IDs within a group describes
6560 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6561 last node of a border.
6562 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6563 groups of coincident free borders, each group including two borders.
6564 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6565 polygons if a node of opposite border falls on a face edge, else such
6566 faces are split into several ones.
6567 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6568 polyhedra if a node of opposite border falls on a volume edge, else such
6569 volumes, if any, remain intact and the mesh becomes non-conformal.
6572 a number of successfully sewed groups
6575 This operation can create gaps in numeration of nodes or elements.
6576 Call :meth:`RenumberElements` to remove the gaps.
6579 if freeBorders and isinstance( freeBorders, list ):
6580 # construct SMESH.CoincidentFreeBorders
6581 if isinstance( freeBorders[0], int ):
6582 freeBorders = [freeBorders]
6584 coincidentGroups = []
6585 for nodeList in freeBorders:
6586 if not nodeList or len( nodeList ) % 3:
6587 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6590 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6591 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6592 nodeList = nodeList[3:]
6594 coincidentGroups.append( group )
6596 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6598 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6600 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6601 FirstNodeID2, SecondNodeID2, LastNodeID2,
6602 CreatePolygons, CreatePolyedrs):
6607 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6610 This operation can create gaps in numeration of nodes or elements.
6611 Call :meth:`RenumberElements` to remove the gaps.
6614 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6615 FirstNodeID2, SecondNodeID2, LastNodeID2,
6616 CreatePolygons, CreatePolyedrs)
6618 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6619 FirstNodeID2, SecondNodeID2):
6621 Sew conform free borders
6624 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6627 This operation can create gaps in numeration of elements.
6628 Call :meth:`RenumberElements` to remove the gaps.
6631 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6632 FirstNodeID2, SecondNodeID2)
6634 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6635 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6640 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6643 This operation can create gaps in numeration of elements.
6644 Call :meth:`RenumberElements` to remove the gaps.
6647 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6648 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6650 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6651 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6652 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6654 Sew two sides of a mesh. The nodes belonging to Side1 are
6655 merged with the nodes of elements of Side2.
6656 The number of elements in theSide1 and in theSide2 must be
6657 equal and they should have similar nodal connectivity.
6658 The nodes to merge should belong to side borders and
6659 the first node should be linked to the second.
6662 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6665 This operation can create gaps in numeration of nodes.
6666 Call :meth:`RenumberElements` to remove the gaps.
6669 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6670 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6671 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6673 def ChangeElemNodes(self, ide, newIDs):
6675 Set new nodes for the given element. Number of nodes should be kept.
6682 False if the number of nodes does not correspond to the type of element
6685 return self.editor.ChangeElemNodes(ide, newIDs)
6687 def GetLastCreatedNodes(self):
6689 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6690 created, this method return the list of their IDs.
6691 If new nodes were not created - return empty list
6694 the list of integer values (can be empty)
6697 return self.editor.GetLastCreatedNodes()
6699 def GetLastCreatedElems(self):
6701 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6702 created this method return the list of their IDs.
6703 If new elements were not created - return empty list
6706 the list of integer values (can be empty)
6709 return self.editor.GetLastCreatedElems()
6711 def ClearLastCreated(self):
6713 Forget what nodes and elements were created by the last mesh edition operation
6716 self.editor.ClearLastCreated()
6718 def DoubleElements(self, theElements, theGroupName=""):
6720 Create duplicates of given elements, i.e. create new elements based on the
6721 same nodes as the given ones.
6724 theElements: container of elements to duplicate. It can be a
6725 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6726 or a list of element IDs. If *theElements* is
6727 a :class:`Mesh`, elements of highest dimension are duplicated
6728 theGroupName: a name of group to contain the generated elements.
6729 If a group with such a name already exists, the new elements
6730 are added to the existing group, else a new group is created.
6731 If *theGroupName* is empty, new elements are not added
6735 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6736 None if *theGroupName* == "".
6739 unRegister = genObjUnRegister()
6740 if isinstance( theElements, Mesh ):
6741 theElements = theElements.mesh
6742 elif isinstance( theElements, list ):
6743 theElements = self.GetIDSource( theElements, SMESH.ALL )
6744 unRegister.set( theElements )
6745 return self.editor.DoubleElements(theElements, theGroupName)
6747 def DoubleNodes(self, theNodes, theModifiedElems):
6749 Create a hole in a mesh by doubling the nodes of some particular elements
6752 theNodes: IDs of nodes to be doubled
6753 theModifiedElems: IDs of elements to be updated by the new (doubled)
6754 nodes. If list of element identifiers is empty then nodes are doubled but
6755 they not assigned to elements
6758 True if operation has been completed successfully, False otherwise
6761 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6763 def DoubleNode(self, theNodeId, theModifiedElems):
6765 Create a hole in a mesh by doubling the nodes of some particular elements.
6766 This method provided for convenience works as :meth:`DoubleNodes`.
6769 theNodeId: IDs of node to double
6770 theModifiedElems: IDs of elements to update
6773 True if operation has been completed successfully, False otherwise
6776 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6778 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6780 Create a hole in a mesh by doubling the nodes of some particular elements.
6781 This method provided for convenience works as :meth:`DoubleNodes`.
6784 theNodes: group of nodes to double.
6785 theModifiedElems: group of elements to update.
6786 theMakeGroup: forces the generation of a group containing new nodes.
6789 True or a created group if operation has been completed successfully,
6790 False or None otherwise
6794 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6795 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6797 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6799 Create a hole in a mesh by doubling the nodes of some particular elements.
6800 This method provided for convenience works as :meth:`DoubleNodes`.
6803 theNodes: list of groups of nodes to double.
6804 theModifiedElems: list of groups of elements to update.
6805 theMakeGroup: forces the generation of a group containing new nodes.
6808 True if operation has been completed successfully, False otherwise
6812 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6813 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6815 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6817 Create a hole in a mesh by doubling the nodes of some particular elements
6820 theElems: the list of elements (edges or faces) to replicate.
6821 The nodes for duplication could be found from these elements
6822 theNodesNot: list of nodes NOT to replicate
6823 theAffectedElems: the list of elements (cells and edges) to which the
6824 replicated nodes should be associated to
6827 True if operation has been completed successfully, False otherwise
6830 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6832 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6834 Create a hole in a mesh by doubling the nodes of some particular elements
6837 theElems: the list of elements (edges or faces) to replicate.
6838 The nodes for duplication could be found from these elements
6839 theNodesNot: list of nodes NOT to replicate
6840 theShape: shape to detect affected elements (element which geometric center
6841 located on or inside shape).
6842 The replicated nodes should be associated to affected elements.
6845 True if operation has been completed successfully, False otherwise
6848 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6850 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6851 theMakeGroup=False, theMakeNodeGroup=False):
6853 Create a hole in a mesh by doubling the nodes of some particular elements.
6854 This method provided for convenience works as :meth:`DoubleNodes`.
6857 theElems: group of of elements (edges or faces) to replicate.
6858 theNodesNot: group of nodes NOT to replicate.
6859 theAffectedElems: group of elements to which the replicated nodes
6860 should be associated to.
6861 theMakeGroup: forces the generation of a group containing new elements.
6862 theMakeNodeGroup: forces the generation of a group containing new nodes.
6865 True or created groups (one or two) if operation has been completed successfully,
6866 False or None otherwise
6869 if theMakeGroup or theMakeNodeGroup:
6870 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6872 theMakeGroup, theMakeNodeGroup)
6873 if theMakeGroup and theMakeNodeGroup:
6876 return twoGroups[ int(theMakeNodeGroup) ]
6877 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6879 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6881 Create a hole in a mesh by doubling the nodes of some particular elements.
6882 This method provided for convenience works as :meth:`DoubleNodes`.
6885 theElems: group of of elements (edges or faces) to replicate
6886 theNodesNot: group of nodes not to replicate
6887 theShape: shape to detect affected elements (element which geometric center
6888 located on or inside shape).
6889 The replicated nodes should be associated to affected elements
6892 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6894 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6895 theMakeGroup=False, theMakeNodeGroup=False):
6897 Create a hole in a mesh by doubling the nodes of some particular elements.
6898 This method provided for convenience works as :meth:`DoubleNodes`.
6901 theElems: list of groups of elements (edges or faces) to replicate
6902 theNodesNot: list of groups of nodes NOT to replicate
6903 theAffectedElems: group of elements to which the replicated nodes
6904 should be associated to
6905 theMakeGroup: forces generation of a group containing new elements.
6906 theMakeNodeGroup: forces generation of a group containing new nodes
6909 True or created groups (one or two) if operation has been completed successfully,
6910 False or None otherwise
6913 if theMakeGroup or theMakeNodeGroup:
6914 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6916 theMakeGroup, theMakeNodeGroup)
6917 if theMakeGroup and theMakeNodeGroup:
6920 return twoGroups[ int(theMakeNodeGroup) ]
6921 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6923 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6925 Create a hole in a mesh by doubling the nodes of some particular elements.
6926 This method provided for convenience works as :meth:`DoubleNodes`.
6929 theElems: list of groups of elements (edges or faces) to replicate
6930 theNodesNot: list of groups of nodes NOT to replicate
6931 theShape: shape to detect affected elements (element which geometric center
6932 located on or inside shape).
6933 The replicated nodes should be associated to affected elements
6936 True if operation has been completed successfully, False otherwise
6939 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6941 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6943 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6944 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6947 theElems: list of groups of nodes or elements (edges or faces) to replicate
6948 theNodesNot: list of groups of nodes NOT to replicate
6949 theShape: shape to detect affected elements (element which geometric center
6950 located on or inside shape).
6951 The replicated nodes should be associated to affected elements
6954 groups of affected elements in order: volumes, faces, edges
6957 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6959 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6962 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6963 The list of groups must describe a partition of the mesh volumes.
6964 The nodes of the internal faces at the boundaries of the groups are doubled.
6965 In option, the internal faces are replaced by flat elements.
6966 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6969 theDomains: list of groups of volumes
6970 createJointElems: if True, create the elements
6971 onAllBoundaries: if True, the nodes and elements are also created on
6972 the boundary between *theDomains* and the rest mesh
6975 True if operation has been completed successfully, False otherwise
6978 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6980 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6982 Double nodes on some external faces and create flat elements.
6983 Flat elements are mainly used by some types of mechanic calculations.
6985 Each group of the list must be constituted of faces.
6986 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6989 theGroupsOfFaces: list of groups of faces
6992 True if operation has been completed successfully, False otherwise
6995 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6997 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6999 Identify all the elements around a geom shape, get the faces delimiting the hole
7001 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7003 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7005 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7006 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7007 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7008 If there are several paths connecting a pair of points, the shortest path is
7009 selected by the module. Position of the cutting plane is defined by the two
7010 points and an optional vector lying on the plane specified by a PolySegment.
7011 By default the vector is defined by Mesh module as following. A middle point
7012 of the two given points is computed. The middle point is projected to the mesh.
7013 The vector goes from the middle point to the projection point. In case of planar
7014 mesh, the vector is normal to the mesh.
7016 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7019 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7020 groupName: optional name of a group where created mesh segments will be added.
7023 editor = self.editor
7025 editor = self.mesh.GetMeshEditPreviewer()
7026 segmentsRes = editor.MakePolyLine( segments, groupName )
7027 for i, seg in enumerate( segmentsRes ):
7028 segments[i].vector = seg.vector
7030 return editor.GetPreviewData()
7033 def MakeSlot(self, segmentGroup, width ):
7035 Create a slot of given width around given 1D elements lying on a triangle mesh.
7036 The slot is constructed by cutting faces by cylindrical surfaces made
7037 around each segment. Segments are expected to be created by MakePolyLine().
7040 FaceEdge's located at the slot boundary
7042 return self.editor.MakeSlot( segmentGroup, width )
7044 def GetFunctor(self, funcType ):
7046 Return a cached numerical functor by its type.
7049 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7050 Note that not all items correspond to numerical functors.
7053 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7056 fn = self.functors[ funcType._v ]
7058 fn = self.smeshpyD.GetFunctor(funcType)
7059 fn.SetMesh(self.mesh)
7060 self.functors[ funcType._v ] = fn
7063 def FunctorValue(self, funcType, elemId, isElem=True):
7065 Return value of a functor for a given element
7068 funcType: an item of :class:`SMESH.FunctorType` enum.
7069 elemId: element or node ID
7070 isElem: *elemId* is ID of element or node
7073 the functor value or zero in case of invalid arguments
7076 fn = self.GetFunctor( funcType )
7077 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7078 val = fn.GetValue(elemId)
7083 def GetLength(self, elemId=None):
7085 Get length of given 1D elements or of all 1D mesh elements
7088 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.
7091 Sum of lengths of given elements
7096 length = self.smeshpyD.GetLength(self)
7097 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7098 length = self.smeshpyD.GetLength(elemId)
7101 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7103 length += self.smeshpyD.GetLength(obj)
7104 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7105 unRegister = genObjUnRegister()
7106 obj = self.GetIDSource( elemId )
7107 unRegister.set( obj )
7108 length = self.smeshpyD.GetLength( obj )
7110 length = self.FunctorValue(SMESH.FT_Length, elemId)
7113 def GetArea(self, elemId=None):
7115 Get area of given 2D elements or of all 2D mesh elements
7118 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.
7121 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7126 area = self.smeshpyD.GetArea(self)
7127 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7128 area = self.smeshpyD.GetArea(elemId)
7131 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7133 area += self.smeshpyD.GetArea(obj)
7134 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7135 unRegister = genObjUnRegister()
7136 obj = self.GetIDSource( elemId )
7137 unRegister.set( obj )
7138 area = self.smeshpyD.GetArea( obj )
7140 area = self.FunctorValue(SMESH.FT_Area, elemId)
7143 def GetVolume(self, elemId=None):
7145 Get volume of given 3D elements or of all 3D mesh elements
7148 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.
7151 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7156 volume= self.smeshpyD.GetVolume(self)
7157 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7158 volume= self.smeshpyD.GetVolume(elemId)
7161 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7163 volume+= self.smeshpyD.GetVolume(obj)
7164 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7165 unRegister = genObjUnRegister()
7166 obj = self.GetIDSource( elemId )
7167 unRegister.set( obj )
7168 volume= self.smeshpyD.GetVolume( obj )
7170 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7173 def GetAngle(self, node1, node2, node3 ):
7175 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7178 node1,node2,node3: IDs of the three nodes
7181 Angle in radians [0,PI]. -1 if failure case.
7183 p1 = self.GetNodeXYZ( node1 )
7184 p2 = self.GetNodeXYZ( node2 )
7185 p3 = self.GetNodeXYZ( node3 )
7186 if p1 and p2 and p3:
7187 return self.smeshpyD.GetAngle( p1,p2,p3 )
7191 def GetMaxElementLength(self, elemId):
7193 Get maximum element length.
7196 elemId: mesh element ID
7199 element's maximum length value
7202 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7203 ftype = SMESH.FT_MaxElementLength3D
7205 ftype = SMESH.FT_MaxElementLength2D
7206 return self.FunctorValue(ftype, elemId)
7208 def GetAspectRatio(self, elemId):
7210 Get aspect ratio of 2D or 3D element.
7213 elemId: mesh element ID
7216 element's aspect ratio value
7219 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7220 ftype = SMESH.FT_AspectRatio3D
7222 ftype = SMESH.FT_AspectRatio
7223 return self.FunctorValue(ftype, elemId)
7225 def GetWarping(self, elemId):
7227 Get warping angle of 2D element.
7230 elemId: mesh element ID
7233 element's warping angle value
7236 return self.FunctorValue(SMESH.FT_Warping, elemId)
7238 def GetMinimumAngle(self, elemId):
7240 Get minimum angle of 2D element.
7243 elemId: mesh element ID
7246 element's minimum angle value
7249 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7251 def GetTaper(self, elemId):
7253 Get taper of 2D element.
7256 elemId: mesh element ID
7259 element's taper value
7262 return self.FunctorValue(SMESH.FT_Taper, elemId)
7264 def GetSkew(self, elemId):
7266 Get skew of 2D element.
7269 elemId: mesh element ID
7272 element's skew value
7275 return self.FunctorValue(SMESH.FT_Skew, elemId)
7277 def GetMinMax(self, funType, meshPart=None):
7279 Return minimal and maximal value of a given functor.
7282 funType (SMESH.FunctorType): a functor type.
7283 Note that not all items of :class:`SMESH.FunctorType` corresponds
7284 to numerical functors.
7285 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7291 unRegister = genObjUnRegister()
7292 if isinstance( meshPart, list ):
7293 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7294 unRegister.set( meshPart )
7295 if isinstance( meshPart, Mesh ):
7296 meshPart = meshPart.mesh
7297 fun = self.GetFunctor( funType )
7300 if hasattr( meshPart, "SetMesh" ):
7301 meshPart.SetMesh( self.mesh ) # set mesh to filter
7302 hist = fun.GetLocalHistogram( 1, False, meshPart )
7304 hist = fun.GetHistogram( 1, False )
7306 return hist[0].min, hist[0].max
7309 pass # end of Mesh class
7312 class meshProxy(SMESH._objref_SMESH_Mesh):
7314 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7315 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7317 def __init__(self,*args):
7318 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7319 def __deepcopy__(self, memo=None):
7320 new = self.__class__(self)
7322 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7323 if len( args ) == 3:
7324 args += SMESH.ALL_NODES, True
7325 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7326 def ExportToMEDX(self, *args): # function removed
7327 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7328 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7329 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7330 def ExportToMED(self, *args): # function removed
7331 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7332 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7334 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7336 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7337 def ExportPartToMED(self, *args): # 'version' parameter removed
7338 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7339 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7340 def ExportMED(self, *args): # signature of method changed
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)
7347 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7350 class submeshProxy(SMESH._objref_SMESH_subMesh):
7353 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7355 def __init__(self,*args):
7356 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7358 def __deepcopy__(self, memo=None):
7359 new = self.__class__(self)
7362 def Compute(self,refresh=False):
7364 Compute the sub-mesh and return the status of the computation
7367 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7372 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7373 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7377 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7379 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7381 if salome.sg.hasDesktop():
7382 if refresh: salome.sg.updateObjBrowser()
7387 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7390 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7392 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7393 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7396 def __init__(self,*args):
7397 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7399 def __getattr__(self, name ): # method called if an attribute not found
7400 if not self.mesh: # look for name() method in Mesh class
7401 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7402 if hasattr( self.mesh, name ):
7403 return getattr( self.mesh, name )
7404 if name == "ExtrusionAlongPathObjX":
7405 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7406 print("meshEditor: attribute '%s' NOT FOUND" % name)
7408 def __deepcopy__(self, memo=None):
7409 new = self.__class__(self)
7411 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7412 if len( args ) == 1: args += False,
7413 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7414 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7415 if len( args ) == 2: args += False,
7416 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7417 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7418 if len( args ) == 1:
7419 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7420 NodesToKeep = args[1]
7421 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7422 unRegister = genObjUnRegister()
7424 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7425 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7426 if not isinstance( NodesToKeep, list ):
7427 NodesToKeep = [ NodesToKeep ]
7428 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7430 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7432 class Pattern(SMESH._objref_SMESH_Pattern):
7434 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7435 variables in some methods
7438 def LoadFromFile(self, patternTextOrFile ):
7439 text = patternTextOrFile
7440 if os.path.exists( text ):
7441 text = open( patternTextOrFile ).read()
7443 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7445 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7446 decrFun = lambda i: i-1
7447 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7448 theMesh.SetParameters(Parameters)
7449 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7451 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7452 decrFun = lambda i: i-1
7453 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7454 theMesh.SetParameters(Parameters)
7455 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7457 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7458 if isinstance( mesh, Mesh ):
7459 mesh = mesh.GetMesh()
7460 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7462 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7464 Registering the new proxy for Pattern
7469 Private class used to bind methods creating algorithms to the class Mesh
7472 def __init__(self, method):
7474 self.defaultAlgoType = ""
7475 self.algoTypeToClass = {}
7476 self.method = method
7478 def add(self, algoClass):
7480 Store a python class of algorithm
7482 if inspect.isclass(algoClass) and \
7483 hasattr( algoClass, "algoType"):
7484 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7485 if not self.defaultAlgoType and \
7486 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7487 self.defaultAlgoType = algoClass.algoType
7488 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7490 def copy(self, mesh):
7492 Create a copy of self and assign mesh to the copy
7495 other = algoCreator( self.method )
7496 other.defaultAlgoType = self.defaultAlgoType
7497 other.algoTypeToClass = self.algoTypeToClass
7501 def __call__(self,algo="",geom=0,*args):
7503 Create an instance of algorithm
7507 if isinstance( algo, str ):
7509 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7510 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7515 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7517 elif not algoType and isinstance( geom, str ):
7522 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7524 elif isinstance( arg, str ) and not algoType:
7527 import traceback, sys
7528 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7529 sys.stderr.write( msg + '\n' )
7530 tb = traceback.extract_stack(None,2)
7531 traceback.print_list( [tb[0]] )
7533 algoType = self.defaultAlgoType
7534 if not algoType and self.algoTypeToClass:
7535 algoType = sorted( self.algoTypeToClass.keys() )[0]
7536 if algoType in self.algoTypeToClass:
7537 #print("Create algo",algoType)
7538 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7539 raise RuntimeError( "No class found for algo type %s" % algoType)
7542 class hypMethodWrapper:
7544 Private class used to substitute and store variable parameters of hypotheses.
7547 def __init__(self, hyp, method):
7549 self.method = method
7550 #print("REBIND:", method.__name__)
7553 def __call__(self,*args):
7555 call a method of hypothesis with calling SetVarParameter() before
7559 return self.method( self.hyp, *args ) # hypothesis method with no args
7561 #print("MethWrapper.__call__", self.method.__name__, args)
7563 parsed = ParseParameters(*args) # replace variables with their values
7564 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7565 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7566 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7567 # maybe there is a replaced string arg which is not variable
7568 result = self.method( self.hyp, *args )
7569 except ValueError as detail: # raised by ParseParameters()
7571 result = self.method( self.hyp, *args )
7572 except omniORB.CORBA.BAD_PARAM:
7573 raise ValueError(detail) # wrong variable name
7578 class genObjUnRegister:
7580 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7583 def __init__(self, genObj=None):
7584 self.genObjList = []
7588 def set(self, genObj):
7589 "Store one or a list of of SALOME.GenericObj'es"
7590 if isinstance( genObj, list ):
7591 self.genObjList.extend( genObj )
7593 self.genObjList.append( genObj )
7597 for genObj in self.genObjList:
7598 if genObj and hasattr( genObj, "UnRegister" ):
7601 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7603 Bind methods creating mesher plug-ins to the Mesh class
7606 # print("pluginName: ", pluginName)
7607 pluginBuilderName = pluginName + "Builder"
7609 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7610 except Exception as e:
7611 from salome_utils import verbose
7612 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7614 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7615 plugin = eval( pluginBuilderName )
7616 # print(" plugin:" , str(plugin))
7618 # add methods creating algorithms to Mesh
7619 for k in dir( plugin ):
7620 if k[0] == '_': continue
7621 algo = getattr( plugin, k )
7622 #print(" algo:", str(algo))
7623 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7624 #print(" meshMethod:" , str(algo.meshMethod))
7625 if not hasattr( Mesh, algo.meshMethod ):
7626 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7628 _mmethod = getattr( Mesh, algo.meshMethod )
7629 if hasattr( _mmethod, "add" ):