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 GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1255 Create hypothesis initialized according to parameters
1258 hypType (string): hypothesis type
1259 libName (string): plug-in library name
1260 mesh: optional mesh by which a hypotheses can initialize self
1261 shape: optional geometry by size of which a hypotheses can initialize self
1262 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1265 created hypothesis instance
1267 if isinstance( mesh, Mesh ):
1268 mesh = mesh.GetMesh()
1269 if isinstance( initParams, (bool,int)):
1270 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1271 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1272 mesh, shape, initParams )
1274 def GetMeshInfo(self, obj):
1276 Get the mesh statistic.
1279 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1282 if isinstance( obj, Mesh ):
1285 if hasattr(obj, "GetMeshInfo"):
1286 values = obj.GetMeshInfo()
1287 for i in range(SMESH.Entity_Last._v):
1288 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1292 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1294 Get minimum distance between two objects
1296 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1297 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1300 src1 (SMESH.SMESH_IDSource): first source object
1301 src2 (SMESH.SMESH_IDSource): second source object
1302 id1 (int): node/element id from the first source
1303 id2 (int): node/element id from the second (or first) source
1304 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1305 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1308 minimum distance value
1311 :meth:`GetMinDistance`
1314 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1318 result = result.value
1321 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1323 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1325 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1326 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1329 src1 (SMESH.SMESH_IDSource): first source object
1330 src2 (SMESH.SMESH_IDSource): second source object
1331 id1 (int): node/element id from the first source
1332 id2 (int): node/element id from the second (or first) source
1333 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1334 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1337 :class:`SMESH.Measure` structure or None if input data is invalid
1342 if isinstance(src1, Mesh): src1 = src1.mesh
1343 if isinstance(src2, Mesh): src2 = src2.mesh
1344 if src2 is None and id2 != 0: src2 = src1
1345 if not hasattr(src1, "_narrow"): return None
1346 src1 = src1._narrow(SMESH.SMESH_IDSource)
1347 if not src1: return None
1348 unRegister = genObjUnRegister()
1351 e = m.GetMeshEditor()
1353 src1 = e.MakeIDSource([id1], SMESH.FACE)
1355 src1 = e.MakeIDSource([id1], SMESH.NODE)
1356 unRegister.set( src1 )
1358 if hasattr(src2, "_narrow"):
1359 src2 = src2._narrow(SMESH.SMESH_IDSource)
1360 if src2 and id2 != 0:
1362 e = m.GetMeshEditor()
1364 src2 = e.MakeIDSource([id2], SMESH.FACE)
1366 src2 = e.MakeIDSource([id2], SMESH.NODE)
1367 unRegister.set( src2 )
1370 aMeasurements = self.CreateMeasurements()
1371 unRegister.set( aMeasurements )
1372 result = aMeasurements.MinDistance(src1, src2)
1375 def BoundingBox(self, objects):
1377 Get bounding box of the specified object(s)
1380 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1383 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1386 :meth:`GetBoundingBox`
1389 result = self.GetBoundingBox(objects)
1393 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1396 def GetBoundingBox(self, objects):
1398 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1401 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1404 :class:`SMESH.Measure` structure
1410 if isinstance(objects, tuple):
1411 objects = list(objects)
1412 if not isinstance(objects, list):
1416 if isinstance(o, Mesh):
1417 srclist.append(o.mesh)
1418 elif hasattr(o, "_narrow"):
1419 src = o._narrow(SMESH.SMESH_IDSource)
1420 if src: srclist.append(src)
1423 aMeasurements = self.CreateMeasurements()
1424 result = aMeasurements.BoundingBox(srclist)
1425 aMeasurements.UnRegister()
1428 def GetLength(self, obj):
1430 Get sum of lengths of all 1D elements in the mesh object.
1433 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1436 sum of lengths of all 1D elements
1439 if isinstance(obj, Mesh): obj = obj.mesh
1440 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1441 aMeasurements = self.CreateMeasurements()
1442 value = aMeasurements.Length(obj)
1443 aMeasurements.UnRegister()
1446 def GetArea(self, obj):
1448 Get sum of areas of all 2D elements in the mesh object.
1451 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1454 sum of areas of all 2D elements
1457 if isinstance(obj, Mesh): obj = obj.mesh
1458 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1459 aMeasurements = self.CreateMeasurements()
1460 value = aMeasurements.Area(obj)
1461 aMeasurements.UnRegister()
1464 def GetVolume(self, obj):
1466 Get sum of volumes of all 3D elements in the mesh object.
1469 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1472 sum of volumes of all 3D elements
1475 if isinstance(obj, Mesh): obj = obj.mesh
1476 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1477 aMeasurements = self.CreateMeasurements()
1478 value = aMeasurements.Volume(obj)
1479 aMeasurements.UnRegister()
1482 def GetGravityCenter(self, obj):
1484 Get gravity center of all nodes of a mesh object.
1487 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1490 Three components of the gravity center (x,y,z)
1493 :meth:`Mesh.BaryCenter`
1495 if isinstance(obj, Mesh): obj = obj.mesh
1496 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1497 aMeasurements = self.CreateMeasurements()
1498 pointStruct = aMeasurements.GravityCenter(obj)
1499 aMeasurements.UnRegister()
1500 return pointStruct.x, pointStruct.y, pointStruct.z
1502 def GetAngle(self, p1, p2, p3 ):
1504 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1507 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1513 if isinstance( p1, list ): p1 = PointStruct(*p1)
1514 if isinstance( p2, list ): p2 = PointStruct(*p2)
1515 if isinstance( p3, list ): p3 = PointStruct(*p3)
1517 aMeasurements = self.CreateMeasurements()
1518 angle = aMeasurements.Angle(p1,p2,p3)
1519 aMeasurements.UnRegister()
1524 pass # end of class smeshBuilder
1527 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1528 """Registering the new proxy for SMESH.SMESH_Gen"""
1531 def New( instance=None, instanceGeom=None):
1533 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1534 interface to create or load meshes.
1539 salome.salome_init()
1540 from salome.smesh import smeshBuilder
1541 smesh = smeshBuilder.New()
1544 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1545 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1547 :class:`smeshBuilder` instance
1552 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1554 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1559 smeshInst = smeshBuilder()
1560 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1561 smeshInst.init_smesh(instanceGeom)
1565 # Public class: Mesh
1566 # ==================
1569 class Mesh(metaclass = MeshMeta):
1571 This class allows defining and managing a mesh.
1572 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1573 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1574 new nodes and elements and by changing the existing entities), to get information
1575 about a mesh and to export a mesh in different formats.
1582 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1587 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1588 sets the GUI name of this mesh to *name*.
1591 smeshpyD: an instance of smeshBuilder class
1592 geompyD: an instance of geomBuilder class
1593 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1594 name: Study name of the mesh
1597 self.smeshpyD = smeshpyD
1598 self.geompyD = geompyD
1603 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1606 # publish geom of mesh (issue 0021122)
1607 if not self.geom.GetStudyEntry():
1611 geo_name = name + " shape"
1613 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1614 geompyD.addToStudy( self.geom, geo_name )
1615 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1617 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1620 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1622 self.smeshpyD.SetName(self.mesh, name)
1624 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1627 self.geom = self.mesh.GetShapeToMesh()
1629 self.editor = self.mesh.GetMeshEditor()
1630 self.functors = [None] * SMESH.FT_Undefined._v
1632 # set self to algoCreator's
1633 for attrName in dir(self):
1634 attr = getattr( self, attrName )
1635 if isinstance( attr, algoCreator ):
1636 setattr( self, attrName, attr.copy( self ))
1643 Destructor. Clean-up resources
1646 #self.mesh.UnRegister()
1650 def SetMesh(self, theMesh):
1652 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1655 theMesh: a :class:`SMESH.SMESH_Mesh` object
1659 # do not call Register() as this prevents mesh servant deletion at closing study
1660 #if self.mesh: self.mesh.UnRegister()
1663 #self.mesh.Register()
1664 self.geom = self.mesh.GetShapeToMesh()
1669 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1672 a :class:`SMESH.SMESH_Mesh` object
1677 def GetEngine(self):
1679 Return a smeshBuilder instance created this mesh
1681 return self.smeshpyD
1683 def GetGeomEngine(self):
1685 Return a geomBuilder instance
1691 Get the name of the mesh
1694 the name of the mesh as a string
1697 name = GetName(self.GetMesh())
1700 def SetName(self, name):
1702 Set a name to the mesh
1705 name: a new name of the mesh
1708 self.smeshpyD.SetName(self.GetMesh(), name)
1710 def GetSubMesh(self, geom, name):
1712 Get a sub-mesh object associated to a *geom* geometrical object.
1715 geom: a geometrical object (shape)
1716 name: a name for the sub-mesh in the Object Browser
1719 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1720 which lies on the given shape
1723 A sub-mesh is implicitly created when a sub-shape is specified at
1724 creating an algorithm, for example::
1726 algo1D = mesh.Segment(geom=Edge_1)
1728 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1729 The created sub-mesh can be retrieved from the algorithm::
1731 submesh = algo1D.GetSubMesh()
1734 AssureGeomPublished( self, geom, name )
1735 submesh = self.mesh.GetSubMesh( geom, name )
1740 Return the shape associated to the mesh
1748 def SetShape(self, geom):
1750 Associate the given shape to the mesh (entails the recreation of the mesh)
1753 geom: the shape to be meshed (GEOM_Object)
1756 self.mesh = self.smeshpyD.CreateMesh(geom)
1758 def HasShapeToMesh(self):
1760 Return ``True`` if this mesh is based on geometry
1762 return self.mesh.HasShapeToMesh()
1766 Load mesh from the study after opening the study
1770 def IsReadyToCompute(self, theSubObject):
1772 Return true if the hypotheses are defined well
1775 theSubObject: a sub-shape of a mesh shape
1781 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1783 def GetAlgoState(self, theSubObject):
1785 Return errors of hypotheses definition.
1786 The list of errors is empty if everything is OK.
1789 theSubObject: a sub-shape of a mesh shape
1795 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1797 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1799 Return a geometrical object on which the given element was built.
1800 The returned geometrical object, if not nil, is either found in the
1801 study or published by this method with the given name
1804 theElementID: the id of the mesh element
1805 theGeomName: the user-defined name of the geometrical object
1808 GEOM.GEOM_Object instance
1811 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1813 def MeshDimension(self):
1815 Return the mesh dimension depending on the dimension of the underlying shape
1816 or, if the mesh is not based on any shape, basing on deimension of elements
1819 mesh dimension as an integer value [0,3]
1822 if self.mesh.HasShapeToMesh():
1823 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1824 if len( shells ) > 0 :
1826 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1828 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1833 if self.NbVolumes() > 0: return 3
1834 if self.NbFaces() > 0: return 2
1835 if self.NbEdges() > 0: return 1
1838 def Evaluate(self, geom=0):
1840 Evaluate size of prospective mesh on a shape
1843 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1844 To know predicted number of e.g. edges, inquire it this way::
1846 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1849 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1851 geom = self.mesh.GetShapeToMesh()
1854 return self.smeshpyD.Evaluate(self.mesh, geom)
1857 def Compute(self, geom=0, discardModifs=False, refresh=False):
1859 Compute the mesh and return the status of the computation
1862 geom: geomtrical shape on which mesh data should be computed
1863 discardModifs: if True and the mesh has been edited since
1864 a last total re-compute and that may prevent successful partial re-compute,
1865 then the mesh is cleaned before Compute()
1866 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1872 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1874 geom = self.mesh.GetShapeToMesh()
1879 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1881 ok = self.smeshpyD.Compute(self.mesh, geom)
1882 except SALOME.SALOME_Exception as ex:
1883 print("Mesh computation failed, exception caught:")
1884 print(" ", ex.details.text)
1887 print("Mesh computation failed, exception caught:")
1888 traceback.print_exc()
1892 # Treat compute errors
1893 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1895 for err in computeErrors:
1896 if self.mesh.HasShapeToMesh():
1897 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1899 stdErrors = ["OK", #COMPERR_OK
1900 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1901 "std::exception", #COMPERR_STD_EXCEPTION
1902 "OCC exception", #COMPERR_OCC_EXCEPTION
1903 "..", #COMPERR_SLM_EXCEPTION
1904 "Unknown exception", #COMPERR_EXCEPTION
1905 "Memory allocation problem", #COMPERR_MEMORY_PB
1906 "Algorithm failed", #COMPERR_ALGO_FAILED
1907 "Unexpected geometry", #COMPERR_BAD_SHAPE
1908 "Warning", #COMPERR_WARNING
1909 "Computation cancelled",#COMPERR_CANCELED
1910 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1912 if err.code < len(stdErrors): errText = stdErrors[err.code]
1914 errText = "code %s" % -err.code
1915 if errText: errText += ". "
1916 errText += err.comment
1917 if allReasons: allReasons += "\n"
1919 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1921 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1925 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1927 if err.isGlobalAlgo:
1935 reason = '%s %sD algorithm is missing' % (glob, dim)
1936 elif err.state == HYP_MISSING:
1937 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1938 % (glob, dim, name, dim))
1939 elif err.state == HYP_NOTCONFORM:
1940 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1941 elif err.state == HYP_BAD_PARAMETER:
1942 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1943 % ( glob, dim, name ))
1944 elif err.state == HYP_BAD_GEOMETRY:
1945 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1946 'geometry' % ( glob, dim, name ))
1947 elif err.state == HYP_HIDDEN_ALGO:
1948 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1949 'algorithm of upper dimension generating %sD mesh'
1950 % ( glob, dim, name, glob, dim ))
1952 reason = ("For unknown reason. "
1953 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1955 if allReasons: allReasons += "\n"
1956 allReasons += "- " + reason
1958 if not ok or allReasons != "":
1959 msg = '"' + GetName(self.mesh) + '"'
1960 if ok: msg += " has been computed with warnings"
1961 else: msg += " has not been computed"
1962 if allReasons != "": msg += ":"
1967 if salome.sg.hasDesktop():
1968 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1969 if refresh: salome.sg.updateObjBrowser()
1973 def GetComputeErrors(self, shape=0 ):
1975 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1979 shape = self.mesh.GetShapeToMesh()
1980 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1982 def GetSubShapeName(self, subShapeID ):
1984 Return a name of a sub-shape by its ID.
1985 Possible variants (for *subShapeID* == 3):
1987 - **"Face_12"** - published sub-shape
1988 - **FACE #3** - not published sub-shape
1989 - **sub-shape #3** - invalid sub-shape ID
1990 - **#3** - error in this function
1993 subShapeID: a unique ID of a sub-shape
1996 a string describing the sub-shape
2000 if not self.mesh.HasShapeToMesh():
2004 mainIOR = salome.orb.object_to_string( self.GetShape() )
2006 mainSO = s.FindObjectIOR(mainIOR)
2009 shapeText = '"%s"' % mainSO.GetName()
2010 subIt = s.NewChildIterator(mainSO)
2012 subSO = subIt.Value()
2014 obj = subSO.GetObject()
2015 if not obj: continue
2016 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2019 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2022 if ids == subShapeID:
2023 shapeText = '"%s"' % subSO.GetName()
2026 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2028 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2030 shapeText = 'sub-shape #%s' % (subShapeID)
2032 shapeText = "#%s" % (subShapeID)
2035 def GetFailedShapes(self, publish=False):
2037 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2038 error of an algorithm
2041 publish: if *True*, the returned groups will be published in the study
2044 a list of GEOM groups each named after a failed algorithm
2049 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2050 for err in computeErrors:
2051 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2052 if not shape: continue
2053 if err.algoName in algo2shapes:
2054 algo2shapes[ err.algoName ].append( shape )
2056 algo2shapes[ err.algoName ] = [ shape ]
2060 for algoName, shapes in list(algo2shapes.items()):
2062 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2063 otherTypeShapes = []
2065 group = self.geompyD.CreateGroup( self.geom, groupType )
2066 for shape in shapes:
2067 if shape.GetShapeType() == shapes[0].GetShapeType():
2068 sameTypeShapes.append( shape )
2070 otherTypeShapes.append( shape )
2071 self.geompyD.UnionList( group, sameTypeShapes )
2073 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2075 group.SetName( algoName )
2076 groups.append( group )
2077 shapes = otherTypeShapes
2080 for group in groups:
2081 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2084 def GetMeshOrder(self):
2086 Return sub-mesh objects list in meshing order
2089 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2092 return self.mesh.GetMeshOrder()
2094 def SetMeshOrder(self, submeshes):
2096 Set priority of sub-meshes. It works in two ways:
2098 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2099 *several dimensions*, it sets the order in which the sub-meshes are computed.
2100 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2101 when looking for meshing parameters to apply to a sub-shape. To impose the
2102 order in which sub-meshes with uni-dimensional algorithms are computed,
2103 call **submesh.Compute()** in a desired order.
2106 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2109 return self.mesh.SetMeshOrder(submeshes)
2111 def Clear(self, refresh=False):
2113 Remove all nodes and elements generated on geometry. Imported elements remain.
2116 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2120 if ( salome.sg.hasDesktop() ):
2121 if refresh: salome.sg.updateObjBrowser()
2123 def ClearSubMesh(self, geomId, refresh=False):
2125 Remove all nodes and elements of indicated shape
2128 geomId: the ID of a sub-shape to remove elements on
2129 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2132 self.mesh.ClearSubMesh(geomId)
2133 if salome.sg.hasDesktop():
2134 if refresh: salome.sg.updateObjBrowser()
2136 def AutomaticTetrahedralization(self, fineness=0):
2138 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2141 fineness: [0.0,1.0] defines mesh fineness
2147 dim = self.MeshDimension()
2149 self.RemoveGlobalHypotheses()
2150 self.Segment().AutomaticLength(fineness)
2152 self.Triangle().LengthFromEdges()
2157 return self.Compute()
2159 def AutomaticHexahedralization(self, fineness=0):
2161 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2164 fineness: [0.0, 1.0] defines mesh fineness
2170 dim = self.MeshDimension()
2171 # assign the hypotheses
2172 self.RemoveGlobalHypotheses()
2173 self.Segment().AutomaticLength(fineness)
2180 return self.Compute()
2182 def AddHypothesis(self, hyp, geom=0):
2187 hyp: a hypothesis to assign
2188 geom: a subhape of mesh geometry
2191 :class:`SMESH.Hypothesis_Status`
2194 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2195 hyp, geom = geom, hyp
2196 if isinstance( hyp, Mesh_Algorithm ):
2197 hyp = hyp.GetAlgorithm()
2202 geom = self.mesh.GetShapeToMesh()
2205 if self.mesh.HasShapeToMesh():
2206 hyp_type = hyp.GetName()
2207 lib_name = hyp.GetLibName()
2208 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2209 # if checkAll and geom:
2210 # checkAll = geom.GetType() == 37
2212 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2214 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2215 status = self.mesh.AddHypothesis(geom, hyp)
2217 status = HYP_BAD_GEOMETRY, ""
2218 hyp_name = GetName( hyp )
2221 geom_name = geom.GetName()
2222 isAlgo = hyp._narrow( SMESH_Algo )
2223 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2226 def IsUsedHypothesis(self, hyp, geom):
2228 Return True if an algorithm or hypothesis is assigned to a given shape
2231 hyp: an algorithm or hypothesis to check
2232 geom: a subhape of mesh geometry
2238 if not hyp: # or not geom
2240 if isinstance( hyp, Mesh_Algorithm ):
2241 hyp = hyp.GetAlgorithm()
2243 hyps = self.GetHypothesisList(geom)
2245 if h.GetId() == hyp.GetId():
2249 def RemoveHypothesis(self, hyp, geom=0):
2251 Unassign a hypothesis
2254 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2255 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2258 :class:`SMESH.Hypothesis_Status`
2263 if isinstance( hyp, Mesh_Algorithm ):
2264 hyp = hyp.GetAlgorithm()
2270 if self.IsUsedHypothesis( hyp, shape ):
2271 return self.mesh.RemoveHypothesis( shape, hyp )
2272 hypName = GetName( hyp )
2273 geoName = GetName( shape )
2274 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2277 def GetHypothesisList(self, geom):
2279 Get the list of hypotheses added on a geometry
2282 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2285 the sequence of :class:`SMESH.SMESH_Hypothesis`
2288 return self.mesh.GetHypothesisList( geom )
2290 def RemoveGlobalHypotheses(self):
2292 Remove all global hypotheses
2295 current_hyps = self.mesh.GetHypothesisList( self.geom )
2296 for hyp in current_hyps:
2297 self.mesh.RemoveHypothesis( self.geom, hyp )
2300 def ExportMED(self, *args, **kwargs):
2302 Export the mesh in a file in MED format
2303 allowing to overwrite the file if it exists or add the exported data to its contents
2306 fileName: is the file name
2307 auto_groups (boolean): parameter for creating/not creating
2308 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2309 the typical use is auto_groups=False.
2310 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2311 The minor must be between 0 and the current minor version of MED file library.
2312 If minor is equal to -1, the minor version is not changed (default).
2313 The major version (x, where version is x.y.z) cannot be changed.
2314 overwrite (boolean): parameter for overwriting/not overwriting the file
2315 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2316 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2318 - 1D if all mesh nodes lie on OX coordinate axis, or
2319 - 2D if all mesh nodes lie on XOY coordinate plane, or
2320 - 3D in the rest cases.
2322 If *autoDimension* is *False*, the space dimension is always 3.
2323 fields: list of GEOM fields defined on the shape to mesh.
2324 geomAssocFields: each character of this string means a need to export a
2325 corresponding field; correspondence between fields and characters
2328 - 'v' stands for "_vertices_" field;
2329 - 'e' stands for "_edges_" field;
2330 - 'f' stands for "_faces_" field;
2331 - 's' stands for "_solids_" field.
2333 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2334 close to zero within a given tolerance, the coordinate is set to zero.
2335 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2337 # process positional arguments
2338 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2340 auto_groups = args[1] if len(args) > 1 else False
2341 minor = args[2] if len(args) > 2 else -1
2342 overwrite = args[3] if len(args) > 3 else True
2343 meshPart = args[4] if len(args) > 4 else None
2344 autoDimension = args[5] if len(args) > 5 else True
2345 fields = args[6] if len(args) > 6 else []
2346 geomAssocFields = args[7] if len(args) > 7 else ''
2347 z_tolerance = args[8] if len(args) > 8 else -1.
2348 # process keywords arguments
2349 auto_groups = kwargs.get("auto_groups", auto_groups)
2350 minor = kwargs.get("minor", minor)
2351 overwrite = kwargs.get("overwrite", overwrite)
2352 meshPart = kwargs.get("meshPart", meshPart)
2353 autoDimension = kwargs.get("autoDimension", autoDimension)
2354 fields = kwargs.get("fields", fields)
2355 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2356 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2358 # invoke engine's function
2359 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2360 unRegister = genObjUnRegister()
2361 if isinstance( meshPart, list ):
2362 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2363 unRegister.set( meshPart )
2365 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2366 self.mesh.SetParameters(Parameters)
2368 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2369 fields, geomAssocFields, z_tolerance)
2371 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2373 def ExportSAUV(self, f, auto_groups=0):
2375 Export the mesh in a file in SAUV format
2380 auto_groups: boolean parameter for creating/not creating
2381 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2382 the typical use is auto_groups=False.
2385 self.mesh.ExportSAUV(f, auto_groups)
2387 def ExportDAT(self, f, meshPart=None):
2389 Export the mesh in a file in DAT format
2393 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2397 unRegister = genObjUnRegister()
2398 if isinstance( meshPart, list ):
2399 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2400 unRegister.set( meshPart )
2401 self.mesh.ExportPartToDAT( meshPart, f )
2403 self.mesh.ExportDAT(f)
2405 def ExportUNV(self, f, meshPart=None):
2407 Export the mesh in a file in UNV format
2411 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2415 unRegister = genObjUnRegister()
2416 if isinstance( meshPart, list ):
2417 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2418 unRegister.set( meshPart )
2419 self.mesh.ExportPartToUNV( meshPart, f )
2421 self.mesh.ExportUNV(f)
2423 def ExportSTL(self, f, ascii=1, meshPart=None):
2425 Export the mesh in a file in STL format
2429 ascii: defines the file encoding
2430 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2434 unRegister = genObjUnRegister()
2435 if isinstance( meshPart, list ):
2436 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2437 unRegister.set( meshPart )
2438 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2440 self.mesh.ExportSTL(f, ascii)
2442 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2444 Export the mesh in a file in CGNS format
2448 overwrite: boolean parameter for overwriting/not overwriting the file
2449 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2450 groupElemsByType: if True all elements of same entity type are exported at ones,
2451 else elements are exported in order of their IDs which can cause creation
2452 of multiple cgns sections
2455 unRegister = genObjUnRegister()
2456 if isinstance( meshPart, list ):
2457 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2458 unRegister.set( meshPart )
2459 if isinstance( meshPart, Mesh ):
2460 meshPart = meshPart.mesh
2462 meshPart = self.mesh
2463 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2465 def ExportGMF(self, f, meshPart=None):
2467 Export the mesh in a file in GMF format.
2468 GMF files must have .mesh extension for the ASCII format and .meshb for
2469 the bynary format. Other extensions are not allowed.
2473 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2476 unRegister = genObjUnRegister()
2477 if isinstance( meshPart, list ):
2478 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2479 unRegister.set( meshPart )
2480 if isinstance( meshPart, Mesh ):
2481 meshPart = meshPart.mesh
2483 meshPart = self.mesh
2484 self.mesh.ExportGMF(meshPart, f, True)
2486 def ExportToMED(self, *args, **kwargs):
2488 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2489 Export the mesh in a file in MED format
2490 allowing to overwrite the file if it exists or add the exported data to its contents
2493 fileName: the file name
2494 opt (boolean): parameter for creating/not creating
2495 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2496 overwrite: boolean parameter for overwriting/not overwriting the file
2497 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2499 - 1D if all mesh nodes lie on OX coordinate axis, or
2500 - 2D if all mesh nodes lie on XOY coordinate plane, or
2501 - 3D in the rest cases.
2503 If **autoDimension** is *False*, the space dimension is always 3.
2506 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2507 # process positional arguments
2508 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2510 auto_groups = args[1] if len(args) > 1 else False
2511 overwrite = args[2] if len(args) > 2 else True
2512 autoDimension = args[3] if len(args) > 3 else True
2513 # process keywords arguments
2514 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2515 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2516 overwrite = kwargs.get("overwrite", overwrite)
2517 autoDimension = kwargs.get("autoDimension", autoDimension)
2519 # invoke engine's function
2520 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2522 def ExportToMEDX(self, *args, **kwargs):
2524 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2525 Export the mesh in a file in MED format
2528 fileName: the file name
2529 opt (boolean): parameter for creating/not creating
2530 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2531 overwrite: boolean parameter for overwriting/not overwriting the file
2532 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2534 - 1D if all mesh nodes lie on OX coordinate axis, or
2535 - 2D if all mesh nodes lie on XOY coordinate plane, or
2536 - 3D in the rest cases.
2538 If **autoDimension** is *False*, the space dimension is always 3.
2541 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2542 # process positional arguments
2543 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2545 auto_groups = args[1] if len(args) > 1 else False
2546 overwrite = args[2] if len(args) > 2 else True
2547 autoDimension = args[3] if len(args) > 3 else True
2548 # process keywords arguments
2549 auto_groups = kwargs.get("auto_groups", auto_groups)
2550 overwrite = kwargs.get("overwrite", overwrite)
2551 autoDimension = kwargs.get("autoDimension", autoDimension)
2553 # invoke engine's function
2554 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2558 def Append(self, meshes, uniteIdenticalGroups = True,
2559 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2561 Append given meshes into this mesh.
2562 All groups of input meshes will be created in this mesh.
2565 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2566 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2567 mergeNodesAndElements: if True, equal nodes and elements are merged
2568 mergeTolerance: tolerance for merging nodes
2569 allGroups: forces creation of groups corresponding to every input mesh
2571 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2572 mergeNodesAndElements, mergeTolerance, allGroups,
2573 meshToAppendTo = self.GetMesh() )
2575 # Operations with groups:
2576 # ----------------------
2577 def CreateEmptyGroup(self, elementType, name):
2579 Create an empty standalone mesh group
2582 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2583 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2584 name: the name of the mesh group
2587 :class:`SMESH.SMESH_Group`
2590 return self.mesh.CreateGroup(elementType, name)
2592 def Group(self, grp, name=""):
2594 Create a mesh group based on the geometric object *grp*
2595 and give it a *name*.
2596 If *name* is not defined the name of the geometric group is used
2599 Works like :meth:`GroupOnGeom`.
2602 grp: a geometric group, a vertex, an edge, a face or a solid
2603 name: the name of the mesh group
2606 :class:`SMESH.SMESH_GroupOnGeom`
2609 return self.GroupOnGeom(grp, name)
2611 def GroupOnGeom(self, grp, name="", typ=None):
2613 Create a mesh group based on the geometrical object *grp*
2614 and give it a *name*.
2615 if *name* is not defined the name of the geometric group is used
2618 grp: a geometrical group, a vertex, an edge, a face or a solid
2619 name: the name of the mesh group
2620 typ: the type of elements in the group; either of
2621 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2622 automatically detected by the type of the geometry
2625 :class:`SMESH.SMESH_GroupOnGeom`
2628 AssureGeomPublished( self, grp, name )
2630 name = grp.GetName()
2632 typ = self._groupTypeFromShape( grp )
2633 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2635 def _groupTypeFromShape( self, shape ):
2637 Pivate method to get a type of group on geometry
2639 tgeo = str(shape.GetShapeType())
2640 if tgeo == "VERTEX":
2642 elif tgeo == "EDGE" or tgeo == "WIRE":
2644 elif tgeo == "FACE" or tgeo == "SHELL":
2646 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2648 elif tgeo == "COMPOUND":
2649 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2651 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2652 return self._groupTypeFromShape( sub[0] )
2654 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2657 def GroupOnFilter(self, typ, name, filter):
2659 Create a mesh group with given *name* based on the *filter*.
2660 It is a special type of group dynamically updating it's contents during
2664 typ: the type of elements in the group; either of
2665 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2666 name: the name of the mesh group
2667 filter (SMESH.Filter): the filter defining group contents
2670 :class:`SMESH.SMESH_GroupOnFilter`
2673 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2675 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2677 Create a mesh group by the given ids of elements
2680 groupName: the name of the mesh group
2681 elementType: the type of elements in the group; either of
2682 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2683 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2686 :class:`SMESH.SMESH_Group`
2689 group = self.mesh.CreateGroup(elementType, groupName)
2690 if isinstance( elemIDs, Mesh ):
2691 elemIDs = elemIDs.GetMesh()
2692 if hasattr( elemIDs, "GetIDs" ):
2693 if hasattr( elemIDs, "SetMesh" ):
2694 elemIDs.SetMesh( self.GetMesh() )
2695 group.AddFrom( elemIDs )
2703 CritType=FT_Undefined,
2706 UnaryOp=FT_Undefined,
2709 Create a mesh group by the given conditions
2712 groupName: the name of the mesh group
2713 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2714 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2715 Note that the items starting from FT_LessThan are not suitable for CritType.
2716 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2717 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2718 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2719 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2720 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2723 :class:`SMESH.SMESH_GroupOnFilter`
2726 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2727 group = self.MakeGroupByCriterion(groupName, aCriterion)
2730 def MakeGroupByCriterion(self, groupName, Criterion):
2732 Create a mesh group by the given criterion
2735 groupName: the name of the mesh group
2736 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2739 :class:`SMESH.SMESH_GroupOnFilter`
2742 :meth:`smeshBuilder.GetCriterion`
2745 return self.MakeGroupByCriteria( groupName, [Criterion] )
2747 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2749 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2752 groupName: the name of the mesh group
2753 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2754 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2757 :class:`SMESH.SMESH_GroupOnFilter`
2760 :meth:`smeshBuilder.GetCriterion`
2763 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2764 group = self.MakeGroupByFilter(groupName, aFilter)
2767 def MakeGroupByFilter(self, groupName, theFilter):
2769 Create a mesh group by the given filter
2772 groupName (string): the name of the mesh group
2773 theFilter (SMESH.Filter): the filter
2776 :class:`SMESH.SMESH_GroupOnFilter`
2779 :meth:`smeshBuilder.GetFilter`
2782 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2783 #theFilter.SetMesh( self.mesh )
2784 #group.AddFrom( theFilter )
2785 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2788 def RemoveGroup(self, group):
2793 group (SMESH.SMESH_GroupBase): group to remove
2796 self.mesh.RemoveGroup(group)
2798 def RemoveGroupWithContents(self, group):
2800 Remove a group with its contents
2803 group (SMESH.SMESH_GroupBase): group to remove
2806 This operation can create gaps in numeration of nodes or elements.
2807 Call :meth:`RenumberElements` to remove the gaps.
2810 self.mesh.RemoveGroupWithContents(group)
2812 def GetGroups(self, elemType = SMESH.ALL):
2814 Get the list of groups existing in the mesh in the order of creation
2815 (starting from the oldest one)
2818 elemType (SMESH.ElementType): type of elements the groups contain;
2819 by default groups of elements of all types are returned
2822 a list of :class:`SMESH.SMESH_GroupBase`
2825 groups = self.mesh.GetGroups()
2826 if elemType == SMESH.ALL:
2830 if g.GetType() == elemType:
2831 typedGroups.append( g )
2838 Get the number of groups existing in the mesh
2841 the quantity of groups as an integer value
2844 return self.mesh.NbGroups()
2846 def GetGroupNames(self):
2848 Get the list of names of groups existing in the mesh
2854 groups = self.GetGroups()
2856 for group in groups:
2857 names.append(group.GetName())
2860 def GetGroupByName(self, name, elemType = None):
2862 Find groups by name and type
2865 name (string): name of the group of interest
2866 elemType (SMESH.ElementType): type of elements the groups contain;
2867 by default one group of any type is returned;
2868 if elemType == SMESH.ALL then all groups of any type are returned
2871 a list of :class:`SMESH.SMESH_GroupBase`
2875 for group in self.GetGroups():
2876 if group.GetName() == name:
2877 if elemType is None:
2879 if ( elemType == SMESH.ALL or
2880 group.GetType() == elemType ):
2881 groups.append( group )
2884 def UnionGroups(self, group1, group2, name):
2886 Produce a union of two groups.
2887 A new group is created. All mesh elements that are
2888 present in the initial groups are added to the new one
2891 group1 (SMESH.SMESH_GroupBase): a group
2892 group2 (SMESH.SMESH_GroupBase): another group
2895 instance of :class:`SMESH.SMESH_Group`
2898 return self.mesh.UnionGroups(group1, group2, name)
2900 def UnionListOfGroups(self, groups, name):
2902 Produce a union list of groups.
2903 New group is created. All mesh elements that are present in
2904 initial groups are added to the new one
2907 groups: list of :class:`SMESH.SMESH_GroupBase`
2910 instance of :class:`SMESH.SMESH_Group`
2912 return self.mesh.UnionListOfGroups(groups, name)
2914 def IntersectGroups(self, group1, group2, name):
2916 Prodice an intersection of two groups.
2917 A new group is created. All mesh elements that are common
2918 for the two initial groups are added to the new one.
2921 group1 (SMESH.SMESH_GroupBase): a group
2922 group2 (SMESH.SMESH_GroupBase): another group
2925 instance of :class:`SMESH.SMESH_Group`
2928 return self.mesh.IntersectGroups(group1, group2, name)
2930 def IntersectListOfGroups(self, groups, name):
2932 Produce an intersection of groups.
2933 New group is created. All mesh elements that are present in all
2934 initial groups simultaneously are added to the new one
2937 groups: a list of :class:`SMESH.SMESH_GroupBase`
2940 instance of :class:`SMESH.SMESH_Group`
2942 return self.mesh.IntersectListOfGroups(groups, name)
2944 def CutGroups(self, main_group, tool_group, name):
2946 Produce a cut of two groups.
2947 A new group is created. All mesh elements that are present in
2948 the main group but are not present in the tool group are added to the new one
2951 main_group (SMESH.SMESH_GroupBase): a group to cut from
2952 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2955 an instance of :class:`SMESH.SMESH_Group`
2958 return self.mesh.CutGroups(main_group, tool_group, name)
2960 def CutListOfGroups(self, main_groups, tool_groups, name):
2962 Produce a cut of groups.
2963 A new group is created. All mesh elements that are present in main groups
2964 but do not present in tool groups are added to the new one
2967 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2968 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2971 an instance of :class:`SMESH.SMESH_Group`
2974 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2976 def CreateDimGroup(self, groups, elemType, name,
2977 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2979 Create a standalone group of entities basing on nodes of other groups.
2982 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2983 elemType: a type of elements to include to the new group; either of
2984 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2985 name: a name of the new group.
2986 nbCommonNodes: a criterion of inclusion of an element to the new group
2987 basing on number of element nodes common with reference *groups*.
2988 Meaning of possible values are:
2990 - SMESH.ALL_NODES - include if all nodes are common,
2991 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2992 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2993 - SMEHS.MAJORITY - include if half of nodes or more are common.
2994 underlyingOnly: if *True* (default), an element is included to the
2995 new group provided that it is based on nodes of an element of *groups*;
2996 in this case the reference *groups* are supposed to be of higher dimension
2997 than *elemType*, which can be useful for example to get all faces lying on
2998 volumes of the reference *groups*.
3001 an instance of :class:`SMESH.SMESH_Group`
3004 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3006 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3008 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3010 Distribute all faces of the mesh among groups using sharp edges and optionally
3011 existing 1D elements as group boundaries.
3014 sharpAngle: edge is considered sharp if an angle between normals of
3015 adjacent faces is more than \a sharpAngle in degrees.
3016 createEdges (boolean): to create 1D elements for detected sharp edges.
3017 useExistingEdges (boolean): to use existing edges as group boundaries
3019 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3021 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3022 self.mesh.SetParameters(Parameters)
3023 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3025 def ConvertToStandalone(self, group):
3027 Convert group on geom into standalone group
3030 return self.mesh.ConvertToStandalone(group)
3032 # Get some info about mesh:
3033 # ------------------------
3035 def GetLog(self, clearAfterGet):
3037 Return the log of nodes and elements added or removed
3038 since the previous clear of the log.
3041 clearAfterGet: log is emptied after Get (safe if concurrents access)
3044 list of SMESH.log_block structures { commandType, number, coords, indexes }
3047 return self.mesh.GetLog(clearAfterGet)
3051 Clear the log of nodes and elements added or removed since the previous
3052 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3055 self.mesh.ClearLog()
3057 def SetAutoColor(self, theAutoColor):
3059 Toggle auto color mode on the object.
3060 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3063 theAutoColor (boolean): the flag which toggles auto color mode.
3066 self.mesh.SetAutoColor(theAutoColor)
3068 def GetAutoColor(self):
3070 Get flag of object auto color mode.
3076 return self.mesh.GetAutoColor()
3083 integer value, which is the internal Id of the mesh
3086 return self.mesh.GetId()
3088 def HasDuplicatedGroupNamesMED(self):
3090 Check the group names for duplications.
3091 Consider the maximum group name length stored in MED file.
3097 return self.mesh.HasDuplicatedGroupNamesMED()
3099 def GetMeshEditor(self):
3101 Obtain the mesh editor tool
3104 an instance of :class:`SMESH.SMESH_MeshEditor`
3109 def GetIDSource(self, ids, elemType = SMESH.ALL):
3111 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3112 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3116 elemType: type of elements; this parameter is used to distinguish
3117 IDs of nodes from IDs of elements; by default ids are treated as
3118 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3121 an instance of :class:`SMESH.SMESH_IDSource`
3124 call UnRegister() for the returned object as soon as it is no more useful::
3126 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3127 mesh.DoSomething( idSrc )
3131 if isinstance( ids, int ):
3133 return self.editor.MakeIDSource(ids, elemType)
3136 # Get information about mesh contents:
3137 # ------------------------------------
3139 def GetMeshInfo(self, obj = None):
3141 Get the mesh statistic.
3144 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3147 if not obj: obj = self.mesh
3148 return self.smeshpyD.GetMeshInfo(obj)
3152 Return the number of nodes in the mesh
3158 return self.mesh.NbNodes()
3160 def NbElements(self):
3162 Return the number of elements in the mesh
3168 return self.mesh.NbElements()
3170 def Nb0DElements(self):
3172 Return the number of 0d elements in the mesh
3178 return self.mesh.Nb0DElements()
3182 Return the number of ball discrete elements in the mesh
3188 return self.mesh.NbBalls()
3192 Return the number of edges in the mesh
3198 return self.mesh.NbEdges()
3200 def NbEdgesOfOrder(self, elementOrder):
3202 Return the number of edges with the given order in the mesh
3205 elementOrder: the order of elements
3206 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3212 return self.mesh.NbEdgesOfOrder(elementOrder)
3216 Return the number of faces in the mesh
3222 return self.mesh.NbFaces()
3224 def NbFacesOfOrder(self, elementOrder):
3226 Return the number of faces with the given order in the mesh
3229 elementOrder: the order of elements
3230 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3236 return self.mesh.NbFacesOfOrder(elementOrder)
3238 def NbTriangles(self):
3240 Return the number of triangles in the mesh
3246 return self.mesh.NbTriangles()
3248 def NbTrianglesOfOrder(self, elementOrder):
3250 Return the number of triangles with the given order in the mesh
3253 elementOrder: is the order of elements
3254 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3260 return self.mesh.NbTrianglesOfOrder(elementOrder)
3262 def NbBiQuadTriangles(self):
3264 Return the number of biquadratic triangles in the mesh
3270 return self.mesh.NbBiQuadTriangles()
3272 def NbQuadrangles(self):
3274 Return the number of quadrangles in the mesh
3280 return self.mesh.NbQuadrangles()
3282 def NbQuadranglesOfOrder(self, elementOrder):
3284 Return the number of quadrangles with the given order in the mesh
3287 elementOrder: the order of elements
3288 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3294 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3296 def NbBiQuadQuadrangles(self):
3298 Return the number of biquadratic quadrangles in the mesh
3304 return self.mesh.NbBiQuadQuadrangles()
3306 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3308 Return the number of polygons of given order in the mesh
3311 elementOrder: the order of elements
3312 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3318 return self.mesh.NbPolygonsOfOrder(elementOrder)
3320 def NbVolumes(self):
3322 Return the number of volumes in the mesh
3328 return self.mesh.NbVolumes()
3331 def NbVolumesOfOrder(self, elementOrder):
3333 Return the number of volumes with the given order in the mesh
3336 elementOrder: the order of elements
3337 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3343 return self.mesh.NbVolumesOfOrder(elementOrder)
3347 Return the number of tetrahedrons in the mesh
3353 return self.mesh.NbTetras()
3355 def NbTetrasOfOrder(self, elementOrder):
3357 Return the number of tetrahedrons with the given order in the mesh
3360 elementOrder: the order of elements
3361 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3367 return self.mesh.NbTetrasOfOrder(elementOrder)
3371 Return the number of hexahedrons in the mesh
3377 return self.mesh.NbHexas()
3379 def NbHexasOfOrder(self, elementOrder):
3381 Return the number of hexahedrons with the given order in the mesh
3384 elementOrder: the order of elements
3385 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3391 return self.mesh.NbHexasOfOrder(elementOrder)
3393 def NbTriQuadraticHexas(self):
3395 Return the number of triquadratic hexahedrons in the mesh
3401 return self.mesh.NbTriQuadraticHexas()
3403 def NbPyramids(self):
3405 Return the number of pyramids in the mesh
3411 return self.mesh.NbPyramids()
3413 def NbPyramidsOfOrder(self, elementOrder):
3415 Return the number of pyramids with the given order in the mesh
3418 elementOrder: the order of elements
3419 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3425 return self.mesh.NbPyramidsOfOrder(elementOrder)
3429 Return the number of prisms in the mesh
3435 return self.mesh.NbPrisms()
3437 def NbPrismsOfOrder(self, elementOrder):
3439 Return the number of prisms with the given order in the mesh
3442 elementOrder: the order of elements
3443 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3449 return self.mesh.NbPrismsOfOrder(elementOrder)
3451 def NbHexagonalPrisms(self):
3453 Return the number of hexagonal prisms in the mesh
3459 return self.mesh.NbHexagonalPrisms()
3461 def NbPolyhedrons(self):
3463 Return the number of polyhedrons in the mesh
3469 return self.mesh.NbPolyhedrons()
3471 def NbSubMesh(self):
3473 Return the number of submeshes in the mesh
3479 return self.mesh.NbSubMesh()
3481 def GetElementsId(self):
3483 Return the list of all mesh elements IDs
3486 the list of integer values
3489 :meth:`GetElementsByType`
3492 return self.mesh.GetElementsId()
3494 def GetElementsByType(self, elementType):
3496 Return the list of IDs of mesh elements with the given type
3499 elementType (SMESH.ElementType): the required type of elements
3502 list of integer values
3505 return self.mesh.GetElementsByType(elementType)
3507 def GetNodesId(self):
3509 Return the list of mesh nodes IDs
3512 the list of integer values
3515 return self.mesh.GetNodesId()
3517 # Get the information about mesh elements:
3518 # ------------------------------------
3520 def GetElementType(self, id, iselem=True):
3522 Return the type of mesh element or node
3525 the value from :class:`SMESH.ElementType` enumeration.
3526 Return SMESH.ALL if element or node with the given ID does not exist
3529 return self.mesh.GetElementType(id, iselem)
3531 def GetElementGeomType(self, id):
3533 Return the geometric type of mesh element
3536 the value from :class:`SMESH.EntityType` enumeration.
3539 return self.mesh.GetElementGeomType(id)
3541 def GetElementShape(self, id):
3543 Return the shape type of mesh element
3546 the value from :class:`SMESH.GeometryType` enumeration.
3549 return self.mesh.GetElementShape(id)
3551 def GetSubMeshElementsId(self, Shape):
3553 Return the list of sub-mesh elements IDs
3556 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3557 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3560 list of integer values
3563 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3564 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3567 return self.mesh.GetSubMeshElementsId(ShapeID)
3569 def GetSubMeshNodesId(self, Shape, all):
3571 Return the list of sub-mesh nodes IDs
3574 Shape: a geom object (sub-shape).
3575 *Shape* must be the sub-shape of a :meth:`GetShape`
3576 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3579 list of integer values
3582 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3583 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3586 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3588 def GetSubMeshElementType(self, Shape):
3590 Return type of elements on given shape
3593 Shape: a geom object (sub-shape).
3594 *Shape* must be a sub-shape of a ShapeToMesh()
3597 :class:`SMESH.ElementType`
3600 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3601 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3604 return self.mesh.GetSubMeshElementType(ShapeID)
3608 Get the mesh description
3614 return self.mesh.Dump()
3617 # Get the information about nodes and elements of a mesh by its IDs:
3618 # -----------------------------------------------------------
3620 def GetNodeXYZ(self, id):
3622 Get XYZ coordinates of a node.
3623 If there is no node for the given ID - return an empty list
3626 list of float values
3629 return self.mesh.GetNodeXYZ(id)
3631 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3633 Return list of IDs of inverse elements for the given node.
3634 If there is no node for the given ID - return an empty list
3638 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3641 list of integer values
3644 return self.mesh.GetNodeInverseElements(id,elemType)
3646 def GetNodePosition(self,NodeID):
3648 Return the position of a node on the shape
3651 :class:`SMESH.NodePosition`
3654 return self.mesh.GetNodePosition(NodeID)
3656 def GetElementPosition(self,ElemID):
3658 Return the position of an element on the shape
3661 :class:`SMESH.ElementPosition`
3664 return self.mesh.GetElementPosition(ElemID)
3666 def GetShapeID(self, id):
3668 Return the ID of the shape, on which the given node was generated.
3671 an integer value > 0 or -1 if there is no node for the given
3672 ID or the node is not assigned to any geometry
3675 return self.mesh.GetShapeID(id)
3677 def GetShapeIDForElem(self,id):
3679 Return the ID of the shape, on which the given element was generated.
3682 an integer value > 0 or -1 if there is no element for the given
3683 ID or the element is not assigned to any geometry
3686 return self.mesh.GetShapeIDForElem(id)
3688 def GetElemNbNodes(self, id):
3690 Return the number of nodes of the given element
3693 an integer value > 0 or -1 if there is no element for the given ID
3696 return self.mesh.GetElemNbNodes(id)
3698 def GetElemNode(self, id, index):
3700 Return the node ID the given (zero based) index for the given element.
3702 * If there is no element for the given ID - return -1.
3703 * If there is no node for the given index - return -2.
3706 id (int): element ID
3707 index (int): node index within the element
3710 an integer value (ID)
3713 :meth:`GetElemNodes`
3716 return self.mesh.GetElemNode(id, index)
3718 def GetElemNodes(self, id):
3720 Return the IDs of nodes of the given element
3723 a list of integer values
3726 return self.mesh.GetElemNodes(id)
3728 def IsMediumNode(self, elementID, nodeID):
3730 Return true if the given node is the medium node in the given quadratic element
3733 return self.mesh.IsMediumNode(elementID, nodeID)
3735 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3737 Return true if the given node is the medium node in one of quadratic elements
3740 nodeID: ID of the node
3741 elementType: the type of elements to check a state of the node, either of
3742 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3745 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3747 def ElemNbEdges(self, id):
3749 Return the number of edges for the given element
3752 return self.mesh.ElemNbEdges(id)
3754 def ElemNbFaces(self, id):
3756 Return the number of faces for the given element
3759 return self.mesh.ElemNbFaces(id)
3761 def GetElemFaceNodes(self,elemId, faceIndex):
3763 Return nodes of given face (counted from zero) for given volumic element.
3766 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3768 def GetFaceNormal(self, faceId, normalized=False):
3770 Return three components of normal of given mesh face
3771 (or an empty array in KO case)
3774 return self.mesh.GetFaceNormal(faceId,normalized)
3776 def FindElementByNodes(self, nodes):
3778 Return an element based on all given nodes.
3781 return self.mesh.FindElementByNodes(nodes)
3783 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3785 Return elements including all given nodes.
3788 return self.mesh.GetElementsByNodes( nodes, elemType )
3790 def IsPoly(self, id):
3792 Return true if the given element is a polygon
3795 return self.mesh.IsPoly(id)
3797 def IsQuadratic(self, id):
3799 Return true if the given element is quadratic
3802 return self.mesh.IsQuadratic(id)
3804 def GetBallDiameter(self, id):
3806 Return diameter of a ball discrete element or zero in case of an invalid *id*
3809 return self.mesh.GetBallDiameter(id)
3811 def BaryCenter(self, id):
3813 Return XYZ coordinates of the barycenter of the given element.
3814 If there is no element for the given ID - return an empty list
3817 a list of three double values
3820 :meth:`smeshBuilder.GetGravityCenter`
3823 return self.mesh.BaryCenter(id)
3825 def GetIdsFromFilter(self, filter, meshParts=[] ):
3827 Pass mesh elements through the given filter and return IDs of fitting elements
3830 filter: :class:`SMESH.Filter`
3831 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3837 :meth:`SMESH.Filter.GetIDs`
3838 :meth:`SMESH.Filter.GetElementsIdFromParts`
3841 filter.SetMesh( self.mesh )
3844 if isinstance( meshParts, Mesh ):
3845 filter.SetMesh( meshParts.GetMesh() )
3846 return theFilter.GetIDs()
3847 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3848 meshParts = [ meshParts ]
3849 return filter.GetElementsIdFromParts( meshParts )
3851 return filter.GetIDs()
3853 # Get mesh measurements information:
3854 # ------------------------------------
3856 def GetFreeBorders(self):
3858 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3859 Return a list of special structures (borders).
3862 a list of :class:`SMESH.FreeEdges.Border`
3865 aFilterMgr = self.smeshpyD.CreateFilterManager()
3866 aPredicate = aFilterMgr.CreateFreeEdges()
3867 aPredicate.SetMesh(self.mesh)
3868 aBorders = aPredicate.GetBorders()
3869 aFilterMgr.UnRegister()
3872 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3874 Get minimum distance between two nodes, elements or distance to the origin
3877 id1: first node/element id
3878 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3879 isElem1: *True* if *id1* is element id, *False* if it is node id
3880 isElem2: *True* if *id2* is element id, *False* if it is node id
3883 minimum distance value
3885 :meth:`GetMinDistance`
3888 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3889 return aMeasure.value
3891 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3893 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3896 id1: first node/element id
3897 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3898 isElem1: *True* if *id1* is element id, *False* if it is node id
3899 isElem2: *True* if *id2* is element id, *False* if it is node id
3902 :class:`SMESH.Measure` structure
3908 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3910 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3913 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3915 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3920 aMeasurements = self.smeshpyD.CreateMeasurements()
3921 aMeasure = aMeasurements.MinDistance(id1, id2)
3922 genObjUnRegister([aMeasurements,id1, id2])
3925 def BoundingBox(self, objects=None, isElem=False):
3927 Get bounding box of the specified object(s)
3930 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3931 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3932 *False* specifies that *objects* are nodes
3935 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3938 :meth:`GetBoundingBox()`
3941 result = self.GetBoundingBox(objects, isElem)
3945 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3948 def GetBoundingBox(self, objects=None, isElem=False):
3950 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3953 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3954 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3955 False means that *objects* are nodes
3958 :class:`SMESH.Measure` structure
3961 :meth:`BoundingBox()`
3965 objects = [self.mesh]
3966 elif isinstance(objects, tuple):
3967 objects = list(objects)
3968 if not isinstance(objects, list):
3970 if len(objects) > 0 and isinstance(objects[0], int):
3973 unRegister = genObjUnRegister()
3975 if isinstance(o, Mesh):
3976 srclist.append(o.mesh)
3977 elif hasattr(o, "_narrow"):
3978 src = o._narrow(SMESH.SMESH_IDSource)
3979 if src: srclist.append(src)
3981 elif isinstance(o, list):
3983 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3985 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3986 unRegister.set( srclist[-1] )
3989 aMeasurements = self.smeshpyD.CreateMeasurements()
3990 unRegister.set( aMeasurements )
3991 aMeasure = aMeasurements.BoundingBox(srclist)
3994 # Mesh edition (SMESH_MeshEditor functionality):
3995 # ---------------------------------------------
3997 def RemoveElements(self, IDsOfElements):
3999 Remove the elements from the mesh by ids
4002 IDsOfElements: is a list of ids of elements to remove
4008 This operation can create gaps in numeration of elements.
4009 Call :meth:`RenumberElements` to remove the gaps.
4012 return self.editor.RemoveElements(IDsOfElements)
4014 def RemoveNodes(self, IDsOfNodes):
4016 Remove nodes from mesh by ids
4019 IDsOfNodes: is a list of ids of nodes to remove
4025 This operation can create gaps in numeration of nodes.
4026 Call :meth:`RenumberElements` to remove the gaps.
4029 return self.editor.RemoveNodes(IDsOfNodes)
4031 def RemoveOrphanNodes(self):
4033 Remove all orphan (free) nodes from mesh
4036 number of the removed nodes
4039 This operation can create gaps in numeration of nodes.
4040 Call :meth:`RenumberElements` to remove the gaps.
4043 return self.editor.RemoveOrphanNodes()
4045 def AddNode(self, x, y, z):
4047 Add a node to the mesh by coordinates
4053 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4054 if hasVars: self.mesh.SetParameters(Parameters)
4055 return self.editor.AddNode( x, y, z)
4057 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4059 Create a 0D element on a node with given number.
4062 IDOfNode: the ID of node for creation of the element.
4063 DuplicateElements: to add one more 0D element to a node or not
4066 ID of the new 0D element
4069 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4071 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4073 Create 0D elements on all nodes of the given elements except those
4074 nodes on which a 0D element already exists.
4077 theObject: an object on whose nodes 0D elements will be created.
4078 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4079 theGroupName: optional name of a group to add 0D elements created
4080 and/or found on nodes of *theObject*.
4081 DuplicateElements: to add one more 0D element to a node or not
4084 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4085 IDs of new and/or found 0D elements. IDs of 0D elements
4086 can be retrieved from the returned object by
4087 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4090 unRegister = genObjUnRegister()
4091 if isinstance( theObject, Mesh ):
4092 theObject = theObject.GetMesh()
4093 elif isinstance( theObject, list ):
4094 theObject = self.GetIDSource( theObject, SMESH.ALL )
4095 unRegister.set( theObject )
4096 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4098 def AddBall(self, IDOfNode, diameter):
4100 Create a ball element on a node with given ID.
4103 IDOfNode: the ID of node for creation of the element.
4104 diameter: the bal diameter.
4107 ID of the new ball element
4110 return self.editor.AddBall( IDOfNode, diameter )
4112 def AddEdge(self, IDsOfNodes):
4114 Create a linear or quadratic edge (this is determined
4115 by the number of given nodes).
4118 IDsOfNodes: list of node IDs for creation of the element.
4119 The order of nodes in this list should correspond to
4120 the :ref:`connectivity convention <connectivity_page>`.
4126 return self.editor.AddEdge(IDsOfNodes)
4128 def AddFace(self, IDsOfNodes):
4130 Create a linear or quadratic face (this is determined
4131 by the number of given nodes).
4134 IDsOfNodes: list of node IDs for creation of the element.
4135 The order of nodes in this list should correspond to
4136 the :ref:`connectivity convention <connectivity_page>`.
4142 return self.editor.AddFace(IDsOfNodes)
4144 def AddPolygonalFace(self, IdsOfNodes):
4146 Add a polygonal face defined by a list of node IDs
4149 IdsOfNodes: the list of node IDs for creation of the element.
4155 return self.editor.AddPolygonalFace(IdsOfNodes)
4157 def AddQuadPolygonalFace(self, IdsOfNodes):
4159 Add a quadratic polygonal face defined by a list of node IDs
4162 IdsOfNodes: the list of node IDs for creation of the element;
4163 corner nodes follow first.
4169 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4171 def AddVolume(self, IDsOfNodes):
4173 Create both simple and quadratic volume (this is determined
4174 by the number of given nodes).
4177 IDsOfNodes: list of node IDs for creation of the element.
4178 The order of nodes in this list should correspond to
4179 the :ref:`connectivity convention <connectivity_page>`.
4182 ID of the new volumic element
4185 return self.editor.AddVolume(IDsOfNodes)
4187 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4189 Create a volume of many faces, giving nodes for each face.
4192 IdsOfNodes: list of node IDs for volume creation, face by face.
4193 Quantities: list of integer values, Quantities[i]
4194 gives the quantity of nodes in face number i.
4197 ID of the new volumic element
4200 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4202 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4204 Create a volume of many faces, giving the IDs of the existing faces.
4207 The created volume will refer only to the nodes
4208 of the given faces, not to the faces themselves.
4211 IdsOfFaces: the list of face IDs for volume creation.
4214 ID of the new volumic element
4217 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4220 def SetNodeOnVertex(self, NodeID, Vertex):
4222 Bind a node to a vertex
4226 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4229 True if succeed else raises an exception
4232 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4233 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4237 self.editor.SetNodeOnVertex(NodeID, VertexID)
4238 except SALOME.SALOME_Exception as inst:
4239 raise ValueError(inst.details.text)
4243 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4245 Store the node position on an edge
4249 Edge: an edge (GEOM.GEOM_Object) or edge ID
4250 paramOnEdge: a parameter on the edge where the node is located
4253 True if succeed else raises an exception
4256 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4257 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4261 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4262 except SALOME.SALOME_Exception as inst:
4263 raise ValueError(inst.details.text)
4266 def SetNodeOnFace(self, NodeID, Face, u, v):
4268 Store node position on a face
4272 Face: a face (GEOM.GEOM_Object) or face ID
4273 u: U parameter on the face where the node is located
4274 v: V parameter on the face where the node is located
4277 True if succeed else raises an exception
4280 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4281 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4285 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4286 except SALOME.SALOME_Exception as inst:
4287 raise ValueError(inst.details.text)
4290 def SetNodeInVolume(self, NodeID, Solid):
4292 Bind a node to a solid
4296 Solid: a solid (GEOM.GEOM_Object) or solid ID
4299 True if succeed else raises an exception
4302 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4303 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4307 self.editor.SetNodeInVolume(NodeID, SolidID)
4308 except SALOME.SALOME_Exception as inst:
4309 raise ValueError(inst.details.text)
4312 def SetMeshElementOnShape(self, ElementID, Shape):
4314 Bind an element to a shape
4317 ElementID: an element ID
4318 Shape: a shape (GEOM.GEOM_Object) or shape ID
4321 True if succeed else raises an exception
4324 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4325 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4329 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4330 except SALOME.SALOME_Exception as inst:
4331 raise ValueError(inst.details.text)
4335 def MoveNode(self, NodeID, x, y, z):
4337 Move the node with the given id
4340 NodeID: the id of the node
4341 x: a new X coordinate
4342 y: a new Y coordinate
4343 z: a new Z coordinate
4346 True if succeed else False
4349 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4350 if hasVars: self.mesh.SetParameters(Parameters)
4351 return self.editor.MoveNode(NodeID, x, y, z)
4353 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4355 Find the node closest to a point and moves it to a point location
4358 x: the X coordinate of a point
4359 y: the Y coordinate of a point
4360 z: the Z coordinate of a point
4361 NodeID: if specified (>0), the node with this ID is moved,
4362 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4365 the ID of a moved node
4368 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4369 if hasVars: self.mesh.SetParameters(Parameters)
4370 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4372 def FindNodeClosestTo(self, x, y, z):
4374 Find the node closest to a point
4377 x: the X coordinate of a point
4378 y: the Y coordinate of a point
4379 z: the Z coordinate of a point
4385 return self.editor.FindNodeClosestTo(x, y, z)
4387 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4389 Find the elements where a point lays IN or ON
4392 x,y,z (float): coordinates of the point
4393 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4394 means elements of any type excluding nodes, discrete and 0D elements.
4395 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4398 list of IDs of found elements
4401 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4403 return self.editor.FindElementsByPoint(x, y, z, elementType)
4405 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4407 Project a point to a mesh object.
4408 Return ID of an element of given type where the given point is projected
4409 and coordinates of the projection point.
4410 In the case if nothing found, return -1 and []
4412 if isinstance( meshObject, Mesh ):
4413 meshObject = meshObject.GetMesh()
4415 meshObject = self.GetMesh()
4416 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4418 def GetPointState(self, x, y, z):
4420 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4421 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4422 UNKNOWN state means that either mesh is wrong or the analysis fails.
4425 return self.editor.GetPointState(x, y, z)
4427 def IsManifold(self):
4429 Check if a 2D mesh is manifold
4432 return self.editor.IsManifold()
4434 def IsCoherentOrientation2D(self):
4436 Check if orientation of 2D elements is coherent
4439 return self.editor.IsCoherentOrientation2D()
4441 def Get1DBranches( self, edges, startNode = 0 ):
4443 Partition given 1D elements into groups of contiguous edges.
4444 A node where number of meeting edges != 2 is a group end.
4445 An optional startNode is used to orient groups it belongs to.
4448 A list of edge groups and a list of corresponding node groups,
4449 where the group is a list of IDs of edges or elements, like follows
4450 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4451 If a group is closed, the first and last nodes of the group are same.
4453 if isinstance( edges, Mesh ):
4454 edges = edges.GetMesh()
4455 unRegister = genObjUnRegister()
4456 if isinstance( edges, list ):
4457 edges = self.GetIDSource( edges, SMESH.EDGE )
4458 unRegister.set( edges )
4459 return self.editor.Get1DBranches( edges, startNode )
4461 def FindSharpEdges( self, angle, addExisting=False ):
4463 Return sharp edges of faces and non-manifold ones.
4464 Optionally add existing edges.
4467 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4468 addExisting: to return existing edges (1D elements) as well
4471 list of FaceEdge structures
4473 angle = ParseParameters( angle )[0]
4474 return self.editor.FindSharpEdges( angle, addExisting )
4476 def MeshToPassThroughAPoint(self, x, y, z):
4478 Find the node closest to a point and moves it to a point location
4481 x: the X coordinate of a point
4482 y: the Y coordinate of a point
4483 z: the Z coordinate of a point
4486 the ID of a moved node
4489 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4491 def InverseDiag(self, NodeID1, NodeID2):
4493 Replace two neighbour triangles sharing Node1-Node2 link
4494 with the triangles built on the same 4 nodes but having other common link.
4497 NodeID1: the ID of the first node
4498 NodeID2: the ID of the second node
4501 False if proper faces were not found
4503 return self.editor.InverseDiag(NodeID1, NodeID2)
4505 def DeleteDiag(self, NodeID1, NodeID2):
4507 Replace two neighbour triangles sharing *Node1-Node2* link
4508 with a quadrangle built on the same 4 nodes.
4511 NodeID1: ID of the first node
4512 NodeID2: ID of the second node
4515 False if proper faces were not found
4518 This operation can create gaps in numeration of elements.
4519 Call :meth:`RenumberElements` to remove the gaps.
4522 return self.editor.DeleteDiag(NodeID1, NodeID2)
4524 def Reorient(self, IDsOfElements=None):
4526 Reorient elements by ids
4529 IDsOfElements: if undefined reorients all mesh elements
4532 True if succeed else False
4535 if IDsOfElements == None:
4536 IDsOfElements = self.GetElementsId()
4537 return self.editor.Reorient(IDsOfElements)
4539 def ReorientObject(self, theObject):
4541 Reorient all elements of the object
4544 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4547 True if succeed else False
4550 if ( isinstance( theObject, Mesh )):
4551 theObject = theObject.GetMesh()
4552 return self.editor.ReorientObject(theObject)
4554 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4556 Reorient faces contained in *the2DObject*.
4559 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4560 theDirection: a desired direction of normal of *theFace*.
4561 It can be either a GEOM vector or a list of coordinates [x,y,z].
4562 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4563 compared with theDirection. It can be either ID of face or a point
4564 by which the face will be found. The point can be given as either
4565 a GEOM vertex or a list of point coordinates.
4568 number of reoriented faces
4571 unRegister = genObjUnRegister()
4573 if isinstance( the2DObject, Mesh ):
4574 the2DObject = the2DObject.GetMesh()
4575 if isinstance( the2DObject, list ):
4576 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4577 unRegister.set( the2DObject )
4578 # check theDirection
4579 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4580 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4581 if isinstance( theDirection, list ):
4582 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4583 # prepare theFace and thePoint
4584 theFace = theFaceOrPoint
4585 thePoint = PointStruct(0,0,0)
4586 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4587 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4589 if isinstance( theFaceOrPoint, list ):
4590 thePoint = PointStruct( *theFaceOrPoint )
4592 if isinstance( theFaceOrPoint, PointStruct ):
4593 thePoint = theFaceOrPoint
4595 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4597 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4599 Reorient faces according to adjacent volumes.
4602 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4603 either IDs of faces or face groups.
4604 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4605 theOutsideNormal: to orient faces to have their normals
4606 pointing either *outside* or *inside* the adjacent volumes.
4609 number of reoriented faces.
4612 unRegister = genObjUnRegister()
4614 if not isinstance( the2DObject, list ):
4615 the2DObject = [ the2DObject ]
4616 elif the2DObject and isinstance( the2DObject[0], int ):
4617 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4618 unRegister.set( the2DObject )
4619 the2DObject = [ the2DObject ]
4620 for i,obj2D in enumerate( the2DObject ):
4621 if isinstance( obj2D, Mesh ):
4622 the2DObject[i] = obj2D.GetMesh()
4623 if isinstance( obj2D, list ):
4624 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4625 unRegister.set( the2DObject[i] )
4627 if isinstance( the3DObject, Mesh ):
4628 the3DObject = the3DObject.GetMesh()
4629 if isinstance( the3DObject, list ):
4630 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4631 unRegister.set( the3DObject )
4632 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4634 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4636 Fuse the neighbouring triangles into quadrangles.
4639 IDsOfElements: The triangles to be fused.
4640 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4641 applied to possible quadrangles to choose a neighbour to fuse with.
4642 Note that not all items of :class:`SMESH.FunctorType` corresponds
4643 to numerical functors.
4644 MaxAngle: is the maximum angle between element normals at which the fusion
4645 is still performed; theMaxAngle is measured in radians.
4646 Also it could be a name of variable which defines angle in degrees.
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 not IDsOfElements:
4659 IDsOfElements = self.GetElementsId()
4660 Functor = self.smeshpyD.GetFunctor(theCriterion)
4661 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4663 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4665 Fuse the neighbouring triangles of the object into quadrangles
4668 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4669 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4670 applied to possible quadrangles to choose a neighbour to fuse with.
4671 Note that not all items of :class:`SMESH.FunctorType` corresponds
4672 to numerical functors.
4673 MaxAngle: a max angle between element normals at which the fusion
4674 is still performed; theMaxAngle is measured in radians.
4677 True in case of success, False otherwise.
4680 This operation can create gaps in numeration of elements.
4681 Call :meth:`RenumberElements` to remove the gaps.
4684 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4685 self.mesh.SetParameters(Parameters)
4686 if isinstance( theObject, Mesh ):
4687 theObject = theObject.GetMesh()
4688 Functor = self.smeshpyD.GetFunctor(theCriterion)
4689 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4691 def QuadToTri (self, IDsOfElements, theCriterion = None):
4693 Split quadrangles into triangles.
4696 IDsOfElements: the faces to be splitted.
4697 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4698 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4699 value, then quadrangles will be split by the smallest diagonal.
4700 Note that not all items of :class:`SMESH.FunctorType` corresponds
4701 to numerical functors.
4704 True in case of success, False otherwise.
4707 This operation can create gaps in numeration of elements.
4708 Call :meth:`RenumberElements` to remove the gaps.
4710 if IDsOfElements == []:
4711 IDsOfElements = self.GetElementsId()
4712 if theCriterion is None:
4713 theCriterion = FT_MaxElementLength2D
4714 Functor = self.smeshpyD.GetFunctor(theCriterion)
4715 return self.editor.QuadToTri(IDsOfElements, Functor)
4717 def QuadToTriObject (self, theObject, theCriterion = None):
4719 Split quadrangles into triangles.
4722 theObject: the object from which the list of elements is taken,
4723 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4724 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4725 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4726 value, then quadrangles will be split by the smallest diagonal.
4727 Note that not all items of :class:`SMESH.FunctorType` corresponds
4728 to numerical functors.
4731 True in case of success, False otherwise.
4734 This operation can create gaps in numeration of elements.
4735 Call :meth:`RenumberElements` to remove the gaps.
4737 if ( isinstance( theObject, Mesh )):
4738 theObject = theObject.GetMesh()
4739 if theCriterion is None:
4740 theCriterion = FT_MaxElementLength2D
4741 Functor = self.smeshpyD.GetFunctor(theCriterion)
4742 return self.editor.QuadToTriObject(theObject, Functor)
4744 def QuadTo4Tri (self, theElements=[]):
4746 Split each of given quadrangles into 4 triangles. A node is added at the center of
4750 theElements: the faces to be splitted. This can be either
4751 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4752 or a list of face IDs. By default all quadrangles are split
4755 This operation can create gaps in numeration of elements.
4756 Call :meth:`RenumberElements` to remove the gaps.
4758 unRegister = genObjUnRegister()
4759 if isinstance( theElements, Mesh ):
4760 theElements = theElements.mesh
4761 elif not theElements:
4762 theElements = self.mesh
4763 elif isinstance( theElements, list ):
4764 theElements = self.GetIDSource( theElements, SMESH.FACE )
4765 unRegister.set( theElements )
4766 return self.editor.QuadTo4Tri( theElements )
4768 def SplitQuad (self, IDsOfElements, Diag13):
4770 Split quadrangles into triangles.
4773 IDsOfElements: the faces to be splitted
4774 Diag13 (boolean): is used to choose a diagonal for splitting.
4777 True in case of success, False otherwise.
4780 This operation can create gaps in numeration of elements.
4781 Call :meth:`RenumberElements` to remove the gaps.
4783 if IDsOfElements == []:
4784 IDsOfElements = self.GetElementsId()
4785 return self.editor.SplitQuad(IDsOfElements, Diag13)
4787 def SplitQuadObject (self, theObject, Diag13):
4789 Split quadrangles into triangles.
4792 theObject: the object from which the list of elements is taken,
4793 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4794 Diag13 (boolean): is used to choose a diagonal for splitting.
4797 True in case of success, False otherwise.
4800 This operation can create gaps in numeration of elements.
4801 Call :meth:`RenumberElements` to remove the gaps.
4803 if ( isinstance( theObject, Mesh )):
4804 theObject = theObject.GetMesh()
4805 return self.editor.SplitQuadObject(theObject, Diag13)
4807 def BestSplit (self, IDOfQuad, theCriterion):
4809 Find a better splitting of the given quadrangle.
4812 IDOfQuad: the ID of the quadrangle to be splitted.
4813 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4814 choose a diagonal for splitting.
4815 Note that not all items of :class:`SMESH.FunctorType` corresponds
4816 to numerical functors.
4819 * 1 if 1-3 diagonal is better,
4820 * 2 if 2-4 diagonal is better,
4821 * 0 if error occurs.
4824 This operation can create gaps in numeration of elements.
4825 Call :meth:`RenumberElements` to remove the gaps.
4827 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4829 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4831 Split volumic elements into tetrahedrons
4834 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4835 method: flags passing splitting method:
4836 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4837 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4840 This operation can create gaps in numeration of elements.
4841 Call :meth:`RenumberElements` to remove the gaps.
4843 unRegister = genObjUnRegister()
4844 if isinstance( elems, Mesh ):
4845 elems = elems.GetMesh()
4846 if ( isinstance( elems, list )):
4847 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4848 unRegister.set( elems )
4849 self.editor.SplitVolumesIntoTetra(elems, method)
4852 def SplitBiQuadraticIntoLinear(self, elems=None):
4854 Split bi-quadratic elements into linear ones without creation of additional nodes:
4856 - bi-quadratic triangle will be split into 3 linear quadrangles;
4857 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4858 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4860 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4861 will be split in order to keep the mesh conformal.
4864 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4865 if None (default), all bi-quadratic elements will be split
4868 This operation can create gaps in numeration of elements.
4869 Call :meth:`RenumberElements` to remove the gaps.
4871 unRegister = genObjUnRegister()
4872 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4873 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4874 unRegister.set( elems )
4876 elems = [ self.GetMesh() ]
4877 if isinstance( elems, Mesh ):
4878 elems = [ elems.GetMesh() ]
4879 if not isinstance( elems, list ):
4881 self.editor.SplitBiQuadraticIntoLinear( elems )
4883 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4884 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4886 Split hexahedra into prisms
4889 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4890 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4891 gives a normal vector defining facets to split into triangles.
4892 *startHexPoint* can be either a triple of coordinates or a vertex.
4893 facetNormal: a normal to a facet to split into triangles of a
4894 hexahedron found by *startHexPoint*.
4895 *facetNormal* can be either a triple of coordinates or an edge.
4896 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4897 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4898 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4899 to *startHexPoint* are split, else *startHexPoint*
4900 is used to find the facet to split in all domains present in *elems*.
4903 This operation can create gaps in numeration of elements.
4904 Call :meth:`RenumberElements` to remove the gaps.
4907 unRegister = genObjUnRegister()
4908 if isinstance( elems, Mesh ):
4909 elems = elems.GetMesh()
4910 if ( isinstance( elems, list )):
4911 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4912 unRegister.set( elems )
4915 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4916 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4917 elif isinstance( startHexPoint, list ):
4918 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4921 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4922 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4923 elif isinstance( facetNormal, list ):
4924 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4927 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4929 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4931 def SplitQuadsNearTriangularFacets(self):
4933 Split quadrangle faces near triangular facets of volumes
4936 This operation can create gaps in numeration of elements.
4937 Call :meth:`RenumberElements` to remove the gaps.
4939 faces_array = self.GetElementsByType(SMESH.FACE)
4940 for face_id in faces_array:
4941 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4942 quad_nodes = self.mesh.GetElemNodes(face_id)
4943 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4944 isVolumeFound = False
4945 for node1_elem in node1_elems:
4946 if not isVolumeFound:
4947 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4948 nb_nodes = self.GetElemNbNodes(node1_elem)
4949 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4950 volume_elem = node1_elem
4951 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4952 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4953 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4954 isVolumeFound = True
4955 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4956 self.SplitQuad([face_id], False) # diagonal 2-4
4957 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4958 isVolumeFound = True
4959 self.SplitQuad([face_id], True) # diagonal 1-3
4960 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4961 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4962 isVolumeFound = True
4963 self.SplitQuad([face_id], True) # diagonal 1-3
4965 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4967 Split hexahedrons into tetrahedrons.
4969 This operation uses :doc:`pattern_mapping` functionality for splitting.
4972 theObject: the object from which the list of hexahedrons is taken;
4973 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4974 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4975 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4976 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4977 key-point will be mapped into *theNode001*-th node of each volume.
4978 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4981 True in case of success, False otherwise.
4984 This operation can create gaps in numeration of elements.
4985 Call :meth:`RenumberElements` to remove the gaps.
4993 # (0,0,1) 4.---------.7 * |
5000 # (0,0,0) 0.---------.3
5001 pattern_tetra = "!!! Nb of points: \n 8 \n\
5011 !!! Indices of points of 6 tetras: \n\
5019 pattern = self.smeshpyD.GetPattern()
5020 isDone = pattern.LoadFromFile(pattern_tetra)
5022 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5025 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5026 isDone = pattern.MakeMesh(self.mesh, False, False)
5027 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5029 # split quafrangle faces near triangular facets of volumes
5030 self.SplitQuadsNearTriangularFacets()
5034 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5036 Split hexahedrons into prisms.
5038 Uses the :doc:`pattern_mapping` functionality for splitting.
5041 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5042 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5043 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5044 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5045 will be mapped into the *theNode001* -th node of each volume.
5046 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5049 True in case of success, False otherwise.
5052 This operation can create gaps in numeration of elements.
5053 Call :meth:`RenumberElements` to remove the gaps.
5055 # Pattern: 5.---------.6
5060 # (0,0,1) 4.---------.7 |
5067 # (0,0,0) 0.---------.3
5068 pattern_prism = "!!! Nb of points: \n 8 \n\
5078 !!! Indices of points of 2 prisms: \n\
5082 pattern = self.smeshpyD.GetPattern()
5083 isDone = pattern.LoadFromFile(pattern_prism)
5085 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5088 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5089 isDone = pattern.MakeMesh(self.mesh, False, False)
5090 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5092 # Split quafrangle faces near triangular facets of volumes
5093 self.SplitQuadsNearTriangularFacets()
5097 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5098 MaxNbOfIterations, MaxAspectRatio, Method):
5103 IDsOfElements: the list if ids of elements to smooth
5104 IDsOfFixedNodes: the list of ids of fixed nodes.
5105 Note that nodes built on edges and boundary nodes are always fixed.
5106 MaxNbOfIterations: the maximum number of iterations
5107 MaxAspectRatio: varies in range [1.0, inf]
5108 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5109 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5112 True in case of success, False otherwise.
5115 if IDsOfElements == []:
5116 IDsOfElements = self.GetElementsId()
5117 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5118 self.mesh.SetParameters(Parameters)
5119 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5120 MaxNbOfIterations, MaxAspectRatio, Method)
5122 def SmoothObject(self, theObject, IDsOfFixedNodes,
5123 MaxNbOfIterations, MaxAspectRatio, Method):
5125 Smooth elements which belong to the given object
5128 theObject: the object to smooth
5129 IDsOfFixedNodes: the list of ids of fixed nodes.
5130 Note that nodes built on edges and boundary nodes are always fixed.
5131 MaxNbOfIterations: the maximum number of iterations
5132 MaxAspectRatio: varies in range [1.0, inf]
5133 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5134 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5137 True in case of success, False otherwise.
5140 if ( isinstance( theObject, Mesh )):
5141 theObject = theObject.GetMesh()
5142 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5143 MaxNbOfIterations, MaxAspectRatio, Method)
5145 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5146 MaxNbOfIterations, MaxAspectRatio, Method):
5148 Parametrically smooth the given elements
5151 IDsOfElements: the list if ids of elements to smooth
5152 IDsOfFixedNodes: the list of ids of fixed nodes.
5153 Note that nodes built on edges and boundary nodes are always fixed.
5154 MaxNbOfIterations: the maximum number of iterations
5155 MaxAspectRatio: varies in range [1.0, inf]
5156 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5157 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5160 True in case of success, False otherwise.
5163 if IDsOfElements == []:
5164 IDsOfElements = self.GetElementsId()
5165 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5166 self.mesh.SetParameters(Parameters)
5167 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5168 MaxNbOfIterations, MaxAspectRatio, Method)
5170 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5171 MaxNbOfIterations, MaxAspectRatio, Method):
5173 Parametrically smooth the elements which belong to the given object
5176 theObject: the object to smooth
5177 IDsOfFixedNodes: the list of ids of fixed nodes.
5178 Note that nodes built on edges and boundary nodes are always fixed.
5179 MaxNbOfIterations: the maximum number of iterations
5180 MaxAspectRatio: varies in range [1.0, inf]
5181 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5182 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5185 True in case of success, False otherwise.
5188 if ( isinstance( theObject, Mesh )):
5189 theObject = theObject.GetMesh()
5190 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5191 MaxNbOfIterations, MaxAspectRatio, Method)
5193 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5195 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5196 them with quadratic with the same id.
5199 theForce3d: method of new node creation:
5201 * False - the medium node lies at the geometrical entity from which the mesh element is built
5202 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5203 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5204 theToBiQuad: If True, converts the mesh to bi-quadratic
5207 :class:`SMESH.ComputeError` which can hold a warning
5210 If *theSubMesh* is provided, the mesh can become non-conformal
5213 This operation can create gaps in numeration of nodes or elements.
5214 Call :meth:`RenumberElements` to remove the gaps.
5217 if isinstance( theSubMesh, Mesh ):
5218 theSubMesh = theSubMesh.mesh
5220 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5223 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5225 self.editor.ConvertToQuadratic(theForce3d)
5226 error = self.editor.GetLastError()
5227 if error and error.comment:
5228 print(error.comment)
5231 def ConvertFromQuadratic(self, theSubMesh=None):
5233 Convert the mesh from quadratic to ordinary,
5234 deletes old quadratic elements,
5235 replacing them with ordinary mesh elements with the same id.
5238 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5241 If *theSubMesh* is provided, the mesh can become non-conformal
5244 This operation can create gaps in numeration of nodes or elements.
5245 Call :meth:`RenumberElements` to remove the gaps.
5249 self.editor.ConvertFromQuadraticObject(theSubMesh)
5251 return self.editor.ConvertFromQuadratic()
5253 def Make2DMeshFrom3D(self):
5255 Create 2D mesh as skin on boundary faces of a 3D mesh
5258 True if operation has been completed successfully, False otherwise
5261 return self.editor.Make2DMeshFrom3D()
5263 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5264 toCopyElements=False, toCopyExistingBondary=False):
5266 Create missing boundary elements
5269 elements: elements whose boundary is to be checked:
5270 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5271 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5272 dimension: defines type of boundary elements to create, either of
5273 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5274 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5275 groupName: a name of group to store created boundary elements in,
5276 "" means not to create the group
5277 meshName: a name of new mesh to store created boundary elements in,
5278 "" means not to create the new mesh
5279 toCopyElements: if True, the checked elements will be copied into
5280 the new mesh else only boundary elements will be copied into the new mesh
5281 toCopyExistingBondary: if True, not only new but also pre-existing
5282 boundary elements will be copied into the new mesh
5285 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5288 unRegister = genObjUnRegister()
5289 if isinstance( elements, Mesh ):
5290 elements = elements.GetMesh()
5291 if ( isinstance( elements, list )):
5292 elemType = SMESH.ALL
5293 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5294 elements = self.editor.MakeIDSource(elements, elemType)
5295 unRegister.set( elements )
5296 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5297 toCopyElements,toCopyExistingBondary)
5298 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5301 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5302 toCopyAll=False, groups=[]):
5304 Create missing boundary elements around either the whole mesh or
5308 dimension: defines type of boundary elements to create, either of
5309 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5310 groupName: a name of group to store all boundary elements in,
5311 "" means not to create the group
5312 meshName: a name of a new mesh, which is a copy of the initial
5313 mesh + created boundary elements; "" means not to create the new mesh
5314 toCopyAll: if True, the whole initial mesh will be copied into
5315 the new mesh else only boundary elements will be copied into the new mesh
5316 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5319 tuple( long, mesh, group )
5320 - long - number of added boundary elements
5321 - mesh - the :class:`Mesh` where elements were added to
5322 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5325 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5327 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5328 return nb, mesh, group
5330 def RenumberNodes(self):
5332 Renumber mesh nodes to remove unused node IDs
5334 self.editor.RenumberNodes()
5336 def RenumberElements(self):
5338 Renumber mesh elements to remove unused element IDs
5340 self.editor.RenumberElements()
5342 def _getIdSourceList(self, arg, idType, unRegister):
5344 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5346 if arg and isinstance( arg, list ):
5347 if isinstance( arg[0], int ):
5348 arg = self.GetIDSource( arg, idType )
5349 unRegister.set( arg )
5350 elif isinstance( arg[0], Mesh ):
5351 arg[0] = arg[0].GetMesh()
5352 elif isinstance( arg, Mesh ):
5354 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5358 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5359 MakeGroups=False, TotalAngle=False):
5361 Generate new elements by rotation of the given elements and nodes around the axis
5364 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5365 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5366 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5367 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5368 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5369 which defines angle in degrees
5370 NbOfSteps: the number of steps
5371 Tolerance: tolerance
5372 MakeGroups: forces the generation of new groups from existing ones
5373 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5374 of all steps, else - size of each step
5377 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5380 unRegister = genObjUnRegister()
5381 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5382 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5383 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5385 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5386 Axis = self.smeshpyD.GetAxisStruct( Axis )
5387 if isinstance( Axis, list ):
5388 Axis = SMESH.AxisStruct( *Axis )
5390 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5391 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5392 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5393 self.mesh.SetParameters(Parameters)
5394 if TotalAngle and NbOfSteps:
5395 AngleInRadians /= NbOfSteps
5396 return self.editor.RotationSweepObjects( nodes, edges, faces,
5397 Axis, AngleInRadians,
5398 NbOfSteps, Tolerance, MakeGroups)
5400 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5401 MakeGroups=False, TotalAngle=False):
5403 Generate new elements by rotation of the elements around the axis
5406 IDsOfElements: the list of ids of elements to sweep
5407 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5408 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5409 NbOfSteps: the number of steps
5410 Tolerance: tolerance
5411 MakeGroups: forces the generation of new groups from existing ones
5412 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5413 of all steps, else - size of each step
5416 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5419 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5420 AngleInRadians, NbOfSteps, Tolerance,
5421 MakeGroups, TotalAngle)
5423 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5424 MakeGroups=False, TotalAngle=False):
5426 Generate new elements by rotation of the elements of object around the axis
5427 theObject object which elements should be sweeped.
5428 It can be a mesh, a sub mesh or a group.
5431 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5432 AngleInRadians: the angle of Rotation
5433 NbOfSteps: number of steps
5434 Tolerance: tolerance
5435 MakeGroups: forces the generation of new groups from existing ones
5436 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5437 of all steps, else - size of each step
5440 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5443 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5444 AngleInRadians, NbOfSteps, Tolerance,
5445 MakeGroups, TotalAngle )
5447 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5448 MakeGroups=False, TotalAngle=False):
5450 Generate new elements by rotation of the elements of object around the axis
5451 theObject object which elements should be sweeped.
5452 It can be a mesh, a sub mesh or a group.
5455 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5456 AngleInRadians: the angle of Rotation
5457 NbOfSteps: number of steps
5458 Tolerance: tolerance
5459 MakeGroups: forces the generation of new groups from existing ones
5460 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5461 of all steps, else - size of each step
5464 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5465 empty list otherwise
5468 return self.RotationSweepObjects([],theObject,[], Axis,
5469 AngleInRadians, NbOfSteps, Tolerance,
5470 MakeGroups, TotalAngle)
5472 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5473 MakeGroups=False, TotalAngle=False):
5475 Generate new elements by rotation of the elements of object around the axis
5476 theObject object which elements should be sweeped.
5477 It can be a mesh, a sub mesh or a group.
5480 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5481 AngleInRadians: the angle of Rotation
5482 NbOfSteps: number of steps
5483 Tolerance: tolerance
5484 MakeGroups: forces the generation of new groups from existing ones
5485 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5486 of all steps, else - size of each step
5489 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5492 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5493 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5495 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5496 scaleFactors=[], linearVariation=False, basePoint=[],
5497 angles=[], anglesVariation=False):
5499 Generate new elements by extrusion of the given elements and nodes
5502 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5503 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5504 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5505 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5506 the direction and value of extrusion for one step (the total extrusion
5507 length will be NbOfSteps * ||StepVector||)
5508 NbOfSteps: the number of steps
5509 MakeGroups: forces the generation of new groups from existing ones
5510 scaleFactors: optional scale factors to apply during extrusion
5511 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5512 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5513 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5514 nodes and elements being extruded is used as the scaling center.
5517 - a list of tree components of the point or
5520 angles: list of angles in radians. Nodes at each extrusion step are rotated
5521 around *basePoint*, additionally to previous steps.
5522 anglesVariation: forces the computation of rotation angles as linear
5523 variation of the given *angles* along path steps
5525 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5527 Example: :ref:`tui_extrusion`
5529 unRegister = genObjUnRegister()
5530 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5531 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5532 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5534 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5535 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5536 if isinstance( StepVector, list ):
5537 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5539 if isinstance( basePoint, int):
5540 xyz = self.GetNodeXYZ( basePoint )
5542 raise RuntimeError("Invalid node ID: %s" % basePoint)
5544 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5545 basePoint = self.geompyD.PointCoordinates( basePoint )
5547 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5548 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5549 angles,angleParameters,hasVars = ParseAngles(angles)
5550 Parameters = StepVector.PS.parameters + var_separator + \
5551 Parameters + var_separator + \
5552 scaleParameters + var_separator + angleParameters
5553 self.mesh.SetParameters(Parameters)
5555 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5556 StepVector, NbOfSteps, MakeGroups,
5557 scaleFactors, linearVariation, basePoint,
5558 angles, anglesVariation )
5561 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5563 Generate new elements by extrusion of the elements with given ids
5566 IDsOfElements: the list of ids of elements or nodes for extrusion
5567 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5568 the direction and value of extrusion for one step (the total extrusion
5569 length will be NbOfSteps * ||StepVector||)
5570 NbOfSteps: the number of steps
5571 MakeGroups: forces the generation of new groups from existing ones
5572 IsNodes: is True if elements with given ids are nodes
5575 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5577 Example: :ref:`tui_extrusion`
5580 if IsNodes: n = IDsOfElements
5581 else : e,f, = IDsOfElements,IDsOfElements
5582 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5584 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5585 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5587 Generate new elements by extrusion along the normal to a discretized surface or wire
5590 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5591 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5592 StepSize: length of one extrusion step (the total extrusion
5593 length will be *NbOfSteps* *StepSize*).
5594 NbOfSteps: number of extrusion steps.
5595 ByAverageNormal: if True each node is translated by *StepSize*
5596 along the average of the normal vectors to the faces sharing the node;
5597 else each node is translated along the same average normal till
5598 intersection with the plane got by translation of the face sharing
5599 the node along its own normal by *StepSize*.
5600 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5601 for every node of *Elements*.
5602 MakeGroups: forces generation of new groups from existing ones.
5603 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5604 is not yet implemented. This parameter is used if *Elements* contains
5605 both faces and edges, i.e. *Elements* is a Mesh.
5608 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5609 empty list otherwise.
5610 Example: :ref:`tui_extrusion`
5613 unRegister = genObjUnRegister()
5614 if isinstance( Elements, Mesh ):
5615 Elements = [ Elements.GetMesh() ]
5616 if isinstance( Elements, list ):
5618 raise RuntimeError("Elements empty!")
5619 if isinstance( Elements[0], Mesh ):
5620 Elements = [ Elements[0].GetMesh() ]
5621 if isinstance( Elements[0], int ):
5622 Elements = self.GetIDSource( Elements, SMESH.ALL )
5623 unRegister.set( Elements )
5624 if not isinstance( Elements, list ):
5625 Elements = [ Elements ]
5626 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5627 self.mesh.SetParameters(Parameters)
5628 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5629 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5631 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5633 Generate new elements by extrusion of the elements or nodes which belong to the object
5636 theObject: the object whose elements or nodes should be processed.
5637 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5638 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5639 the direction and value of extrusion for one step (the total extrusion
5640 length will be NbOfSteps * ||StepVector||)
5641 NbOfSteps: the number of steps
5642 MakeGroups: forces the generation of new groups from existing ones
5643 IsNodes: is True if elements to extrude are nodes
5646 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5647 Example: :ref:`tui_extrusion`
5651 if IsNodes: n = theObject
5652 else : e,f, = theObject,theObject
5653 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5655 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5657 Generate new elements by extrusion of edges which belong to the object
5660 theObject: object whose 1D elements should be processed.
5661 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5662 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5663 the direction and value of extrusion for one step (the total extrusion
5664 length will be NbOfSteps * ||StepVector||)
5665 NbOfSteps: the number of steps
5666 MakeGroups: to generate new groups from existing ones
5669 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5670 Example: :ref:`tui_extrusion`
5673 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5675 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5677 Generate new elements by extrusion of faces which belong to the object
5680 theObject: object whose 2D elements should be processed.
5681 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5682 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5683 the direction and value of extrusion for one step (the total extrusion
5684 length will be NbOfSteps * ||StepVector||)
5685 NbOfSteps: the number of steps
5686 MakeGroups: forces the generation of new groups from existing ones
5689 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5690 Example: :ref:`tui_extrusion`
5693 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5695 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5696 ExtrFlags, SewTolerance, MakeGroups=False):
5698 Generate new elements by extrusion of the elements with given ids
5701 IDsOfElements: is ids of elements
5702 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5703 the direction and value of extrusion for one step (the total extrusion
5704 length will be NbOfSteps * ||StepVector||)
5705 NbOfSteps: the number of steps
5706 ExtrFlags: sets flags for extrusion
5707 SewTolerance: uses for comparing locations of nodes if flag
5708 EXTRUSION_FLAG_SEW is set
5709 MakeGroups: forces the generation of new groups from existing ones
5712 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5715 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5716 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5717 if isinstance( StepVector, list ):
5718 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5719 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5720 ExtrFlags, SewTolerance, MakeGroups)
5722 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5723 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5724 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5725 ScaleFactors=[], ScalesVariation=False):
5727 Generate new elements by extrusion of the given elements and nodes along the path.
5728 The path of extrusion must be a meshed edge.
5731 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5732 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5733 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5734 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5735 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
5736 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5737 HasAngles: not used obsolete
5738 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5739 around *basePoint*, additionally to previous steps.
5740 LinearVariation: forces the computation of rotation angles as linear
5741 variation of the given Angles along path steps
5742 HasRefPoint: allows using the reference point
5743 RefPoint: optional scaling and rotation center (mass center of the extruded
5744 elements by default). The User can specify any point as the Reference Point.
5745 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5746 MakeGroups: forces the generation of new groups from existing ones
5747 ScaleFactors: optional scale factors to apply during extrusion
5748 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5749 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5752 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5753 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5754 Example: :ref:`tui_extrusion_along_path`
5757 unRegister = genObjUnRegister()
5758 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5759 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5760 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5762 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5763 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5764 if isinstance( RefPoint, list ):
5765 if not RefPoint: RefPoint = [0,0,0]
5766 RefPoint = SMESH.PointStruct( *RefPoint )
5767 if isinstance( PathObject, Mesh ):
5768 PathObject = PathObject.GetMesh()
5769 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5770 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5771 Parameters = AnglesParameters + var_separator + \
5772 RefPoint.parameters + var_separator + ScalesParameters
5773 self.mesh.SetParameters(Parameters)
5774 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5775 PathObject, PathShape, NodeStart,
5776 HasAngles, Angles, LinearVariation,
5777 HasRefPoint, RefPoint, MakeGroups,
5778 ScaleFactors, ScalesVariation)
5780 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5781 HasAngles=False, Angles=[], LinearVariation=False,
5782 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5783 ElemType=SMESH.FACE):
5785 Generate new elements by extrusion of the given elements.
5786 The path of extrusion must be a meshed edge.
5789 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5790 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5791 NodeStart: the start node from Path. Defines the direction of extrusion
5792 HasAngles: not used obsolete
5793 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5794 around *basePoint*, additionally to previous steps.
5795 LinearVariation: forces the computation of rotation angles as linear
5796 variation of the given Angles along path steps
5797 HasRefPoint: allows using the reference point
5798 RefPoint: the reference point around which the elements are rotated (the mass
5799 center of the elements by default).
5800 The User can specify any point as the Reference Point.
5801 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5802 MakeGroups: forces the generation of new groups from existing ones
5803 ElemType: type of elements for extrusion (if param Base is a mesh)
5806 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5807 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5808 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5810 Example: :ref:`tui_extrusion_along_path`
5814 if ElemType == SMESH.NODE: n = Base
5815 if ElemType == SMESH.EDGE: e = Base
5816 if ElemType == SMESH.FACE: f = Base
5817 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5818 HasAngles, Angles, LinearVariation,
5819 HasRefPoint, RefPoint, MakeGroups)
5820 if MakeGroups: return gr,er
5823 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5824 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5825 MakeGroups=False, LinearVariation=False):
5827 Generate new elements by extrusion of the given elements.
5828 The path of extrusion must be a meshed edge.
5831 IDsOfElements: ids of elements
5832 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5833 PathShape: shape (edge) defines the sub-mesh for the path
5834 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5835 HasAngles: not used obsolete
5836 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5837 around *basePoint*, additionally to previous steps.
5838 HasRefPoint: allows using the reference point
5839 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5840 The User can specify any point as the Reference Point.
5841 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5842 MakeGroups: forces the generation of new groups from existing ones
5843 LinearVariation: forces the computation of rotation angles as linear
5844 variation of the given Angles along path steps
5847 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5848 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5849 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5850 Example: :ref:`tui_extrusion_along_path`
5853 if not IDsOfElements:
5854 IDsOfElements = [ self.GetMesh() ]
5855 n,e,f = [],IDsOfElements,IDsOfElements
5856 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5857 NodeStart, HasAngles, Angles,
5859 HasRefPoint, RefPoint, MakeGroups)
5860 if MakeGroups: return gr,er
5863 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5864 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5865 MakeGroups=False, LinearVariation=False):
5867 Generate new elements by extrusion of the elements which belong to the object.
5868 The path of extrusion must be a meshed edge.
5871 theObject: the object whose elements should be processed.
5872 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5873 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5874 PathShape: shape (edge) defines the sub-mesh for the path
5875 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5876 HasAngles: not used obsolete
5877 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5878 around *basePoint*, additionally to previous steps.
5879 HasRefPoint: allows using the reference point
5880 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5881 The User can specify any point as the Reference Point.
5882 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5883 MakeGroups: forces the generation of new groups from existing ones
5884 LinearVariation: forces the computation of rotation angles as linear
5885 variation of the given Angles along path steps
5888 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5889 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5890 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5891 Example: :ref:`tui_extrusion_along_path`
5894 n,e,f = [],theObject,theObject
5895 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5896 HasAngles, Angles, LinearVariation,
5897 HasRefPoint, RefPoint, MakeGroups)
5898 if MakeGroups: return gr,er
5901 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5902 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5903 MakeGroups=False, LinearVariation=False):
5905 Generate new elements by extrusion of mesh segments which belong to the object.
5906 The path of extrusion must be a meshed edge.
5909 theObject: the object whose 1D elements should be processed.
5910 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5911 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5912 PathShape: shape (edge) defines the sub-mesh for the path
5913 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5914 HasAngles: not used obsolete
5915 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5916 around *basePoint*, additionally to previous steps.
5917 HasRefPoint: allows using the reference point
5918 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5919 The User can specify any point as the Reference Point.
5920 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5921 MakeGroups: forces the generation of new groups from existing ones
5922 LinearVariation: forces the computation of rotation angles as linear
5923 variation of the given Angles along path steps
5926 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5927 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5928 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5929 Example: :ref:`tui_extrusion_along_path`
5932 n,e,f = [],theObject,[]
5933 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5934 HasAngles, Angles, LinearVariation,
5935 HasRefPoint, RefPoint, MakeGroups)
5936 if MakeGroups: return gr,er
5939 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5940 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5941 MakeGroups=False, LinearVariation=False):
5943 Generate new elements by extrusion of faces which belong to the object.
5944 The path of extrusion must be a meshed edge.
5947 theObject: the object whose 2D elements should be processed.
5948 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5949 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5950 PathShape: shape (edge) defines the sub-mesh for the path
5951 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5952 HasAngles: not used obsolete
5953 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5954 around *basePoint*, additionally to previous steps.
5955 HasRefPoint: allows using the reference point
5956 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5957 The User can specify any point as the Reference Point.
5958 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5959 MakeGroups: forces the generation of new groups from existing ones
5960 LinearVariation: forces the computation of rotation angles as linear
5961 variation of the given Angles along path steps
5964 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5965 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5966 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5967 Example: :ref:`tui_extrusion_along_path`
5970 n,e,f = [],[],theObject
5971 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5972 HasAngles, Angles, LinearVariation,
5973 HasRefPoint, RefPoint, MakeGroups)
5974 if MakeGroups: return gr,er
5977 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5979 Create a symmetrical copy of mesh elements
5982 IDsOfElements: list of elements ids
5983 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5984 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5985 If the *Mirror* is a geom object this parameter is unnecessary
5986 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5987 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5990 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5993 if IDsOfElements == []:
5994 IDsOfElements = self.GetElementsId()
5995 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5996 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5997 theMirrorType = Mirror._mirrorType
5999 self.mesh.SetParameters(Mirror.parameters)
6000 if Copy and MakeGroups:
6001 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6002 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6005 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6007 Create a new mesh by a symmetrical copy of mesh elements
6010 IDsOfElements: the list of elements ids
6011 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6012 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6013 If the *Mirror* is a geom object this parameter is unnecessary
6014 MakeGroups: to generate new groups from existing ones
6015 NewMeshName: a name of the new mesh to create
6018 instance of class :class:`Mesh`
6021 if IDsOfElements == []:
6022 IDsOfElements = self.GetElementsId()
6023 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6024 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6025 theMirrorType = Mirror._mirrorType
6027 self.mesh.SetParameters(Mirror.parameters)
6028 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6029 MakeGroups, NewMeshName)
6030 return Mesh(self.smeshpyD,self.geompyD,mesh)
6032 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6034 Create a symmetrical copy of the object
6037 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6038 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6039 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6040 If the *Mirror* is a geom object this parameter is unnecessary
6041 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6042 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6045 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6048 if ( isinstance( theObject, Mesh )):
6049 theObject = theObject.GetMesh()
6050 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6051 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6052 theMirrorType = Mirror._mirrorType
6054 self.mesh.SetParameters(Mirror.parameters)
6055 if Copy and MakeGroups:
6056 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6057 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6060 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6062 Create a new mesh by a symmetrical copy of the object
6065 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6066 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6067 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6068 If the *Mirror* is a geom object this parameter is unnecessary
6069 MakeGroups: forces the generation of new groups from existing ones
6070 NewMeshName: the name of the new mesh to create
6073 instance of class :class:`Mesh`
6076 if ( isinstance( theObject, Mesh )):
6077 theObject = theObject.GetMesh()
6078 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6079 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6080 theMirrorType = Mirror._mirrorType
6082 self.mesh.SetParameters(Mirror.parameters)
6083 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6084 MakeGroups, NewMeshName)
6085 return Mesh( self.smeshpyD,self.geompyD,mesh )
6087 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6089 Translate the elements
6092 IDsOfElements: list of elements ids
6093 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6094 Copy: allows copying the translated elements
6095 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6098 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6101 if IDsOfElements == []:
6102 IDsOfElements = self.GetElementsId()
6103 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6104 Vector = self.smeshpyD.GetDirStruct(Vector)
6105 if isinstance( Vector, list ):
6106 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6107 self.mesh.SetParameters(Vector.PS.parameters)
6108 if Copy and MakeGroups:
6109 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6110 self.editor.Translate(IDsOfElements, Vector, Copy)
6113 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6115 Create a new mesh of translated elements
6118 IDsOfElements: list of elements ids
6119 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6120 MakeGroups: forces the generation of new groups from existing ones
6121 NewMeshName: the name of the newly created mesh
6124 instance of class :class:`Mesh`
6127 if IDsOfElements == []:
6128 IDsOfElements = self.GetElementsId()
6129 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6130 Vector = self.smeshpyD.GetDirStruct(Vector)
6131 if isinstance( Vector, list ):
6132 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6133 self.mesh.SetParameters(Vector.PS.parameters)
6134 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6135 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6137 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6139 Translate the object
6142 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6143 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6144 Copy: allows copying the translated elements
6145 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6148 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6151 if ( isinstance( theObject, Mesh )):
6152 theObject = theObject.GetMesh()
6153 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6154 Vector = self.smeshpyD.GetDirStruct(Vector)
6155 if isinstance( Vector, list ):
6156 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6157 self.mesh.SetParameters(Vector.PS.parameters)
6158 if Copy and MakeGroups:
6159 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6160 self.editor.TranslateObject(theObject, Vector, Copy)
6163 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6165 Create a new mesh from the translated object
6168 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6169 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6170 MakeGroups: forces the generation of new groups from existing ones
6171 NewMeshName: the name of the newly created mesh
6174 instance of class :class:`Mesh`
6177 if isinstance( theObject, Mesh ):
6178 theObject = theObject.GetMesh()
6179 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6180 Vector = self.smeshpyD.GetDirStruct(Vector)
6181 if isinstance( Vector, list ):
6182 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6183 self.mesh.SetParameters(Vector.PS.parameters)
6184 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6185 return Mesh( self.smeshpyD, self.geompyD, mesh )
6189 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6194 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6195 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6196 theScaleFact: list of 1-3 scale factors for axises
6197 Copy: allows copying the translated elements
6198 MakeGroups: forces the generation of new groups from existing
6202 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6203 empty list otherwise
6205 unRegister = genObjUnRegister()
6206 if ( isinstance( theObject, Mesh )):
6207 theObject = theObject.GetMesh()
6208 if ( isinstance( theObject, list )):
6209 theObject = self.GetIDSource(theObject, SMESH.ALL)
6210 unRegister.set( theObject )
6211 if ( isinstance( thePoint, list )):
6212 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6213 if ( isinstance( theScaleFact, float )):
6214 theScaleFact = [theScaleFact]
6215 if ( isinstance( theScaleFact, int )):
6216 theScaleFact = [ float(theScaleFact)]
6218 self.mesh.SetParameters(thePoint.parameters)
6220 if Copy and MakeGroups:
6221 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6222 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6225 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6227 Create a new mesh from the translated object
6230 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6231 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6232 theScaleFact: list of 1-3 scale factors for axises
6233 MakeGroups: forces the generation of new groups from existing ones
6234 NewMeshName: the name of the newly created mesh
6237 instance of class :class:`Mesh`
6239 unRegister = genObjUnRegister()
6240 if (isinstance(theObject, Mesh)):
6241 theObject = theObject.GetMesh()
6242 if ( isinstance( theObject, list )):
6243 theObject = self.GetIDSource(theObject,SMESH.ALL)
6244 unRegister.set( theObject )
6245 if ( isinstance( thePoint, list )):
6246 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6247 if ( isinstance( theScaleFact, float )):
6248 theScaleFact = [theScaleFact]
6249 if ( isinstance( theScaleFact, int )):
6250 theScaleFact = [ float(theScaleFact)]
6252 self.mesh.SetParameters(thePoint.parameters)
6253 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6254 MakeGroups, NewMeshName)
6255 return Mesh( self.smeshpyD, self.geompyD, mesh )
6259 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6264 IDsOfElements: list of elements ids
6265 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6266 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6267 Copy: allows copying the rotated elements
6268 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6271 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6275 if IDsOfElements == []:
6276 IDsOfElements = self.GetElementsId()
6277 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6278 Axis = self.smeshpyD.GetAxisStruct(Axis)
6279 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6280 Parameters = Axis.parameters + var_separator + Parameters
6281 self.mesh.SetParameters(Parameters)
6282 if Copy and MakeGroups:
6283 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6284 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6287 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6289 Create a new mesh of rotated elements
6292 IDsOfElements: list of element ids
6293 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6294 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6295 MakeGroups: forces the generation of new groups from existing ones
6296 NewMeshName: the name of the newly created mesh
6299 instance of class :class:`Mesh`
6302 if IDsOfElements == []:
6303 IDsOfElements = self.GetElementsId()
6304 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6305 Axis = self.smeshpyD.GetAxisStruct(Axis)
6306 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6307 Parameters = Axis.parameters + var_separator + Parameters
6308 self.mesh.SetParameters(Parameters)
6309 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6310 MakeGroups, NewMeshName)
6311 return Mesh( self.smeshpyD, self.geompyD, mesh )
6313 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6318 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6319 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6320 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6321 Copy: allows copying the rotated elements
6322 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6325 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6328 if (isinstance(theObject, Mesh)):
6329 theObject = theObject.GetMesh()
6330 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6331 Axis = self.smeshpyD.GetAxisStruct(Axis)
6332 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6333 Parameters = Axis.parameters + ":" + Parameters
6334 self.mesh.SetParameters(Parameters)
6335 if Copy and MakeGroups:
6336 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6337 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6340 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6342 Create a new mesh from the rotated object
6345 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6346 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6347 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6348 MakeGroups: forces the generation of new groups from existing ones
6349 NewMeshName: the name of the newly created mesh
6352 instance of class :class:`Mesh`
6355 if (isinstance( theObject, Mesh )):
6356 theObject = theObject.GetMesh()
6357 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6358 Axis = self.smeshpyD.GetAxisStruct(Axis)
6359 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6360 Parameters = Axis.parameters + ":" + Parameters
6361 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6362 MakeGroups, NewMeshName)
6363 self.mesh.SetParameters(Parameters)
6364 return Mesh( self.smeshpyD, self.geompyD, mesh )
6366 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6368 Create an offset mesh from the given 2D object
6371 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6372 theValue (float): signed offset size
6373 MakeGroups (boolean): forces the generation of new groups from existing ones
6374 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6375 False means to remove original elements.
6376 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6379 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6382 if isinstance( theObject, Mesh ):
6383 theObject = theObject.GetMesh()
6384 theValue,Parameters,hasVars = ParseParameters(Value)
6385 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6386 self.mesh.SetParameters(Parameters)
6387 # if mesh_groups[0]:
6388 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6391 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6393 Find groups of adjacent nodes within Tolerance.
6396 Tolerance (float): the value of tolerance
6397 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6398 corner and medium nodes in separate groups thus preventing
6399 their further merge.
6402 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6405 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6407 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6408 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6410 Find groups of adjacent nodes within Tolerance.
6413 Tolerance: the value of tolerance
6414 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6415 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6416 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6417 corner and medium nodes in separate groups thus preventing
6418 their further merge.
6421 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6424 unRegister = genObjUnRegister()
6425 if not isinstance( SubMeshOrGroup, list ):
6426 SubMeshOrGroup = [ SubMeshOrGroup ]
6427 for i,obj in enumerate( SubMeshOrGroup ):
6428 if isinstance( obj, Mesh ):
6429 SubMeshOrGroup = [ obj.GetMesh() ]
6431 if isinstance( obj, int ):
6432 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6433 unRegister.set( SubMeshOrGroup )
6436 if not isinstance( exceptNodes, list ):
6437 exceptNodes = [ exceptNodes ]
6438 if exceptNodes and isinstance( exceptNodes[0], int ):
6439 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6440 unRegister.set( exceptNodes )
6442 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6443 exceptNodes, SeparateCornerAndMediumNodes)
6445 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6450 GroupsOfNodes: a list of groups of nodes IDs for merging.
6451 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6452 in all elements and mesh groups by nodes 1 and 25 correspondingly
6453 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6454 If *NodesToKeep* does not include a node to keep for some group to merge,
6455 then the first node in the group is kept.
6456 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6460 This operation can create gaps in numeration of nodes or elements.
6461 Call :meth:`RenumberElements` to remove the gaps.
6463 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6465 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6467 Find the elements built on the same nodes.
6470 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6471 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6475 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6478 unRegister = genObjUnRegister()
6479 if MeshOrSubMeshOrGroup is None:
6480 MeshOrSubMeshOrGroup = [ self.mesh ]
6481 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6482 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6483 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6484 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6485 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6486 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6487 unRegister.set( MeshOrSubMeshOrGroup )
6488 for item in MeshOrSubMeshOrGroup:
6489 if isinstance( item, Mesh ):
6490 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6492 if not isinstance( exceptElements, list ):
6493 exceptElements = [ exceptElements ]
6494 if exceptElements and isinstance( exceptElements[0], int ):
6495 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6496 unRegister.set( exceptElements )
6498 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6500 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6502 Merge elements in each given group.
6505 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6506 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6507 replaced in all mesh groups by elements 1 and 25)
6508 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6509 If *ElementsToKeep* does not include an element to keep for some group to merge,
6510 then the first element in the group is kept.
6513 This operation can create gaps in numeration of elements.
6514 Call :meth:`RenumberElements` to remove the gaps.
6517 unRegister = genObjUnRegister()
6519 if not isinstance( ElementsToKeep, list ):
6520 ElementsToKeep = [ ElementsToKeep ]
6521 if isinstance( ElementsToKeep[0], int ):
6522 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6523 unRegister.set( ElementsToKeep )
6525 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6527 def MergeEqualElements(self):
6529 Leave one element and remove all other elements built on the same nodes.
6532 This operation can create gaps in numeration of elements.
6533 Call :meth:`RenumberElements` to remove the gaps.
6536 self.editor.MergeEqualElements()
6538 def FindFreeBorders(self, ClosedOnly=True):
6540 Returns all or only closed free borders
6543 list of SMESH.FreeBorder's
6546 return self.editor.FindFreeBorders( ClosedOnly )
6548 def FillHole(self, holeNodes, groupName=""):
6550 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6553 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6554 must describe all sequential nodes of the hole border. The first and the last
6555 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6556 groupName (string): name of a group to add new faces
6558 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6562 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6563 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6564 if not isinstance( holeNodes, SMESH.FreeBorder ):
6565 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6566 return self.editor.FillHole( holeNodes, groupName )
6568 def FindCoincidentFreeBorders (self, tolerance=0.):
6570 Return groups of FreeBorder's coincident within the given tolerance.
6573 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6574 size of elements adjacent to free borders being compared is used.
6577 SMESH.CoincidentFreeBorders structure
6580 return self.editor.FindCoincidentFreeBorders( tolerance )
6582 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6584 Sew FreeBorder's of each group
6587 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6588 where each enclosed list contains node IDs of a group of coincident free
6589 borders such that each consequent triple of IDs within a group describes
6590 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6591 last node of a border.
6592 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6593 groups of coincident free borders, each group including two borders.
6594 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6595 polygons if a node of opposite border falls on a face edge, else such
6596 faces are split into several ones.
6597 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6598 polyhedra if a node of opposite border falls on a volume edge, else such
6599 volumes, if any, remain intact and the mesh becomes non-conformal.
6602 a number of successfully sewed groups
6605 This operation can create gaps in numeration of nodes or elements.
6606 Call :meth:`RenumberElements` to remove the gaps.
6609 if freeBorders and isinstance( freeBorders, list ):
6610 # construct SMESH.CoincidentFreeBorders
6611 if isinstance( freeBorders[0], int ):
6612 freeBorders = [freeBorders]
6614 coincidentGroups = []
6615 for nodeList in freeBorders:
6616 if not nodeList or len( nodeList ) % 3:
6617 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6620 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6621 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6622 nodeList = nodeList[3:]
6624 coincidentGroups.append( group )
6626 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6628 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6630 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6631 FirstNodeID2, SecondNodeID2, LastNodeID2,
6632 CreatePolygons, CreatePolyedrs):
6637 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6640 This operation can create gaps in numeration of nodes or elements.
6641 Call :meth:`RenumberElements` to remove the gaps.
6644 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6645 FirstNodeID2, SecondNodeID2, LastNodeID2,
6646 CreatePolygons, CreatePolyedrs)
6648 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6649 FirstNodeID2, SecondNodeID2):
6651 Sew conform free borders
6654 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6657 This operation can create gaps in numeration of elements.
6658 Call :meth:`RenumberElements` to remove the gaps.
6661 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6662 FirstNodeID2, SecondNodeID2)
6664 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6665 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6670 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6673 This operation can create gaps in numeration of elements.
6674 Call :meth:`RenumberElements` to remove the gaps.
6677 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6678 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6680 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6681 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6682 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6684 Sew two sides of a mesh. The nodes belonging to Side1 are
6685 merged with the nodes of elements of Side2.
6686 The number of elements in theSide1 and in theSide2 must be
6687 equal and they should have similar nodal connectivity.
6688 The nodes to merge should belong to side borders and
6689 the first node should be linked to the second.
6692 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6695 This operation can create gaps in numeration of nodes.
6696 Call :meth:`RenumberElements` to remove the gaps.
6699 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6700 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6701 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6703 def ChangeElemNodes(self, ide, newIDs):
6705 Set new nodes for the given element. Number of nodes should be kept.
6712 False if the number of nodes does not correspond to the type of element
6715 return self.editor.ChangeElemNodes(ide, newIDs)
6717 def GetLastCreatedNodes(self):
6719 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6720 created, this method return the list of their IDs.
6721 If new nodes were not created - return empty list
6724 the list of integer values (can be empty)
6727 return self.editor.GetLastCreatedNodes()
6729 def GetLastCreatedElems(self):
6731 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6732 created this method return the list of their IDs.
6733 If new elements were not created - return empty list
6736 the list of integer values (can be empty)
6739 return self.editor.GetLastCreatedElems()
6741 def ClearLastCreated(self):
6743 Forget what nodes and elements were created by the last mesh edition operation
6746 self.editor.ClearLastCreated()
6748 def DoubleElements(self, theElements, theGroupName=""):
6750 Create duplicates of given elements, i.e. create new elements based on the
6751 same nodes as the given ones.
6754 theElements: container of elements to duplicate. It can be a
6755 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6756 or a list of element IDs. If *theElements* is
6757 a :class:`Mesh`, elements of highest dimension are duplicated
6758 theGroupName: a name of group to contain the generated elements.
6759 If a group with such a name already exists, the new elements
6760 are added to the existing group, else a new group is created.
6761 If *theGroupName* is empty, new elements are not added
6765 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6766 None if *theGroupName* == "".
6769 unRegister = genObjUnRegister()
6770 if isinstance( theElements, Mesh ):
6771 theElements = theElements.mesh
6772 elif isinstance( theElements, list ):
6773 theElements = self.GetIDSource( theElements, SMESH.ALL )
6774 unRegister.set( theElements )
6775 return self.editor.DoubleElements(theElements, theGroupName)
6777 def DoubleNodes(self, theNodes, theModifiedElems):
6779 Create a hole in a mesh by doubling the nodes of some particular elements
6782 theNodes: IDs of nodes to be doubled
6783 theModifiedElems: IDs of elements to be updated by the new (doubled)
6784 nodes. If list of element identifiers is empty then nodes are doubled but
6785 they not assigned to elements
6788 True if operation has been completed successfully, False otherwise
6791 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6793 def DoubleNode(self, theNodeId, theModifiedElems):
6795 Create a hole in a mesh by doubling the nodes of some particular elements.
6796 This method provided for convenience works as :meth:`DoubleNodes`.
6799 theNodeId: IDs of node to double
6800 theModifiedElems: IDs of elements to update
6803 True if operation has been completed successfully, False otherwise
6806 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6808 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6810 Create a hole in a mesh by doubling the nodes of some particular elements.
6811 This method provided for convenience works as :meth:`DoubleNodes`.
6814 theNodes: group of nodes to double.
6815 theModifiedElems: group of elements to update.
6816 theMakeGroup: forces the generation of a group containing new nodes.
6819 True or a created group if operation has been completed successfully,
6820 False or None otherwise
6824 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6825 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6827 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6829 Create a hole in a mesh by doubling the nodes of some particular elements.
6830 This method provided for convenience works as :meth:`DoubleNodes`.
6833 theNodes: list of groups of nodes to double.
6834 theModifiedElems: list of groups of elements to update.
6835 theMakeGroup: forces the generation of a group containing new nodes.
6838 True if operation has been completed successfully, False otherwise
6842 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6843 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6845 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6847 Create a hole in a mesh by doubling the nodes of some particular elements
6850 theElems: the list of elements (edges or faces) to replicate.
6851 The nodes for duplication could be found from these elements
6852 theNodesNot: list of nodes NOT to replicate
6853 theAffectedElems: the list of elements (cells and edges) to which the
6854 replicated nodes should be associated to
6857 True if operation has been completed successfully, False otherwise
6860 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6862 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6864 Create a hole in a mesh by doubling the nodes of some particular elements
6867 theElems: the list of elements (edges or faces) to replicate.
6868 The nodes for duplication could be found from these elements
6869 theNodesNot: list of nodes NOT to replicate
6870 theShape: shape to detect affected elements (element which geometric center
6871 located on or inside shape).
6872 The replicated nodes should be associated to affected elements.
6875 True if operation has been completed successfully, False otherwise
6878 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6880 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6881 theMakeGroup=False, theMakeNodeGroup=False):
6883 Create a hole in a mesh by doubling the nodes of some particular elements.
6884 This method provided for convenience works as :meth:`DoubleNodes`.
6887 theElems: group of of elements (edges or faces) to replicate.
6888 theNodesNot: group of nodes NOT to replicate.
6889 theAffectedElems: group of elements to which the replicated nodes
6890 should be associated to.
6891 theMakeGroup: forces the generation of a group containing new elements.
6892 theMakeNodeGroup: forces the generation of a group containing new nodes.
6895 True or created groups (one or two) if operation has been completed successfully,
6896 False or None otherwise
6899 if theMakeGroup or theMakeNodeGroup:
6900 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6902 theMakeGroup, theMakeNodeGroup)
6903 if theMakeGroup and theMakeNodeGroup:
6906 return twoGroups[ int(theMakeNodeGroup) ]
6907 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6909 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6911 Create a hole in a mesh by doubling the nodes of some particular elements.
6912 This method provided for convenience works as :meth:`DoubleNodes`.
6915 theElems: group of of elements (edges or faces) to replicate
6916 theNodesNot: group of nodes not to replicate
6917 theShape: shape to detect affected elements (element which geometric center
6918 located on or inside shape).
6919 The replicated nodes should be associated to affected elements
6922 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6924 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6925 theMakeGroup=False, theMakeNodeGroup=False):
6927 Create a hole in a mesh by doubling the nodes of some particular elements.
6928 This method provided for convenience works as :meth:`DoubleNodes`.
6931 theElems: list of groups of elements (edges or faces) to replicate
6932 theNodesNot: list of groups of nodes NOT to replicate
6933 theAffectedElems: group of elements to which the replicated nodes
6934 should be associated to
6935 theMakeGroup: forces generation of a group containing new elements.
6936 theMakeNodeGroup: forces generation of a group containing new nodes
6939 True or created groups (one or two) if operation has been completed successfully,
6940 False or None otherwise
6943 if theMakeGroup or theMakeNodeGroup:
6944 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6946 theMakeGroup, theMakeNodeGroup)
6947 if theMakeGroup and theMakeNodeGroup:
6950 return twoGroups[ int(theMakeNodeGroup) ]
6951 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6953 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6955 Create a hole in a mesh by doubling the nodes of some particular elements.
6956 This method provided for convenience works as :meth:`DoubleNodes`.
6959 theElems: list of groups of elements (edges or faces) to replicate
6960 theNodesNot: list of groups of nodes NOT to replicate
6961 theShape: shape to detect affected elements (element which geometric center
6962 located on or inside shape).
6963 The replicated nodes should be associated to affected elements
6966 True if operation has been completed successfully, False otherwise
6969 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6971 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6973 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6974 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6977 theElems: list of groups of nodes or elements (edges or faces) to replicate
6978 theNodesNot: list of groups of nodes NOT to replicate
6979 theShape: shape to detect affected elements (element which geometric center
6980 located on or inside shape).
6981 The replicated nodes should be associated to affected elements
6984 groups of affected elements in order: volumes, faces, edges
6987 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6989 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6992 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6993 The list of groups must describe a partition of the mesh volumes.
6994 The nodes of the internal faces at the boundaries of the groups are doubled.
6995 In option, the internal faces are replaced by flat elements.
6996 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6999 theDomains: list of groups of volumes
7000 createJointElems: if True, create the elements
7001 onAllBoundaries: if True, the nodes and elements are also created on
7002 the boundary between *theDomains* and the rest mesh
7005 True if operation has been completed successfully, False otherwise
7008 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7010 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7012 Double nodes on some external faces and create flat elements.
7013 Flat elements are mainly used by some types of mechanic calculations.
7015 Each group of the list must be constituted of faces.
7016 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7019 theGroupsOfFaces: list of groups of faces
7022 True if operation has been completed successfully, False otherwise
7025 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7027 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7029 Identify all the elements around a geom shape, get the faces delimiting the hole
7031 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7033 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7035 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7036 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7037 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7038 If there are several paths connecting a pair of points, the shortest path is
7039 selected by the module. Position of the cutting plane is defined by the two
7040 points and an optional vector lying on the plane specified by a PolySegment.
7041 By default the vector is defined by Mesh module as following. A middle point
7042 of the two given points is computed. The middle point is projected to the mesh.
7043 The vector goes from the middle point to the projection point. In case of planar
7044 mesh, the vector is normal to the mesh.
7046 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7049 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7050 groupName: optional name of a group where created mesh segments will be added.
7053 editor = self.editor
7055 editor = self.mesh.GetMeshEditPreviewer()
7056 segmentsRes = editor.MakePolyLine( segments, groupName )
7057 for i, seg in enumerate( segmentsRes ):
7058 segments[i].vector = seg.vector
7060 return editor.GetPreviewData()
7063 def MakeSlot(self, segmentGroup, width ):
7065 Create a slot of given width around given 1D elements lying on a triangle mesh.
7066 The slot is constructed by cutting faces by cylindrical surfaces made
7067 around each segment. Segments are expected to be created by MakePolyLine().
7070 FaceEdge's located at the slot boundary
7072 return self.editor.MakeSlot( segmentGroup, width )
7074 def GetFunctor(self, funcType ):
7076 Return a cached numerical functor by its type.
7079 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7080 Note that not all items correspond to numerical functors.
7083 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7086 fn = self.functors[ funcType._v ]
7088 fn = self.smeshpyD.GetFunctor(funcType)
7089 fn.SetMesh(self.mesh)
7090 self.functors[ funcType._v ] = fn
7093 def FunctorValue(self, funcType, elemId, isElem=True):
7095 Return value of a functor for a given element
7098 funcType: an item of :class:`SMESH.FunctorType` enum.
7099 elemId: element or node ID
7100 isElem: *elemId* is ID of element or node
7103 the functor value or zero in case of invalid arguments
7106 fn = self.GetFunctor( funcType )
7107 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7108 val = fn.GetValue(elemId)
7113 def GetLength(self, elemId=None):
7115 Get length of given 1D elements or of all 1D 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 length of all 1D elements will be calculated.
7121 Sum of lengths of given elements
7126 length = self.smeshpyD.GetLength(self)
7127 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7128 length = self.smeshpyD.GetLength(elemId)
7131 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7133 length += self.smeshpyD.GetLength(obj)
7134 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7135 unRegister = genObjUnRegister()
7136 obj = self.GetIDSource( elemId )
7137 unRegister.set( obj )
7138 length = self.smeshpyD.GetLength( obj )
7140 length = self.FunctorValue(SMESH.FT_Length, elemId)
7143 def GetArea(self, elemId=None):
7145 Get area of given 2D elements or of all 2D 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 area of all 2D elements will be calculated.
7151 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7156 area = self.smeshpyD.GetArea(self)
7157 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7158 area = self.smeshpyD.GetArea(elemId)
7161 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7163 area += self.smeshpyD.GetArea(obj)
7164 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7165 unRegister = genObjUnRegister()
7166 obj = self.GetIDSource( elemId )
7167 unRegister.set( obj )
7168 area = self.smeshpyD.GetArea( obj )
7170 area = self.FunctorValue(SMESH.FT_Area, elemId)
7173 def GetVolume(self, elemId=None):
7175 Get volume of given 3D elements or of all 3D mesh elements
7178 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.
7181 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7186 volume= self.smeshpyD.GetVolume(self)
7187 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7188 volume= self.smeshpyD.GetVolume(elemId)
7191 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7193 volume+= self.smeshpyD.GetVolume(obj)
7194 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7195 unRegister = genObjUnRegister()
7196 obj = self.GetIDSource( elemId )
7197 unRegister.set( obj )
7198 volume= self.smeshpyD.GetVolume( obj )
7200 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7203 def GetAngle(self, node1, node2, node3 ):
7205 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7208 node1,node2,node3: IDs of the three nodes
7211 Angle in radians [0,PI]. -1 if failure case.
7213 p1 = self.GetNodeXYZ( node1 )
7214 p2 = self.GetNodeXYZ( node2 )
7215 p3 = self.GetNodeXYZ( node3 )
7216 if p1 and p2 and p3:
7217 return self.smeshpyD.GetAngle( p1,p2,p3 )
7221 def GetMaxElementLength(self, elemId):
7223 Get maximum element length.
7226 elemId: mesh element ID
7229 element's maximum length value
7232 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7233 ftype = SMESH.FT_MaxElementLength3D
7235 ftype = SMESH.FT_MaxElementLength2D
7236 return self.FunctorValue(ftype, elemId)
7238 def GetAspectRatio(self, elemId):
7240 Get aspect ratio of 2D or 3D element.
7243 elemId: mesh element ID
7246 element's aspect ratio value
7249 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7250 ftype = SMESH.FT_AspectRatio3D
7252 ftype = SMESH.FT_AspectRatio
7253 return self.FunctorValue(ftype, elemId)
7255 def GetWarping(self, elemId):
7257 Get warping angle of 2D element.
7260 elemId: mesh element ID
7263 element's warping angle value
7266 return self.FunctorValue(SMESH.FT_Warping, elemId)
7268 def GetMinimumAngle(self, elemId):
7270 Get minimum angle of 2D element.
7273 elemId: mesh element ID
7276 element's minimum angle value
7279 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7281 def GetTaper(self, elemId):
7283 Get taper of 2D element.
7286 elemId: mesh element ID
7289 element's taper value
7292 return self.FunctorValue(SMESH.FT_Taper, elemId)
7294 def GetSkew(self, elemId):
7296 Get skew of 2D element.
7299 elemId: mesh element ID
7302 element's skew value
7305 return self.FunctorValue(SMESH.FT_Skew, elemId)
7307 def GetMinMax(self, funType, meshPart=None):
7309 Return minimal and maximal value of a given functor.
7312 funType (SMESH.FunctorType): a functor type.
7313 Note that not all items of :class:`SMESH.FunctorType` corresponds
7314 to numerical functors.
7315 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7321 unRegister = genObjUnRegister()
7322 if isinstance( meshPart, list ):
7323 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7324 unRegister.set( meshPart )
7325 if isinstance( meshPart, Mesh ):
7326 meshPart = meshPart.mesh
7327 fun = self.GetFunctor( funType )
7330 if hasattr( meshPart, "SetMesh" ):
7331 meshPart.SetMesh( self.mesh ) # set mesh to filter
7332 hist = fun.GetLocalHistogram( 1, False, meshPart )
7334 hist = fun.GetHistogram( 1, False )
7336 return hist[0].min, hist[0].max
7339 pass # end of Mesh class
7342 class meshProxy(SMESH._objref_SMESH_Mesh):
7344 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7345 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7347 def __init__(self,*args):
7348 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7349 def __deepcopy__(self, memo=None):
7350 new = self.__class__(self)
7352 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7353 if len( args ) == 3:
7354 args += SMESH.ALL_NODES, True
7355 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7356 def ExportToMEDX(self, *args): # function removed
7357 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7358 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7359 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7360 def ExportToMED(self, *args): # function removed
7361 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7362 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7364 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7366 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7367 def ExportPartToMED(self, *args): # 'version' parameter removed
7368 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7369 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7370 def ExportMED(self, *args): # signature of method changed
7371 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7373 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7375 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7377 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7380 class submeshProxy(SMESH._objref_SMESH_subMesh):
7383 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7385 def __init__(self,*args):
7386 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7388 def __deepcopy__(self, memo=None):
7389 new = self.__class__(self)
7392 def Compute(self,refresh=False):
7394 Compute the sub-mesh and return the status of the computation
7397 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7402 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7403 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7407 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7409 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7411 if salome.sg.hasDesktop():
7412 if refresh: salome.sg.updateObjBrowser()
7417 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7420 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7422 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7423 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7426 def __init__(self,*args):
7427 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7429 def __getattr__(self, name ): # method called if an attribute not found
7430 if not self.mesh: # look for name() method in Mesh class
7431 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7432 if hasattr( self.mesh, name ):
7433 return getattr( self.mesh, name )
7434 if name == "ExtrusionAlongPathObjX":
7435 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7436 print("meshEditor: attribute '%s' NOT FOUND" % name)
7438 def __deepcopy__(self, memo=None):
7439 new = self.__class__(self)
7441 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7442 if len( args ) == 1: args += False,
7443 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7444 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7445 if len( args ) == 2: args += False,
7446 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7447 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7448 if len( args ) == 1:
7449 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7450 NodesToKeep = args[1]
7451 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7452 unRegister = genObjUnRegister()
7454 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7455 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7456 if not isinstance( NodesToKeep, list ):
7457 NodesToKeep = [ NodesToKeep ]
7458 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7460 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7462 class Pattern(SMESH._objref_SMESH_Pattern):
7464 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7465 variables in some methods
7468 def LoadFromFile(self, patternTextOrFile ):
7469 text = patternTextOrFile
7470 if os.path.exists( text ):
7471 text = open( patternTextOrFile ).read()
7473 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7475 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7476 decrFun = lambda i: i-1
7477 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7478 theMesh.SetParameters(Parameters)
7479 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7481 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7482 decrFun = lambda i: i-1
7483 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7484 theMesh.SetParameters(Parameters)
7485 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7487 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7488 if isinstance( mesh, Mesh ):
7489 mesh = mesh.GetMesh()
7490 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7492 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7494 Registering the new proxy for Pattern
7499 Private class used to bind methods creating algorithms to the class Mesh
7502 def __init__(self, method):
7504 self.defaultAlgoType = ""
7505 self.algoTypeToClass = {}
7506 self.method = method
7508 def add(self, algoClass):
7510 Store a python class of algorithm
7512 if inspect.isclass(algoClass) and \
7513 hasattr( algoClass, "algoType"):
7514 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7515 if not self.defaultAlgoType and \
7516 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7517 self.defaultAlgoType = algoClass.algoType
7518 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7520 def copy(self, mesh):
7522 Create a copy of self and assign mesh to the copy
7525 other = algoCreator( self.method )
7526 other.defaultAlgoType = self.defaultAlgoType
7527 other.algoTypeToClass = self.algoTypeToClass
7531 def __call__(self,algo="",geom=0,*args):
7533 Create an instance of algorithm
7537 if isinstance( algo, str ):
7539 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7540 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7545 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7547 elif not algoType and isinstance( geom, str ):
7552 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7554 elif isinstance( arg, str ) and not algoType:
7557 import traceback, sys
7558 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7559 sys.stderr.write( msg + '\n' )
7560 tb = traceback.extract_stack(None,2)
7561 traceback.print_list( [tb[0]] )
7563 algoType = self.defaultAlgoType
7564 if not algoType and self.algoTypeToClass:
7565 algoType = sorted( self.algoTypeToClass.keys() )[0]
7566 if algoType in self.algoTypeToClass:
7567 #print("Create algo",algoType)
7568 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7569 raise RuntimeError( "No class found for algo type %s" % algoType)
7572 class hypMethodWrapper:
7574 Private class used to substitute and store variable parameters of hypotheses.
7577 def __init__(self, hyp, method):
7579 self.method = method
7580 #print("REBIND:", method.__name__)
7583 def __call__(self,*args):
7585 call a method of hypothesis with calling SetVarParameter() before
7589 return self.method( self.hyp, *args ) # hypothesis method with no args
7591 #print("MethWrapper.__call__", self.method.__name__, args)
7593 parsed = ParseParameters(*args) # replace variables with their values
7594 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7595 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7596 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7597 # maybe there is a replaced string arg which is not variable
7598 result = self.method( self.hyp, *args )
7599 except ValueError as detail: # raised by ParseParameters()
7601 result = self.method( self.hyp, *args )
7602 except omniORB.CORBA.BAD_PARAM:
7603 raise ValueError(detail) # wrong variable name
7608 class genObjUnRegister:
7610 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7613 def __init__(self, genObj=None):
7614 self.genObjList = []
7618 def set(self, genObj):
7619 "Store one or a list of of SALOME.GenericObj'es"
7620 if isinstance( genObj, list ):
7621 self.genObjList.extend( genObj )
7623 self.genObjList.append( genObj )
7627 for genObj in self.genObjList:
7628 if genObj and hasattr( genObj, "UnRegister" ):
7631 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7633 Bind methods creating mesher plug-ins to the Mesh class
7636 # print("pluginName: ", pluginName)
7637 pluginBuilderName = pluginName + "Builder"
7639 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7640 except Exception as e:
7641 from salome_utils import verbose
7642 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7644 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7645 plugin = eval( pluginBuilderName )
7646 # print(" plugin:" , str(plugin))
7648 # add methods creating algorithms to Mesh
7649 for k in dir( plugin ):
7650 if k[0] == '_': continue
7651 algo = getattr( plugin, k )
7652 #print(" algo:", str(algo))
7653 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7654 #print(" meshMethod:" , str(algo.meshMethod))
7655 if not hasattr( Mesh, algo.meshMethod ):
7656 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7658 _mmethod = getattr( Mesh, algo.meshMethod )
7659 if hasattr( _mmethod, "add" ):