1 # Copyright (C) 2007-2022 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
43 from StdMeshers import BlockCS
50 # In case the omniORBpy EnumItem class does not fully support Python 3
51 # (for instance in version 4.2.1-2), the comparison ordering methods must be
55 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
57 def enumitem_eq(self, other):
59 if isinstance(other, omniORB.EnumItem):
60 if other._parent_id == self._parent_id:
61 return self._v == other._v
63 return self._parent_id == other._parent_id
65 return id(self) == id(other)
67 return id(self) == id(other)
69 def enumitem_lt(self, other):
71 if isinstance(other, omniORB.EnumItem):
72 if other._parent_id == self._parent_id:
73 return self._v < other._v
75 return self._parent_id < other._parent_id
77 return id(self) < id(other)
79 return id(self) < id(other)
81 def enumitem_le(self, other):
83 if isinstance(other, omniORB.EnumItem):
84 if other._parent_id == self._parent_id:
85 return self._v <= other._v
87 return self._parent_id <= other._parent_id
89 return id(self) <= id(other)
91 return id(self) <= id(other)
93 def enumitem_gt(self, other):
95 if isinstance(other, omniORB.EnumItem):
96 if other._parent_id == self._parent_id:
97 return self._v > other._v
99 return self._parent_id > other._parent_id
101 return id(self) > id(other)
103 return id(self) > id(other)
105 def enumitem_ge(self, other):
107 if isinstance(other, omniORB.EnumItem):
108 if other._parent_id == self._parent_id:
109 return self._v >= other._v
111 return self._parent_id >= other._parent_id
113 return id(self) >= id(other)
115 return id(self) >= id(other)
117 omniORB.EnumItem.__eq__ = enumitem_eq
118 omniORB.EnumItem.__lt__ = enumitem_lt
119 omniORB.EnumItem.__le__ = enumitem_le
120 omniORB.EnumItem.__gt__ = enumitem_gt
121 omniORB.EnumItem.__ge__ = enumitem_ge
124 class MeshMeta(type):
125 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
127 def __instancecheck__(cls, inst):
128 """Implement isinstance(inst, cls)."""
129 return any(cls.__subclasscheck__(c)
130 for c in {type(inst), inst.__class__})
132 def __subclasscheck__(cls, sub):
133 """Implement issubclass(sub, cls)."""
134 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
136 def DegreesToRadians(AngleInDegrees):
137 """Convert an angle from degrees to radians
140 return AngleInDegrees * pi / 180.0
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
147 def ParseParameters(*args):
149 Return list of variable values from salome notebook.
150 The last argument, if is callable, is used to modify values got from notebook
156 if args and callable(args[-1]):
157 args, varModifFun = args[:-1], args[-1]
158 for parameter in args:
160 Parameters += str(parameter) + var_separator
162 if isinstance(parameter,str):
163 # check if there is an inexistent variable name
164 if not notebook.isVariable(parameter):
165 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
166 parameter = notebook.get(parameter)
169 parameter = varModifFun(parameter)
172 Result.append(parameter)
175 Parameters = Parameters[:-1]
176 Result.append( Parameters )
177 Result.append( hasVariables )
180 def ParseAngles(*args):
182 Parse parameters while converting variables to radians
184 return ParseParameters( *( args + (DegreesToRadians, )))
186 def __initPointStruct(point,*args):
188 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189 Parameters are stored in PointStruct.parameters attribute
191 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
193 SMESH.PointStruct.__init__ = __initPointStruct
195 def __initAxisStruct(ax,*args):
197 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198 Parameters are stored in AxisStruct.parameters attribute
201 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
202 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
204 SMESH.AxisStruct.__init__ = __initAxisStruct
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208 """Compare real values using smeshPrecisionConfusion as tolerance
210 if abs(val1 - val2) < tol:
218 Return a name of an object
225 if isinstance(obj, SALOMEDS._objref_SObject):
229 ior = salome.orb.object_to_string(obj)
233 sobj = salome.myStudy.FindObjectIOR(ior)
235 return sobj.GetName()
236 if hasattr(obj, "GetName"):
237 # unknown CORBA object, having GetName() method
240 # unknown CORBA object, no GetName() method
243 if hasattr(obj, "GetName"):
244 # unknown non-CORBA object, having GetName() method
247 raise RuntimeError("Null or invalid object")
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
251 Print error message if a hypothesis was not assigned.
254 hypType = "algorithm"
256 hypType = "hypothesis"
259 if hasattr( status, "__getitem__" ):
260 status, reason = status[0], status[1]
261 if status == HYP_UNKNOWN_FATAL:
262 reason = "for unknown reason"
263 elif status == HYP_INCOMPATIBLE:
264 reason = "this hypothesis mismatches the algorithm"
265 elif status == HYP_NOTCONFORM:
266 reason = "a non-conform mesh would be built"
267 elif status == HYP_ALREADY_EXIST:
268 if isAlgo: return # it does not influence anything
269 reason = hypType + " of the same dimension is already assigned to this shape"
270 elif status == HYP_BAD_DIM:
271 reason = hypType + " mismatches the shape"
272 elif status == HYP_CONCURRENT :
273 reason = "there are concurrent hypotheses on sub-shapes"
274 elif status == HYP_BAD_SUBSHAPE:
275 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
276 elif status == HYP_BAD_GEOMETRY:
277 reason = "the algorithm is not applicable to this geometry"
278 elif status == HYP_HIDDEN_ALGO:
279 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
280 elif status == HYP_HIDING_ALGO:
281 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
282 elif status == HYP_NEED_SHAPE:
283 reason = "algorithm can't work without shape"
284 elif status == HYP_INCOMPAT_HYPS:
290 where = '"%s"' % geomName
292 meshName = GetName( mesh )
293 if meshName and meshName != NO_NAME:
294 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
295 if status < HYP_UNKNOWN_FATAL and where:
296 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
298 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
300 print('"%s" was not assigned : %s' %( hypName, reason ))
303 def AssureGeomPublished(mesh, geom, name=''):
305 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
307 if not mesh.smeshpyD.IsEnablePublish():
309 if not hasattr( geom, "GetShapeType" ):
311 if not geom.GetStudyEntry():
313 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
314 # for all groups SubShapeName() return "Compound_-1"
315 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
317 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
319 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
322 # def FirstVertexOnCurve(mesh, edge):
325 # the first vertex of a geometrical edge by ignoring orientation
327 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
333 smeshInst is a singleton
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
341 This class allows to create, load or manipulate meshes.
342 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
343 It also has methods to get infos and measure meshes.
346 # MirrorType enumeration
347 POINT = SMESH_MeshEditor.POINT
348 AXIS = SMESH_MeshEditor.AXIS
349 PLANE = SMESH_MeshEditor.PLANE
351 # Smooth_Method enumeration
352 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
355 PrecisionConfusion = smeshPrecisionConfusion
357 # TopAbs_State enumeration
358 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
360 # Methods of splitting a hexahedron into tetrahedra
361 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
363 def __new__(cls, *args):
367 #print("==== __new__", engine, smeshInst, doLcc)
369 if smeshInst is None:
370 # smesh engine is either retrieved from engine, or created
372 # Following test avoids a recursive loop
374 if smeshInst is not None:
375 # smesh engine not created: existing engine found
379 # FindOrLoadComponent called:
380 # 1. CORBA resolution of server
381 # 2. the __new__ method is called again
382 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
383 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
385 # FindOrLoadComponent not called
386 if smeshInst is None:
387 # smeshBuilder instance is created from lcc.FindOrLoadComponent
388 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
389 smeshInst = super(smeshBuilder,cls).__new__(cls)
391 # smesh engine not created: existing engine found
392 #print("==== existing ", engine, smeshInst, doLcc)
394 #print("====1 ", smeshInst)
397 #print("====2 ", smeshInst)
400 def __init__(self, *args):
402 #print("--------------- smeshbuilder __init__ ---", created)
405 SMESH._objref_SMESH_Gen.__init__(self, *args)
408 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
410 Dump component to the Python script.
411 This method overrides IDL function to allow default values for the parameters.
414 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
416 def SetDumpPythonHistorical(self, isHistorical):
418 Set mode of DumpPython(), *historical* or *snapshot*.
419 In the *historical* mode, the Python Dump script includes all commands
420 performed by SMESH engine. In the *snapshot* mode, commands
421 relating to objects removed from the Study are excluded from the script
422 as well as commands not influencing the current state of meshes
425 if isHistorical: val = "true"
427 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
429 def init_smesh(self,geompyD = None):
431 Set Geometry component
434 self.UpdateStudy(geompyD)
435 notebook.myStudy = salome.myStudy
437 def Mesh(self, obj=0, name=0):
439 Create a mesh. This mesh can be either
441 * an empty mesh not bound to geometry, if *obj* == 0
442 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
443 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
448 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
451 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
453 2. a geometrical object for meshing
455 name: the name for the new mesh.
458 an instance of class :class:`Mesh`.
461 if isinstance(obj,str):
463 return Mesh(self, self.geompyD, obj, name)
465 def RemoveMesh( self, mesh ):
469 if isinstance( mesh, Mesh ):
470 mesh = mesh.GetMesh()
472 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
473 raise TypeError("%s is not a mesh" % mesh )
474 so = salome.ObjectToSObject( mesh )
476 sb = salome.myStudy.NewBuilder()
477 sb.RemoveObjectWithChildren( so )
483 def EnumToLong(self,theItem):
485 Return a long value from enumeration
490 def ColorToString(self,c):
492 Convert SALOMEDS.Color to string.
493 To be used with filters.
496 c: color value (SALOMEDS.Color)
499 a string representation of the color.
503 if isinstance(c, SALOMEDS.Color):
504 val = "%s;%s;%s" % (c.R, c.G, c.B)
505 elif isinstance(c, str):
508 raise ValueError("Color value should be of string or SALOMEDS.Color type")
511 def GetPointStruct(self,theVertex):
513 Get :class:`SMESH.PointStruct` from vertex
516 theVertex (GEOM.GEOM_Object): vertex
519 :class:`SMESH.PointStruct`
521 geompyD = theVertex.GetGen()
522 [x, y, z] = geompyD.PointCoordinates(theVertex)
523 return PointStruct(x,y,z)
525 def GetDirStruct(self,theVector):
527 Get :class:`SMESH.DirStruct` from vector
530 theVector (GEOM.GEOM_Object): vector
533 :class:`SMESH.DirStruct`
535 geompyD = theVector.GetGen()
536 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
537 if(len(vertices) != 2):
538 print("Error: vector object is incorrect.")
540 p1 = geompyD.PointCoordinates(vertices[0])
541 p2 = geompyD.PointCoordinates(vertices[1])
542 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
543 dirst = DirStruct(pnt)
546 def MakeDirStruct(self,x,y,z):
548 Make :class:`SMESH.DirStruct` from a triplet of floats
551 x,y,z (float): vector components
554 :class:`SMESH.DirStruct`
557 pnt = PointStruct(x,y,z)
558 return DirStruct(pnt)
560 def GetAxisStruct(self,theObj):
562 Get :class:`SMESH.AxisStruct` from a geometrical object
565 theObj (GEOM.GEOM_Object): line or plane
568 :class:`SMESH.AxisStruct`
571 geompyD = theObj.GetGen()
572 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
575 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
577 vertex1 = geompyD.PointCoordinates(vertex1)
578 vertex2 = geompyD.PointCoordinates(vertex2)
579 vertex3 = geompyD.PointCoordinates(vertex3)
580 vertex4 = geompyD.PointCoordinates(vertex4)
581 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
582 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
583 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] ]
584 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
586 elif len(edges) == 1:
587 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588 p1 = geompyD.PointCoordinates( vertex1 )
589 p2 = geompyD.PointCoordinates( vertex2 )
590 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
591 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
592 elif theObj.GetShapeType() == GEOM.VERTEX:
593 x,y,z = geompyD.PointCoordinates( theObj )
594 axis = AxisStruct( x,y,z, 1,0,0,)
595 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
598 # From SMESH_Gen interface:
599 # ------------------------
601 def SetName(self, obj, name):
603 Set the given name to an object
606 obj: the object to rename
607 name: a new object name
610 if isinstance( obj, Mesh ):
612 elif isinstance( obj, Mesh_Algorithm ):
613 obj = obj.GetAlgorithm()
614 ior = salome.orb.object_to_string(obj)
615 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
617 def SetEmbeddedMode( self,theMode ):
622 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
624 def IsEmbeddedMode(self):
629 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
631 def UpdateStudy( self, geompyD = None ):
633 Update the current study. Calling UpdateStudy() allows to
634 update meshes at switching GEOM->SMESH
638 from salome.geom import geomBuilder
639 geompyD = geomBuilder.geom
641 geompyD = geomBuilder.New()
644 self.SetGeomEngine(geompyD)
645 SMESH._objref_SMESH_Gen.UpdateStudy(self)
646 sb = salome.myStudy.NewBuilder()
647 sc = salome.myStudy.FindComponent("SMESH")
649 sb.LoadWith(sc, self)
652 def SetEnablePublish( self, theIsEnablePublish ):
654 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
655 switch **off** publishing in the Study of mesh objects.
657 #self.SetEnablePublish(theIsEnablePublish)
658 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
660 notebook = salome_notebook.NoteBook( theIsEnablePublish )
663 def CreateMeshesFromUNV( self,theFileName ):
665 Create a Mesh object importing data from the given UNV file
668 an instance of class :class:`Mesh`
671 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
672 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
675 def CreateMeshesFromMED( self,theFileName ):
677 Create a Mesh object(s) importing data from the given MED file
680 a tuple ( list of class :class:`Mesh` instances,
681 :class:`SMESH.DriverMED_ReadStatus` )
684 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
685 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
686 return aMeshes, aStatus
688 def CreateMeshesFromSTL( self, theFileName ):
690 Create a Mesh object importing data from the given STL file
693 an instance of class :class:`Mesh`
696 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
697 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
700 def CreateMeshesFromCGNS( self, theFileName ):
702 Create Mesh objects importing data from the given CGNS file
705 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
708 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
709 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710 return aMeshes, aStatus
712 def CreateMeshesFromGMF( self, theFileName ):
714 Create a Mesh object importing data from the given GMF file.
715 GMF files must have .mesh extension for the ASCII format and .meshb for
719 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
722 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
725 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
726 return Mesh(self, self.geompyD, aSmeshMesh), error
728 def Concatenate( self, meshes, uniteIdenticalGroups,
729 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
730 name = "", meshToAppendTo = None):
732 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
733 All groups of input meshes will be present in the new mesh.
736 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
737 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
738 mergeNodesAndElements: if True, equal nodes and elements are merged
739 mergeTolerance: tolerance for merging nodes
740 allGroups: forces creation of groups corresponding to every input mesh
741 name: name of a new mesh
742 meshToAppendTo: a mesh to append all given meshes
745 an instance of class :class:`Mesh`
751 if not meshes: return None
752 if not isinstance( meshes, list ):
754 for i,m in enumerate( meshes ):
755 if isinstance( m, Mesh ):
756 meshes[i] = m.GetMesh()
757 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
758 if hasattr(meshes[0], "SetParameters"):
759 meshes[0].SetParameters( Parameters )
761 meshes[0].GetMesh().SetParameters( Parameters )
762 if isinstance( meshToAppendTo, Mesh ):
763 meshToAppendTo = meshToAppendTo.GetMesh()
765 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
766 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
767 mergeTolerance,meshToAppendTo )
769 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
770 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
771 mergeTolerance,meshToAppendTo )
773 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
776 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
778 Create a mesh by copying a part of another mesh.
781 meshPart: a part of mesh to copy, either
782 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
783 To copy nodes or elements not forming any mesh object,
784 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
785 meshName: a name of the new mesh
786 toCopyGroups: to create in the new mesh groups the copied elements belongs to
787 toKeepIDs: to preserve order of the copied elements or not
790 an instance of class :class:`Mesh`
793 if isinstance( meshPart, Mesh ):
794 meshPart = meshPart.GetMesh()
795 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
796 return Mesh(self, self.geompyD, mesh)
798 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
799 toReuseHypotheses=True, toCopyElements=True):
801 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
802 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
803 To facilitate and speed up the operation, consider using
804 "Set presentation parameters and sub-shapes from arguments" option in
805 a dialog of geometrical operation used to create the new geometry.
808 sourceMesh: the mesh to copy definition of.
809 newGeom: the new geometry.
810 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
811 toCopyGroups: to create groups in the new mesh.
812 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
813 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
816 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
817 *invalidEntries* are study entries of objects whose
818 counterparts are not found in the *newGeom*, followed by entries
819 of mesh sub-objects that are invalid because they depend on a not found
822 if isinstance( sourceMesh, Mesh ):
823 sourceMesh = sourceMesh.GetMesh()
825 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
826 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
830 return ( ok, Mesh(self, self.geompyD, newMesh),
831 newGroups, newSubMeshes, newHypotheses, invalidEntries )
833 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
835 Return IDs of sub-shapes
838 theMainObject (GEOM.GEOM_Object): a shape
839 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
841 the list of integer values
844 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
846 def GetPattern(self):
848 Create a pattern mapper.
851 an instance of :class:`SMESH.SMESH_Pattern`
853 :ref:`Example of Patterns usage <tui_pattern_mapping>`
856 return SMESH._objref_SMESH_Gen.GetPattern(self)
858 def SetBoundaryBoxSegmentation(self, nbSegments):
860 Set number of segments per diagonal of boundary box of geometry, by which
861 default segment length of appropriate 1D hypotheses is defined in GUI.
865 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
867 # Filtering. Auxiliary functions:
868 # ------------------------------
870 def GetEmptyCriterion(self):
872 Create an empty criterion
875 :class:`SMESH.Filter.Criterion`
878 Type = self.EnumToLong(FT_Undefined)
879 Compare = self.EnumToLong(FT_Undefined)
883 UnaryOp = self.EnumToLong(FT_Undefined)
884 BinaryOp = self.EnumToLong(FT_Undefined)
887 Precision = -1 ##@1e-07
888 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
889 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
891 def GetCriterion(self,elementType,
893 Compare = FT_EqualTo,
895 UnaryOp=FT_Undefined,
896 BinaryOp=FT_Undefined,
899 Create a criterion by the given parameters
900 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
903 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
904 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
905 Note that the items starting from FT_LessThan are not suitable for *CritType*.
906 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
907 Threshold: the threshold value (range of ids as string, shape, numeric)
908 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
909 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
911 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
912 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
915 :class:`SMESH.Filter.Criterion`
917 Example: :ref:`combining_filters`
920 if not CritType in SMESH.FunctorType._items:
921 raise TypeError("CritType should be of SMESH.FunctorType")
922 aCriterion = self.GetEmptyCriterion()
923 aCriterion.TypeOfElement = elementType
924 aCriterion.Type = self.EnumToLong(CritType)
925 aCriterion.Tolerance = Tolerance
927 aThreshold = Threshold
929 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
930 aCriterion.Compare = self.EnumToLong(Compare)
931 elif Compare == "=" or Compare == "==":
932 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
934 aCriterion.Compare = self.EnumToLong(FT_LessThan)
936 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
937 elif Compare != FT_Undefined:
938 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
941 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
942 FT_BelongToCylinder, FT_LyingOnGeom]:
943 # Check that Threshold is GEOM object
944 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
945 aCriterion.ThresholdStr = GetName(aThreshold)
946 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
947 if not aCriterion.ThresholdID:
948 name = aCriterion.ThresholdStr
950 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
951 geompyD = aThreshold.GetGen()
952 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
953 # or a name of GEOM object
954 elif isinstance( aThreshold, str ):
955 aCriterion.ThresholdStr = aThreshold
957 raise TypeError("The Threshold should be a shape.")
958 if isinstance(UnaryOp,float):
959 aCriterion.Tolerance = UnaryOp
960 UnaryOp = FT_Undefined
962 elif CritType == FT_BelongToMeshGroup:
963 # Check that Threshold is a group
964 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
965 if aThreshold.GetType() != elementType:
966 raise ValueError("Group type mismatches Element type")
967 aCriterion.ThresholdStr = aThreshold.GetName()
968 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
969 study = salome.myStudy
971 so = study.FindObjectIOR( aCriterion.ThresholdID )
975 aCriterion.ThresholdID = entry
977 raise TypeError("The Threshold should be a Mesh Group")
978 elif CritType == FT_RangeOfIds:
979 # Check that Threshold is string
980 if isinstance(aThreshold, str):
981 aCriterion.ThresholdStr = aThreshold
983 raise TypeError("The Threshold should be a string.")
984 elif CritType == FT_CoplanarFaces:
985 # Check the Threshold
986 if isinstance(aThreshold, int):
987 aCriterion.ThresholdID = str(aThreshold)
988 elif isinstance(aThreshold, str):
991 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
992 aCriterion.ThresholdID = aThreshold
994 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
995 elif CritType == FT_ConnectedElements:
996 # Check the Threshold
997 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
998 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
999 if not aCriterion.ThresholdID:
1000 name = aThreshold.GetName()
1002 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1003 geompyD = aThreshold.GetGen()
1004 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1005 elif isinstance(aThreshold, int): # node id
1006 aCriterion.Threshold = aThreshold
1007 elif isinstance(aThreshold, list): # 3 point coordinates
1008 if len( aThreshold ) < 3:
1009 raise ValueError("too few point coordinates, must be 3")
1010 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1011 elif isinstance(aThreshold, str):
1012 if aThreshold.isdigit():
1013 aCriterion.Threshold = aThreshold # node id
1015 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1017 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1018 "or a list of point coordinates and not '%s'"%aThreshold)
1019 elif CritType == FT_ElemGeomType:
1020 # Check the Threshold
1022 aCriterion.Threshold = self.EnumToLong(aThreshold)
1023 assert( aThreshold in SMESH.GeometryType._items )
1025 if isinstance(aThreshold, int):
1026 aCriterion.Threshold = aThreshold
1028 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1031 elif CritType == FT_EntityType:
1032 # Check the Threshold
1034 aCriterion.Threshold = self.EnumToLong(aThreshold)
1035 assert( aThreshold in SMESH.EntityType._items )
1037 if isinstance(aThreshold, int):
1038 aCriterion.Threshold = aThreshold
1040 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1044 elif CritType == FT_GroupColor:
1045 # Check the Threshold
1047 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1049 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1051 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1052 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1053 FT_BareBorderFace, FT_BareBorderVolume,
1054 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1055 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1056 # At this point the Threshold is unnecessary
1057 if aThreshold == FT_LogicalNOT:
1058 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1059 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1060 aCriterion.BinaryOp = aThreshold
1064 aThreshold = float(aThreshold)
1065 aCriterion.Threshold = aThreshold
1067 raise TypeError("The Threshold should be a number.")
1070 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1071 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1073 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1074 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1076 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1077 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1079 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1080 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1084 def GetFilter(self,elementType,
1085 CritType=FT_Undefined,
1088 UnaryOp=FT_Undefined,
1092 Create a filter with the given parameters
1095 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1096 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1097 Note that the items starting from FT_LessThan are not suitable for CritType.
1098 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1099 Threshold: the threshold value (range of ids as string, shape, numeric)
1100 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1101 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1102 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1103 mesh: the mesh to initialize the filter with
1106 :class:`SMESH.Filter`
1109 See :doc:`Filters usage examples <tui_filters>`
1112 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1113 aFilterMgr = self.CreateFilterManager()
1114 aFilter = aFilterMgr.CreateFilter()
1116 aCriteria.append(aCriterion)
1117 aFilter.SetCriteria(aCriteria)
1119 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1120 else : aFilter.SetMesh( mesh )
1121 aFilterMgr.UnRegister()
1124 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1126 Create a filter from criteria
1129 criteria: a list of :class:`SMESH.Filter.Criterion`
1130 binOp: binary operator used when binary operator of criteria is undefined
1133 :class:`SMESH.Filter`
1136 See :doc:`Filters usage examples <tui_filters>`
1139 for i in range( len( criteria ) - 1 ):
1140 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1141 criteria[i].BinaryOp = self.EnumToLong( binOp )
1142 aFilterMgr = self.CreateFilterManager()
1143 aFilter = aFilterMgr.CreateFilter()
1144 aFilter.SetCriteria(criteria)
1145 aFilterMgr.UnRegister()
1148 def GetFunctor(self,theCriterion):
1150 Create a numerical functor by its type
1153 theCriterion (SMESH.FunctorType): functor type.
1154 Note that not all items correspond to numerical functors.
1157 :class:`SMESH.NumericalFunctor`
1160 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1162 aFilterMgr = self.CreateFilterManager()
1164 if theCriterion == FT_AspectRatio:
1165 functor = aFilterMgr.CreateAspectRatio()
1166 elif theCriterion == FT_AspectRatio3D:
1167 functor = aFilterMgr.CreateAspectRatio3D()
1168 elif theCriterion == FT_Warping:
1169 functor = aFilterMgr.CreateWarping()
1170 elif theCriterion == FT_MinimumAngle:
1171 functor = aFilterMgr.CreateMinimumAngle()
1172 elif theCriterion == FT_Taper:
1173 functor = aFilterMgr.CreateTaper()
1174 elif theCriterion == FT_Skew:
1175 functor = aFilterMgr.CreateSkew()
1176 elif theCriterion == FT_Area:
1177 functor = aFilterMgr.CreateArea()
1178 elif theCriterion == FT_Volume3D:
1179 functor = aFilterMgr.CreateVolume3D()
1180 elif theCriterion == FT_MaxElementLength2D:
1181 functor = aFilterMgr.CreateMaxElementLength2D()
1182 elif theCriterion == FT_MaxElementLength3D:
1183 functor = aFilterMgr.CreateMaxElementLength3D()
1184 elif theCriterion == FT_MultiConnection:
1185 functor = aFilterMgr.CreateMultiConnection()
1186 elif theCriterion == FT_MultiConnection2D:
1187 functor = aFilterMgr.CreateMultiConnection2D()
1188 elif theCriterion == FT_Length:
1189 functor = aFilterMgr.CreateLength()
1190 elif theCriterion == FT_Length2D:
1191 functor = aFilterMgr.CreateLength2D()
1192 elif theCriterion == FT_Length3D:
1193 functor = aFilterMgr.CreateLength3D()
1194 elif theCriterion == FT_Deflection2D:
1195 functor = aFilterMgr.CreateDeflection2D()
1196 elif theCriterion == FT_NodeConnectivityNumber:
1197 functor = aFilterMgr.CreateNodeConnectivityNumber()
1198 elif theCriterion == FT_BallDiameter:
1199 functor = aFilterMgr.CreateBallDiameter()
1201 print("Error: given parameter is not numerical functor type.")
1202 aFilterMgr.UnRegister()
1205 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1210 theHType (string): mesh hypothesis type
1211 theLibName (string): mesh plug-in library name
1214 created hypothesis instance
1216 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1218 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1221 # wrap hypothesis methods
1222 for meth_name in dir( hyp.__class__ ):
1223 if not meth_name.startswith("Get") and \
1224 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1225 method = getattr ( hyp.__class__, meth_name )
1226 if callable(method):
1227 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1231 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1233 Create hypothesis initialized according to parameters
1236 hypType (string): hypothesis type
1237 libName (string): plug-in library name
1238 mesh: optional mesh by which a hypotheses can initialize self
1239 shape: optional geometry by size of which a hypotheses can initialize self
1240 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1243 created hypothesis instance
1245 if isinstance( mesh, Mesh ):
1246 mesh = mesh.GetMesh()
1247 if isinstance( initParams, (bool,int)):
1248 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1249 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1250 mesh, shape, initParams )
1252 def GetMeshInfo(self, obj):
1254 Get the mesh statistic.
1257 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1260 if isinstance( obj, Mesh ):
1263 if hasattr(obj, "GetMeshInfo"):
1264 values = obj.GetMeshInfo()
1265 for i in range(SMESH.Entity_Last._v):
1266 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1270 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1272 Get minimum distance between two objects
1274 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1275 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1278 src1 (SMESH.SMESH_IDSource): first source object
1279 src2 (SMESH.SMESH_IDSource): second source object
1280 id1 (int): node/element id from the first source
1281 id2 (int): node/element id from the second (or first) source
1282 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1283 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1286 minimum distance value
1289 :meth:`GetMinDistance`
1292 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1296 result = result.value
1299 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1301 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1303 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1304 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1307 src1 (SMESH.SMESH_IDSource): first source object
1308 src2 (SMESH.SMESH_IDSource): second source object
1309 id1 (int): node/element id from the first source
1310 id2 (int): node/element id from the second (or first) source
1311 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1312 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1315 :class:`SMESH.Measure` structure or None if input data is invalid
1320 if isinstance(src1, Mesh): src1 = src1.mesh
1321 if isinstance(src2, Mesh): src2 = src2.mesh
1322 if src2 is None and id2 != 0: src2 = src1
1323 if not hasattr(src1, "_narrow"): return None
1324 src1 = src1._narrow(SMESH.SMESH_IDSource)
1325 if not src1: return None
1326 unRegister = genObjUnRegister()
1329 e = m.GetMeshEditor()
1331 src1 = e.MakeIDSource([id1], SMESH.FACE)
1333 src1 = e.MakeIDSource([id1], SMESH.NODE)
1334 unRegister.set( src1 )
1336 if hasattr(src2, "_narrow"):
1337 src2 = src2._narrow(SMESH.SMESH_IDSource)
1338 if src2 and id2 != 0:
1340 e = m.GetMeshEditor()
1342 src2 = e.MakeIDSource([id2], SMESH.FACE)
1344 src2 = e.MakeIDSource([id2], SMESH.NODE)
1345 unRegister.set( src2 )
1348 aMeasurements = self.CreateMeasurements()
1349 unRegister.set( aMeasurements )
1350 result = aMeasurements.MinDistance(src1, src2)
1353 def BoundingBox(self, objects):
1355 Get bounding box of the specified object(s)
1358 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1361 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1364 :meth:`GetBoundingBox`
1367 result = self.GetBoundingBox(objects)
1371 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1374 def GetBoundingBox(self, objects):
1376 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1379 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1382 :class:`SMESH.Measure` structure
1388 if isinstance(objects, tuple):
1389 objects = list(objects)
1390 if not isinstance(objects, list):
1394 if isinstance(o, Mesh):
1395 srclist.append(o.mesh)
1396 elif hasattr(o, "_narrow"):
1397 src = o._narrow(SMESH.SMESH_IDSource)
1398 if src: srclist.append(src)
1401 aMeasurements = self.CreateMeasurements()
1402 result = aMeasurements.BoundingBox(srclist)
1403 aMeasurements.UnRegister()
1406 def GetLength(self, obj):
1408 Get sum of lengths of all 1D elements in the mesh object.
1411 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1414 sum of lengths of all 1D elements
1417 if isinstance(obj, Mesh): obj = obj.mesh
1418 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1419 aMeasurements = self.CreateMeasurements()
1420 value = aMeasurements.Length(obj)
1421 aMeasurements.UnRegister()
1424 def GetArea(self, obj):
1426 Get sum of areas of all 2D elements in the mesh object.
1429 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1432 sum of areas of all 2D elements
1435 if isinstance(obj, Mesh): obj = obj.mesh
1436 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1437 aMeasurements = self.CreateMeasurements()
1438 value = aMeasurements.Area(obj)
1439 aMeasurements.UnRegister()
1442 def GetVolume(self, obj):
1444 Get sum of volumes of all 3D elements in the mesh object.
1447 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1450 sum of volumes of all 3D elements
1453 if isinstance(obj, Mesh): obj = obj.mesh
1454 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1455 aMeasurements = self.CreateMeasurements()
1456 value = aMeasurements.Volume(obj)
1457 aMeasurements.UnRegister()
1460 def GetGravityCenter(self, obj):
1462 Get gravity center of all nodes of a mesh object.
1465 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1468 Three components of the gravity center (x,y,z)
1471 :meth:`Mesh.BaryCenter`
1473 if isinstance(obj, Mesh): obj = obj.mesh
1474 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1475 aMeasurements = self.CreateMeasurements()
1476 pointStruct = aMeasurements.GravityCenter(obj)
1477 aMeasurements.UnRegister()
1478 return pointStruct.x, pointStruct.y, pointStruct.z
1480 def GetAngle(self, p1, p2, p3 ):
1482 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1485 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1491 if isinstance( p1, list ): p1 = PointStruct(*p1)
1492 if isinstance( p2, list ): p2 = PointStruct(*p2)
1493 if isinstance( p3, list ): p3 = PointStruct(*p3)
1495 aMeasurements = self.CreateMeasurements()
1496 angle = aMeasurements.Angle(p1,p2,p3)
1497 aMeasurements.UnRegister()
1502 pass # end of class smeshBuilder
1505 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1506 """Registering the new proxy for SMESH.SMESH_Gen"""
1509 def New( instance=None, instanceGeom=None):
1511 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1512 interface to create or load meshes.
1517 salome.salome_init()
1518 from salome.smesh import smeshBuilder
1519 smesh = smeshBuilder.New()
1522 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1523 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1525 :class:`smeshBuilder` instance
1530 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1532 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1537 smeshInst = smeshBuilder()
1538 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1539 smeshInst.init_smesh(instanceGeom)
1543 # Public class: Mesh
1544 # ==================
1547 class Mesh(metaclass = MeshMeta):
1549 This class allows defining and managing a mesh.
1550 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1551 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1552 new nodes and elements and by changing the existing entities), to get information
1553 about a mesh and to export a mesh in different formats.
1560 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1565 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1566 sets the GUI name of this mesh to *name*.
1569 smeshpyD: an instance of smeshBuilder class
1570 geompyD: an instance of geomBuilder class
1571 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1572 name: Study name of the mesh
1575 self.smeshpyD = smeshpyD
1576 self.geompyD = geompyD
1581 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1584 # publish geom of mesh (issue 0021122)
1585 if not self.geom.GetStudyEntry():
1589 geo_name = name + " shape"
1591 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1592 geompyD.addToStudy( self.geom, geo_name )
1593 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1595 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1598 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1600 self.smeshpyD.SetName(self.mesh, name)
1602 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1605 self.geom = self.mesh.GetShapeToMesh()
1607 self.editor = self.mesh.GetMeshEditor()
1608 self.functors = [None] * SMESH.FT_Undefined._v
1610 # set self to algoCreator's
1611 for attrName in dir(self):
1612 attr = getattr( self, attrName )
1613 if isinstance( attr, algoCreator ):
1614 setattr( self, attrName, attr.copy( self ))
1621 Destructor. Clean-up resources
1624 #self.mesh.UnRegister()
1628 def SetMesh(self, theMesh):
1630 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1633 theMesh: a :class:`SMESH.SMESH_Mesh` object
1635 # do not call Register() as this prevents mesh servant deletion at closing study
1636 #if self.mesh: self.mesh.UnRegister()
1639 #self.mesh.Register()
1640 self.geom = self.mesh.GetShapeToMesh()
1644 if salome.sg.hasDesktop():
1645 so = salome.ObjectToSObject( self.geom )
1646 comp = so.GetFatherComponent()
1647 if comp.ComponentDataType() == "SHAPERSTUDY":
1648 import shaperBuilder
1649 self.geompyD = shaperBuilder.New()
1652 if not self.geompyD:
1653 self.geompyD = self.geom.GetGen()
1658 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1661 a :class:`SMESH.SMESH_Mesh` object
1666 def GetEngine(self):
1668 Return a smeshBuilder instance created this mesh
1670 return self.smeshpyD
1672 def GetGeomEngine(self):
1674 Return a geomBuilder instance
1680 Get the name of the mesh
1683 the name of the mesh as a string
1686 name = GetName(self.GetMesh())
1689 def SetName(self, name):
1691 Set a name to the mesh
1694 name: a new name of the mesh
1697 self.smeshpyD.SetName(self.GetMesh(), name)
1699 def GetSubMesh(self, geom, name):
1701 Get a sub-mesh object associated to a *geom* geometrical object.
1704 geom: a geometrical object (shape)
1705 name: a name for the sub-mesh in the Object Browser
1708 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1709 which lies on the given shape
1712 A sub-mesh is implicitly created when a sub-shape is specified at
1713 creating an algorithm, for example::
1715 algo1D = mesh.Segment(geom=Edge_1)
1717 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1718 The created sub-mesh can be retrieved from the algorithm::
1720 submesh = algo1D.GetSubMesh()
1723 AssureGeomPublished( self, geom, name )
1724 submesh = self.mesh.GetSubMesh( geom, name )
1729 Return the shape associated to the mesh
1737 def SetShape(self, geom):
1739 Associate the given shape to the mesh (entails the recreation of the mesh)
1742 geom: the shape to be meshed (GEOM_Object)
1745 self.mesh = self.smeshpyD.CreateMesh(geom)
1747 def HasShapeToMesh(self):
1749 Return ``True`` if this mesh is based on geometry
1751 return self.mesh.HasShapeToMesh()
1755 Load mesh from the study after opening the study
1759 def IsReadyToCompute(self, theSubObject):
1761 Return true if the hypotheses are defined well
1764 theSubObject: a sub-shape of a mesh shape
1770 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1772 def GetAlgoState(self, theSubObject):
1774 Return errors of hypotheses definition.
1775 The list of errors is empty if everything is OK.
1778 theSubObject: a sub-shape of a mesh shape
1784 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1786 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1788 Return a geometrical object on which the given element was built.
1789 The returned geometrical object, if not nil, is either found in the
1790 study or published by this method with the given name
1793 theElementID: the id of the mesh element
1794 theGeomName: the user-defined name of the geometrical object
1797 GEOM.GEOM_Object instance
1800 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1802 def MeshDimension(self):
1804 Return the mesh dimension depending on the dimension of the underlying shape
1805 or, if the mesh is not based on any shape, basing on deimension of elements
1808 mesh dimension as an integer value [0,3]
1811 if self.mesh.HasShapeToMesh():
1812 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1813 if len( shells ) > 0 :
1815 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1817 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1822 if self.NbVolumes() > 0: return 3
1823 if self.NbFaces() > 0: return 2
1824 if self.NbEdges() > 0: return 1
1827 def Evaluate(self, geom=0):
1829 Evaluate size of prospective mesh on a shape
1832 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1833 To know predicted number of e.g. edges, inquire it this way::
1835 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1838 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1840 geom = self.mesh.GetShapeToMesh()
1843 return self.smeshpyD.Evaluate(self.mesh, geom)
1846 def Compute(self, geom=0, discardModifs=False, refresh=False):
1848 Compute the mesh and return the status of the computation
1851 geom: geomtrical shape on which mesh data should be computed
1852 discardModifs: if True and the mesh has been edited since
1853 a last total re-compute and that may prevent successful partial re-compute,
1854 then the mesh is cleaned before Compute()
1855 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1861 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1862 geom = self.mesh.GetShapeToMesh()
1865 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1867 ok = self.smeshpyD.Compute(self.mesh, geom)
1868 except SALOME.SALOME_Exception as ex:
1869 print("Mesh computation failed, exception caught:")
1870 print(" ", ex.details.text)
1873 print("Mesh computation failed, exception caught:")
1874 traceback.print_exc()
1878 # Treat compute errors
1879 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1881 for err in computeErrors:
1882 if self.mesh.HasShapeToMesh():
1883 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1885 stdErrors = ["OK", #COMPERR_OK
1886 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1887 "std::exception", #COMPERR_STD_EXCEPTION
1888 "OCC exception", #COMPERR_OCC_EXCEPTION
1889 "..", #COMPERR_SLM_EXCEPTION
1890 "Unknown exception", #COMPERR_EXCEPTION
1891 "Memory allocation problem", #COMPERR_MEMORY_PB
1892 "Algorithm failed", #COMPERR_ALGO_FAILED
1893 "Unexpected geometry", #COMPERR_BAD_SHAPE
1894 "Warning", #COMPERR_WARNING
1895 "Computation cancelled",#COMPERR_CANCELED
1896 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1898 if err.code < len(stdErrors): errText = stdErrors[err.code]
1900 errText = "code %s" % -err.code
1901 if errText: errText += ". "
1902 errText += err.comment
1903 if allReasons: allReasons += "\n"
1905 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1907 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1911 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1913 if err.isGlobalAlgo:
1921 reason = '%s %sD algorithm is missing' % (glob, dim)
1922 elif err.state == HYP_MISSING:
1923 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1924 % (glob, dim, name, dim))
1925 elif err.state == HYP_NOTCONFORM:
1926 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1927 elif err.state == HYP_BAD_PARAMETER:
1928 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1929 % ( glob, dim, name ))
1930 elif err.state == HYP_BAD_GEOMETRY:
1931 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1932 'geometry' % ( glob, dim, name ))
1933 elif err.state == HYP_HIDDEN_ALGO:
1934 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1935 'algorithm of upper dimension generating %sD mesh'
1936 % ( glob, dim, name, glob, dim ))
1938 reason = ("For unknown reason. "
1939 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1941 if allReasons: allReasons += "\n"
1942 allReasons += "- " + reason
1944 if not ok or allReasons != "":
1945 msg = '"' + GetName(self.mesh) + '"'
1946 if ok: msg += " has been computed with warnings"
1947 else: msg += " has not been computed"
1948 if allReasons != "": msg += ":"
1954 if salome.sg.hasDesktop():
1955 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1956 if refresh: salome.sg.updateObjBrowser()
1960 def GetComputeErrors(self, shape=0 ):
1962 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1966 shape = self.mesh.GetShapeToMesh()
1967 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1969 def GetSubShapeName(self, subShapeID ):
1971 Return a name of a sub-shape by its ID.
1972 Possible variants (for *subShapeID* == 3):
1974 - **"Face_12"** - published sub-shape
1975 - **FACE #3** - not published sub-shape
1976 - **sub-shape #3** - invalid sub-shape ID
1977 - **#3** - error in this function
1980 subShapeID: a unique ID of a sub-shape
1983 a string describing the sub-shape
1987 if not self.mesh.HasShapeToMesh():
1991 mainIOR = salome.orb.object_to_string( self.GetShape() )
1993 mainSO = s.FindObjectIOR(mainIOR)
1996 shapeText = '"%s"' % mainSO.GetName()
1997 subIt = s.NewChildIterator(mainSO)
1999 subSO = subIt.Value()
2001 obj = subSO.GetObject()
2002 if not obj: continue
2003 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2006 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2009 if ids == subShapeID:
2010 shapeText = '"%s"' % subSO.GetName()
2013 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2015 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2017 shapeText = 'sub-shape #%s' % (subShapeID)
2019 shapeText = "#%s" % (subShapeID)
2022 def GetFailedShapes(self, publish=False):
2024 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2025 error of an algorithm
2028 publish: if *True*, the returned groups will be published in the study
2031 a list of GEOM groups each named after a failed algorithm
2036 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2037 for err in computeErrors:
2038 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2039 if not shape: continue
2040 if err.algoName in algo2shapes:
2041 algo2shapes[ err.algoName ].append( shape )
2043 algo2shapes[ err.algoName ] = [ shape ]
2047 for algoName, shapes in list(algo2shapes.items()):
2049 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2050 otherTypeShapes = []
2052 group = self.geompyD.CreateGroup( self.geom, groupType )
2053 for shape in shapes:
2054 if shape.GetShapeType() == shapes[0].GetShapeType():
2055 sameTypeShapes.append( shape )
2057 otherTypeShapes.append( shape )
2058 self.geompyD.UnionList( group, sameTypeShapes )
2060 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2062 group.SetName( algoName )
2063 groups.append( group )
2064 shapes = otherTypeShapes
2067 for group in groups:
2068 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2071 def GetMeshOrder(self):
2073 Return sub-mesh objects list in meshing order
2076 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2079 return self.mesh.GetMeshOrder()
2081 def SetMeshOrder(self, submeshes):
2083 Set priority of sub-meshes. It works in two ways:
2085 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2086 *several dimensions*, it sets the order in which the sub-meshes are computed.
2087 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2088 when looking for meshing parameters to apply to a sub-shape. To impose the
2089 order in which sub-meshes with uni-dimensional algorithms are computed,
2090 call **submesh.Compute()** in a desired order.
2093 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2095 Warning: the method is for setting the order for all sub-meshes at once:
2096 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2099 return self.mesh.SetMeshOrder(submeshes)
2101 def Clear(self, refresh=False):
2103 Remove all nodes and elements generated on geometry. Imported elements remain.
2106 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2110 if ( salome.sg.hasDesktop() ):
2111 if refresh: salome.sg.updateObjBrowser()
2113 def ClearSubMesh(self, geomId, refresh=False):
2115 Remove all nodes and elements of indicated shape
2118 geomId: the ID of a sub-shape to remove elements on
2119 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2122 self.mesh.ClearSubMesh(geomId)
2123 if salome.sg.hasDesktop():
2124 if refresh: salome.sg.updateObjBrowser()
2126 def AutomaticTetrahedralization(self, fineness=0):
2128 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2131 fineness: [0.0,1.0] defines mesh fineness
2137 dim = self.MeshDimension()
2139 self.RemoveGlobalHypotheses()
2140 self.Segment().AutomaticLength(fineness)
2142 self.Triangle().LengthFromEdges()
2147 return self.Compute()
2149 def AutomaticHexahedralization(self, fineness=0):
2151 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2154 fineness: [0.0, 1.0] defines mesh fineness
2160 dim = self.MeshDimension()
2161 # assign the hypotheses
2162 self.RemoveGlobalHypotheses()
2163 self.Segment().AutomaticLength(fineness)
2170 return self.Compute()
2172 def AddHypothesis(self, hyp, geom=0):
2177 hyp: a hypothesis to assign
2178 geom: a subhape of mesh geometry
2181 :class:`SMESH.Hypothesis_Status`
2184 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2185 hyp, geom = geom, hyp
2186 if isinstance( hyp, Mesh_Algorithm ):
2187 hyp = hyp.GetAlgorithm()
2192 geom = self.mesh.GetShapeToMesh()
2195 if self.mesh.HasShapeToMesh():
2196 hyp_type = hyp.GetName()
2197 lib_name = hyp.GetLibName()
2198 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2199 # if checkAll and geom:
2200 # checkAll = geom.GetType() == 37
2202 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2204 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2205 status = self.mesh.AddHypothesis(geom, hyp)
2207 status = HYP_BAD_GEOMETRY, ""
2208 hyp_name = GetName( hyp )
2211 geom_name = geom.GetName()
2212 isAlgo = hyp._narrow( SMESH_Algo )
2213 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2216 def IsUsedHypothesis(self, hyp, geom):
2218 Return True if an algorithm or hypothesis is assigned to a given shape
2221 hyp: an algorithm or hypothesis to check
2222 geom: a subhape of mesh geometry
2228 if not hyp: # or not geom
2230 if isinstance( hyp, Mesh_Algorithm ):
2231 hyp = hyp.GetAlgorithm()
2233 hyps = self.GetHypothesisList(geom)
2235 if h.GetId() == hyp.GetId():
2239 def RemoveHypothesis(self, hyp, geom=0):
2241 Unassign a hypothesis
2244 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2245 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2248 :class:`SMESH.Hypothesis_Status`
2253 if isinstance( hyp, Mesh_Algorithm ):
2254 hyp = hyp.GetAlgorithm()
2260 if self.IsUsedHypothesis( hyp, shape ):
2261 return self.mesh.RemoveHypothesis( shape, hyp )
2262 hypName = GetName( hyp )
2263 geoName = GetName( shape )
2264 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2267 def GetHypothesisList(self, geom):
2269 Get the list of hypotheses added on a geometry
2272 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2275 the sequence of :class:`SMESH.SMESH_Hypothesis`
2278 return self.mesh.GetHypothesisList( geom )
2280 def RemoveGlobalHypotheses(self):
2282 Remove all global hypotheses
2285 current_hyps = self.mesh.GetHypothesisList( self.geom )
2286 for hyp in current_hyps:
2287 self.mesh.RemoveHypothesis( self.geom, hyp )
2291 def ExportMEDCoupling(self, *args, **kwargs):
2293 Export the mesh in a memory representation.
2296 auto_groups (boolean): parameter for creating/not creating
2297 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2298 the typical use is auto_groups=False.
2299 overwrite (boolean): parameter for overwriting/not overwriting the file
2300 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2301 to export instead of the mesh
2302 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2304 - 1D if all mesh nodes lie on OX coordinate axis, or
2305 - 2D if all mesh nodes lie on XOY coordinate plane, or
2306 - 3D in the rest cases.
2308 If *autoDimension* is *False*, the space dimension is always 3.
2309 fields: list of GEOM fields defined on the shape to mesh.
2310 geomAssocFields: each character of this string means a need to export a
2311 corresponding field; correspondence between fields and characters
2314 - 'v' stands for "_vertices_" field;
2315 - 'e' stands for "_edges_" field;
2316 - 'f' stands for "_faces_" field;
2317 - 's' stands for "_solids_" field.
2319 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2320 close to zero within a given tolerance, the coordinate is set to zero.
2321 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2322 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2324 auto_groups = args[0] if len(args) > 0 else False
2325 meshPart = args[1] if len(args) > 1 else None
2326 autoDimension = args[2] if len(args) > 2 else True
2327 fields = args[3] if len(args) > 3 else []
2328 geomAssocFields = args[4] if len(args) > 4 else ''
2329 z_tolerance = args[5] if len(args) > 5 else -1.
2330 saveNumbers = args[6] if len(args) > 6 else True
2331 # process keywords arguments
2332 auto_groups = kwargs.get("auto_groups", auto_groups)
2333 meshPart = kwargs.get("meshPart", meshPart)
2334 autoDimension = kwargs.get("autoDimension", autoDimension)
2335 fields = kwargs.get("fields", fields)
2336 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2337 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2338 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2340 # invoke engine's function
2341 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2342 unRegister = genObjUnRegister()
2343 if isinstance( meshPart, list ):
2344 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2345 unRegister.set( meshPart )
2347 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2348 self.mesh.SetParameters(Parameters)
2350 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2351 fields, geomAssocFields, z_tolerance,
2354 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2355 return medcoupling.MEDFileData.New(dab)
2357 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2359 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2360 return medcoupling.MEDFileMesh.New(dab)
2362 def ExportMED(self, *args, **kwargs):
2364 Export the mesh in a file in MED format
2365 allowing to overwrite the file if it exists or add the exported data to its contents
2368 fileName: is the file name
2369 auto_groups (boolean): parameter for creating/not creating
2370 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2371 the typical use is auto_groups=False.
2372 version (int): define the version (xy, where version is x.y.z) of MED file format.
2373 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2374 The rules of compatibility to write a mesh in an older version than
2375 the current version depend on the current version. For instance,
2376 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2377 or 3.2.1 or 3.3.1 formats.
2378 If the version is equal to -1, the version is not changed (default).
2379 overwrite (boolean): parameter for overwriting/not overwriting the file
2380 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2381 to export instead of the mesh
2382 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2384 - 1D if all mesh nodes lie on OX coordinate axis, or
2385 - 2D if all mesh nodes lie on XOY coordinate plane, or
2386 - 3D in the rest cases.
2388 If *autoDimension* is *False*, the space dimension is always 3.
2389 fields: list of GEOM fields defined on the shape to mesh.
2390 geomAssocFields: each character of this string means a need to export a
2391 corresponding field; correspondence between fields and characters
2394 - 'v' stands for "_vertices_" field;
2395 - 'e' stands for "_edges_" field;
2396 - 'f' stands for "_faces_" field;
2397 - 's' stands for "_solids_" field.
2399 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2400 close to zero within a given tolerance, the coordinate is set to zero.
2401 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2402 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2404 # process positional arguments
2405 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2407 auto_groups = args[1] if len(args) > 1 else False
2408 version = args[2] if len(args) > 2 else -1
2409 overwrite = args[3] if len(args) > 3 else True
2410 meshPart = args[4] if len(args) > 4 else None
2411 autoDimension = args[5] if len(args) > 5 else True
2412 fields = args[6] if len(args) > 6 else []
2413 geomAssocFields = args[7] if len(args) > 7 else ''
2414 z_tolerance = args[8] if len(args) > 8 else -1.
2415 saveNumbers = args[9] if len(args) > 9 else True
2416 # process keywords arguments
2417 auto_groups = kwargs.get("auto_groups", auto_groups)
2418 version = kwargs.get("version", version)
2419 version = kwargs.get("minor", version)
2420 overwrite = kwargs.get("overwrite", overwrite)
2421 meshPart = kwargs.get("meshPart", meshPart)
2422 autoDimension = kwargs.get("autoDimension", autoDimension)
2423 fields = kwargs.get("fields", fields)
2424 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2425 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2426 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2428 if isinstance( meshPart, Mesh):
2429 meshPart = meshPart.GetMesh()
2431 # invoke engine's function
2432 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2433 unRegister = genObjUnRegister()
2434 if isinstance( meshPart, list ):
2435 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2436 unRegister.set( meshPart )
2438 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2439 self.mesh.SetParameters(Parameters)
2441 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2442 version, overwrite, autoDimension,
2443 fields, geomAssocFields, z_tolerance, saveNumbers )
2445 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2447 def ExportDAT(self, f, meshPart=None, renumber=True):
2449 Export the mesh in a file in DAT format
2453 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2454 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2457 if meshPart or not renumber:
2458 unRegister = genObjUnRegister()
2459 if isinstance( meshPart, list ):
2460 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2461 unRegister.set( meshPart )
2462 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2464 self.mesh.ExportDAT( f, renumber )
2466 def ExportUNV(self, f, meshPart=None, renumber=True):
2468 Export the mesh in a file in UNV format
2472 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2473 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2476 if meshPart or not renumber:
2477 unRegister = genObjUnRegister()
2478 if isinstance( meshPart, list ):
2479 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2480 unRegister.set( meshPart )
2481 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2483 self.mesh.ExportUNV( f, renumber )
2485 def ExportSTL(self, f, ascii=1, meshPart=None):
2487 Export the mesh in a file in STL format
2491 ascii: defines the file encoding
2492 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2496 unRegister = genObjUnRegister()
2497 if isinstance( meshPart, list ):
2498 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2499 unRegister.set( meshPart )
2500 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2502 self.mesh.ExportSTL(f, ascii)
2504 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2506 Export the mesh in a file in CGNS format
2510 overwrite: boolean parameter for overwriting/not overwriting the file
2511 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2512 groupElemsByType: if True all elements of same entity type are exported at ones,
2513 else elements are exported in order of their IDs which can cause creation
2514 of multiple cgns sections
2517 unRegister = genObjUnRegister()
2518 if isinstance( meshPart, list ):
2519 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2520 unRegister.set( meshPart )
2521 if isinstance( meshPart, Mesh ):
2522 meshPart = meshPart.mesh
2524 meshPart = self.mesh
2525 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2527 def ExportGMF(self, f, meshPart=None):
2529 Export the mesh in a file in GMF format.
2530 GMF files must have .mesh extension for the ASCII format and .meshb for
2531 the bynary format. Other extensions are not allowed.
2535 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538 unRegister = genObjUnRegister()
2539 if isinstance( meshPart, list ):
2540 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2541 unRegister.set( meshPart )
2542 if isinstance( meshPart, Mesh ):
2543 meshPart = meshPart.mesh
2545 meshPart = self.mesh
2546 self.mesh.ExportGMF(meshPart, f, True)
2548 def ExportToMED(self, *args, **kwargs):
2550 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2551 Export the mesh in a file in MED format
2552 allowing to overwrite the file if it exists or add the exported data to its contents
2555 fileName: the file name
2556 opt (boolean): parameter for creating/not creating
2557 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2558 overwrite: boolean parameter for overwriting/not overwriting the file
2559 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2561 - 1D if all mesh nodes lie on OX coordinate axis, or
2562 - 2D if all mesh nodes lie on XOY coordinate plane, or
2563 - 3D in the rest cases.
2565 If **autoDimension** is *False*, the space dimension is always 3.
2568 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2569 # process positional arguments
2570 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2572 auto_groups = args[1] if len(args) > 1 else False
2573 overwrite = args[2] if len(args) > 2 else True
2574 autoDimension = args[3] if len(args) > 3 else True
2575 # process keywords arguments
2576 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2577 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2578 overwrite = kwargs.get("overwrite", overwrite)
2579 autoDimension = kwargs.get("autoDimension", autoDimension)
2581 # invoke engine's function
2582 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2584 def ExportToMEDX(self, *args, **kwargs):
2586 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2587 Export the mesh in a file in MED format
2590 fileName: the file name
2591 opt (boolean): parameter for creating/not creating
2592 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2593 overwrite: boolean parameter for overwriting/not overwriting the file
2594 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2596 - 1D if all mesh nodes lie on OX coordinate axis, or
2597 - 2D if all mesh nodes lie on XOY coordinate plane, or
2598 - 3D in the rest cases.
2600 If **autoDimension** is *False*, the space dimension is always 3.
2603 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2604 # process positional arguments
2605 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2607 auto_groups = args[1] if len(args) > 1 else False
2608 overwrite = args[2] if len(args) > 2 else True
2609 autoDimension = args[3] if len(args) > 3 else True
2610 # process keywords arguments
2611 auto_groups = kwargs.get("auto_groups", auto_groups)
2612 overwrite = kwargs.get("overwrite", overwrite)
2613 autoDimension = kwargs.get("autoDimension", autoDimension)
2615 # invoke engine's function
2616 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2620 def Append(self, meshes, uniteIdenticalGroups = True,
2621 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2623 Append given meshes into this mesh.
2624 All groups of input meshes will be created in this mesh.
2627 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2628 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2629 mergeNodesAndElements: if True, equal nodes and elements are merged
2630 mergeTolerance: tolerance for merging nodes
2631 allGroups: forces creation of groups corresponding to every input mesh
2633 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2634 mergeNodesAndElements, mergeTolerance, allGroups,
2635 meshToAppendTo = self.GetMesh() )
2637 # Operations with groups:
2638 # ----------------------
2639 def CreateEmptyGroup(self, elementType, name):
2641 Create an empty standalone mesh group
2644 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2645 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2646 name: the name of the mesh group
2649 :class:`SMESH.SMESH_Group`
2652 return self.mesh.CreateGroup(elementType, name)
2654 def Group(self, grp, name=""):
2656 Create a mesh group based on the geometric object *grp*
2657 and give it a *name*.
2658 If *name* is not defined the name of the geometric group is used
2661 Works like :meth:`GroupOnGeom`.
2664 grp: a geometric group, a vertex, an edge, a face or a solid
2665 name: the name of the mesh group
2668 :class:`SMESH.SMESH_GroupOnGeom`
2671 return self.GroupOnGeom(grp, name)
2673 def GroupOnGeom(self, grp, name="", typ=None):
2675 Create a mesh group based on the geometrical object *grp*
2676 and give it a *name*.
2677 if *name* is not defined the name of the geometric group is used
2680 grp: a geometrical group, a vertex, an edge, a face or a solid
2681 name: the name of the mesh group
2682 typ: the type of elements in the group; either of
2683 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2684 automatically detected by the type of the geometry
2687 :class:`SMESH.SMESH_GroupOnGeom`
2690 AssureGeomPublished( self, grp, name )
2692 name = grp.GetName()
2694 typ = self._groupTypeFromShape( grp )
2695 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2697 def _groupTypeFromShape( self, shape ):
2699 Pivate method to get a type of group on geometry
2701 tgeo = str(shape.GetShapeType())
2702 if tgeo == "VERTEX":
2704 elif tgeo == "EDGE" or tgeo == "WIRE":
2706 elif tgeo == "FACE" or tgeo == "SHELL":
2708 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2710 elif tgeo == "COMPOUND":
2712 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2714 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2715 # simplification of access in geomBuilder: omniORB.registerObjref
2716 from SHAPERSTUDY_utils import getEngine
2719 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2721 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2722 return self._groupTypeFromShape( sub[0] )
2724 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2727 def GroupOnFilter(self, typ, name, filter):
2729 Create a mesh group with given *name* based on the *filter*.
2730 It is a special type of group dynamically updating it's contents during
2734 typ: the type of elements in the group; either of
2735 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2736 name: the name of the mesh group
2737 filter (SMESH.Filter): the filter defining group contents
2740 :class:`SMESH.SMESH_GroupOnFilter`
2743 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2745 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2747 Create a mesh group by the given ids of elements
2750 groupName: the name of the mesh group
2751 elementType: the type of elements in the group; either of
2752 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2753 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2756 :class:`SMESH.SMESH_Group`
2759 group = self.mesh.CreateGroup(elementType, groupName)
2760 if isinstance( elemIDs, Mesh ):
2761 elemIDs = elemIDs.GetMesh()
2762 if hasattr( elemIDs, "GetIDs" ):
2763 if hasattr( elemIDs, "SetMesh" ):
2764 elemIDs.SetMesh( self.GetMesh() )
2765 group.AddFrom( elemIDs )
2773 CritType=FT_Undefined,
2776 UnaryOp=FT_Undefined,
2779 Create a mesh group by the given conditions
2782 groupName: the name of the mesh group
2783 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2784 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2785 Note that the items starting from FT_LessThan are not suitable for CritType.
2786 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2787 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2788 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2789 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2790 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2793 :class:`SMESH.SMESH_GroupOnFilter`
2796 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2797 group = self.MakeGroupByCriterion(groupName, aCriterion)
2800 def MakeGroupByCriterion(self, groupName, Criterion):
2802 Create a mesh group by the given criterion
2805 groupName: the name of the mesh group
2806 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2809 :class:`SMESH.SMESH_GroupOnFilter`
2812 :meth:`smeshBuilder.GetCriterion`
2815 return self.MakeGroupByCriteria( groupName, [Criterion] )
2817 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2819 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2822 groupName: the name of the mesh group
2823 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2824 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2827 :class:`SMESH.SMESH_GroupOnFilter`
2830 :meth:`smeshBuilder.GetCriterion`
2833 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2834 group = self.MakeGroupByFilter(groupName, aFilter)
2837 def MakeGroupByFilter(self, groupName, theFilter):
2839 Create a mesh group by the given filter
2842 groupName (string): the name of the mesh group
2843 theFilter (SMESH.Filter): the filter
2846 :class:`SMESH.SMESH_GroupOnFilter`
2849 :meth:`smeshBuilder.GetFilter`
2852 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2853 #theFilter.SetMesh( self.mesh )
2854 #group.AddFrom( theFilter )
2855 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2858 def RemoveGroup(self, group):
2863 group (SMESH.SMESH_GroupBase): group to remove
2866 self.mesh.RemoveGroup(group)
2868 def RemoveGroupWithContents(self, group):
2870 Remove a group with its contents
2873 group (SMESH.SMESH_GroupBase): group to remove
2876 This operation can create gaps in numeration of nodes or elements.
2877 Call :meth:`RenumberElements` to remove the gaps.
2880 self.mesh.RemoveGroupWithContents(group)
2882 def GetGroups(self, elemType = SMESH.ALL):
2884 Get the list of groups existing in the mesh in the order of creation
2885 (starting from the oldest one)
2888 elemType (SMESH.ElementType): type of elements the groups contain;
2889 by default groups of elements of all types are returned
2892 a list of :class:`SMESH.SMESH_GroupBase`
2895 groups = self.mesh.GetGroups()
2896 if elemType == SMESH.ALL:
2900 if g.GetType() == elemType:
2901 typedGroups.append( g )
2908 Get the number of groups existing in the mesh
2911 the quantity of groups as an integer value
2914 return self.mesh.NbGroups()
2916 def GetGroupNames(self):
2918 Get the list of names of groups existing in the mesh
2924 groups = self.GetGroups()
2926 for group in groups:
2927 names.append(group.GetName())
2930 def GetGroupByName(self, name, elemType = None):
2932 Find groups by name and type
2935 name (string): name of the group of interest
2936 elemType (SMESH.ElementType): type of elements the groups contain;
2937 by default one group of any type is returned;
2938 if elemType == SMESH.ALL then all groups of any type are returned
2941 a list of :class:`SMESH.SMESH_GroupBase`
2945 for group in self.GetGroups():
2946 if group.GetName() == name:
2947 if elemType is None:
2949 if ( elemType == SMESH.ALL or
2950 group.GetType() == elemType ):
2951 groups.append( group )
2954 def UnionGroups(self, group1, group2, name):
2956 Produce a union of two groups.
2957 A new group is created. All mesh elements that are
2958 present in the initial groups are added to the new one
2961 group1 (SMESH.SMESH_GroupBase): a group
2962 group2 (SMESH.SMESH_GroupBase): another group
2965 instance of :class:`SMESH.SMESH_Group`
2968 return self.mesh.UnionGroups(group1, group2, name)
2970 def UnionListOfGroups(self, groups, name):
2972 Produce a union list of groups.
2973 New group is created. All mesh elements that are present in
2974 initial groups are added to the new one
2977 groups: list of :class:`SMESH.SMESH_GroupBase`
2980 instance of :class:`SMESH.SMESH_Group`
2982 return self.mesh.UnionListOfGroups(groups, name)
2984 def IntersectGroups(self, group1, group2, name):
2986 Prodice an intersection of two groups.
2987 A new group is created. All mesh elements that are common
2988 for the two initial groups are added to the new one.
2991 group1 (SMESH.SMESH_GroupBase): a group
2992 group2 (SMESH.SMESH_GroupBase): another group
2995 instance of :class:`SMESH.SMESH_Group`
2998 return self.mesh.IntersectGroups(group1, group2, name)
3000 def IntersectListOfGroups(self, groups, name):
3002 Produce an intersection of groups.
3003 New group is created. All mesh elements that are present in all
3004 initial groups simultaneously are added to the new one
3007 groups: a list of :class:`SMESH.SMESH_GroupBase`
3010 instance of :class:`SMESH.SMESH_Group`
3012 return self.mesh.IntersectListOfGroups(groups, name)
3014 def CutGroups(self, main_group, tool_group, name):
3016 Produce a cut of two groups.
3017 A new group is created. All mesh elements that are present in
3018 the main group but are not present in the tool group are added to the new one
3021 main_group (SMESH.SMESH_GroupBase): a group to cut from
3022 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3025 an instance of :class:`SMESH.SMESH_Group`
3028 return self.mesh.CutGroups(main_group, tool_group, name)
3030 def CutListOfGroups(self, main_groups, tool_groups, name):
3032 Produce a cut of groups.
3033 A new group is created. All mesh elements that are present in main groups
3034 but do not present in tool groups are added to the new one
3037 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3038 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3041 an instance of :class:`SMESH.SMESH_Group`
3044 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3046 def CreateDimGroup(self, groups, elemType, name,
3047 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3049 Create a standalone group of entities basing on nodes of other groups.
3052 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3053 elemType: a type of elements to include to the new group; either of
3054 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3055 name: a name of the new group.
3056 nbCommonNodes: a criterion of inclusion of an element to the new group
3057 basing on number of element nodes common with reference *groups*.
3058 Meaning of possible values are:
3060 - SMESH.ALL_NODES - include if all nodes are common,
3061 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3062 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3063 - SMEHS.MAJORITY - include if half of nodes or more are common.
3064 underlyingOnly: if *True* (default), an element is included to the
3065 new group provided that it is based on nodes of an element of *groups*;
3066 in this case the reference *groups* are supposed to be of higher dimension
3067 than *elemType*, which can be useful for example to get all faces lying on
3068 volumes of the reference *groups*.
3071 an instance of :class:`SMESH.SMESH_Group`
3074 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3076 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3078 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3080 Distribute all faces of the mesh among groups using sharp edges and optionally
3081 existing 1D elements as group boundaries.
3084 sharpAngle: edge is considered sharp if an angle between normals of
3085 adjacent faces is more than \a sharpAngle in degrees.
3086 createEdges (boolean): to create 1D elements for detected sharp edges.
3087 useExistingEdges (boolean): to use existing edges as group boundaries
3089 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3091 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3092 self.mesh.SetParameters(Parameters)
3093 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3095 def ConvertToStandalone(self, group):
3097 Convert group on geom into standalone group
3100 return self.mesh.ConvertToStandalone(group)
3102 # Get some info about mesh:
3103 # ------------------------
3105 def GetLog(self, clearAfterGet):
3107 Return the log of nodes and elements added or removed
3108 since the previous clear of the log.
3111 clearAfterGet: log is emptied after Get (safe if concurrents access)
3114 list of SMESH.log_block structures { commandType, number, coords, indexes }
3117 return self.mesh.GetLog(clearAfterGet)
3121 Clear the log of nodes and elements added or removed since the previous
3122 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3125 self.mesh.ClearLog()
3127 def SetAutoColor(self, theAutoColor):
3129 Toggle auto color mode on the object.
3130 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3133 theAutoColor (boolean): the flag which toggles auto color mode.
3136 self.mesh.SetAutoColor(theAutoColor)
3138 def GetAutoColor(self):
3140 Get flag of object auto color mode.
3146 return self.mesh.GetAutoColor()
3153 integer value, which is the internal Id of the mesh
3156 return self.mesh.GetId()
3158 def HasDuplicatedGroupNamesMED(self):
3160 Check the group names for duplications.
3161 Consider the maximum group name length stored in MED file.
3167 return self.mesh.HasDuplicatedGroupNamesMED()
3169 def GetMeshEditor(self):
3171 Obtain the mesh editor tool
3174 an instance of :class:`SMESH.SMESH_MeshEditor`
3179 def GetIDSource(self, ids, elemType = SMESH.ALL):
3181 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3182 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3186 elemType: type of elements; this parameter is used to distinguish
3187 IDs of nodes from IDs of elements; by default ids are treated as
3188 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3191 an instance of :class:`SMESH.SMESH_IDSource`
3194 call UnRegister() for the returned object as soon as it is no more useful::
3196 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3197 mesh.DoSomething( idSrc )
3201 if isinstance( ids, int ):
3203 return self.editor.MakeIDSource(ids, elemType)
3206 # Get information about mesh contents:
3207 # ------------------------------------
3209 def GetMeshInfo(self, obj = None):
3211 Get the mesh statistic.
3214 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3217 if not obj: obj = self.mesh
3218 return self.smeshpyD.GetMeshInfo(obj)
3222 Return the number of nodes in the mesh
3228 return self.mesh.NbNodes()
3230 def NbElements(self):
3232 Return the number of elements in the mesh
3238 return self.mesh.NbElements()
3240 def Nb0DElements(self):
3242 Return the number of 0d elements in the mesh
3248 return self.mesh.Nb0DElements()
3252 Return the number of ball discrete elements in the mesh
3258 return self.mesh.NbBalls()
3262 Return the number of edges in the mesh
3268 return self.mesh.NbEdges()
3270 def NbEdgesOfOrder(self, elementOrder):
3272 Return the number of edges with the given order in the mesh
3275 elementOrder: the order of elements
3276 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3282 return self.mesh.NbEdgesOfOrder(elementOrder)
3286 Return the number of faces in the mesh
3292 return self.mesh.NbFaces()
3294 def NbFacesOfOrder(self, elementOrder):
3296 Return the number of faces with the given order in the mesh
3299 elementOrder: the order of elements
3300 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3306 return self.mesh.NbFacesOfOrder(elementOrder)
3308 def NbTriangles(self):
3310 Return the number of triangles in the mesh
3316 return self.mesh.NbTriangles()
3318 def NbTrianglesOfOrder(self, elementOrder):
3320 Return the number of triangles with the given order in the mesh
3323 elementOrder: is the order of elements
3324 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3330 return self.mesh.NbTrianglesOfOrder(elementOrder)
3332 def NbBiQuadTriangles(self):
3334 Return the number of biquadratic triangles in the mesh
3340 return self.mesh.NbBiQuadTriangles()
3342 def NbQuadrangles(self):
3344 Return the number of quadrangles in the mesh
3350 return self.mesh.NbQuadrangles()
3352 def NbQuadranglesOfOrder(self, elementOrder):
3354 Return the number of quadrangles with the given order in the mesh
3357 elementOrder: the order of elements
3358 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3364 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3366 def NbBiQuadQuadrangles(self):
3368 Return the number of biquadratic quadrangles in the mesh
3374 return self.mesh.NbBiQuadQuadrangles()
3376 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3378 Return the number of polygons of given order in the mesh
3381 elementOrder: the order of elements
3382 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3388 return self.mesh.NbPolygonsOfOrder(elementOrder)
3390 def NbVolumes(self):
3392 Return the number of volumes in the mesh
3398 return self.mesh.NbVolumes()
3401 def NbVolumesOfOrder(self, elementOrder):
3403 Return the number of volumes with the given order in the mesh
3406 elementOrder: the order of elements
3407 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3413 return self.mesh.NbVolumesOfOrder(elementOrder)
3417 Return the number of tetrahedrons in the mesh
3423 return self.mesh.NbTetras()
3425 def NbTetrasOfOrder(self, elementOrder):
3427 Return the number of tetrahedrons with the given order in the mesh
3430 elementOrder: the order of elements
3431 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3437 return self.mesh.NbTetrasOfOrder(elementOrder)
3441 Return the number of hexahedrons in the mesh
3447 return self.mesh.NbHexas()
3449 def NbHexasOfOrder(self, elementOrder):
3451 Return the number of hexahedrons with the given order in the mesh
3454 elementOrder: the order of elements
3455 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3461 return self.mesh.NbHexasOfOrder(elementOrder)
3463 def NbTriQuadraticHexas(self):
3465 Return the number of triquadratic hexahedrons in the mesh
3471 return self.mesh.NbTriQuadraticHexas()
3473 def NbPyramids(self):
3475 Return the number of pyramids in the mesh
3481 return self.mesh.NbPyramids()
3483 def NbPyramidsOfOrder(self, elementOrder):
3485 Return the number of pyramids with the given order in the mesh
3488 elementOrder: the order of elements
3489 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3495 return self.mesh.NbPyramidsOfOrder(elementOrder)
3499 Return the number of prisms in the mesh
3505 return self.mesh.NbPrisms()
3507 def NbPrismsOfOrder(self, elementOrder):
3509 Return the number of prisms with the given order in the mesh
3512 elementOrder: the order of elements
3513 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3519 return self.mesh.NbPrismsOfOrder(elementOrder)
3521 def NbHexagonalPrisms(self):
3523 Return the number of hexagonal prisms in the mesh
3529 return self.mesh.NbHexagonalPrisms()
3531 def NbPolyhedrons(self):
3533 Return the number of polyhedrons in the mesh
3539 return self.mesh.NbPolyhedrons()
3541 def NbSubMesh(self):
3543 Return the number of submeshes in the mesh
3549 return self.mesh.NbSubMesh()
3551 def GetElementsId(self):
3553 Return the list of all mesh elements IDs
3556 the list of integer values
3559 :meth:`GetElementsByType`
3562 return self.mesh.GetElementsId()
3564 def GetElementsByType(self, elementType):
3566 Return the list of IDs of mesh elements with the given type
3569 elementType (SMESH.ElementType): the required type of elements
3572 list of integer values
3575 return self.mesh.GetElementsByType(elementType)
3577 def GetNodesId(self):
3579 Return the list of mesh nodes IDs
3582 the list of integer values
3585 return self.mesh.GetNodesId()
3587 # Get the information about mesh elements:
3588 # ------------------------------------
3590 def GetElementType(self, id, iselem=True):
3592 Return the type of mesh element or node
3595 the value from :class:`SMESH.ElementType` enumeration.
3596 Return SMESH.ALL if element or node with the given ID does not exist
3599 return self.mesh.GetElementType(id, iselem)
3601 def GetElementGeomType(self, id):
3603 Return the geometric type of mesh element
3606 the value from :class:`SMESH.EntityType` enumeration.
3609 return self.mesh.GetElementGeomType(id)
3611 def GetElementShape(self, id):
3613 Return the shape type of mesh element
3616 the value from :class:`SMESH.GeometryType` enumeration.
3619 return self.mesh.GetElementShape(id)
3621 def GetSubMeshElementsId(self, Shape):
3623 Return the list of sub-mesh elements IDs
3626 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3627 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3630 list of integer values
3633 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3634 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3637 return self.mesh.GetSubMeshElementsId(ShapeID)
3639 def GetSubMeshNodesId(self, Shape, all):
3641 Return the list of sub-mesh nodes IDs
3644 Shape: a geom object (sub-shape).
3645 *Shape* must be the sub-shape of a :meth:`GetShape`
3646 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3649 list of integer values
3652 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3653 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3656 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3658 def GetSubMeshElementType(self, Shape):
3660 Return type of elements on given shape
3663 Shape: a geom object (sub-shape).
3664 *Shape* must be a sub-shape of a ShapeToMesh()
3667 :class:`SMESH.ElementType`
3670 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3671 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3674 return self.mesh.GetSubMeshElementType(ShapeID)
3678 Get the mesh description
3684 return self.mesh.Dump()
3687 # Get the information about nodes and elements of a mesh by its IDs:
3688 # -----------------------------------------------------------
3690 def GetNodeXYZ(self, id):
3692 Get XYZ coordinates of a node.
3693 If there is no node for the given ID - return an empty list
3696 list of float values
3699 return self.mesh.GetNodeXYZ(id)
3701 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3703 Return list of IDs of inverse elements for the given node.
3704 If there is no node for the given ID - return an empty list
3708 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3711 list of integer values
3714 return self.mesh.GetNodeInverseElements(id,elemType)
3716 def GetNodePosition(self,NodeID):
3718 Return the position of a node on the shape
3721 :class:`SMESH.NodePosition`
3724 return self.mesh.GetNodePosition(NodeID)
3726 def GetElementPosition(self,ElemID):
3728 Return the position of an element on the shape
3731 :class:`SMESH.ElementPosition`
3734 return self.mesh.GetElementPosition(ElemID)
3736 def GetShapeID(self, id):
3738 Return the ID of the shape, on which the given node was generated.
3741 an integer value > 0 or -1 if there is no node for the given
3742 ID or the node is not assigned to any geometry
3745 return self.mesh.GetShapeID(id)
3747 def GetShapeIDForElem(self,id):
3749 Return the ID of the shape, on which the given element was generated.
3752 an integer value > 0 or -1 if there is no element for the given
3753 ID or the element is not assigned to any geometry
3756 return self.mesh.GetShapeIDForElem(id)
3758 def GetElemNbNodes(self, id):
3760 Return the number of nodes of the given element
3763 an integer value > 0 or -1 if there is no element for the given ID
3766 return self.mesh.GetElemNbNodes(id)
3768 def GetElemNode(self, id, index):
3770 Return the node ID the given (zero based) index for the given element.
3772 * If there is no element for the given ID - return -1.
3773 * If there is no node for the given index - return -2.
3776 id (int): element ID
3777 index (int): node index within the element
3780 an integer value (ID)
3783 :meth:`GetElemNodes`
3786 return self.mesh.GetElemNode(id, index)
3788 def GetElemNodes(self, id):
3790 Return the IDs of nodes of the given element
3793 a list of integer values
3796 return self.mesh.GetElemNodes(id)
3798 def IsMediumNode(self, elementID, nodeID):
3800 Return true if the given node is the medium node in the given quadratic element
3803 return self.mesh.IsMediumNode(elementID, nodeID)
3805 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3807 Return true if the given node is the medium node in one of quadratic elements
3810 nodeID: ID of the node
3811 elementType: the type of elements to check a state of the node, either of
3812 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3815 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3817 def ElemNbEdges(self, id):
3819 Return the number of edges for the given element
3822 return self.mesh.ElemNbEdges(id)
3824 def ElemNbFaces(self, id):
3826 Return the number of faces for the given element
3829 return self.mesh.ElemNbFaces(id)
3831 def GetElemFaceNodes(self,elemId, faceIndex):
3833 Return nodes of given face (counted from zero) for given volumic element.
3836 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3838 def GetFaceNormal(self, faceId, normalized=False):
3840 Return three components of normal of given mesh face
3841 (or an empty array in KO case)
3844 return self.mesh.GetFaceNormal(faceId,normalized)
3846 def FindElementByNodes(self, nodes):
3848 Return an element based on all given nodes.
3851 return self.mesh.FindElementByNodes(nodes)
3853 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3855 Return elements including all given nodes.
3858 return self.mesh.GetElementsByNodes( nodes, elemType )
3860 def IsPoly(self, id):
3862 Return true if the given element is a polygon
3865 return self.mesh.IsPoly(id)
3867 def IsQuadratic(self, id):
3869 Return true if the given element is quadratic
3872 return self.mesh.IsQuadratic(id)
3874 def GetBallDiameter(self, id):
3876 Return diameter of a ball discrete element or zero in case of an invalid *id*
3879 return self.mesh.GetBallDiameter(id)
3881 def BaryCenter(self, id):
3883 Return XYZ coordinates of the barycenter of the given element.
3884 If there is no element for the given ID - return an empty list
3887 a list of three double values
3890 :meth:`smeshBuilder.GetGravityCenter`
3893 return self.mesh.BaryCenter(id)
3895 def GetIdsFromFilter(self, filter, meshParts=[] ):
3897 Pass mesh elements through the given filter and return IDs of fitting elements
3900 filter: :class:`SMESH.Filter`
3901 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3907 :meth:`SMESH.Filter.GetIDs`
3908 :meth:`SMESH.Filter.GetElementsIdFromParts`
3911 filter.SetMesh( self.mesh )
3914 if isinstance( meshParts, Mesh ):
3915 filter.SetMesh( meshParts.GetMesh() )
3916 return theFilter.GetIDs()
3917 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3918 meshParts = [ meshParts ]
3919 return filter.GetElementsIdFromParts( meshParts )
3921 return filter.GetIDs()
3923 # Get mesh measurements information:
3924 # ------------------------------------
3926 def GetFreeBorders(self):
3928 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3929 Return a list of special structures (borders).
3932 a list of :class:`SMESH.FreeEdges.Border`
3935 aFilterMgr = self.smeshpyD.CreateFilterManager()
3936 aPredicate = aFilterMgr.CreateFreeEdges()
3937 aPredicate.SetMesh(self.mesh)
3938 aBorders = aPredicate.GetBorders()
3939 aFilterMgr.UnRegister()
3942 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3944 Get minimum distance between two nodes, elements or distance to the origin
3947 id1: first node/element id
3948 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3949 isElem1: *True* if *id1* is element id, *False* if it is node id
3950 isElem2: *True* if *id2* is element id, *False* if it is node id
3953 minimum distance value
3955 :meth:`GetMinDistance`
3958 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3959 return aMeasure.value
3961 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3963 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3966 id1: first node/element id
3967 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3968 isElem1: *True* if *id1* is element id, *False* if it is node id
3969 isElem2: *True* if *id2* is element id, *False* if it is node id
3972 :class:`SMESH.Measure` structure
3978 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3980 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3983 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3985 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3990 aMeasurements = self.smeshpyD.CreateMeasurements()
3991 aMeasure = aMeasurements.MinDistance(id1, id2)
3992 genObjUnRegister([aMeasurements,id1, id2])
3995 def BoundingBox(self, objects=None, isElem=False):
3997 Get bounding box of the specified object(s)
4000 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4001 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4002 *False* specifies that *objects* are nodes
4005 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4008 :meth:`GetBoundingBox()`
4011 result = self.GetBoundingBox(objects, isElem)
4015 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4018 def GetBoundingBox(self, objects=None, isElem=False):
4020 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4023 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4024 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4025 False means that *objects* are nodes
4028 :class:`SMESH.Measure` structure
4031 :meth:`BoundingBox()`
4035 objects = [self.mesh]
4036 elif isinstance(objects, tuple):
4037 objects = list(objects)
4038 if not isinstance(objects, list):
4040 if len(objects) > 0 and isinstance(objects[0], int):
4043 unRegister = genObjUnRegister()
4045 if isinstance(o, Mesh):
4046 srclist.append(o.mesh)
4047 elif hasattr(o, "_narrow"):
4048 src = o._narrow(SMESH.SMESH_IDSource)
4049 if src: srclist.append(src)
4051 elif isinstance(o, list):
4053 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4055 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4056 unRegister.set( srclist[-1] )
4059 aMeasurements = self.smeshpyD.CreateMeasurements()
4060 unRegister.set( aMeasurements )
4061 aMeasure = aMeasurements.BoundingBox(srclist)
4064 # Mesh edition (SMESH_MeshEditor functionality):
4065 # ---------------------------------------------
4067 def RemoveElements(self, IDsOfElements):
4069 Remove the elements from the mesh by ids
4072 IDsOfElements: is a list of ids of elements to remove
4078 This operation can create gaps in numeration of elements.
4079 Call :meth:`RenumberElements` to remove the gaps.
4082 return self.editor.RemoveElements(IDsOfElements)
4084 def RemoveNodes(self, IDsOfNodes):
4086 Remove nodes from mesh by ids
4089 IDsOfNodes: is a list of ids of nodes to remove
4095 This operation can create gaps in numeration of nodes.
4096 Call :meth:`RenumberElements` to remove the gaps.
4099 return self.editor.RemoveNodes(IDsOfNodes)
4101 def RemoveNodeWithReconnection(self, nodeID ):
4103 Remove a node along with changing surrounding faces to cover a hole.
4106 nodeID: ID of node to remove
4109 return self.editor.RemoveNodeWithReconnection( nodeID )
4111 def RemoveOrphanNodes(self):
4113 Remove all orphan (free) nodes from mesh
4116 number of the removed nodes
4119 This operation can create gaps in numeration of nodes.
4120 Call :meth:`RenumberElements` to remove the gaps.
4123 return self.editor.RemoveOrphanNodes()
4125 def AddNode(self, x, y, z):
4127 Add a node to the mesh by coordinates
4133 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4134 if hasVars: self.mesh.SetParameters(Parameters)
4135 return self.editor.AddNode( x, y, z)
4137 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4139 Create a 0D element on a node with given number.
4142 IDOfNode: the ID of node for creation of the element.
4143 DuplicateElements: to add one more 0D element to a node or not
4146 ID of the new 0D element
4149 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4151 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4153 Create 0D elements on all nodes of the given elements except those
4154 nodes on which a 0D element already exists.
4157 theObject: an object on whose nodes 0D elements will be created.
4158 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4159 theGroupName: optional name of a group to add 0D elements created
4160 and/or found on nodes of *theObject*.
4161 DuplicateElements: to add one more 0D element to a node or not
4164 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4165 IDs of new and/or found 0D elements. IDs of 0D elements
4166 can be retrieved from the returned object by
4167 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4170 unRegister = genObjUnRegister()
4171 if isinstance( theObject, Mesh ):
4172 theObject = theObject.GetMesh()
4173 elif isinstance( theObject, list ):
4174 theObject = self.GetIDSource( theObject, SMESH.ALL )
4175 unRegister.set( theObject )
4176 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4178 def AddBall(self, IDOfNode, diameter):
4180 Create a ball element on a node with given ID.
4183 IDOfNode: the ID of node for creation of the element.
4184 diameter: the bal diameter.
4187 ID of the new ball element
4190 return self.editor.AddBall( IDOfNode, diameter )
4192 def AddEdge(self, IDsOfNodes):
4194 Create a linear or quadratic edge (this is determined
4195 by the number of given nodes).
4198 IDsOfNodes: list of node IDs for creation of the element.
4199 The order of nodes in this list should correspond to
4200 the :ref:`connectivity convention <connectivity_page>`.
4206 return self.editor.AddEdge(IDsOfNodes)
4208 def AddFace(self, IDsOfNodes):
4210 Create a linear or quadratic face (this is determined
4211 by the number of given nodes).
4214 IDsOfNodes: list of node IDs for creation of the element.
4215 The order of nodes in this list should correspond to
4216 the :ref:`connectivity convention <connectivity_page>`.
4222 return self.editor.AddFace(IDsOfNodes)
4224 def AddPolygonalFace(self, IdsOfNodes):
4226 Add a polygonal face defined by a list of node IDs
4229 IdsOfNodes: the list of node IDs for creation of the element.
4235 return self.editor.AddPolygonalFace(IdsOfNodes)
4237 def AddQuadPolygonalFace(self, IdsOfNodes):
4239 Add a quadratic polygonal face defined by a list of node IDs
4242 IdsOfNodes: the list of node IDs for creation of the element;
4243 corner nodes follow first.
4249 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4251 def AddVolume(self, IDsOfNodes):
4253 Create both simple and quadratic volume (this is determined
4254 by the number of given nodes).
4257 IDsOfNodes: list of node IDs for creation of the element.
4258 The order of nodes in this list should correspond to
4259 the :ref:`connectivity convention <connectivity_page>`.
4262 ID of the new volumic element
4265 return self.editor.AddVolume(IDsOfNodes)
4267 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4269 Create a volume of many faces, giving nodes for each face.
4272 IdsOfNodes: list of node IDs for volume creation, face by face.
4273 Quantities: list of integer values, Quantities[i]
4274 gives the quantity of nodes in face number i.
4277 ID of the new volumic element
4280 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4282 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4284 Create a volume of many faces, giving the IDs of the existing faces.
4287 The created volume will refer only to the nodes
4288 of the given faces, not to the faces themselves.
4291 IdsOfFaces: the list of face IDs for volume creation.
4294 ID of the new volumic element
4297 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4300 def SetNodeOnVertex(self, NodeID, Vertex):
4302 Bind a node to a vertex
4306 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4309 True if succeed else raises an exception
4312 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4313 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4317 self.editor.SetNodeOnVertex(NodeID, VertexID)
4318 except SALOME.SALOME_Exception as inst:
4319 raise ValueError(inst.details.text)
4323 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4325 Store the node position on an edge
4329 Edge: an edge (GEOM.GEOM_Object) or edge ID
4330 paramOnEdge: a parameter on the edge where the node is located
4333 True if succeed else raises an exception
4336 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4337 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4341 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4342 except SALOME.SALOME_Exception as inst:
4343 raise ValueError(inst.details.text)
4346 def SetNodeOnFace(self, NodeID, Face, u, v):
4348 Store node position on a face
4352 Face: a face (GEOM.GEOM_Object) or face ID
4353 u: U parameter on the face where the node is located
4354 v: V parameter on the face where the node is located
4357 True if succeed else raises an exception
4360 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4361 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4365 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4366 except SALOME.SALOME_Exception as inst:
4367 raise ValueError(inst.details.text)
4370 def SetNodeInVolume(self, NodeID, Solid):
4372 Bind a node to a solid
4376 Solid: a solid (GEOM.GEOM_Object) or solid ID
4379 True if succeed else raises an exception
4382 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4383 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4387 self.editor.SetNodeInVolume(NodeID, SolidID)
4388 except SALOME.SALOME_Exception as inst:
4389 raise ValueError(inst.details.text)
4392 def SetMeshElementOnShape(self, ElementID, Shape):
4394 Bind an element to a shape
4397 ElementID: an element ID
4398 Shape: a shape (GEOM.GEOM_Object) or shape ID
4401 True if succeed else raises an exception
4404 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4405 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4409 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4410 except SALOME.SALOME_Exception as inst:
4411 raise ValueError(inst.details.text)
4415 def MoveNode(self, NodeID, x, y, z):
4417 Move the node with the given id
4420 NodeID: the id of the node
4421 x: a new X coordinate
4422 y: a new Y coordinate
4423 z: a new Z coordinate
4426 True if succeed else False
4429 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4430 if hasVars: self.mesh.SetParameters(Parameters)
4431 return self.editor.MoveNode(NodeID, x, y, z)
4433 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4435 Find the node closest to a point and moves it to a point location
4438 x: the X coordinate of a point
4439 y: the Y coordinate of a point
4440 z: the Z coordinate of a point
4441 NodeID: if specified (>0), the node with this ID is moved,
4442 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4445 the ID of a moved node
4448 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4449 if hasVars: self.mesh.SetParameters(Parameters)
4450 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4452 def FindNodeClosestTo(self, x, y, z):
4454 Find the node closest to a point
4457 x: the X coordinate of a point
4458 y: the Y coordinate of a point
4459 z: the Z coordinate of a point
4465 return self.editor.FindNodeClosestTo(x, y, z)
4467 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4469 Find the elements where a point lays IN or ON
4472 x,y,z (float): coordinates of the point
4473 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4474 means elements of any type excluding nodes, discrete and 0D elements.
4475 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4478 list of IDs of found elements
4481 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4483 return self.editor.FindElementsByPoint(x, y, z, elementType)
4485 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4487 Project a point to a mesh object.
4488 Return ID of an element of given type where the given point is projected
4489 and coordinates of the projection point.
4490 In the case if nothing found, return -1 and []
4492 if isinstance( meshObject, Mesh ):
4493 meshObject = meshObject.GetMesh()
4495 meshObject = self.GetMesh()
4496 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4498 def GetPointState(self, x, y, z):
4500 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4501 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4502 UNKNOWN state means that either mesh is wrong or the analysis fails.
4505 return self.editor.GetPointState(x, y, z)
4507 def IsManifold(self):
4509 Check if a 2D mesh is manifold
4512 return self.editor.IsManifold()
4514 def IsCoherentOrientation2D(self):
4516 Check if orientation of 2D elements is coherent
4519 return self.editor.IsCoherentOrientation2D()
4521 def Get1DBranches( self, edges, startNode = 0 ):
4523 Partition given 1D elements into groups of contiguous edges.
4524 A node where number of meeting edges != 2 is a group end.
4525 An optional startNode is used to orient groups it belongs to.
4528 A list of edge groups and a list of corresponding node groups,
4529 where the group is a list of IDs of edges or nodes, like follows
4530 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4531 If a group is closed, the first and last nodes of the group are same.
4533 if isinstance( edges, Mesh ):
4534 edges = edges.GetMesh()
4535 unRegister = genObjUnRegister()
4536 if isinstance( edges, list ):
4537 edges = self.GetIDSource( edges, SMESH.EDGE )
4538 unRegister.set( edges )
4539 return self.editor.Get1DBranches( edges, startNode )
4541 def FindSharpEdges( self, angle, addExisting=False ):
4543 Return sharp edges of faces and non-manifold ones.
4544 Optionally add existing edges.
4547 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4548 addExisting: to return existing edges (1D elements) as well
4551 list of FaceEdge structures
4553 angle = ParseParameters( angle )[0]
4554 return self.editor.FindSharpEdges( angle, addExisting )
4556 def MeshToPassThroughAPoint(self, x, y, z):
4558 Find the node closest to a point and moves it to a point location
4561 x: the X coordinate of a point
4562 y: the Y coordinate of a point
4563 z: the Z coordinate of a point
4566 the ID of a moved node
4569 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4571 def InverseDiag(self, NodeID1, NodeID2):
4573 Replace two neighbour triangles sharing Node1-Node2 link
4574 with the triangles built on the same 4 nodes but having other common link.
4577 NodeID1: the ID of the first node
4578 NodeID2: the ID of the second node
4581 False if proper faces were not found
4583 return self.editor.InverseDiag(NodeID1, NodeID2)
4585 def DeleteDiag(self, NodeID1, NodeID2):
4587 Replace two neighbour triangles sharing *Node1-Node2* link
4588 with a quadrangle built on the same 4 nodes.
4591 NodeID1: ID of the first node
4592 NodeID2: ID of the second node
4595 False if proper faces were not found
4598 This operation can create gaps in numeration of elements.
4599 Call :meth:`RenumberElements` to remove the gaps.
4602 return self.editor.DeleteDiag(NodeID1, NodeID2)
4604 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4606 Replace each triangle bound by Node1-Node2 segment with
4607 two triangles by connecting a node made on the link with a node
4608 opposite to the link.
4611 Node1: ID of the first node
4612 Node2: ID of the second node
4613 position: location [0,1] of the new node on the segment
4615 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4617 def AddNodeOnFace(self, face, x, y, z):
4619 Split a face into triangles by adding a new node onto the face
4620 and connecting the new node with face nodes
4623 face: ID of the face
4624 x,y,z: coordinates of the new node
4626 return self.editor.AddNodeOnFace(face, x, y, z)
4628 def Reorient(self, IDsOfElements=None):
4630 Reorient elements by ids
4633 IDsOfElements: if undefined reorients all mesh elements
4636 True if succeed else False
4639 if IDsOfElements == None:
4640 IDsOfElements = self.GetElementsId()
4641 return self.editor.Reorient(IDsOfElements)
4643 def ReorientObject(self, theObject):
4645 Reorient all elements of the object
4648 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4651 True if succeed else False
4654 if ( isinstance( theObject, Mesh )):
4655 theObject = theObject.GetMesh()
4656 return self.editor.ReorientObject(theObject)
4658 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4660 Reorient faces contained in *the2DObject*.
4663 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4664 theDirection: a desired direction of normal of *theFace*.
4665 It can be either a GEOM vector or a list of coordinates [x,y,z].
4666 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4667 compared with theDirection. It can be either ID of face or a point
4668 by which the face will be found. The point can be given as either
4669 a GEOM vertex or a list of point coordinates.
4672 number of reoriented faces
4675 unRegister = genObjUnRegister()
4677 if isinstance( the2DObject, Mesh ):
4678 the2DObject = the2DObject.GetMesh()
4679 if isinstance( the2DObject, list ):
4680 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4681 unRegister.set( the2DObject )
4682 # check theDirection
4683 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4684 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4685 if isinstance( theDirection, list ):
4686 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4687 # prepare theFace and thePoint
4688 theFace = theFaceOrPoint
4689 thePoint = PointStruct(0,0,0)
4690 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4691 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4693 if isinstance( theFaceOrPoint, list ):
4694 thePoint = PointStruct( *theFaceOrPoint )
4696 if isinstance( theFaceOrPoint, PointStruct ):
4697 thePoint = theFaceOrPoint
4699 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4701 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4703 Reorient faces contained in a list of *objectFaces*
4704 equally to faces contained in a list of *referenceFaces*.
4707 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4708 referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference.
4711 number of reoriented faces.
4713 if not isinstance( objectFaces, list ):
4714 objectFaces = [ objectFaces ]
4715 for i,obj2D in enumerate( objectFaces ):
4716 if isinstance( obj2D, Mesh ):
4717 objectFaces[i] = obj2D.GetMesh()
4718 if not isinstance( referenceFaces, list ):
4719 referenceFaces = [ referenceFaces ]
4721 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4724 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4726 Reorient faces according to adjacent volumes.
4729 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4730 either IDs of faces or face groups.
4731 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4732 theOutsideNormal: to orient faces to have their normals
4733 pointing either *outside* or *inside* the adjacent volumes.
4736 number of reoriented faces.
4739 unRegister = genObjUnRegister()
4741 if not isinstance( the2DObject, list ):
4742 the2DObject = [ the2DObject ]
4743 elif the2DObject and isinstance( the2DObject[0], int ):
4744 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4745 unRegister.set( the2DObject )
4746 the2DObject = [ the2DObject ]
4747 for i,obj2D in enumerate( the2DObject ):
4748 if isinstance( obj2D, Mesh ):
4749 the2DObject[i] = obj2D.GetMesh()
4750 if isinstance( obj2D, list ):
4751 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4752 unRegister.set( the2DObject[i] )
4754 if isinstance( the3DObject, Mesh ):
4755 the3DObject = the3DObject.GetMesh()
4756 if isinstance( the3DObject, list ):
4757 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4758 unRegister.set( the3DObject )
4759 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4761 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4763 Fuse the neighbouring triangles into quadrangles.
4766 IDsOfElements: The triangles to be fused.
4767 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4768 applied to possible quadrangles to choose a neighbour to fuse with.
4769 Note that not all items of :class:`SMESH.FunctorType` corresponds
4770 to numerical functors.
4771 MaxAngle: is the maximum angle between element normals at which the fusion
4772 is still performed; theMaxAngle is measured in radians.
4773 Also it could be a name of variable which defines angle in degrees.
4776 True in case of success, False otherwise.
4779 This operation can create gaps in numeration of elements.
4780 Call :meth:`RenumberElements` to remove the gaps.
4783 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4784 self.mesh.SetParameters(Parameters)
4785 if not IDsOfElements:
4786 IDsOfElements = self.GetElementsId()
4787 Functor = self.smeshpyD.GetFunctor(theCriterion)
4788 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4790 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4792 Fuse the neighbouring triangles of the object into quadrangles
4795 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4796 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4797 applied to possible quadrangles to choose a neighbour to fuse with.
4798 Note that not all items of :class:`SMESH.FunctorType` corresponds
4799 to numerical functors.
4800 MaxAngle: a max angle between element normals at which the fusion
4801 is still performed; theMaxAngle is measured in radians.
4804 True in case of success, False otherwise.
4807 This operation can create gaps in numeration of elements.
4808 Call :meth:`RenumberElements` to remove the gaps.
4811 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4812 self.mesh.SetParameters(Parameters)
4813 if isinstance( theObject, Mesh ):
4814 theObject = theObject.GetMesh()
4815 Functor = self.smeshpyD.GetFunctor(theCriterion)
4816 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4818 def QuadToTri (self, IDsOfElements, theCriterion = None):
4820 Split quadrangles into triangles.
4823 IDsOfElements: the faces to be splitted.
4824 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4825 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4826 value, then quadrangles will be split by the smallest diagonal.
4827 Note that not all items of :class:`SMESH.FunctorType` corresponds
4828 to numerical functors.
4831 True in case of success, False otherwise.
4834 This operation can create gaps in numeration of elements.
4835 Call :meth:`RenumberElements` to remove the gaps.
4837 if IDsOfElements == []:
4838 IDsOfElements = self.GetElementsId()
4839 if theCriterion is None:
4840 theCriterion = FT_MaxElementLength2D
4841 Functor = self.smeshpyD.GetFunctor(theCriterion)
4842 return self.editor.QuadToTri(IDsOfElements, Functor)
4844 def QuadToTriObject (self, theObject, theCriterion = None):
4846 Split quadrangles into triangles.
4849 theObject: the object from which the list of elements is taken,
4850 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4851 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4852 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4853 value, then quadrangles will be split by the smallest diagonal.
4854 Note that not all items of :class:`SMESH.FunctorType` corresponds
4855 to numerical functors.
4858 True in case of success, False otherwise.
4861 This operation can create gaps in numeration of elements.
4862 Call :meth:`RenumberElements` to remove the gaps.
4864 if ( isinstance( theObject, Mesh )):
4865 theObject = theObject.GetMesh()
4866 if theCriterion is None:
4867 theCriterion = FT_MaxElementLength2D
4868 Functor = self.smeshpyD.GetFunctor(theCriterion)
4869 return self.editor.QuadToTriObject(theObject, Functor)
4871 def QuadTo4Tri (self, theElements=[]):
4873 Split each of given quadrangles into 4 triangles. A node is added at the center of
4877 theElements: the faces to be splitted. This can be either
4878 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4879 or a list of face IDs. By default all quadrangles are split
4882 This operation can create gaps in numeration of elements.
4883 Call :meth:`RenumberElements` to remove the gaps.
4885 unRegister = genObjUnRegister()
4886 if isinstance( theElements, Mesh ):
4887 theElements = theElements.mesh
4888 elif not theElements:
4889 theElements = self.mesh
4890 elif isinstance( theElements, list ):
4891 theElements = self.GetIDSource( theElements, SMESH.FACE )
4892 unRegister.set( theElements )
4893 return self.editor.QuadTo4Tri( theElements )
4895 def SplitQuad (self, IDsOfElements, Diag13):
4897 Split quadrangles into triangles.
4900 IDsOfElements: the faces to be splitted
4901 Diag13 (boolean): is used to choose a diagonal for splitting.
4904 True in case of success, False otherwise.
4907 This operation can create gaps in numeration of elements.
4908 Call :meth:`RenumberElements` to remove the gaps.
4910 if IDsOfElements == []:
4911 IDsOfElements = self.GetElementsId()
4912 return self.editor.SplitQuad(IDsOfElements, Diag13)
4914 def SplitQuadObject (self, theObject, Diag13):
4916 Split quadrangles into triangles.
4919 theObject: the object from which the list of elements is taken,
4920 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4921 Diag13 (boolean): is used to choose a diagonal for splitting.
4924 True in case of success, False otherwise.
4927 This operation can create gaps in numeration of elements.
4928 Call :meth:`RenumberElements` to remove the gaps.
4930 if ( isinstance( theObject, Mesh )):
4931 theObject = theObject.GetMesh()
4932 return self.editor.SplitQuadObject(theObject, Diag13)
4934 def BestSplit (self, IDOfQuad, theCriterion):
4936 Find a better splitting of the given quadrangle.
4939 IDOfQuad: the ID of the quadrangle to be splitted.
4940 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4941 choose a diagonal for splitting.
4942 Note that not all items of :class:`SMESH.FunctorType` corresponds
4943 to numerical functors.
4946 * 1 if 1-3 diagonal is better,
4947 * 2 if 2-4 diagonal is better,
4948 * 0 if error occurs.
4951 This operation can create gaps in numeration of elements.
4952 Call :meth:`RenumberElements` to remove the gaps.
4954 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4956 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4958 Split volumic elements into tetrahedrons
4961 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4962 method: flags passing splitting method:
4963 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4964 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4967 This operation can create gaps in numeration of elements.
4968 Call :meth:`RenumberElements` to remove the gaps.
4970 unRegister = genObjUnRegister()
4971 if isinstance( elems, Mesh ):
4972 elems = elems.GetMesh()
4973 if ( isinstance( elems, list )):
4974 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4975 unRegister.set( elems )
4976 self.editor.SplitVolumesIntoTetra(elems, method)
4979 def SplitBiQuadraticIntoLinear(self, elems=None):
4981 Split bi-quadratic elements into linear ones without creation of additional nodes:
4983 - bi-quadratic triangle will be split into 3 linear quadrangles;
4984 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4985 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4987 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4988 will be split in order to keep the mesh conformal.
4991 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4992 if None (default), all bi-quadratic elements will be split
4995 This operation can create gaps in numeration of elements.
4996 Call :meth:`RenumberElements` to remove the gaps.
4998 unRegister = genObjUnRegister()
4999 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5000 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5001 unRegister.set( elems )
5003 elems = [ self.GetMesh() ]
5004 if isinstance( elems, Mesh ):
5005 elems = [ elems.GetMesh() ]
5006 if not isinstance( elems, list ):
5008 self.editor.SplitBiQuadraticIntoLinear( elems )
5010 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5011 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5013 Split hexahedra into prisms
5016 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5017 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5018 gives a normal vector defining facets to split into triangles.
5019 *startHexPoint* can be either a triple of coordinates or a vertex.
5020 facetNormal: a normal to a facet to split into triangles of a
5021 hexahedron found by *startHexPoint*.
5022 *facetNormal* can be either a triple of coordinates or an edge.
5023 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5024 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5025 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5026 to *startHexPoint* are split, else *startHexPoint*
5027 is used to find the facet to split in all domains present in *elems*.
5030 This operation can create gaps in numeration of elements.
5031 Call :meth:`RenumberElements` to remove the gaps.
5034 unRegister = genObjUnRegister()
5035 if isinstance( elems, Mesh ):
5036 elems = elems.GetMesh()
5037 if ( isinstance( elems, list )):
5038 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5039 unRegister.set( elems )
5042 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5043 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5044 elif isinstance( startHexPoint, list ):
5045 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5048 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5049 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5050 elif isinstance( facetNormal, list ):
5051 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5054 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5056 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5058 def SplitQuadsNearTriangularFacets(self):
5060 Split quadrangle faces near triangular facets of volumes
5063 This operation can create gaps in numeration of elements.
5064 Call :meth:`RenumberElements` to remove the gaps.
5066 faces_array = self.GetElementsByType(SMESH.FACE)
5067 for face_id in faces_array:
5068 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5069 quad_nodes = self.mesh.GetElemNodes(face_id)
5070 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5071 isVolumeFound = False
5072 for node1_elem in node1_elems:
5073 if not isVolumeFound:
5074 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5075 nb_nodes = self.GetElemNbNodes(node1_elem)
5076 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5077 volume_elem = node1_elem
5078 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5079 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5080 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5081 isVolumeFound = True
5082 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5083 self.SplitQuad([face_id], False) # diagonal 2-4
5084 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5085 isVolumeFound = True
5086 self.SplitQuad([face_id], True) # diagonal 1-3
5087 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5088 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5089 isVolumeFound = True
5090 self.SplitQuad([face_id], True) # diagonal 1-3
5092 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5094 Split hexahedrons into tetrahedrons.
5096 This operation uses :doc:`pattern_mapping` functionality for splitting.
5099 theObject: the object from which the list of hexahedrons is taken;
5100 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5101 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5102 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5103 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5104 key-point will be mapped into *theNode001*-th node of each volume.
5105 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5108 True in case of success, False otherwise.
5111 This operation can create gaps in numeration of elements.
5112 Call :meth:`RenumberElements` to remove the gaps.
5120 # (0,0,1) 4.---------.7 * |
5127 # (0,0,0) 0.---------.3
5128 pattern_tetra = "!!! Nb of points: \n 8 \n\
5138 !!! Indices of points of 6 tetras: \n\
5146 pattern = self.smeshpyD.GetPattern()
5147 isDone = pattern.LoadFromFile(pattern_tetra)
5149 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5152 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5153 isDone = pattern.MakeMesh(self.mesh, False, False)
5154 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5156 # split quafrangle faces near triangular facets of volumes
5157 self.SplitQuadsNearTriangularFacets()
5161 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5163 Split hexahedrons into prisms.
5165 Uses the :doc:`pattern_mapping` functionality for splitting.
5168 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5169 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5170 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5171 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5172 will be mapped into the *theNode001* -th node of each volume.
5173 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5176 True in case of success, False otherwise.
5179 This operation can create gaps in numeration of elements.
5180 Call :meth:`RenumberElements` to remove the gaps.
5182 # Pattern: 5.---------.6
5187 # (0,0,1) 4.---------.7 |
5194 # (0,0,0) 0.---------.3
5195 pattern_prism = "!!! Nb of points: \n 8 \n\
5205 !!! Indices of points of 2 prisms: \n\
5209 pattern = self.smeshpyD.GetPattern()
5210 isDone = pattern.LoadFromFile(pattern_prism)
5212 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5215 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5216 isDone = pattern.MakeMesh(self.mesh, False, False)
5217 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5219 # Split quafrangle faces near triangular facets of volumes
5220 self.SplitQuadsNearTriangularFacets()
5224 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5225 MaxNbOfIterations, MaxAspectRatio, Method):
5230 IDsOfElements: the list if ids of elements to smooth
5231 IDsOfFixedNodes: the list of ids of fixed nodes.
5232 Note that nodes built on edges and boundary nodes are always fixed.
5233 MaxNbOfIterations: the maximum number of iterations
5234 MaxAspectRatio: varies in range [1.0, inf]
5235 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5236 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5239 True in case of success, False otherwise.
5242 if IDsOfElements == []:
5243 IDsOfElements = self.GetElementsId()
5244 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5245 self.mesh.SetParameters(Parameters)
5246 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5247 MaxNbOfIterations, MaxAspectRatio, Method)
5249 def SmoothObject(self, theObject, IDsOfFixedNodes,
5250 MaxNbOfIterations, MaxAspectRatio, Method):
5252 Smooth elements which belong to the given object
5255 theObject: the object to smooth
5256 IDsOfFixedNodes: the list of ids of fixed nodes.
5257 Note that nodes built on edges and boundary nodes are always fixed.
5258 MaxNbOfIterations: the maximum number of iterations
5259 MaxAspectRatio: varies in range [1.0, inf]
5260 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5261 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5264 True in case of success, False otherwise.
5267 if ( isinstance( theObject, Mesh )):
5268 theObject = theObject.GetMesh()
5269 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5270 MaxNbOfIterations, MaxAspectRatio, Method)
5272 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5273 MaxNbOfIterations, MaxAspectRatio, Method):
5275 Parametrically smooth the given elements
5278 IDsOfElements: the list if ids of elements to smooth
5279 IDsOfFixedNodes: the list of ids of fixed nodes.
5280 Note that nodes built on edges and boundary nodes are always fixed.
5281 MaxNbOfIterations: the maximum number of iterations
5282 MaxAspectRatio: varies in range [1.0, inf]
5283 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5284 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5287 True in case of success, False otherwise.
5290 if IDsOfElements == []:
5291 IDsOfElements = self.GetElementsId()
5292 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5293 self.mesh.SetParameters(Parameters)
5294 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5295 MaxNbOfIterations, MaxAspectRatio, Method)
5297 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5298 MaxNbOfIterations, MaxAspectRatio, Method):
5300 Parametrically smooth the elements which belong to the given object
5303 theObject: the object to smooth
5304 IDsOfFixedNodes: the list of ids of fixed nodes.
5305 Note that nodes built on edges and boundary nodes are always fixed.
5306 MaxNbOfIterations: the maximum number of iterations
5307 MaxAspectRatio: varies in range [1.0, inf]
5308 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5309 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5312 True in case of success, False otherwise.
5315 if ( isinstance( theObject, Mesh )):
5316 theObject = theObject.GetMesh()
5317 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5318 MaxNbOfIterations, MaxAspectRatio, Method)
5320 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5322 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5323 them with quadratic with the same id.
5326 theForce3d: method of new node creation:
5328 * False - the medium node lies at the geometrical entity from which the mesh element is built
5329 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5330 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5331 theToBiQuad: If True, converts the mesh to bi-quadratic
5334 :class:`SMESH.ComputeError` which can hold a warning
5337 If *theSubMesh* is provided, the mesh can become non-conformal
5340 This operation can create gaps in numeration of nodes or elements.
5341 Call :meth:`RenumberElements` to remove the gaps.
5344 if isinstance( theSubMesh, Mesh ):
5345 theSubMesh = theSubMesh.mesh
5347 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5350 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5352 self.editor.ConvertToQuadratic(theForce3d)
5353 error = self.editor.GetLastError()
5354 if error and error.comment:
5355 print(error.comment)
5358 def ConvertFromQuadratic(self, theSubMesh=None):
5360 Convert the mesh from quadratic to ordinary,
5361 deletes old quadratic elements,
5362 replacing them with ordinary mesh elements with the same id.
5365 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5368 If *theSubMesh* is provided, the mesh can become non-conformal
5371 This operation can create gaps in numeration of nodes or elements.
5372 Call :meth:`RenumberElements` to remove the gaps.
5376 self.editor.ConvertFromQuadraticObject(theSubMesh)
5378 return self.editor.ConvertFromQuadratic()
5380 def Make2DMeshFrom3D(self):
5382 Create 2D mesh as skin on boundary faces of a 3D mesh
5385 True if operation has been completed successfully, False otherwise
5388 return self.editor.Make2DMeshFrom3D()
5390 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5391 toCopyElements=False, toCopyExistingBondary=False):
5393 Create missing boundary elements
5396 elements: elements whose boundary is to be checked:
5397 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5398 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5399 dimension: defines type of boundary elements to create, either of
5400 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5401 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5402 groupName: a name of group to store created boundary elements in,
5403 "" means not to create the group
5404 meshName: a name of new mesh to store created boundary elements in,
5405 "" means not to create the new mesh
5406 toCopyElements: if True, the checked elements will be copied into
5407 the new mesh else only boundary elements will be copied into the new mesh
5408 toCopyExistingBondary: if True, not only new but also pre-existing
5409 boundary elements will be copied into the new mesh
5412 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5415 unRegister = genObjUnRegister()
5416 if isinstance( elements, Mesh ):
5417 elements = elements.GetMesh()
5418 if ( isinstance( elements, list )):
5419 elemType = SMESH.ALL
5420 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5421 elements = self.editor.MakeIDSource(elements, elemType)
5422 unRegister.set( elements )
5423 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5424 toCopyElements,toCopyExistingBondary)
5425 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5428 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5429 toCopyAll=False, groups=[]):
5431 Create missing boundary elements around either the whole mesh or
5435 dimension: defines type of boundary elements to create, either of
5436 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5437 groupName: a name of group to store all boundary elements in,
5438 "" means not to create the group
5439 meshName: a name of a new mesh, which is a copy of the initial
5440 mesh + created boundary elements; "" means not to create the new mesh
5441 toCopyAll: if True, the whole initial mesh will be copied into
5442 the new mesh else only boundary elements will be copied into the new mesh
5443 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5446 tuple( long, mesh, group )
5447 - long - number of added boundary elements
5448 - mesh - the :class:`Mesh` where elements were added to
5449 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5452 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5454 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5455 return nb, mesh, group
5457 def RenumberNodes(self):
5459 Renumber mesh nodes to remove unused node IDs
5461 self.editor.RenumberNodes()
5463 def RenumberElements(self):
5465 Renumber mesh elements to remove unused element IDs
5467 self.editor.RenumberElements()
5469 def _getIdSourceList(self, arg, idType, unRegister):
5471 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5473 if arg and isinstance( arg, list ):
5474 if isinstance( arg[0], int ):
5475 arg = self.GetIDSource( arg, idType )
5476 unRegister.set( arg )
5477 elif isinstance( arg[0], Mesh ):
5478 arg[0] = arg[0].GetMesh()
5479 elif isinstance( arg, Mesh ):
5481 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5485 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5486 MakeGroups=False, TotalAngle=False):
5488 Generate new elements by rotation of the given elements and nodes around the axis
5491 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5492 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5493 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5494 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5495 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5496 which defines angle in degrees
5497 NbOfSteps: the number of steps
5498 Tolerance: tolerance
5499 MakeGroups: forces the generation of new groups from existing ones
5500 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5501 of all steps, else - size of each step
5504 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5507 unRegister = genObjUnRegister()
5508 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5509 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5510 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5512 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5513 Axis = self.smeshpyD.GetAxisStruct( Axis )
5514 if isinstance( Axis, list ):
5515 Axis = SMESH.AxisStruct( *Axis )
5517 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5518 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5519 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5520 self.mesh.SetParameters(Parameters)
5521 if TotalAngle and NbOfSteps:
5522 AngleInRadians /= NbOfSteps
5523 return self.editor.RotationSweepObjects( nodes, edges, faces,
5524 Axis, AngleInRadians,
5525 NbOfSteps, Tolerance, MakeGroups)
5527 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5528 MakeGroups=False, TotalAngle=False):
5530 Generate new elements by rotation of the elements around the axis
5533 IDsOfElements: the list of ids of elements to sweep
5534 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5535 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5536 NbOfSteps: the number of steps
5537 Tolerance: tolerance
5538 MakeGroups: forces the generation of new groups from existing ones
5539 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5540 of all steps, else - size of each step
5543 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5546 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5547 AngleInRadians, NbOfSteps, Tolerance,
5548 MakeGroups, TotalAngle)
5550 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5551 MakeGroups=False, TotalAngle=False):
5553 Generate new elements by rotation of the elements of object around the axis
5554 theObject object which elements should be sweeped.
5555 It can be a mesh, a sub mesh or a group.
5558 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5559 AngleInRadians: the angle of Rotation
5560 NbOfSteps: number of steps
5561 Tolerance: tolerance
5562 MakeGroups: forces the generation of new groups from existing ones
5563 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5564 of all steps, else - size of each step
5567 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5570 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5571 AngleInRadians, NbOfSteps, Tolerance,
5572 MakeGroups, TotalAngle )
5574 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5575 MakeGroups=False, TotalAngle=False):
5577 Generate new elements by rotation of the elements of object around the axis
5578 theObject object which elements should be sweeped.
5579 It can be a mesh, a sub mesh or a group.
5582 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5583 AngleInRadians: the angle of Rotation
5584 NbOfSteps: number of steps
5585 Tolerance: tolerance
5586 MakeGroups: forces the generation of new groups from existing ones
5587 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5588 of all steps, else - size of each step
5591 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5592 empty list otherwise
5595 return self.RotationSweepObjects([],theObject,[], Axis,
5596 AngleInRadians, NbOfSteps, Tolerance,
5597 MakeGroups, TotalAngle)
5599 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5600 MakeGroups=False, TotalAngle=False):
5602 Generate new elements by rotation of the elements of object around the axis
5603 theObject object which elements should be sweeped.
5604 It can be a mesh, a sub mesh or a group.
5607 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5608 AngleInRadians: the angle of Rotation
5609 NbOfSteps: number of steps
5610 Tolerance: tolerance
5611 MakeGroups: forces the generation of new groups from existing ones
5612 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5613 of all steps, else - size of each step
5616 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5619 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5620 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5622 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5623 scaleFactors=[], linearVariation=False, basePoint=[],
5624 angles=[], anglesVariation=False):
5626 Generate new elements by extrusion of the given elements and nodes
5629 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5630 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5631 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5632 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5633 the direction and value of extrusion for one step (the total extrusion
5634 length will be NbOfSteps * ||StepVector||)
5635 NbOfSteps: the number of steps
5636 MakeGroups: forces the generation of new groups from existing ones
5637 scaleFactors: optional scale factors to apply during extrusion
5638 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5639 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5640 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5641 nodes and elements being extruded is used as the scaling center.
5644 - a list of tree components of the point or
5647 angles: list of angles in radians. Nodes at each extrusion step are rotated
5648 around *basePoint*, additionally to previous steps.
5649 anglesVariation: forces the computation of rotation angles as linear
5650 variation of the given *angles* along path steps
5652 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5654 Example: :ref:`tui_extrusion`
5656 unRegister = genObjUnRegister()
5657 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5658 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5659 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5661 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5662 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5663 if isinstance( StepVector, list ):
5664 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5666 if isinstance( basePoint, int):
5667 xyz = self.GetNodeXYZ( basePoint )
5669 raise RuntimeError("Invalid node ID: %s" % basePoint)
5671 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5672 basePoint = self.geompyD.PointCoordinates( basePoint )
5674 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5675 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5676 angles,angleParameters,hasVars = ParseAngles(angles)
5677 Parameters = StepVector.PS.parameters + var_separator + \
5678 Parameters + var_separator + \
5679 scaleParameters + var_separator + angleParameters
5680 self.mesh.SetParameters(Parameters)
5682 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5683 StepVector, NbOfSteps, MakeGroups,
5684 scaleFactors, linearVariation, basePoint,
5685 angles, anglesVariation )
5688 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5690 Generate new elements by extrusion of the elements with given ids
5693 IDsOfElements: the list of ids of elements or nodes for extrusion
5694 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5695 the direction and value of extrusion for one step (the total extrusion
5696 length will be NbOfSteps * ||StepVector||)
5697 NbOfSteps: the number of steps
5698 MakeGroups: forces the generation of new groups from existing ones
5699 IsNodes: is True if elements with given ids are nodes
5702 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5704 Example: :ref:`tui_extrusion`
5707 if IsNodes: n = IDsOfElements
5708 else : e,f, = IDsOfElements,IDsOfElements
5709 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5711 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5712 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5714 Generate new elements by extrusion along the normal to a discretized surface or wire
5717 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5718 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5719 StepSize: length of one extrusion step (the total extrusion
5720 length will be *NbOfSteps* *StepSize*).
5721 NbOfSteps: number of extrusion steps.
5722 ByAverageNormal: if True each node is translated by *StepSize*
5723 along the average of the normal vectors to the faces sharing the node;
5724 else each node is translated along the same average normal till
5725 intersection with the plane got by translation of the face sharing
5726 the node along its own normal by *StepSize*.
5727 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5728 for every node of *Elements*.
5729 MakeGroups: forces generation of new groups from existing ones.
5730 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5731 is not yet implemented. This parameter is used if *Elements* contains
5732 both faces and edges, i.e. *Elements* is a Mesh.
5735 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5736 empty list otherwise.
5737 Example: :ref:`tui_extrusion`
5740 unRegister = genObjUnRegister()
5741 if isinstance( Elements, Mesh ):
5742 Elements = [ Elements.GetMesh() ]
5743 if isinstance( Elements, list ):
5745 raise RuntimeError("Elements empty!")
5746 if isinstance( Elements[0], Mesh ):
5747 Elements = [ Elements[0].GetMesh() ]
5748 if isinstance( Elements[0], int ):
5749 Elements = self.GetIDSource( Elements, SMESH.ALL )
5750 unRegister.set( Elements )
5751 if not isinstance( Elements, list ):
5752 Elements = [ Elements ]
5753 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5754 self.mesh.SetParameters(Parameters)
5755 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5756 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5758 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5760 Generate new elements by extrusion of the elements or nodes which belong to the object
5763 theObject: the object whose elements or nodes should be processed.
5764 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5765 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5766 the direction and value of extrusion for one step (the total extrusion
5767 length will be NbOfSteps * ||StepVector||)
5768 NbOfSteps: the number of steps
5769 MakeGroups: forces the generation of new groups from existing ones
5770 IsNodes: is True if elements to extrude are nodes
5773 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5774 Example: :ref:`tui_extrusion`
5778 if IsNodes: n = theObject
5779 else : e,f, = theObject,theObject
5780 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5782 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5784 Generate new elements by extrusion of edges which belong to the object
5787 theObject: object whose 1D elements should be processed.
5788 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5789 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5790 the direction and value of extrusion for one step (the total extrusion
5791 length will be NbOfSteps * ||StepVector||)
5792 NbOfSteps: the number of steps
5793 MakeGroups: to generate new groups from existing ones
5796 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5797 Example: :ref:`tui_extrusion`
5800 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5802 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5804 Generate new elements by extrusion of faces which belong to the object
5807 theObject: object whose 2D elements should be processed.
5808 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5809 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5810 the direction and value of extrusion for one step (the total extrusion
5811 length will be NbOfSteps * ||StepVector||)
5812 NbOfSteps: the number of steps
5813 MakeGroups: forces the generation of new groups from existing ones
5816 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5817 Example: :ref:`tui_extrusion`
5820 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5822 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5823 ExtrFlags, SewTolerance, MakeGroups=False):
5825 Generate new elements by extrusion of the elements with given ids
5828 IDsOfElements: is ids of elements
5829 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5830 the direction and value of extrusion for one step (the total extrusion
5831 length will be NbOfSteps * ||StepVector||)
5832 NbOfSteps: the number of steps
5833 ExtrFlags: sets flags for extrusion
5834 SewTolerance: uses for comparing locations of nodes if flag
5835 EXTRUSION_FLAG_SEW is set
5836 MakeGroups: forces the generation of new groups from existing ones
5839 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5842 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5843 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5844 if isinstance( StepVector, list ):
5845 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5846 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5847 ExtrFlags, SewTolerance, MakeGroups)
5849 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5850 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5851 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5852 ScaleFactors=[], ScalesVariation=False):
5854 Generate new elements by extrusion of the given elements and nodes along the path.
5855 The path of extrusion must be a meshed edge.
5858 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5859 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5860 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5861 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5862 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
5863 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5864 HasAngles: not used obsolete
5865 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5866 around *basePoint*, additionally to previous steps.
5867 LinearVariation: forces the computation of rotation angles as linear
5868 variation of the given Angles along path steps
5869 HasRefPoint: allows using the reference point
5870 RefPoint: optional scaling and rotation center (mass center of the extruded
5871 elements by default). The User can specify any point as the Reference Point.
5872 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5873 MakeGroups: forces the generation of new groups from existing ones
5874 ScaleFactors: optional scale factors to apply during extrusion
5875 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5876 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5879 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5880 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5881 Example: :ref:`tui_extrusion_along_path`
5884 unRegister = genObjUnRegister()
5885 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5886 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5887 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5889 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5890 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5891 if isinstance( RefPoint, list ):
5892 if not RefPoint: RefPoint = [0,0,0]
5893 RefPoint = SMESH.PointStruct( *RefPoint )
5894 if isinstance( PathObject, Mesh ):
5895 PathObject = PathObject.GetMesh()
5896 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5897 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5898 Parameters = AnglesParameters + var_separator + \
5899 RefPoint.parameters + var_separator + ScalesParameters
5900 self.mesh.SetParameters(Parameters)
5901 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5902 PathObject, PathShape, NodeStart,
5903 HasAngles, Angles, LinearVariation,
5904 HasRefPoint, RefPoint, MakeGroups,
5905 ScaleFactors, ScalesVariation)
5907 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5908 HasAngles=False, Angles=[], LinearVariation=False,
5909 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5910 ElemType=SMESH.FACE):
5912 Generate new elements by extrusion of the given elements.
5913 The path of extrusion must be a meshed edge.
5916 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5917 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5918 NodeStart: the start node from Path. Defines the direction of extrusion
5919 HasAngles: not used obsolete
5920 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5921 around *basePoint*, additionally to previous steps.
5922 LinearVariation: forces the computation of rotation angles as linear
5923 variation of the given Angles along path steps
5924 HasRefPoint: allows using the reference point
5925 RefPoint: the reference point around which the elements are rotated (the mass
5926 center of the elements by default).
5927 The User can specify any point as the Reference Point.
5928 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5929 MakeGroups: forces the generation of new groups from existing ones
5930 ElemType: type of elements for extrusion (if param Base is a mesh)
5933 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5934 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5935 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5937 Example: :ref:`tui_extrusion_along_path`
5941 if ElemType == SMESH.NODE: n = Base
5942 if ElemType == SMESH.EDGE: e = Base
5943 if ElemType == SMESH.FACE: f = Base
5944 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5945 HasAngles, Angles, LinearVariation,
5946 HasRefPoint, RefPoint, MakeGroups)
5947 if MakeGroups: return gr,er
5950 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5951 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5952 MakeGroups=False, LinearVariation=False):
5954 Generate new elements by extrusion of the given elements.
5955 The path of extrusion must be a meshed edge.
5958 IDsOfElements: ids of elements
5959 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5960 PathShape: shape (edge) defines the sub-mesh for the path
5961 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5962 HasAngles: not used obsolete
5963 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5964 around *basePoint*, additionally to previous steps.
5965 HasRefPoint: allows using the reference point
5966 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5967 The User can specify any point as the Reference Point.
5968 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5969 MakeGroups: forces the generation of new groups from existing ones
5970 LinearVariation: forces the computation of rotation angles as linear
5971 variation of the given Angles along path steps
5974 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5975 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5976 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5977 Example: :ref:`tui_extrusion_along_path`
5980 if not IDsOfElements:
5981 IDsOfElements = [ self.GetMesh() ]
5982 n,e,f = [],IDsOfElements,IDsOfElements
5983 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5984 NodeStart, HasAngles, Angles,
5986 HasRefPoint, RefPoint, MakeGroups)
5987 if MakeGroups: return gr,er
5990 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5991 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5992 MakeGroups=False, LinearVariation=False):
5994 Generate new elements by extrusion of the elements which belong to the object.
5995 The path of extrusion must be a meshed edge.
5998 theObject: the object whose elements should be processed.
5999 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6000 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6001 PathShape: shape (edge) defines the sub-mesh for the path
6002 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6003 HasAngles: not used obsolete
6004 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6005 around *basePoint*, additionally to previous steps.
6006 HasRefPoint: allows using the reference point
6007 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6008 The User can specify any point as the Reference Point.
6009 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6010 MakeGroups: forces the generation of new groups from existing ones
6011 LinearVariation: forces the computation of rotation angles as linear
6012 variation of the given Angles along path steps
6015 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6016 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6017 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6018 Example: :ref:`tui_extrusion_along_path`
6021 n,e,f = [],theObject,theObject
6022 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6023 HasAngles, Angles, LinearVariation,
6024 HasRefPoint, RefPoint, MakeGroups)
6025 if MakeGroups: return gr,er
6028 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6029 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6030 MakeGroups=False, LinearVariation=False):
6032 Generate new elements by extrusion of mesh segments which belong to the object.
6033 The path of extrusion must be a meshed edge.
6036 theObject: the object whose 1D elements should be processed.
6037 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6038 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6039 PathShape: shape (edge) defines the sub-mesh for the path
6040 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6041 HasAngles: not used obsolete
6042 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6043 around *basePoint*, additionally to previous steps.
6044 HasRefPoint: allows using the reference point
6045 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6046 The User can specify any point as the Reference Point.
6047 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6048 MakeGroups: forces the generation of new groups from existing ones
6049 LinearVariation: forces the computation of rotation angles as linear
6050 variation of the given Angles along path steps
6053 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6054 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6055 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6056 Example: :ref:`tui_extrusion_along_path`
6059 n,e,f = [],theObject,[]
6060 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6061 HasAngles, Angles, LinearVariation,
6062 HasRefPoint, RefPoint, MakeGroups)
6063 if MakeGroups: return gr,er
6066 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6067 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6068 MakeGroups=False, LinearVariation=False):
6070 Generate new elements by extrusion of faces which belong to the object.
6071 The path of extrusion must be a meshed edge.
6074 theObject: the object whose 2D elements should be processed.
6075 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6076 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6077 PathShape: shape (edge) defines the sub-mesh for the path
6078 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6079 HasAngles: not used obsolete
6080 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6081 around *basePoint*, additionally to previous steps.
6082 HasRefPoint: allows using the reference point
6083 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6084 The User can specify any point as the Reference Point.
6085 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6086 MakeGroups: forces the generation of new groups from existing ones
6087 LinearVariation: forces the computation of rotation angles as linear
6088 variation of the given Angles along path steps
6091 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6092 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6093 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6094 Example: :ref:`tui_extrusion_along_path`
6097 n,e,f = [],[],theObject
6098 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6099 HasAngles, Angles, LinearVariation,
6100 HasRefPoint, RefPoint, MakeGroups)
6101 if MakeGroups: return gr,er
6104 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6106 Create a symmetrical copy of mesh elements
6109 IDsOfElements: list of elements ids
6110 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6111 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6112 If the *Mirror* is a geom object this parameter is unnecessary
6113 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6114 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6117 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6120 if IDsOfElements == []:
6121 IDsOfElements = self.GetElementsId()
6122 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6123 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6124 theMirrorType = Mirror._mirrorType
6126 self.mesh.SetParameters(Mirror.parameters)
6127 if Copy and MakeGroups:
6128 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6129 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6132 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6134 Create a new mesh by a symmetrical copy of mesh elements
6137 IDsOfElements: the list of elements ids
6138 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6139 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6140 If the *Mirror* is a geom object this parameter is unnecessary
6141 MakeGroups: to generate new groups from existing ones
6142 NewMeshName: a name of the new mesh to create
6145 instance of class :class:`Mesh`
6148 if IDsOfElements == []:
6149 IDsOfElements = self.GetElementsId()
6150 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6151 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6152 theMirrorType = Mirror._mirrorType
6154 self.mesh.SetParameters(Mirror.parameters)
6155 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6156 MakeGroups, NewMeshName)
6157 return Mesh(self.smeshpyD,self.geompyD,mesh)
6159 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6161 Create a symmetrical copy of the object
6164 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6165 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6166 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6167 If the *Mirror* is a geom object this parameter is unnecessary
6168 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6169 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6172 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6175 if ( isinstance( theObject, Mesh )):
6176 theObject = theObject.GetMesh()
6177 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6178 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6179 theMirrorType = Mirror._mirrorType
6181 self.mesh.SetParameters(Mirror.parameters)
6182 if Copy and MakeGroups:
6183 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6184 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6187 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6189 Create a new mesh by a symmetrical copy of the object
6192 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6193 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6194 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6195 If the *Mirror* is a geom object this parameter is unnecessary
6196 MakeGroups: forces the generation of new groups from existing ones
6197 NewMeshName: the name of the new mesh to create
6200 instance of class :class:`Mesh`
6203 if ( isinstance( theObject, Mesh )):
6204 theObject = theObject.GetMesh()
6205 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6206 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6207 theMirrorType = Mirror._mirrorType
6209 self.mesh.SetParameters(Mirror.parameters)
6210 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6211 MakeGroups, NewMeshName)
6212 return Mesh( self.smeshpyD,self.geompyD,mesh )
6214 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6216 Translate the elements
6219 IDsOfElements: list of elements ids
6220 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6221 Copy: allows copying the translated elements
6222 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6225 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6228 if IDsOfElements == []:
6229 IDsOfElements = self.GetElementsId()
6230 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6231 Vector = self.smeshpyD.GetDirStruct(Vector)
6232 if isinstance( Vector, list ):
6233 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6234 self.mesh.SetParameters(Vector.PS.parameters)
6235 if Copy and MakeGroups:
6236 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6237 self.editor.Translate(IDsOfElements, Vector, Copy)
6240 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6242 Create a new mesh of translated elements
6245 IDsOfElements: list of elements ids
6246 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6247 MakeGroups: forces the generation of new groups from existing ones
6248 NewMeshName: the name of the newly created mesh
6251 instance of class :class:`Mesh`
6254 if IDsOfElements == []:
6255 IDsOfElements = self.GetElementsId()
6256 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6257 Vector = self.smeshpyD.GetDirStruct(Vector)
6258 if isinstance( Vector, list ):
6259 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6260 self.mesh.SetParameters(Vector.PS.parameters)
6261 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6262 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6264 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6266 Translate the object
6269 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6270 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6271 Copy: allows copying the translated elements
6272 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6275 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6278 if ( isinstance( theObject, Mesh )):
6279 theObject = theObject.GetMesh()
6280 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6281 Vector = self.smeshpyD.GetDirStruct(Vector)
6282 if isinstance( Vector, list ):
6283 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6284 self.mesh.SetParameters(Vector.PS.parameters)
6285 if Copy and MakeGroups:
6286 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6287 self.editor.TranslateObject(theObject, Vector, Copy)
6290 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6292 Create a new mesh from the translated object
6295 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6296 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6297 MakeGroups: forces the generation of new groups from existing ones
6298 NewMeshName: the name of the newly created mesh
6301 instance of class :class:`Mesh`
6304 if isinstance( theObject, Mesh ):
6305 theObject = theObject.GetMesh()
6306 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6307 Vector = self.smeshpyD.GetDirStruct(Vector)
6308 if isinstance( Vector, list ):
6309 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6310 self.mesh.SetParameters(Vector.PS.parameters)
6311 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6312 return Mesh( self.smeshpyD, self.geompyD, mesh )
6316 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6321 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6322 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6323 theScaleFact: list of 1-3 scale factors for axises
6324 Copy: allows copying the translated elements
6325 MakeGroups: forces the generation of new groups from existing
6329 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6330 empty list otherwise
6332 unRegister = genObjUnRegister()
6333 if ( isinstance( theObject, Mesh )):
6334 theObject = theObject.GetMesh()
6335 if ( isinstance( theObject, list )):
6336 theObject = self.GetIDSource(theObject, SMESH.ALL)
6337 unRegister.set( theObject )
6338 if ( isinstance( thePoint, list )):
6339 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6340 if ( isinstance( theScaleFact, float )):
6341 theScaleFact = [theScaleFact]
6342 if ( isinstance( theScaleFact, int )):
6343 theScaleFact = [ float(theScaleFact)]
6345 self.mesh.SetParameters(thePoint.parameters)
6347 if Copy and MakeGroups:
6348 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6349 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6352 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6354 Create a new mesh from the translated object
6357 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6358 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6359 theScaleFact: list of 1-3 scale factors for axises
6360 MakeGroups: forces the generation of new groups from existing ones
6361 NewMeshName: the name of the newly created mesh
6364 instance of class :class:`Mesh`
6366 unRegister = genObjUnRegister()
6367 if (isinstance(theObject, Mesh)):
6368 theObject = theObject.GetMesh()
6369 if ( isinstance( theObject, list )):
6370 theObject = self.GetIDSource(theObject,SMESH.ALL)
6371 unRegister.set( theObject )
6372 if ( isinstance( thePoint, list )):
6373 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6374 if ( isinstance( theScaleFact, float )):
6375 theScaleFact = [theScaleFact]
6376 if ( isinstance( theScaleFact, int )):
6377 theScaleFact = [ float(theScaleFact)]
6379 self.mesh.SetParameters(thePoint.parameters)
6380 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6381 MakeGroups, NewMeshName)
6382 return Mesh( self.smeshpyD, self.geompyD, mesh )
6386 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6391 IDsOfElements: list of elements ids
6392 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6393 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6394 Copy: allows copying the rotated elements
6395 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6398 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6402 if IDsOfElements == []:
6403 IDsOfElements = self.GetElementsId()
6404 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6405 Axis = self.smeshpyD.GetAxisStruct(Axis)
6406 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6407 Parameters = Axis.parameters + var_separator + Parameters
6408 self.mesh.SetParameters(Parameters)
6409 if Copy and MakeGroups:
6410 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6411 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6414 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6416 Create a new mesh of rotated elements
6419 IDsOfElements: list of element ids
6420 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6421 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6422 MakeGroups: forces the generation of new groups from existing ones
6423 NewMeshName: the name of the newly created mesh
6426 instance of class :class:`Mesh`
6429 if IDsOfElements == []:
6430 IDsOfElements = self.GetElementsId()
6431 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6432 Axis = self.smeshpyD.GetAxisStruct(Axis)
6433 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6434 Parameters = Axis.parameters + var_separator + Parameters
6435 self.mesh.SetParameters(Parameters)
6436 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6437 MakeGroups, NewMeshName)
6438 return Mesh( self.smeshpyD, self.geompyD, mesh )
6440 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6445 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6446 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6447 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6448 Copy: allows copying the rotated elements
6449 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6452 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6455 if (isinstance(theObject, Mesh)):
6456 theObject = theObject.GetMesh()
6457 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6458 Axis = self.smeshpyD.GetAxisStruct(Axis)
6459 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6460 Parameters = Axis.parameters + ":" + Parameters
6461 self.mesh.SetParameters(Parameters)
6462 if Copy and MakeGroups:
6463 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6464 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6467 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6469 Create a new mesh from the rotated object
6472 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6473 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6474 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6475 MakeGroups: forces the generation of new groups from existing ones
6476 NewMeshName: the name of the newly created mesh
6479 instance of class :class:`Mesh`
6482 if (isinstance( theObject, Mesh )):
6483 theObject = theObject.GetMesh()
6484 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6485 Axis = self.smeshpyD.GetAxisStruct(Axis)
6486 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6487 Parameters = Axis.parameters + ":" + Parameters
6488 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6489 MakeGroups, NewMeshName)
6490 self.mesh.SetParameters(Parameters)
6491 return Mesh( self.smeshpyD, self.geompyD, mesh )
6493 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6495 Create an offset mesh from the given 2D object
6498 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6499 theValue (float): signed offset size
6500 MakeGroups (boolean): forces the generation of new groups from existing ones
6501 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6502 False means to remove original elements.
6503 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6506 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6509 if isinstance( theObject, Mesh ):
6510 theObject = theObject.GetMesh()
6511 theValue,Parameters,hasVars = ParseParameters(Value)
6512 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6513 self.mesh.SetParameters(Parameters)
6515 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6518 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6520 Find groups of adjacent nodes within Tolerance.
6523 Tolerance (float): the value of tolerance
6524 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6525 corner and medium nodes in separate groups thus preventing
6526 their further merge.
6529 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6532 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6534 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6535 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6537 Find groups of adjacent nodes within Tolerance.
6540 Tolerance: the value of tolerance
6541 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6542 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6543 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6544 corner and medium nodes in separate groups thus preventing
6545 their further merge.
6548 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6551 unRegister = genObjUnRegister()
6552 if not isinstance( SubMeshOrGroup, list ):
6553 SubMeshOrGroup = [ SubMeshOrGroup ]
6554 for i,obj in enumerate( SubMeshOrGroup ):
6555 if isinstance( obj, Mesh ):
6556 SubMeshOrGroup = [ obj.GetMesh() ]
6558 if isinstance( obj, int ):
6559 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6560 unRegister.set( SubMeshOrGroup )
6563 if not isinstance( exceptNodes, list ):
6564 exceptNodes = [ exceptNodes ]
6565 if exceptNodes and isinstance( exceptNodes[0], int ):
6566 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6567 unRegister.set( exceptNodes )
6569 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6570 exceptNodes, SeparateCornerAndMediumNodes)
6572 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6577 GroupsOfNodes: a list of groups of nodes IDs for merging.
6578 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6579 in all elements and mesh groups by nodes 1 and 25 correspondingly
6580 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6581 If *NodesToKeep* does not include a node to keep for some group to merge,
6582 then the first node in the group is kept.
6583 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6587 This operation can create gaps in numeration of nodes or elements.
6588 Call :meth:`RenumberElements` to remove the gaps.
6590 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6592 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6594 Find the elements built on the same nodes.
6597 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6598 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6602 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6605 unRegister = genObjUnRegister()
6606 if MeshOrSubMeshOrGroup is None:
6607 MeshOrSubMeshOrGroup = [ self.mesh ]
6608 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6609 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6610 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6611 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6612 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6613 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6614 unRegister.set( MeshOrSubMeshOrGroup )
6615 for item in MeshOrSubMeshOrGroup:
6616 if isinstance( item, Mesh ):
6617 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6619 if not isinstance( exceptElements, list ):
6620 exceptElements = [ exceptElements ]
6621 if exceptElements and isinstance( exceptElements[0], int ):
6622 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6623 unRegister.set( exceptElements )
6625 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6627 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6629 Merge elements in each given group.
6632 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6633 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6634 replaced in all mesh groups by elements 1 and 25)
6635 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6636 If *ElementsToKeep* does not include an element to keep for some group to merge,
6637 then the first element in the group is kept.
6640 This operation can create gaps in numeration of elements.
6641 Call :meth:`RenumberElements` to remove the gaps.
6644 unRegister = genObjUnRegister()
6646 if not isinstance( ElementsToKeep, list ):
6647 ElementsToKeep = [ ElementsToKeep ]
6648 if isinstance( ElementsToKeep[0], int ):
6649 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6650 unRegister.set( ElementsToKeep )
6652 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6654 def MergeEqualElements(self):
6656 Leave one element and remove all other elements built on the same nodes.
6659 This operation can create gaps in numeration of elements.
6660 Call :meth:`RenumberElements` to remove the gaps.
6663 self.editor.MergeEqualElements()
6665 def FindFreeBorders(self, ClosedOnly=True):
6667 Returns all or only closed free borders
6670 list of SMESH.FreeBorder's
6673 return self.editor.FindFreeBorders( ClosedOnly )
6675 def FillHole(self, holeNodes, groupName=""):
6677 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6680 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6681 must describe all sequential nodes of the hole border. The first and the last
6682 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6683 groupName (string): name of a group to add new faces
6685 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6689 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6690 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6691 if not isinstance( holeNodes, SMESH.FreeBorder ):
6692 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6693 return self.editor.FillHole( holeNodes, groupName )
6695 def FindCoincidentFreeBorders (self, tolerance=0.):
6697 Return groups of FreeBorder's coincident within the given tolerance.
6700 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6701 size of elements adjacent to free borders being compared is used.
6704 SMESH.CoincidentFreeBorders structure
6707 return self.editor.FindCoincidentFreeBorders( tolerance )
6709 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6711 Sew FreeBorder's of each group
6714 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6715 where each enclosed list contains node IDs of a group of coincident free
6716 borders such that each consequent triple of IDs within a group describes
6717 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6718 last node of a border.
6719 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6720 groups of coincident free borders, each group including two borders.
6721 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6722 polygons if a node of opposite border falls on a face edge, else such
6723 faces are split into several ones.
6724 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6725 polyhedra if a node of opposite border falls on a volume edge, else such
6726 volumes, if any, remain intact and the mesh becomes non-conformal.
6729 a number of successfully sewed groups
6732 This operation can create gaps in numeration of nodes or elements.
6733 Call :meth:`RenumberElements` to remove the gaps.
6736 if freeBorders and isinstance( freeBorders, list ):
6737 # construct SMESH.CoincidentFreeBorders
6738 if isinstance( freeBorders[0], int ):
6739 freeBorders = [freeBorders]
6741 coincidentGroups = []
6742 for nodeList in freeBorders:
6743 if not nodeList or len( nodeList ) % 3:
6744 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6747 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6748 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6749 nodeList = nodeList[3:]
6751 coincidentGroups.append( group )
6753 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6755 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6757 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6758 FirstNodeID2, SecondNodeID2, LastNodeID2,
6759 CreatePolygons, CreatePolyedrs):
6764 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6767 This operation can create gaps in numeration of nodes or elements.
6768 Call :meth:`RenumberElements` to remove the gaps.
6771 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6772 FirstNodeID2, SecondNodeID2, LastNodeID2,
6773 CreatePolygons, CreatePolyedrs)
6775 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6776 FirstNodeID2, SecondNodeID2):
6778 Sew conform free borders
6781 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6784 This operation can create gaps in numeration of elements.
6785 Call :meth:`RenumberElements` to remove the gaps.
6788 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6789 FirstNodeID2, SecondNodeID2)
6791 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6792 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6797 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6800 This operation can create gaps in numeration of elements.
6801 Call :meth:`RenumberElements` to remove the gaps.
6804 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6805 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6807 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6808 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6809 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6811 Sew two sides of a mesh. The nodes belonging to Side1 are
6812 merged with the nodes of elements of Side2.
6813 The number of elements in theSide1 and in theSide2 must be
6814 equal and they should have similar nodal connectivity.
6815 The nodes to merge should belong to side borders and
6816 the first node should be linked to the second.
6819 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6822 This operation can create gaps in numeration of nodes.
6823 Call :meth:`RenumberElements` to remove the gaps.
6826 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6827 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6828 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6830 def ChangeElemNodes(self, ide, newIDs):
6832 Set new nodes for the given element. Number of nodes should be kept.
6839 False if the number of nodes does not correspond to the type of element
6842 return self.editor.ChangeElemNodes(ide, newIDs)
6844 def GetLastCreatedNodes(self):
6846 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6847 created, this method return the list of their IDs.
6848 If new nodes were not created - return empty list
6851 the list of integer values (can be empty)
6854 return self.editor.GetLastCreatedNodes()
6856 def GetLastCreatedElems(self):
6858 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6859 created this method return the list of their IDs.
6860 If new elements were not created - return empty list
6863 the list of integer values (can be empty)
6866 return self.editor.GetLastCreatedElems()
6868 def ClearLastCreated(self):
6870 Forget what nodes and elements were created by the last mesh edition operation
6873 self.editor.ClearLastCreated()
6875 def DoubleElements(self, theElements, theGroupName=""):
6877 Create duplicates of given elements, i.e. create new elements based on the
6878 same nodes as the given ones.
6881 theElements: container of elements to duplicate. It can be a
6882 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6883 or a list of element IDs. If *theElements* is
6884 a :class:`Mesh`, elements of highest dimension are duplicated
6885 theGroupName: a name of group to contain the generated elements.
6886 If a group with such a name already exists, the new elements
6887 are added to the existing group, else a new group is created.
6888 If *theGroupName* is empty, new elements are not added
6892 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6893 None if *theGroupName* == "".
6896 unRegister = genObjUnRegister()
6897 if isinstance( theElements, Mesh ):
6898 theElements = theElements.mesh
6899 elif isinstance( theElements, list ):
6900 theElements = self.GetIDSource( theElements, SMESH.ALL )
6901 unRegister.set( theElements )
6902 return self.editor.DoubleElements(theElements, theGroupName)
6904 def DoubleNodes(self, theNodes, theModifiedElems):
6906 Create a hole in a mesh by doubling the nodes of some particular elements
6909 theNodes: IDs of nodes to be doubled
6910 theModifiedElems: IDs of elements to be updated by the new (doubled)
6911 nodes. If list of element identifiers is empty then nodes are doubled but
6912 they not assigned to elements
6915 True if operation has been completed successfully, False otherwise
6918 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6920 def DoubleNode(self, theNodeId, theModifiedElems):
6922 Create a hole in a mesh by doubling the nodes of some particular elements.
6923 This method provided for convenience works as :meth:`DoubleNodes`.
6926 theNodeId: IDs of node to double
6927 theModifiedElems: IDs of elements to update
6930 True if operation has been completed successfully, False otherwise
6933 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6935 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6937 Create a hole in a mesh by doubling the nodes of some particular elements.
6938 This method provided for convenience works as :meth:`DoubleNodes`.
6941 theNodes: group of nodes to double.
6942 theModifiedElems: group of elements to update.
6943 theMakeGroup: forces the generation of a group containing new nodes.
6946 True or a created group if operation has been completed successfully,
6947 False or None otherwise
6951 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6952 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6954 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6956 Create a hole in a mesh by doubling the nodes of some particular elements.
6957 This method provided for convenience works as :meth:`DoubleNodes`.
6960 theNodes: list of groups of nodes to double.
6961 theModifiedElems: list of groups of elements to update.
6962 theMakeGroup: forces the generation of a group containing new nodes.
6965 True if operation has been completed successfully, False otherwise
6969 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6970 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6972 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6974 Create a hole in a mesh by doubling the nodes of some particular elements
6977 theElems: the list of elements (edges or faces) to replicate.
6978 The nodes for duplication could be found from these elements
6979 theNodesNot: list of nodes NOT to replicate
6980 theAffectedElems: the list of elements (cells and edges) to which the
6981 replicated nodes should be associated to
6984 True if operation has been completed successfully, False otherwise
6987 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6989 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6991 Create a hole in a mesh by doubling the nodes of some particular elements
6994 theElems: the list of elements (edges or faces) to replicate.
6995 The nodes for duplication could be found from these elements
6996 theNodesNot: list of nodes NOT to replicate
6997 theShape: shape to detect affected elements (element which geometric center
6998 located on or inside shape).
6999 The replicated nodes should be associated to affected elements.
7002 True if operation has been completed successfully, False otherwise
7005 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7007 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7008 theMakeGroup=False, theMakeNodeGroup=False):
7010 Create a hole in a mesh by doubling the nodes of some particular elements.
7011 This method provided for convenience works as :meth:`DoubleNodes`.
7014 theElems: group of of elements (edges or faces) to replicate.
7015 theNodesNot: group of nodes NOT to replicate.
7016 theAffectedElems: group of elements to which the replicated nodes
7017 should be associated to.
7018 theMakeGroup: forces the generation of a group containing new elements.
7019 theMakeNodeGroup: forces the generation of a group containing new nodes.
7022 True or created groups (one or two) if operation has been completed successfully,
7023 False or None otherwise
7026 if theMakeGroup or theMakeNodeGroup:
7027 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7029 theMakeGroup, theMakeNodeGroup)
7030 if theMakeGroup and theMakeNodeGroup:
7033 return twoGroups[ int(theMakeNodeGroup) ]
7034 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7036 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7038 Create a hole in a mesh by doubling the nodes of some particular elements.
7039 This method provided for convenience works as :meth:`DoubleNodes`.
7042 theElems: group of of elements (edges or faces) to replicate
7043 theNodesNot: group of nodes not to replicate
7044 theShape: shape to detect affected elements (element which geometric center
7045 located on or inside shape).
7046 The replicated nodes should be associated to affected elements
7049 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7051 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7052 theMakeGroup=False, theMakeNodeGroup=False):
7054 Create a hole in a mesh by doubling the nodes of some particular elements.
7055 This method provided for convenience works as :meth:`DoubleNodes`.
7058 theElems: list of groups of elements (edges or faces) to replicate
7059 theNodesNot: list of groups of nodes NOT to replicate
7060 theAffectedElems: group of elements to which the replicated nodes
7061 should be associated to
7062 theMakeGroup: forces generation of a group containing new elements.
7063 theMakeNodeGroup: forces generation of a group containing new nodes
7066 True or created groups (one or two) if operation has been completed successfully,
7067 False or None otherwise
7070 if theMakeGroup or theMakeNodeGroup:
7071 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7073 theMakeGroup, theMakeNodeGroup)
7074 if theMakeGroup and theMakeNodeGroup:
7077 return twoGroups[ int(theMakeNodeGroup) ]
7078 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7080 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7082 Create a hole in a mesh by doubling the nodes of some particular elements.
7083 This method provided for convenience works as :meth:`DoubleNodes`.
7086 theElems: list of groups of elements (edges or faces) to replicate
7087 theNodesNot: list of groups of nodes NOT to replicate
7088 theShape: shape to detect affected elements (element which geometric center
7089 located on or inside shape).
7090 The replicated nodes should be associated to affected elements
7093 True if operation has been completed successfully, False otherwise
7096 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7098 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7100 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7101 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7104 theElems: list of groups of nodes or elements (edges or faces) to replicate
7105 theNodesNot: list of groups of nodes NOT to replicate
7106 theShape: shape to detect affected elements (element which geometric center
7107 located on or inside shape).
7108 The replicated nodes should be associated to affected elements
7111 groups of affected elements in order: volumes, faces, edges
7114 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7116 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7119 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7120 The list of groups must describe a partition of the mesh volumes.
7121 The nodes of the internal faces at the boundaries of the groups are doubled.
7122 In option, the internal faces are replaced by flat elements.
7123 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7126 theDomains: list of groups of volumes
7127 createJointElems: if True, create the elements
7128 onAllBoundaries: if True, the nodes and elements are also created on
7129 the boundary between *theDomains* and the rest mesh
7132 True if operation has been completed successfully, False otherwise
7135 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7137 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7139 Double nodes on some external faces and create flat elements.
7140 Flat elements are mainly used by some types of mechanic calculations.
7142 Each group of the list must be constituted of faces.
7143 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7146 theGroupsOfFaces: list of groups of faces
7149 True if operation has been completed successfully, False otherwise
7152 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7154 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7156 Identify all the elements around a geom shape, get the faces delimiting the hole
7158 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7160 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7162 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7163 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7164 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7165 If there are several paths connecting a pair of points, the shortest path is
7166 selected by the module. Position of the cutting plane is defined by the two
7167 points and an optional vector lying on the plane specified by a PolySegment.
7168 By default the vector is defined by Mesh module as following. A middle point
7169 of the two given points is computed. The middle point is projected to the mesh.
7170 The vector goes from the middle point to the projection point. In case of planar
7171 mesh, the vector is normal to the mesh.
7173 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7176 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7177 groupName: optional name of a group where created mesh segments will be added.
7180 editor = self.editor
7182 editor = self.mesh.GetMeshEditPreviewer()
7183 segmentsRes = editor.MakePolyLine( segments, groupName )
7184 for i, seg in enumerate( segmentsRes ):
7185 segments[i].vector = seg.vector
7187 return editor.GetPreviewData()
7190 def MakeSlot(self, segmentGroup, width ):
7192 Create a slot of given width around given 1D elements lying on a triangle mesh.
7193 The slot is constructed by cutting faces by cylindrical surfaces made
7194 around each segment. Segments are expected to be created by MakePolyLine().
7197 FaceEdge's located at the slot boundary
7199 return self.editor.MakeSlot( segmentGroup, width )
7201 def GetFunctor(self, funcType ):
7203 Return a cached numerical functor by its type.
7206 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7207 Note that not all items correspond to numerical functors.
7210 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7213 fn = self.functors[ funcType._v ]
7215 fn = self.smeshpyD.GetFunctor(funcType)
7216 fn.SetMesh(self.mesh)
7217 self.functors[ funcType._v ] = fn
7220 def FunctorValue(self, funcType, elemId, isElem=True):
7222 Return value of a functor for a given element
7225 funcType: an item of :class:`SMESH.FunctorType` enum.
7226 elemId: element or node ID
7227 isElem: *elemId* is ID of element or node
7230 the functor value or zero in case of invalid arguments
7233 fn = self.GetFunctor( funcType )
7234 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7235 val = fn.GetValue(elemId)
7240 def GetLength(self, elemId=None):
7242 Get length of given 1D elements or of all 1D mesh elements
7245 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.
7248 Sum of lengths of given elements
7253 length = self.smeshpyD.GetLength(self)
7254 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7255 length = self.smeshpyD.GetLength(elemId)
7258 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7260 length += self.smeshpyD.GetLength(obj)
7261 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7262 unRegister = genObjUnRegister()
7263 obj = self.GetIDSource( elemId )
7264 unRegister.set( obj )
7265 length = self.smeshpyD.GetLength( obj )
7267 length = self.FunctorValue(SMESH.FT_Length, elemId)
7270 def GetArea(self, elemId=None):
7272 Get area of given 2D elements or of all 2D mesh elements
7275 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.
7278 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7283 area = self.smeshpyD.GetArea(self)
7284 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7285 area = self.smeshpyD.GetArea(elemId)
7288 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7290 area += self.smeshpyD.GetArea(obj)
7291 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7292 unRegister = genObjUnRegister()
7293 obj = self.GetIDSource( elemId )
7294 unRegister.set( obj )
7295 area = self.smeshpyD.GetArea( obj )
7297 area = self.FunctorValue(SMESH.FT_Area, elemId)
7300 def GetVolume(self, elemId=None):
7302 Get volume of given 3D elements or of all 3D mesh elements
7305 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.
7308 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7313 volume= self.smeshpyD.GetVolume(self)
7314 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7315 volume= self.smeshpyD.GetVolume(elemId)
7318 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7320 volume+= self.smeshpyD.GetVolume(obj)
7321 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7322 unRegister = genObjUnRegister()
7323 obj = self.GetIDSource( elemId )
7324 unRegister.set( obj )
7325 volume= self.smeshpyD.GetVolume( obj )
7327 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7330 def GetAngle(self, node1, node2, node3 ):
7332 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7335 node1,node2,node3: IDs of the three nodes
7338 Angle in radians [0,PI]. -1 if failure case.
7340 p1 = self.GetNodeXYZ( node1 )
7341 p2 = self.GetNodeXYZ( node2 )
7342 p3 = self.GetNodeXYZ( node3 )
7343 if p1 and p2 and p3:
7344 return self.smeshpyD.GetAngle( p1,p2,p3 )
7348 def GetMaxElementLength(self, elemId):
7350 Get maximum element length.
7353 elemId: mesh element ID
7356 element's maximum length value
7359 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7360 ftype = SMESH.FT_MaxElementLength3D
7362 ftype = SMESH.FT_MaxElementLength2D
7363 return self.FunctorValue(ftype, elemId)
7365 def GetAspectRatio(self, elemId):
7367 Get aspect ratio of 2D or 3D element.
7370 elemId: mesh element ID
7373 element's aspect ratio value
7376 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7377 ftype = SMESH.FT_AspectRatio3D
7379 ftype = SMESH.FT_AspectRatio
7380 return self.FunctorValue(ftype, elemId)
7382 def GetWarping(self, elemId):
7384 Get warping angle of 2D element.
7387 elemId: mesh element ID
7390 element's warping angle value
7393 return self.FunctorValue(SMESH.FT_Warping, elemId)
7395 def GetMinimumAngle(self, elemId):
7397 Get minimum angle of 2D element.
7400 elemId: mesh element ID
7403 element's minimum angle value
7406 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7408 def GetTaper(self, elemId):
7410 Get taper of 2D element.
7413 elemId: mesh element ID
7416 element's taper value
7419 return self.FunctorValue(SMESH.FT_Taper, elemId)
7421 def GetSkew(self, elemId):
7423 Get skew of 2D element.
7426 elemId: mesh element ID
7429 element's skew value
7432 return self.FunctorValue(SMESH.FT_Skew, elemId)
7434 def GetMinMax(self, funType, meshPart=None):
7436 Return minimal and maximal value of a given functor.
7439 funType (SMESH.FunctorType): a functor type.
7440 Note that not all items of :class:`SMESH.FunctorType` corresponds
7441 to numerical functors.
7442 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7448 unRegister = genObjUnRegister()
7449 if isinstance( meshPart, list ):
7450 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7451 unRegister.set( meshPart )
7452 if isinstance( meshPart, Mesh ):
7453 meshPart = meshPart.mesh
7454 fun = self.GetFunctor( funType )
7457 if hasattr( meshPart, "SetMesh" ):
7458 meshPart.SetMesh( self.mesh ) # set mesh to filter
7459 hist = fun.GetLocalHistogram( 1, False, meshPart )
7461 hist = fun.GetHistogram( 1, False )
7463 return hist[0].min, hist[0].max
7466 pass # end of Mesh class
7469 class meshProxy(SMESH._objref_SMESH_Mesh):
7471 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7472 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7474 def __init__(self,*args):
7475 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7476 def __deepcopy__(self, memo=None):
7477 new = self.__class__(self)
7479 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7480 if len( args ) == 3:
7481 args += SMESH.ALL_NODES, True
7482 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7483 def ExportToMEDX(self, *args): # function removed
7484 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7485 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7486 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7487 def ExportToMED(self, *args): # function removed
7488 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7489 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7491 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7493 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7494 def ExportPartToMED(self, *args): # 'version' parameter removed
7495 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7496 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7497 def ExportMED(self, *args): # signature of method changed
7498 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7500 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7502 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7503 def ExportUNV(self, *args): # renumber arg added
7504 if len( args ) == 1:
7506 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7507 def ExportDAT(self, *args): # renumber arg added
7508 if len( args ) == 1:
7510 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7512 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7515 class submeshProxy(SMESH._objref_SMESH_subMesh):
7518 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7520 def __init__(self,*args):
7521 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7523 def __deepcopy__(self, memo=None):
7524 new = self.__class__(self)
7527 def Compute(self,refresh=False):
7529 Compute the sub-mesh and return the status of the computation
7532 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7537 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7538 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7542 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7544 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7546 if salome.sg.hasDesktop():
7547 if refresh: salome.sg.updateObjBrowser()
7552 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7555 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7557 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7558 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7561 def __init__(self,*args):
7562 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7564 def __getattr__(self, name ): # method called if an attribute not found
7565 if not self.mesh: # look for name() method in Mesh class
7566 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7567 if hasattr( self.mesh, name ):
7568 return getattr( self.mesh, name )
7569 if name == "ExtrusionAlongPathObjX":
7570 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7571 print("meshEditor: attribute '%s' NOT FOUND" % name)
7573 def __deepcopy__(self, memo=None):
7574 new = self.__class__(self)
7576 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7577 if len( args ) == 1: args += False,
7578 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7579 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7580 if len( args ) == 2: args += False,
7581 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7582 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7583 if len( args ) == 1:
7584 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7585 NodesToKeep = args[1]
7586 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7587 unRegister = genObjUnRegister()
7589 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7590 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7591 if not isinstance( NodesToKeep, list ):
7592 NodesToKeep = [ NodesToKeep ]
7593 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7595 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7597 class Pattern(SMESH._objref_SMESH_Pattern):
7599 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7600 variables in some methods
7603 def LoadFromFile(self, patternTextOrFile ):
7604 text = patternTextOrFile
7605 if os.path.exists( text ):
7606 text = open( patternTextOrFile ).read()
7608 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7610 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7611 decrFun = lambda i: i-1
7612 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7613 theMesh.SetParameters(Parameters)
7614 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7616 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7617 decrFun = lambda i: i-1
7618 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7619 theMesh.SetParameters(Parameters)
7620 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7622 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7623 if isinstance( mesh, Mesh ):
7624 mesh = mesh.GetMesh()
7625 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7627 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7629 Registering the new proxy for Pattern
7634 Private class used to bind methods creating algorithms to the class Mesh
7637 def __init__(self, method):
7639 self.defaultAlgoType = ""
7640 self.algoTypeToClass = {}
7641 self.method = method
7643 def add(self, algoClass):
7645 Store a python class of algorithm
7647 if inspect.isclass(algoClass) and \
7648 hasattr( algoClass, "algoType"):
7649 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7650 if not self.defaultAlgoType and \
7651 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7652 self.defaultAlgoType = algoClass.algoType
7653 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7655 def copy(self, mesh):
7657 Create a copy of self and assign mesh to the copy
7660 other = algoCreator( self.method )
7661 other.defaultAlgoType = self.defaultAlgoType
7662 other.algoTypeToClass = self.algoTypeToClass
7666 def __call__(self,algo="",geom=0,*args):
7668 Create an instance of algorithm
7672 if isinstance( algo, str ):
7674 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7675 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7680 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7682 elif not algoType and isinstance( geom, str ):
7687 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7689 elif isinstance( arg, str ) and not algoType:
7692 import traceback, sys
7693 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7694 sys.stderr.write( msg + '\n' )
7695 tb = traceback.extract_stack(None,2)
7696 traceback.print_list( [tb[0]] )
7698 algoType = self.defaultAlgoType
7699 if not algoType and self.algoTypeToClass:
7700 algoType = sorted( self.algoTypeToClass.keys() )[0]
7701 if algoType in self.algoTypeToClass:
7702 #print("Create algo",algoType)
7703 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7704 raise RuntimeError( "No class found for algo type %s" % algoType)
7707 class hypMethodWrapper:
7709 Private class used to substitute and store variable parameters of hypotheses.
7712 def __init__(self, hyp, method):
7714 self.method = method
7715 #print("REBIND:", method.__name__)
7718 def __call__(self,*args):
7720 call a method of hypothesis with calling SetVarParameter() before
7724 return self.method( self.hyp, *args ) # hypothesis method with no args
7726 #print("MethWrapper.__call__", self.method.__name__, args)
7728 parsed = ParseParameters(*args) # replace variables with their values
7729 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7730 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7731 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7732 # maybe there is a replaced string arg which is not variable
7733 result = self.method( self.hyp, *args )
7734 except ValueError as detail: # raised by ParseParameters()
7736 result = self.method( self.hyp, *args )
7737 except omniORB.CORBA.BAD_PARAM:
7738 raise ValueError(detail) # wrong variable name
7743 class genObjUnRegister:
7745 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7748 def __init__(self, genObj=None):
7749 self.genObjList = []
7753 def set(self, genObj):
7754 "Store one or a list of of SALOME.GenericObj'es"
7755 if isinstance( genObj, list ):
7756 self.genObjList.extend( genObj )
7758 self.genObjList.append( genObj )
7762 for genObj in self.genObjList:
7763 if genObj and hasattr( genObj, "UnRegister" ):
7766 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7768 Bind methods creating mesher plug-ins to the Mesh class
7771 # print("pluginName: ", pluginName)
7772 pluginBuilderName = pluginName + "Builder"
7774 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7775 except Exception as e:
7776 from salome_utils import verbose
7777 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7779 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7780 plugin = eval( pluginBuilderName )
7781 # print(" plugin:" , str(plugin))
7783 # add methods creating algorithms to Mesh
7784 for k in dir( plugin ):
7785 if k[0] == '_': continue
7786 algo = getattr( plugin, k )
7787 #print(" algo:", str(algo))
7788 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7789 #print(" meshMethod:" , str(algo.meshMethod))
7790 if not hasattr( Mesh, algo.meshMethod ):
7791 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7793 _mmethod = getattr( Mesh, algo.meshMethod )
7794 if hasattr( _mmethod, "add" ):