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 ParallelMesh(self, obj, name=0, split_geom=True):
467 Create a parallel mesh.
470 obj: geometrical object for meshing
471 name: the name for the new mesh.
472 split_geom: If True split the geometry and create the assoicated
476 an instance of class :class:`ParallelMesh`.
478 return ParallelMesh(self, self.geompyD, obj,
479 split_geom=split_geom, name=name)
481 def RemoveMesh( self, mesh ):
485 if isinstance( mesh, Mesh ):
486 mesh = mesh.GetMesh()
488 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
489 raise TypeError("%s is not a mesh" % mesh )
490 so = salome.ObjectToSObject( mesh )
492 sb = salome.myStudy.NewBuilder()
493 sb.RemoveObjectWithChildren( so )
499 def EnumToLong(self,theItem):
501 Return a long value from enumeration
506 def ColorToString(self,c):
508 Convert SALOMEDS.Color to string.
509 To be used with filters.
512 c: color value (SALOMEDS.Color)
515 a string representation of the color.
519 if isinstance(c, SALOMEDS.Color):
520 val = "%s;%s;%s" % (c.R, c.G, c.B)
521 elif isinstance(c, str):
524 raise ValueError("Color value should be of string or SALOMEDS.Color type")
527 def GetPointStruct(self,theVertex):
529 Get :class:`SMESH.PointStruct` from vertex
532 theVertex (GEOM.GEOM_Object): vertex
535 :class:`SMESH.PointStruct`
537 geompyD = theVertex.GetGen()
538 [x, y, z] = geompyD.PointCoordinates(theVertex)
539 return PointStruct(x,y,z)
541 def GetDirStruct(self,theVector):
543 Get :class:`SMESH.DirStruct` from vector
546 theVector (GEOM.GEOM_Object): vector
549 :class:`SMESH.DirStruct`
551 geompyD = theVector.GetGen()
552 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
553 if(len(vertices) != 2):
554 print("Error: vector object is incorrect.")
556 p1 = geompyD.PointCoordinates(vertices[0])
557 p2 = geompyD.PointCoordinates(vertices[1])
558 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
559 dirst = DirStruct(pnt)
562 def MakeDirStruct(self,x,y,z):
564 Make :class:`SMESH.DirStruct` from a triplet of floats
567 x,y,z (float): vector components
570 :class:`SMESH.DirStruct`
573 pnt = PointStruct(x,y,z)
574 return DirStruct(pnt)
576 def GetAxisStruct(self,theObj):
578 Get :class:`SMESH.AxisStruct` from a geometrical object
581 theObj (GEOM.GEOM_Object): line or plane
584 :class:`SMESH.AxisStruct`
587 geompyD = theObj.GetGen()
588 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
591 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
592 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
593 vertex1 = geompyD.PointCoordinates(vertex1)
594 vertex2 = geompyD.PointCoordinates(vertex2)
595 vertex3 = geompyD.PointCoordinates(vertex3)
596 vertex4 = geompyD.PointCoordinates(vertex4)
597 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
598 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
599 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] ]
600 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
601 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
602 elif len(edges) == 1:
603 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
604 p1 = geompyD.PointCoordinates( vertex1 )
605 p2 = geompyD.PointCoordinates( vertex2 )
606 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
607 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
608 elif theObj.GetShapeType() == GEOM.VERTEX:
609 x,y,z = geompyD.PointCoordinates( theObj )
610 axis = AxisStruct( x,y,z, 1,0,0,)
611 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
614 # From SMESH_Gen interface:
615 # ------------------------
617 def SetName(self, obj, name):
619 Set the given name to an object
622 obj: the object to rename
623 name: a new object name
626 if isinstance( obj, Mesh ):
628 elif isinstance( obj, Mesh_Algorithm ):
629 obj = obj.GetAlgorithm()
630 ior = salome.orb.object_to_string(obj)
631 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
633 def SetEmbeddedMode( self,theMode ):
638 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
640 def IsEmbeddedMode(self):
645 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
647 def UpdateStudy( self, geompyD = None ):
649 Update the current study. Calling UpdateStudy() allows to
650 update meshes at switching GEOM->SMESH
654 from salome.geom import geomBuilder
655 geompyD = geomBuilder.geom
657 geompyD = geomBuilder.New()
660 self.SetGeomEngine(geompyD)
661 SMESH._objref_SMESH_Gen.UpdateStudy(self)
662 sb = salome.myStudy.NewBuilder()
663 sc = salome.myStudy.FindComponent("SMESH")
665 sb.LoadWith(sc, self)
668 def SetEnablePublish( self, theIsEnablePublish ):
670 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
671 switch **off** publishing in the Study of mesh objects.
673 #self.SetEnablePublish(theIsEnablePublish)
674 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
676 notebook = salome_notebook.NoteBook( theIsEnablePublish )
679 def CreateMeshesFromUNV( self,theFileName ):
681 Create a Mesh object importing data from the given UNV file
684 an instance of class :class:`Mesh`
687 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
688 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
691 def CreateMeshesFromMED( self,theFileName ):
693 Create a Mesh object(s) importing data from the given MED file
696 a tuple ( list of class :class:`Mesh` instances,
697 :class:`SMESH.DriverMED_ReadStatus` )
700 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
701 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
702 return aMeshes, aStatus
704 def CreateMeshesFromSTL( self, theFileName ):
706 Create a Mesh object importing data from the given STL file
709 an instance of class :class:`Mesh`
712 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
713 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
716 def CreateMeshesFromCGNS( self, theFileName ):
718 Create Mesh objects importing data from the given CGNS file
721 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
724 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
725 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
726 return aMeshes, aStatus
728 def CreateMeshesFromGMF( self, theFileName ):
730 Create a Mesh object importing data from the given GMF file.
731 GMF files must have .mesh extension for the ASCII format and .meshb for
735 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
738 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
741 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
742 return Mesh(self, self.geompyD, aSmeshMesh), error
744 def Concatenate( self, meshes, uniteIdenticalGroups,
745 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
746 name = "", meshToAppendTo = None):
748 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
749 All groups of input meshes will be present in the new mesh.
752 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
753 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
754 mergeNodesAndElements: if True, equal nodes and elements are merged
755 mergeTolerance: tolerance for merging nodes
756 allGroups: forces creation of groups corresponding to every input mesh
757 name: name of a new mesh
758 meshToAppendTo: a mesh to append all given meshes
761 an instance of class :class:`Mesh`
767 if not meshes: return None
768 if not isinstance( meshes, list ):
770 for i,m in enumerate( meshes ):
771 if isinstance( m, Mesh ):
772 meshes[i] = m.GetMesh()
773 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
774 if hasattr(meshes[0], "SetParameters"):
775 meshes[0].SetParameters( Parameters )
777 meshes[0].GetMesh().SetParameters( Parameters )
778 if isinstance( meshToAppendTo, Mesh ):
779 meshToAppendTo = meshToAppendTo.GetMesh()
781 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
782 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
783 mergeTolerance,meshToAppendTo )
785 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
786 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
787 mergeTolerance,meshToAppendTo )
789 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
792 def CreateDualMesh( self, mesh, meshName, adaptToShape):
794 Create a dual of a mesh.
797 mesh: Tetrahedron mesh
798 :class:`mesh, <SMESH.SMESH_IDSource>`.
800 meshName: a name of the new mesh
801 adpatToShape: if true project boundary points on shape
804 an instance of class :class:`Mesh`
806 if isinstance( mesh, Mesh ):
807 mesh = mesh.GetMesh()
808 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
809 return Mesh(self, self.geompyD, dualMesh)
812 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
814 Create a mesh by copying a part of another mesh.
817 meshPart: a part of mesh to copy, either
818 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
819 To copy nodes or elements not forming any mesh object,
820 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
821 meshName: a name of the new mesh
822 toCopyGroups: to create in the new mesh groups the copied elements belongs to
823 toKeepIDs: to preserve order of the copied elements or not
826 an instance of class :class:`Mesh`
829 if isinstance( meshPart, Mesh ):
830 meshPart = meshPart.GetMesh()
831 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
832 return Mesh(self, self.geompyD, mesh)
834 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
835 toReuseHypotheses=True, toCopyElements=True):
837 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
838 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
839 To facilitate and speed up the operation, consider using
840 "Set presentation parameters and sub-shapes from arguments" option in
841 a dialog of geometrical operation used to create the new geometry.
844 sourceMesh: the mesh to copy definition of.
845 newGeom: the new geometry.
846 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
847 toCopyGroups: to create groups in the new mesh.
848 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
849 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
852 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
853 *invalidEntries* are study entries of objects whose
854 counterparts are not found in the *newGeom*, followed by entries
855 of mesh sub-objects that are invalid because they depend on a not found
858 if isinstance( sourceMesh, Mesh ):
859 sourceMesh = sourceMesh.GetMesh()
861 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
862 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
866 return ( ok, Mesh(self, self.geompyD, newMesh),
867 newGroups, newSubMeshes, newHypotheses, invalidEntries )
869 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
871 Return IDs of sub-shapes
874 theMainObject (GEOM.GEOM_Object): a shape
875 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
877 the list of integer values
880 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
882 def GetPattern(self):
884 Create a pattern mapper.
887 an instance of :class:`SMESH.SMESH_Pattern`
889 :ref:`Example of Patterns usage <tui_pattern_mapping>`
892 return SMESH._objref_SMESH_Gen.GetPattern(self)
894 def SetBoundaryBoxSegmentation(self, nbSegments):
896 Set number of segments per diagonal of boundary box of geometry, by which
897 default segment length of appropriate 1D hypotheses is defined in GUI.
901 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
903 # Filtering. Auxiliary functions:
904 # ------------------------------
906 def GetEmptyCriterion(self):
908 Create an empty criterion
911 :class:`SMESH.Filter.Criterion`
914 Type = self.EnumToLong(FT_Undefined)
915 Compare = self.EnumToLong(FT_Undefined)
919 UnaryOp = self.EnumToLong(FT_Undefined)
920 BinaryOp = self.EnumToLong(FT_Undefined)
923 Precision = -1 ##@1e-07
924 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
925 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
927 def GetCriterion(self,elementType,
929 Compare = FT_EqualTo,
931 UnaryOp=FT_Undefined,
932 BinaryOp=FT_Undefined,
935 Create a criterion by the given parameters
936 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
939 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
940 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
941 Note that the items starting from FT_LessThan are not suitable for *CritType*.
942 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
943 Threshold: the threshold value (range of ids as string, shape, numeric)
944 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
945 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
947 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
948 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
951 :class:`SMESH.Filter.Criterion`
953 Example: :ref:`combining_filters`
956 if not CritType in SMESH.FunctorType._items:
957 raise TypeError("CritType should be of SMESH.FunctorType")
958 aCriterion = self.GetEmptyCriterion()
959 aCriterion.TypeOfElement = elementType
960 aCriterion.Type = self.EnumToLong(CritType)
961 aCriterion.Tolerance = Tolerance
963 aThreshold = Threshold
965 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
966 aCriterion.Compare = self.EnumToLong(Compare)
967 elif Compare == "=" or Compare == "==":
968 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
970 aCriterion.Compare = self.EnumToLong(FT_LessThan)
972 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
973 elif Compare != FT_Undefined:
974 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
977 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
978 FT_BelongToCylinder, FT_LyingOnGeom]:
979 # Check that Threshold is GEOM object
980 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
981 aCriterion.ThresholdStr = GetName(aThreshold)
982 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
983 if not aCriterion.ThresholdID:
984 name = aCriterion.ThresholdStr
986 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
987 geompyD = aThreshold.GetGen()
988 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
989 # or a name of GEOM object
990 elif isinstance( aThreshold, str ):
991 aCriterion.ThresholdStr = aThreshold
993 raise TypeError("The Threshold should be a shape.")
994 if isinstance(UnaryOp,float):
995 aCriterion.Tolerance = UnaryOp
996 UnaryOp = FT_Undefined
998 elif CritType == FT_BelongToMeshGroup:
999 # Check that Threshold is a group
1000 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
1001 if aThreshold.GetType() != elementType:
1002 raise ValueError("Group type mismatches Element type")
1003 aCriterion.ThresholdStr = aThreshold.GetName()
1004 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
1005 study = salome.myStudy
1007 so = study.FindObjectIOR( aCriterion.ThresholdID )
1011 aCriterion.ThresholdID = entry
1013 raise TypeError("The Threshold should be a Mesh Group")
1014 elif CritType == FT_RangeOfIds:
1015 # Check that Threshold is string
1016 if isinstance(aThreshold, str):
1017 aCriterion.ThresholdStr = aThreshold
1019 raise TypeError("The Threshold should be a string.")
1020 elif CritType == FT_CoplanarFaces:
1021 # Check the Threshold
1022 if isinstance(aThreshold, int):
1023 aCriterion.ThresholdID = str(aThreshold)
1024 elif isinstance(aThreshold, str):
1025 ID = int(aThreshold)
1027 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1028 aCriterion.ThresholdID = aThreshold
1030 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1031 elif CritType == FT_ConnectedElements:
1032 # Check the Threshold
1033 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1034 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1035 if not aCriterion.ThresholdID:
1036 name = aThreshold.GetName()
1038 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1039 geompyD = aThreshold.GetGen()
1040 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1041 elif isinstance(aThreshold, int): # node id
1042 aCriterion.Threshold = aThreshold
1043 elif isinstance(aThreshold, list): # 3 point coordinates
1044 if len( aThreshold ) < 3:
1045 raise ValueError("too few point coordinates, must be 3")
1046 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1047 elif isinstance(aThreshold, str):
1048 if aThreshold.isdigit():
1049 aCriterion.Threshold = aThreshold # node id
1051 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1053 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1054 "or a list of point coordinates and not '%s'"%aThreshold)
1055 elif CritType == FT_ElemGeomType:
1056 # Check the Threshold
1058 aCriterion.Threshold = self.EnumToLong(aThreshold)
1059 assert( aThreshold in SMESH.GeometryType._items )
1061 if isinstance(aThreshold, int):
1062 aCriterion.Threshold = aThreshold
1064 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1067 elif CritType == FT_EntityType:
1068 # Check the Threshold
1070 aCriterion.Threshold = self.EnumToLong(aThreshold)
1071 assert( aThreshold in SMESH.EntityType._items )
1073 if isinstance(aThreshold, int):
1074 aCriterion.Threshold = aThreshold
1076 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1080 elif CritType == FT_GroupColor:
1081 # Check the Threshold
1083 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1085 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1087 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1088 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1089 FT_BareBorderFace, FT_BareBorderVolume,
1090 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1091 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1092 # At this point the Threshold is unnecessary
1093 if aThreshold == FT_LogicalNOT:
1094 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1095 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1096 aCriterion.BinaryOp = aThreshold
1100 aThreshold = float(aThreshold)
1101 aCriterion.Threshold = aThreshold
1103 raise TypeError("The Threshold should be a number.")
1106 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1107 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1109 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1110 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1112 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1113 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1115 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1116 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1120 def GetFilter(self,elementType,
1121 CritType=FT_Undefined,
1124 UnaryOp=FT_Undefined,
1128 Create a filter with the given parameters
1131 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1132 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1133 Note that the items starting from FT_LessThan are not suitable for CritType.
1134 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1135 Threshold: the threshold value (range of ids as string, shape, numeric)
1136 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1137 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1138 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1139 mesh: the mesh to initialize the filter with
1142 :class:`SMESH.Filter`
1145 See :doc:`Filters usage examples <tui_filters>`
1148 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1149 aFilterMgr = self.CreateFilterManager()
1150 aFilter = aFilterMgr.CreateFilter()
1152 aCriteria.append(aCriterion)
1153 aFilter.SetCriteria(aCriteria)
1155 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1156 else : aFilter.SetMesh( mesh )
1157 aFilterMgr.UnRegister()
1160 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1162 Create a filter from criteria
1165 criteria: a list of :class:`SMESH.Filter.Criterion`
1166 binOp: binary operator used when binary operator of criteria is undefined
1169 :class:`SMESH.Filter`
1172 See :doc:`Filters usage examples <tui_filters>`
1175 for i in range( len( criteria ) - 1 ):
1176 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1177 criteria[i].BinaryOp = self.EnumToLong( binOp )
1178 aFilterMgr = self.CreateFilterManager()
1179 aFilter = aFilterMgr.CreateFilter()
1180 aFilter.SetCriteria(criteria)
1181 aFilterMgr.UnRegister()
1184 def GetFunctor(self,theCriterion):
1186 Create a numerical functor by its type
1189 theCriterion (SMESH.FunctorType): functor type.
1190 Note that not all items correspond to numerical functors.
1193 :class:`SMESH.NumericalFunctor`
1196 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1198 aFilterMgr = self.CreateFilterManager()
1200 if theCriterion == FT_AspectRatio:
1201 functor = aFilterMgr.CreateAspectRatio()
1202 elif theCriterion == FT_AspectRatio3D:
1203 functor = aFilterMgr.CreateAspectRatio3D()
1204 elif theCriterion == FT_Warping:
1205 functor = aFilterMgr.CreateWarping()
1206 elif theCriterion == FT_MinimumAngle:
1207 functor = aFilterMgr.CreateMinimumAngle()
1208 elif theCriterion == FT_Taper:
1209 functor = aFilterMgr.CreateTaper()
1210 elif theCriterion == FT_Skew:
1211 functor = aFilterMgr.CreateSkew()
1212 elif theCriterion == FT_Area:
1213 functor = aFilterMgr.CreateArea()
1214 elif theCriterion == FT_Volume3D:
1215 functor = aFilterMgr.CreateVolume3D()
1216 elif theCriterion == FT_MaxElementLength2D:
1217 functor = aFilterMgr.CreateMaxElementLength2D()
1218 elif theCriterion == FT_MaxElementLength3D:
1219 functor = aFilterMgr.CreateMaxElementLength3D()
1220 elif theCriterion == FT_MultiConnection:
1221 functor = aFilterMgr.CreateMultiConnection()
1222 elif theCriterion == FT_MultiConnection2D:
1223 functor = aFilterMgr.CreateMultiConnection2D()
1224 elif theCriterion == FT_Length:
1225 functor = aFilterMgr.CreateLength()
1226 elif theCriterion == FT_Length2D:
1227 functor = aFilterMgr.CreateLength2D()
1228 elif theCriterion == FT_Length3D:
1229 functor = aFilterMgr.CreateLength3D()
1230 elif theCriterion == FT_Deflection2D:
1231 functor = aFilterMgr.CreateDeflection2D()
1232 elif theCriterion == FT_NodeConnectivityNumber:
1233 functor = aFilterMgr.CreateNodeConnectivityNumber()
1234 elif theCriterion == FT_BallDiameter:
1235 functor = aFilterMgr.CreateBallDiameter()
1237 print("Error: given parameter is not numerical functor type.")
1238 aFilterMgr.UnRegister()
1241 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1246 theHType (string): mesh hypothesis type
1247 theLibName (string): mesh plug-in library name
1250 created hypothesis instance
1252 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1254 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1257 # wrap hypothesis methods
1258 for meth_name in dir( hyp.__class__ ):
1259 if not meth_name.startswith("Get") and \
1260 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1261 method = getattr ( hyp.__class__, meth_name )
1262 if callable(method):
1263 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1267 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1269 Create hypothesis initialized according to parameters
1272 hypType (string): hypothesis type
1273 libName (string): plug-in library name
1274 mesh: optional mesh by which a hypotheses can initialize self
1275 shape: optional geometry by size of which a hypotheses can initialize self
1276 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1279 created hypothesis instance
1281 if isinstance( mesh, Mesh ):
1282 mesh = mesh.GetMesh()
1283 if isinstance( initParams, (bool,int)):
1284 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1285 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1286 mesh, shape, initParams )
1288 def GetMeshInfo(self, obj):
1290 Get the mesh statistic.
1293 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1296 if isinstance( obj, Mesh ):
1299 if hasattr(obj, "GetMeshInfo"):
1300 values = obj.GetMeshInfo()
1301 for i in range(SMESH.Entity_Last._v):
1302 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1306 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1308 Get minimum distance between two objects
1310 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1311 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1314 src1 (SMESH.SMESH_IDSource): first source object
1315 src2 (SMESH.SMESH_IDSource): second source object
1316 id1 (int): node/element id from the first source
1317 id2 (int): node/element id from the second (or first) source
1318 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1319 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1322 minimum distance value
1325 :meth:`GetMinDistance`
1328 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1332 result = result.value
1335 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1337 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1339 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1340 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1343 src1 (SMESH.SMESH_IDSource): first source object
1344 src2 (SMESH.SMESH_IDSource): second source object
1345 id1 (int): node/element id from the first source
1346 id2 (int): node/element id from the second (or first) source
1347 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1348 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1351 :class:`SMESH.Measure` structure or None if input data is invalid
1356 if isinstance(src1, Mesh): src1 = src1.mesh
1357 if isinstance(src2, Mesh): src2 = src2.mesh
1358 if src2 is None and id2 != 0: src2 = src1
1359 if not hasattr(src1, "_narrow"): return None
1360 src1 = src1._narrow(SMESH.SMESH_IDSource)
1361 if not src1: return None
1362 unRegister = genObjUnRegister()
1365 e = m.GetMeshEditor()
1367 src1 = e.MakeIDSource([id1], SMESH.FACE)
1369 src1 = e.MakeIDSource([id1], SMESH.NODE)
1370 unRegister.set( src1 )
1372 if hasattr(src2, "_narrow"):
1373 src2 = src2._narrow(SMESH.SMESH_IDSource)
1374 if src2 and id2 != 0:
1376 e = m.GetMeshEditor()
1378 src2 = e.MakeIDSource([id2], SMESH.FACE)
1380 src2 = e.MakeIDSource([id2], SMESH.NODE)
1381 unRegister.set( src2 )
1384 aMeasurements = self.CreateMeasurements()
1385 unRegister.set( aMeasurements )
1386 result = aMeasurements.MinDistance(src1, src2)
1389 def BoundingBox(self, objects):
1391 Get bounding box of the specified object(s)
1394 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1397 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1400 :meth:`GetBoundingBox`
1403 result = self.GetBoundingBox(objects)
1407 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1410 def GetBoundingBox(self, objects):
1412 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1415 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1418 :class:`SMESH.Measure` structure
1424 if isinstance(objects, tuple):
1425 objects = list(objects)
1426 if not isinstance(objects, list):
1430 if isinstance(o, Mesh):
1431 srclist.append(o.mesh)
1432 elif hasattr(o, "_narrow"):
1433 src = o._narrow(SMESH.SMESH_IDSource)
1434 if src: srclist.append(src)
1437 aMeasurements = self.CreateMeasurements()
1438 result = aMeasurements.BoundingBox(srclist)
1439 aMeasurements.UnRegister()
1442 def GetLength(self, obj):
1444 Get sum of lengths of all 1D elements in the mesh object.
1447 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1450 sum of lengths of all 1D 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.Length(obj)
1457 aMeasurements.UnRegister()
1460 def GetArea(self, obj):
1462 Get sum of areas of all 2D elements in the mesh object.
1465 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1468 sum of areas of all 2D elements
1471 if isinstance(obj, Mesh): obj = obj.mesh
1472 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1473 aMeasurements = self.CreateMeasurements()
1474 value = aMeasurements.Area(obj)
1475 aMeasurements.UnRegister()
1478 def GetVolume(self, obj):
1480 Get sum of volumes of all 3D elements in the mesh object.
1483 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1486 sum of volumes of all 3D elements
1489 if isinstance(obj, Mesh): obj = obj.mesh
1490 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1491 aMeasurements = self.CreateMeasurements()
1492 value = aMeasurements.Volume(obj)
1493 aMeasurements.UnRegister()
1496 def GetGravityCenter(self, obj):
1498 Get gravity center of all nodes of a mesh object.
1501 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1504 Three components of the gravity center (x,y,z)
1507 :meth:`Mesh.BaryCenter`
1509 if isinstance(obj, Mesh): obj = obj.mesh
1510 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1511 aMeasurements = self.CreateMeasurements()
1512 pointStruct = aMeasurements.GravityCenter(obj)
1513 aMeasurements.UnRegister()
1514 return pointStruct.x, pointStruct.y, pointStruct.z
1516 def GetAngle(self, p1, p2, p3 ):
1518 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1521 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1527 if isinstance( p1, list ): p1 = PointStruct(*p1)
1528 if isinstance( p2, list ): p2 = PointStruct(*p2)
1529 if isinstance( p3, list ): p3 = PointStruct(*p3)
1531 aMeasurements = self.CreateMeasurements()
1532 angle = aMeasurements.Angle(p1,p2,p3)
1533 aMeasurements.UnRegister()
1538 pass # end of class smeshBuilder
1541 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1542 """Registering the new proxy for SMESH.SMESH_Gen"""
1545 def New( instance=None, instanceGeom=None):
1547 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1548 interface to create or load meshes.
1553 salome.salome_init()
1554 from salome.smesh import smeshBuilder
1555 smesh = smeshBuilder.New()
1558 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1559 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1561 :class:`smeshBuilder` instance
1566 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1568 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1573 smeshInst = smeshBuilder()
1574 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1575 smeshInst.init_smesh(instanceGeom)
1579 # Public class: Mesh
1580 # ==================
1583 class Mesh(metaclass = MeshMeta):
1585 This class allows defining and managing a mesh.
1586 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1587 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1588 new nodes and elements and by changing the existing entities), to get information
1589 about a mesh and to export a mesh in different formats.
1596 def __init__(self, smeshpyD, geompyD, obj=0, name=0, parallel=False):
1601 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1602 sets the GUI name of this mesh to *name*.
1605 smeshpyD: an instance of smeshBuilder class
1606 geompyD: an instance of geomBuilder class
1607 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1608 name: Study name of the mesh
1611 self.smeshpyD = smeshpyD
1612 self.geompyD = geompyD
1617 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1620 # publish geom of mesh (issue 0021122)
1621 if not self.geom.GetStudyEntry():
1625 geo_name = name + " shape"
1627 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1628 geompyD.addToStudy( self.geom, geo_name )
1629 if parallel and isinstance(self, ParallelMesh):
1630 self.SetMesh( self.smeshpyD.CreateParallelMesh(self.geom) )
1632 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1634 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1637 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1639 self.smeshpyD.SetName(self.mesh, name)
1641 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1644 self.geom = self.mesh.GetShapeToMesh()
1646 self.editor = self.mesh.GetMeshEditor()
1647 self.functors = [None] * SMESH.FT_Undefined._v
1649 # set self to algoCreator's
1650 for attrName in dir(self):
1651 attr = getattr( self, attrName )
1652 if isinstance( attr, algoCreator ):
1653 setattr( self, attrName, attr.copy( self ))
1660 Destructor. Clean-up resources
1663 #self.mesh.UnRegister()
1667 def SetMesh(self, theMesh):
1669 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1672 theMesh: a :class:`SMESH.SMESH_Mesh` object
1674 # do not call Register() as this prevents mesh servant deletion at closing study
1675 #if self.mesh: self.mesh.UnRegister()
1678 #self.mesh.Register()
1679 self.geom = self.mesh.GetShapeToMesh()
1683 if salome.sg.hasDesktop():
1684 so = salome.ObjectToSObject( self.geom )
1685 comp = so.GetFatherComponent()
1686 if comp.ComponentDataType() == "SHAPERSTUDY":
1687 import shaperBuilder
1688 self.geompyD = shaperBuilder.New()
1691 if not self.geompyD:
1692 self.geompyD = self.geom.GetGen()
1697 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1700 a :class:`SMESH.SMESH_Mesh` object
1705 def GetEngine(self):
1707 Return a smeshBuilder instance created this mesh
1709 return self.smeshpyD
1711 def GetGeomEngine(self):
1713 Return a geomBuilder instance
1719 Get the name of the mesh
1722 the name of the mesh as a string
1725 name = GetName(self.GetMesh())
1728 def SetName(self, name):
1730 Set a name to the mesh
1733 name: a new name of the mesh
1736 self.smeshpyD.SetName(self.GetMesh(), name)
1738 def GetSubMesh(self, geom, name):
1740 Get a sub-mesh object associated to a *geom* geometrical object.
1743 geom: a geometrical object (shape)
1744 name: a name for the sub-mesh in the Object Browser
1747 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1748 which lies on the given shape
1751 A sub-mesh is implicitly created when a sub-shape is specified at
1752 creating an algorithm, for example::
1754 algo1D = mesh.Segment(geom=Edge_1)
1756 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1757 The created sub-mesh can be retrieved from the algorithm::
1759 submesh = algo1D.GetSubMesh()
1762 AssureGeomPublished( self, geom, name )
1763 submesh = self.mesh.GetSubMesh( geom, name )
1768 Return the shape associated to the mesh
1776 def SetShape(self, geom):
1778 Associate the given shape to the mesh (entails the recreation of the mesh)
1781 geom: the shape to be meshed (GEOM_Object)
1784 self.mesh = self.smeshpyD.CreateMesh(geom)
1786 def HasShapeToMesh(self):
1788 Return ``True`` if this mesh is based on geometry
1790 return self.mesh.HasShapeToMesh()
1794 Load mesh from the study after opening the study
1798 def IsReadyToCompute(self, theSubObject):
1800 Return true if the hypotheses are defined well
1803 theSubObject: a sub-shape of a mesh shape
1809 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1811 def GetAlgoState(self, theSubObject):
1813 Return errors of hypotheses definition.
1814 The list of errors is empty if everything is OK.
1817 theSubObject: a sub-shape of a mesh shape
1823 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1825 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1827 Return a geometrical object on which the given element was built.
1828 The returned geometrical object, if not nil, is either found in the
1829 study or published by this method with the given name
1832 theElementID: the id of the mesh element
1833 theGeomName: the user-defined name of the geometrical object
1836 GEOM.GEOM_Object instance
1839 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1841 def MeshDimension(self):
1843 Return the mesh dimension depending on the dimension of the underlying shape
1844 or, if the mesh is not based on any shape, basing on deimension of elements
1847 mesh dimension as an integer value [0,3]
1850 if self.mesh.HasShapeToMesh():
1851 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1852 if len( shells ) > 0 :
1854 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1856 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1861 if self.NbVolumes() > 0: return 3
1862 if self.NbFaces() > 0: return 2
1863 if self.NbEdges() > 0: return 1
1866 def Evaluate(self, geom=0):
1868 Evaluate size of prospective mesh on a shape
1871 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1872 To know predicted number of e.g. edges, inquire it this way::
1874 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1877 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1879 geom = self.mesh.GetShapeToMesh()
1882 return self.smeshpyD.Evaluate(self.mesh, geom)
1884 def Compute(self, geom=0, discardModifs=False, refresh=False):
1886 Compute the mesh and return the status of the computation
1889 geom: geomtrical shape on which mesh data should be computed
1890 discardModifs: if True and the mesh has been edited since
1891 a last total re-compute and that may prevent successful partial re-compute,
1892 then the mesh is cleaned before Compute()
1893 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1899 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1900 geom = self.mesh.GetShapeToMesh()
1903 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1905 ok = self.smeshpyD.Compute(self.mesh, geom)
1906 except SALOME.SALOME_Exception as ex:
1907 print("Mesh computation failed, exception caught:")
1908 print(" ", ex.details.text)
1911 print("Mesh computation failed, exception caught:")
1912 traceback.print_exc()
1916 # Treat compute errors
1917 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1919 for err in computeErrors:
1920 if self.mesh.HasShapeToMesh():
1921 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1923 stdErrors = ["OK", #COMPERR_OK
1924 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1925 "std::exception", #COMPERR_STD_EXCEPTION
1926 "OCC exception", #COMPERR_OCC_EXCEPTION
1927 "..", #COMPERR_SLM_EXCEPTION
1928 "Unknown exception", #COMPERR_EXCEPTION
1929 "Memory allocation problem", #COMPERR_MEMORY_PB
1930 "Algorithm failed", #COMPERR_ALGO_FAILED
1931 "Unexpected geometry", #COMPERR_BAD_SHAPE
1932 "Warning", #COMPERR_WARNING
1933 "Computation cancelled",#COMPERR_CANCELED
1934 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1936 if err.code < len(stdErrors): errText = stdErrors[err.code]
1938 errText = "code %s" % -err.code
1939 if errText: errText += ". "
1940 errText += err.comment
1941 if allReasons: allReasons += "\n"
1943 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1945 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1949 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1951 if err.isGlobalAlgo:
1959 reason = '%s %sD algorithm is missing' % (glob, dim)
1960 elif err.state == HYP_MISSING:
1961 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1962 % (glob, dim, name, dim))
1963 elif err.state == HYP_NOTCONFORM:
1964 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1965 elif err.state == HYP_BAD_PARAMETER:
1966 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1967 % ( glob, dim, name ))
1968 elif err.state == HYP_BAD_GEOMETRY:
1969 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1970 'geometry' % ( glob, dim, name ))
1971 elif err.state == HYP_HIDDEN_ALGO:
1972 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1973 'algorithm of upper dimension generating %sD mesh'
1974 % ( glob, dim, name, glob, dim ))
1976 reason = ("For unknown reason. "
1977 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1979 if allReasons: allReasons += "\n"
1980 allReasons += "- " + reason
1982 if not ok or allReasons != "":
1983 msg = '"' + GetName(self.mesh) + '"'
1984 if ok: msg += " has been computed with warnings"
1985 else: msg += " has not been computed"
1986 if allReasons != "": msg += ":"
1992 if salome.sg.hasDesktop():
1993 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1994 if refresh: salome.sg.updateObjBrowser()
1998 def GetComputeErrors(self, shape=0 ):
2000 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2004 shape = self.mesh.GetShapeToMesh()
2005 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2007 def GetSubShapeName(self, subShapeID ):
2009 Return a name of a sub-shape by its ID.
2010 Possible variants (for *subShapeID* == 3):
2012 - **"Face_12"** - published sub-shape
2013 - **FACE #3** - not published sub-shape
2014 - **sub-shape #3** - invalid sub-shape ID
2015 - **#3** - error in this function
2018 subShapeID: a unique ID of a sub-shape
2021 a string describing the sub-shape
2025 if not self.mesh.HasShapeToMesh():
2029 mainIOR = salome.orb.object_to_string( self.GetShape() )
2031 mainSO = s.FindObjectIOR(mainIOR)
2034 shapeText = '"%s"' % mainSO.GetName()
2035 subIt = s.NewChildIterator(mainSO)
2037 subSO = subIt.Value()
2039 obj = subSO.GetObject()
2040 if not obj: continue
2041 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2044 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2047 if ids == subShapeID:
2048 shapeText = '"%s"' % subSO.GetName()
2051 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2053 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2055 shapeText = 'sub-shape #%s' % (subShapeID)
2057 shapeText = "#%s" % (subShapeID)
2060 def GetFailedShapes(self, publish=False):
2062 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2063 error of an algorithm
2066 publish: if *True*, the returned groups will be published in the study
2069 a list of GEOM groups each named after a failed algorithm
2074 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2075 for err in computeErrors:
2076 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2077 if not shape: continue
2078 if err.algoName in algo2shapes:
2079 algo2shapes[ err.algoName ].append( shape )
2081 algo2shapes[ err.algoName ] = [ shape ]
2085 for algoName, shapes in list(algo2shapes.items()):
2087 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2088 otherTypeShapes = []
2090 group = self.geompyD.CreateGroup( self.geom, groupType )
2091 for shape in shapes:
2092 if shape.GetShapeType() == shapes[0].GetShapeType():
2093 sameTypeShapes.append( shape )
2095 otherTypeShapes.append( shape )
2096 self.geompyD.UnionList( group, sameTypeShapes )
2098 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2100 group.SetName( algoName )
2101 groups.append( group )
2102 shapes = otherTypeShapes
2105 for group in groups:
2106 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2109 def GetMeshOrder(self):
2111 Return sub-mesh objects list in meshing order
2114 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2117 return self.mesh.GetMeshOrder()
2119 def SetMeshOrder(self, submeshes):
2121 Set priority of sub-meshes. It works in two ways:
2123 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2124 *several dimensions*, it sets the order in which the sub-meshes are computed.
2125 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2126 when looking for meshing parameters to apply to a sub-shape. To impose the
2127 order in which sub-meshes with uni-dimensional algorithms are computed,
2128 call **submesh.Compute()** in a desired order.
2131 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2133 Warning: the method is for setting the order for all sub-meshes at once:
2134 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2137 return self.mesh.SetMeshOrder(submeshes)
2139 def Clear(self, refresh=False):
2141 Remove all nodes and elements generated on geometry. Imported elements remain.
2144 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2148 if ( salome.sg.hasDesktop() ):
2149 if refresh: salome.sg.updateObjBrowser()
2151 def ClearSubMesh(self, geomId, refresh=False):
2153 Remove all nodes and elements of indicated shape
2156 geomId: the ID of a sub-shape to remove elements on
2157 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2160 self.mesh.ClearSubMesh(geomId)
2161 if salome.sg.hasDesktop():
2162 if refresh: salome.sg.updateObjBrowser()
2164 def AutomaticTetrahedralization(self, fineness=0):
2166 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2169 fineness: [0.0,1.0] defines mesh fineness
2175 dim = self.MeshDimension()
2177 self.RemoveGlobalHypotheses()
2178 self.Segment().AutomaticLength(fineness)
2180 self.Triangle().LengthFromEdges()
2185 return self.Compute()
2187 def AutomaticHexahedralization(self, fineness=0):
2189 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2192 fineness: [0.0, 1.0] defines mesh fineness
2198 dim = self.MeshDimension()
2199 # assign the hypotheses
2200 self.RemoveGlobalHypotheses()
2201 self.Segment().AutomaticLength(fineness)
2208 return self.Compute()
2210 def AddHypothesis(self, hyp, geom=0):
2215 hyp: a hypothesis to assign
2216 geom: a subhape of mesh geometry
2219 :class:`SMESH.Hypothesis_Status`
2222 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2223 hyp, geom = geom, hyp
2224 if isinstance( hyp, Mesh_Algorithm ):
2225 hyp = hyp.GetAlgorithm()
2230 geom = self.mesh.GetShapeToMesh()
2233 if self.mesh.HasShapeToMesh():
2234 hyp_type = hyp.GetName()
2235 lib_name = hyp.GetLibName()
2236 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2237 # if checkAll and geom:
2238 # checkAll = geom.GetType() == 37
2240 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2242 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2243 status = self.mesh.AddHypothesis(geom, hyp)
2245 status = HYP_BAD_GEOMETRY, ""
2246 hyp_name = GetName( hyp )
2249 geom_name = geom.GetName()
2250 isAlgo = hyp._narrow( SMESH_Algo )
2251 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2254 def IsUsedHypothesis(self, hyp, geom):
2256 Return True if an algorithm or hypothesis is assigned to a given shape
2259 hyp: an algorithm or hypothesis to check
2260 geom: a subhape of mesh geometry
2266 if not hyp: # or not geom
2268 if isinstance( hyp, Mesh_Algorithm ):
2269 hyp = hyp.GetAlgorithm()
2271 hyps = self.GetHypothesisList(geom)
2273 if h.GetId() == hyp.GetId():
2277 def RemoveHypothesis(self, hyp, geom=0):
2279 Unassign a hypothesis
2282 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2283 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2286 :class:`SMESH.Hypothesis_Status`
2291 if isinstance( hyp, Mesh_Algorithm ):
2292 hyp = hyp.GetAlgorithm()
2298 if self.IsUsedHypothesis( hyp, shape ):
2299 return self.mesh.RemoveHypothesis( shape, hyp )
2300 hypName = GetName( hyp )
2301 geoName = GetName( shape )
2302 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2305 def GetHypothesisList(self, geom):
2307 Get the list of hypotheses added on a geometry
2310 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2313 the sequence of :class:`SMESH.SMESH_Hypothesis`
2316 return self.mesh.GetHypothesisList( geom )
2318 def RemoveGlobalHypotheses(self):
2320 Remove all global hypotheses
2323 current_hyps = self.mesh.GetHypothesisList( self.geom )
2324 for hyp in current_hyps:
2325 self.mesh.RemoveHypothesis( self.geom, hyp )
2329 def ExportMEDCoupling(self, *args, **kwargs):
2331 Export the mesh in a memory representation.
2334 auto_groups (boolean): parameter for creating/not creating
2335 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2336 the typical use is auto_groups=False.
2337 overwrite (boolean): parameter for overwriting/not overwriting the file
2338 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2339 to export instead of the mesh
2340 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2342 - 1D if all mesh nodes lie on OX coordinate axis, or
2343 - 2D if all mesh nodes lie on XOY coordinate plane, or
2344 - 3D in the rest cases.
2346 If *autoDimension* is *False*, the space dimension is always 3.
2347 fields: list of GEOM fields defined on the shape to mesh.
2348 geomAssocFields: each character of this string means a need to export a
2349 corresponding field; correspondence between fields and characters
2352 - 'v' stands for "_vertices_" field;
2353 - 'e' stands for "_edges_" field;
2354 - 'f' stands for "_faces_" field;
2355 - 's' stands for "_solids_" field.
2357 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2358 close to zero within a given tolerance, the coordinate is set to zero.
2359 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2360 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2362 auto_groups = args[0] if len(args) > 0 else False
2363 meshPart = args[1] if len(args) > 1 else None
2364 autoDimension = args[2] if len(args) > 2 else True
2365 fields = args[3] if len(args) > 3 else []
2366 geomAssocFields = args[4] if len(args) > 4 else ''
2367 z_tolerance = args[5] if len(args) > 5 else -1.
2368 saveNumbers = args[6] if len(args) > 6 else True
2369 # process keywords arguments
2370 auto_groups = kwargs.get("auto_groups", auto_groups)
2371 meshPart = kwargs.get("meshPart", meshPart)
2372 autoDimension = kwargs.get("autoDimension", autoDimension)
2373 fields = kwargs.get("fields", fields)
2374 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2375 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2376 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2378 # invoke engine's function
2379 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2380 unRegister = genObjUnRegister()
2381 if isinstance( meshPart, list ):
2382 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2383 unRegister.set( meshPart )
2385 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2386 self.mesh.SetParameters(Parameters)
2388 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2389 fields, geomAssocFields, z_tolerance,
2392 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2393 return medcoupling.MEDFileData.New(dab)
2395 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2397 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2398 return medcoupling.MEDFileMesh.New(dab)
2400 def ExportMED(self, *args, **kwargs):
2402 Export the mesh in a file in MED format
2403 allowing to overwrite the file if it exists or add the exported data to its contents
2406 fileName: is the file name
2407 auto_groups (boolean): parameter for creating/not creating
2408 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2409 the typical use is auto_groups=False.
2410 version (int): define the version (xy, where version is x.y.z) of MED file format.
2411 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2412 The rules of compatibility to write a mesh in an older version than
2413 the current version depend on the current version. For instance,
2414 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2415 or 3.2.1 or 3.3.1 formats.
2416 If the version is equal to -1, the version is not changed (default).
2417 overwrite (boolean): parameter for overwriting/not overwriting the file
2418 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2419 to export instead of the mesh
2420 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2422 - 1D if all mesh nodes lie on OX coordinate axis, or
2423 - 2D if all mesh nodes lie on XOY coordinate plane, or
2424 - 3D in the rest cases.
2426 If *autoDimension* is *False*, the space dimension is always 3.
2427 fields: list of GEOM fields defined on the shape to mesh.
2428 geomAssocFields: each character of this string means a need to export a
2429 corresponding field; correspondence between fields and characters
2432 - 'v' stands for "_vertices_" field;
2433 - 'e' stands for "_edges_" field;
2434 - 'f' stands for "_faces_" field;
2435 - 's' stands for "_solids_" field.
2437 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2438 close to zero within a given tolerance, the coordinate is set to zero.
2439 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2440 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2442 # process positional arguments
2443 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2445 auto_groups = args[1] if len(args) > 1 else False
2446 version = args[2] if len(args) > 2 else -1
2447 overwrite = args[3] if len(args) > 3 else True
2448 meshPart = args[4] if len(args) > 4 else None
2449 autoDimension = args[5] if len(args) > 5 else True
2450 fields = args[6] if len(args) > 6 else []
2451 geomAssocFields = args[7] if len(args) > 7 else ''
2452 z_tolerance = args[8] if len(args) > 8 else -1.
2453 saveNumbers = args[9] if len(args) > 9 else True
2454 # process keywords arguments
2455 auto_groups = kwargs.get("auto_groups", auto_groups)
2456 version = kwargs.get("version", version)
2457 version = kwargs.get("minor", version)
2458 overwrite = kwargs.get("overwrite", overwrite)
2459 meshPart = kwargs.get("meshPart", meshPart)
2460 autoDimension = kwargs.get("autoDimension", autoDimension)
2461 fields = kwargs.get("fields", fields)
2462 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2463 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2464 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2466 if isinstance( meshPart, Mesh):
2467 meshPart = meshPart.GetMesh()
2469 # invoke engine's function
2470 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2471 unRegister = genObjUnRegister()
2472 if isinstance( meshPart, list ):
2473 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2474 unRegister.set( meshPart )
2476 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2477 self.mesh.SetParameters(Parameters)
2479 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2480 version, overwrite, autoDimension,
2481 fields, geomAssocFields, z_tolerance, saveNumbers )
2483 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2485 def ExportDAT(self, f, meshPart=None, renumber=True):
2487 Export the mesh in a file in DAT format
2491 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2492 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2495 if meshPart or not renumber:
2496 unRegister = genObjUnRegister()
2497 if isinstance( meshPart, list ):
2498 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2499 unRegister.set( meshPart )
2500 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2502 self.mesh.ExportDAT( f, renumber )
2504 def ExportUNV(self, f, meshPart=None, renumber=True):
2506 Export the mesh in a file in UNV format
2510 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2511 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2514 if meshPart or not renumber:
2515 unRegister = genObjUnRegister()
2516 if isinstance( meshPart, list ):
2517 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2518 unRegister.set( meshPart )
2519 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2521 self.mesh.ExportUNV( f, renumber )
2523 def ExportSTL(self, f, ascii=1, meshPart=None):
2525 Export the mesh in a file in STL format
2529 ascii: defines the file encoding
2530 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2534 unRegister = genObjUnRegister()
2535 if isinstance( meshPart, list ):
2536 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2537 unRegister.set( meshPart )
2538 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2540 self.mesh.ExportSTL(f, ascii)
2542 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2544 Export the mesh in a file in CGNS format
2548 overwrite: boolean parameter for overwriting/not overwriting the file
2549 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2550 groupElemsByType: if True all elements of same entity type are exported at ones,
2551 else elements are exported in order of their IDs which can cause creation
2552 of multiple cgns sections
2555 unRegister = genObjUnRegister()
2556 if isinstance( meshPart, list ):
2557 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2558 unRegister.set( meshPart )
2559 if isinstance( meshPart, Mesh ):
2560 meshPart = meshPart.mesh
2562 meshPart = self.mesh
2563 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2565 def ExportGMF(self, f, meshPart=None):
2567 Export the mesh in a file in GMF format.
2568 GMF files must have .mesh extension for the ASCII format and .meshb for
2569 the bynary format. Other extensions are not allowed.
2573 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2576 unRegister = genObjUnRegister()
2577 if isinstance( meshPart, list ):
2578 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2579 unRegister.set( meshPart )
2580 if isinstance( meshPart, Mesh ):
2581 meshPart = meshPart.mesh
2583 meshPart = self.mesh
2584 self.mesh.ExportGMF(meshPart, f, True)
2586 def ExportToMED(self, *args, **kwargs):
2588 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2589 Export the mesh in a file in MED format
2590 allowing to overwrite the file if it exists or add the exported data to its contents
2593 fileName: the file name
2594 opt (boolean): parameter for creating/not creating
2595 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2596 overwrite: boolean parameter for overwriting/not overwriting the file
2597 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2599 - 1D if all mesh nodes lie on OX coordinate axis, or
2600 - 2D if all mesh nodes lie on XOY coordinate plane, or
2601 - 3D in the rest cases.
2603 If **autoDimension** is *False*, the space dimension is always 3.
2606 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2607 # process positional arguments
2608 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2610 auto_groups = args[1] if len(args) > 1 else False
2611 overwrite = args[2] if len(args) > 2 else True
2612 autoDimension = args[3] if len(args) > 3 else True
2613 # process keywords arguments
2614 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2615 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2616 overwrite = kwargs.get("overwrite", overwrite)
2617 autoDimension = kwargs.get("autoDimension", autoDimension)
2619 # invoke engine's function
2620 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2622 def ExportToMEDX(self, *args, **kwargs):
2624 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2625 Export the mesh in a file in MED format
2628 fileName: the file name
2629 opt (boolean): parameter for creating/not creating
2630 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2631 overwrite: boolean parameter for overwriting/not overwriting the file
2632 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2634 - 1D if all mesh nodes lie on OX coordinate axis, or
2635 - 2D if all mesh nodes lie on XOY coordinate plane, or
2636 - 3D in the rest cases.
2638 If **autoDimension** is *False*, the space dimension is always 3.
2641 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2642 # process positional arguments
2643 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2645 auto_groups = args[1] if len(args) > 1 else False
2646 overwrite = args[2] if len(args) > 2 else True
2647 autoDimension = args[3] if len(args) > 3 else True
2648 # process keywords arguments
2649 auto_groups = kwargs.get("auto_groups", auto_groups)
2650 overwrite = kwargs.get("overwrite", overwrite)
2651 autoDimension = kwargs.get("autoDimension", autoDimension)
2653 # invoke engine's function
2654 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2658 def Append(self, meshes, uniteIdenticalGroups = True,
2659 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2661 Append given meshes into this mesh.
2662 All groups of input meshes will be created in this mesh.
2665 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2666 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2667 mergeNodesAndElements: if True, equal nodes and elements are merged
2668 mergeTolerance: tolerance for merging nodes
2669 allGroups: forces creation of groups corresponding to every input mesh
2671 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2672 mergeNodesAndElements, mergeTolerance, allGroups,
2673 meshToAppendTo = self.GetMesh() )
2675 # Operations with groups:
2676 # ----------------------
2677 def CreateEmptyGroup(self, elementType, name):
2679 Create an empty standalone mesh group
2682 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2683 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2684 name: the name of the mesh group
2687 :class:`SMESH.SMESH_Group`
2690 return self.mesh.CreateGroup(elementType, name)
2692 def Group(self, grp, name=""):
2694 Create a mesh group based on the geometric object *grp*
2695 and give it a *name*.
2696 If *name* is not defined the name of the geometric group is used
2699 Works like :meth:`GroupOnGeom`.
2702 grp: a geometric group, a vertex, an edge, a face or a solid
2703 name: the name of the mesh group
2706 :class:`SMESH.SMESH_GroupOnGeom`
2709 return self.GroupOnGeom(grp, name)
2711 def GroupOnGeom(self, grp, name="", typ=None):
2713 Create a mesh group based on the geometrical object *grp*
2714 and give it a *name*.
2715 if *name* is not defined the name of the geometric group is used
2718 grp: a geometrical group, a vertex, an edge, a face or a solid
2719 name: the name of the mesh group
2720 typ: the type of elements in the group; either of
2721 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2722 automatically detected by the type of the geometry
2725 :class:`SMESH.SMESH_GroupOnGeom`
2728 AssureGeomPublished( self, grp, name )
2730 name = grp.GetName()
2732 typ = self._groupTypeFromShape( grp )
2733 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2735 def _groupTypeFromShape( self, shape ):
2737 Pivate method to get a type of group on geometry
2739 tgeo = str(shape.GetShapeType())
2740 if tgeo == "VERTEX":
2742 elif tgeo == "EDGE" or tgeo == "WIRE":
2744 elif tgeo == "FACE" or tgeo == "SHELL":
2746 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2748 elif tgeo == "COMPOUND":
2750 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2752 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2753 # simplification of access in geomBuilder: omniORB.registerObjref
2754 from SHAPERSTUDY_utils import getEngine
2757 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2759 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2760 return self._groupTypeFromShape( sub[0] )
2762 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2765 def GroupOnFilter(self, typ, name, filter):
2767 Create a mesh group with given *name* based on the *filter*.
2768 It is a special type of group dynamically updating it's contents during
2772 typ: the type of elements in the group; either of
2773 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2774 name: the name of the mesh group
2775 filter (SMESH.Filter): the filter defining group contents
2778 :class:`SMESH.SMESH_GroupOnFilter`
2781 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2783 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2785 Create a mesh group by the given ids of elements
2788 groupName: the name of the mesh group
2789 elementType: the type of elements in the group; either of
2790 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2791 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2794 :class:`SMESH.SMESH_Group`
2797 group = self.mesh.CreateGroup(elementType, groupName)
2798 if isinstance( elemIDs, Mesh ):
2799 elemIDs = elemIDs.GetMesh()
2800 if hasattr( elemIDs, "GetIDs" ):
2801 if hasattr( elemIDs, "SetMesh" ):
2802 elemIDs.SetMesh( self.GetMesh() )
2803 group.AddFrom( elemIDs )
2811 CritType=FT_Undefined,
2814 UnaryOp=FT_Undefined,
2817 Create a mesh group by the given conditions
2820 groupName: the name of the mesh group
2821 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2822 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2823 Note that the items starting from FT_LessThan are not suitable for CritType.
2824 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2825 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2826 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2827 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2828 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2831 :class:`SMESH.SMESH_GroupOnFilter`
2834 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2835 group = self.MakeGroupByCriterion(groupName, aCriterion)
2838 def MakeGroupByCriterion(self, groupName, Criterion):
2840 Create a mesh group by the given criterion
2843 groupName: the name of the mesh group
2844 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2847 :class:`SMESH.SMESH_GroupOnFilter`
2850 :meth:`smeshBuilder.GetCriterion`
2853 return self.MakeGroupByCriteria( groupName, [Criterion] )
2855 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2857 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2860 groupName: the name of the mesh group
2861 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2862 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2865 :class:`SMESH.SMESH_GroupOnFilter`
2868 :meth:`smeshBuilder.GetCriterion`
2871 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2872 group = self.MakeGroupByFilter(groupName, aFilter)
2875 def MakeGroupByFilter(self, groupName, theFilter):
2877 Create a mesh group by the given filter
2880 groupName (string): the name of the mesh group
2881 theFilter (SMESH.Filter): the filter
2884 :class:`SMESH.SMESH_GroupOnFilter`
2887 :meth:`smeshBuilder.GetFilter`
2890 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2891 #theFilter.SetMesh( self.mesh )
2892 #group.AddFrom( theFilter )
2893 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2896 def RemoveGroup(self, group):
2901 group (SMESH.SMESH_GroupBase): group to remove
2904 self.mesh.RemoveGroup(group)
2906 def RemoveGroupWithContents(self, group):
2908 Remove a group with its contents
2911 group (SMESH.SMESH_GroupBase): group to remove
2914 This operation can create gaps in numeration of nodes or elements.
2915 Call :meth:`RenumberElements` to remove the gaps.
2918 self.mesh.RemoveGroupWithContents(group)
2920 def GetGroups(self, elemType = SMESH.ALL):
2922 Get the list of groups existing in the mesh in the order of creation
2923 (starting from the oldest one)
2926 elemType (SMESH.ElementType): type of elements the groups contain;
2927 by default groups of elements of all types are returned
2930 a list of :class:`SMESH.SMESH_GroupBase`
2933 groups = self.mesh.GetGroups()
2934 if elemType == SMESH.ALL:
2938 if g.GetType() == elemType:
2939 typedGroups.append( g )
2946 Get the number of groups existing in the mesh
2949 the quantity of groups as an integer value
2952 return self.mesh.NbGroups()
2954 def GetGroupNames(self):
2956 Get the list of names of groups existing in the mesh
2962 groups = self.GetGroups()
2964 for group in groups:
2965 names.append(group.GetName())
2968 def GetGroupByName(self, name, elemType = None):
2970 Find groups by name and type
2973 name (string): name of the group of interest
2974 elemType (SMESH.ElementType): type of elements the groups contain;
2975 by default one group of any type is returned;
2976 if elemType == SMESH.ALL then all groups of any type are returned
2979 a list of :class:`SMESH.SMESH_GroupBase`
2983 for group in self.GetGroups():
2984 if group.GetName() == name:
2985 if elemType is None:
2987 if ( elemType == SMESH.ALL or
2988 group.GetType() == elemType ):
2989 groups.append( group )
2992 def UnionGroups(self, group1, group2, name):
2994 Produce a union of two groups.
2995 A new group is created. All mesh elements that are
2996 present in the initial groups are added to the new one
2999 group1 (SMESH.SMESH_GroupBase): a group
3000 group2 (SMESH.SMESH_GroupBase): another group
3003 instance of :class:`SMESH.SMESH_Group`
3006 return self.mesh.UnionGroups(group1, group2, name)
3008 def UnionListOfGroups(self, groups, name):
3010 Produce a union list of groups.
3011 New group is created. All mesh elements that are present in
3012 initial groups are added to the new one
3015 groups: list of :class:`SMESH.SMESH_GroupBase`
3018 instance of :class:`SMESH.SMESH_Group`
3020 return self.mesh.UnionListOfGroups(groups, name)
3022 def IntersectGroups(self, group1, group2, name):
3024 Prodice an intersection of two groups.
3025 A new group is created. All mesh elements that are common
3026 for the two initial groups are added to the new one.
3029 group1 (SMESH.SMESH_GroupBase): a group
3030 group2 (SMESH.SMESH_GroupBase): another group
3033 instance of :class:`SMESH.SMESH_Group`
3036 return self.mesh.IntersectGroups(group1, group2, name)
3038 def IntersectListOfGroups(self, groups, name):
3040 Produce an intersection of groups.
3041 New group is created. All mesh elements that are present in all
3042 initial groups simultaneously are added to the new one
3045 groups: a list of :class:`SMESH.SMESH_GroupBase`
3048 instance of :class:`SMESH.SMESH_Group`
3050 return self.mesh.IntersectListOfGroups(groups, name)
3052 def CutGroups(self, main_group, tool_group, name):
3054 Produce a cut of two groups.
3055 A new group is created. All mesh elements that are present in
3056 the main group but are not present in the tool group are added to the new one
3059 main_group (SMESH.SMESH_GroupBase): a group to cut from
3060 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3063 an instance of :class:`SMESH.SMESH_Group`
3066 return self.mesh.CutGroups(main_group, tool_group, name)
3068 def CutListOfGroups(self, main_groups, tool_groups, name):
3070 Produce a cut of groups.
3071 A new group is created. All mesh elements that are present in main groups
3072 but do not present in tool groups are added to the new one
3075 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3076 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3079 an instance of :class:`SMESH.SMESH_Group`
3082 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3084 def CreateDimGroup(self, groups, elemType, name,
3085 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3087 Create a standalone group of entities basing on nodes of other groups.
3090 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3091 elemType: a type of elements to include to the new group; either of
3092 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3093 name: a name of the new group.
3094 nbCommonNodes: a criterion of inclusion of an element to the new group
3095 basing on number of element nodes common with reference *groups*.
3096 Meaning of possible values are:
3098 - SMESH.ALL_NODES - include if all nodes are common,
3099 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3100 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3101 - SMEHS.MAJORITY - include if half of nodes or more are common.
3102 underlyingOnly: if *True* (default), an element is included to the
3103 new group provided that it is based on nodes of an element of *groups*;
3104 in this case the reference *groups* are supposed to be of higher dimension
3105 than *elemType*, which can be useful for example to get all faces lying on
3106 volumes of the reference *groups*.
3109 an instance of :class:`SMESH.SMESH_Group`
3112 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3114 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3116 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3118 Distribute all faces of the mesh among groups using sharp edges and optionally
3119 existing 1D elements as group boundaries.
3122 sharpAngle: edge is considered sharp if an angle between normals of
3123 adjacent faces is more than \a sharpAngle in degrees.
3124 createEdges (boolean): to create 1D elements for detected sharp edges.
3125 useExistingEdges (boolean): to use existing edges as group boundaries
3127 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3129 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3130 self.mesh.SetParameters(Parameters)
3131 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3133 def ConvertToStandalone(self, group):
3135 Convert group on geom into standalone group
3138 return self.mesh.ConvertToStandalone(group)
3140 # Get some info about mesh:
3141 # ------------------------
3143 def GetLog(self, clearAfterGet):
3145 Return the log of nodes and elements added or removed
3146 since the previous clear of the log.
3149 clearAfterGet: log is emptied after Get (safe if concurrents access)
3152 list of SMESH.log_block structures { commandType, number, coords, indexes }
3155 return self.mesh.GetLog(clearAfterGet)
3159 Clear the log of nodes and elements added or removed since the previous
3160 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3163 self.mesh.ClearLog()
3165 def SetAutoColor(self, theAutoColor):
3167 Toggle auto color mode on the object.
3168 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3171 theAutoColor (boolean): the flag which toggles auto color mode.
3174 self.mesh.SetAutoColor(theAutoColor)
3176 def GetAutoColor(self):
3178 Get flag of object auto color mode.
3184 return self.mesh.GetAutoColor()
3191 integer value, which is the internal Id of the mesh
3194 return self.mesh.GetId()
3196 def HasDuplicatedGroupNamesMED(self):
3198 Check the group names for duplications.
3199 Consider the maximum group name length stored in MED file.
3205 return self.mesh.HasDuplicatedGroupNamesMED()
3207 def GetMeshEditor(self):
3209 Obtain the mesh editor tool
3212 an instance of :class:`SMESH.SMESH_MeshEditor`
3217 def GetIDSource(self, ids, elemType = SMESH.ALL):
3219 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3220 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3224 elemType: type of elements; this parameter is used to distinguish
3225 IDs of nodes from IDs of elements; by default ids are treated as
3226 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3229 an instance of :class:`SMESH.SMESH_IDSource`
3232 call UnRegister() for the returned object as soon as it is no more useful::
3234 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3235 mesh.DoSomething( idSrc )
3239 if isinstance( ids, int ):
3241 return self.editor.MakeIDSource(ids, elemType)
3244 # Get information about mesh contents:
3245 # ------------------------------------
3247 def GetMeshInfo(self, obj = None):
3249 Get the mesh statistic.
3252 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3255 if not obj: obj = self.mesh
3256 return self.smeshpyD.GetMeshInfo(obj)
3260 Return the number of nodes in the mesh
3266 return self.mesh.NbNodes()
3268 def NbElements(self):
3270 Return the number of elements in the mesh
3276 return self.mesh.NbElements()
3278 def Nb0DElements(self):
3280 Return the number of 0d elements in the mesh
3286 return self.mesh.Nb0DElements()
3290 Return the number of ball discrete elements in the mesh
3296 return self.mesh.NbBalls()
3300 Return the number of edges in the mesh
3306 return self.mesh.NbEdges()
3308 def NbEdgesOfOrder(self, elementOrder):
3310 Return the number of edges with the given order in the mesh
3313 elementOrder: the order of elements
3314 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3320 return self.mesh.NbEdgesOfOrder(elementOrder)
3324 Return the number of faces in the mesh
3330 return self.mesh.NbFaces()
3332 def NbFacesOfOrder(self, elementOrder):
3334 Return the number of faces with the given order in the mesh
3337 elementOrder: the order of elements
3338 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3344 return self.mesh.NbFacesOfOrder(elementOrder)
3346 def NbTriangles(self):
3348 Return the number of triangles in the mesh
3354 return self.mesh.NbTriangles()
3356 def NbTrianglesOfOrder(self, elementOrder):
3358 Return the number of triangles with the given order in the mesh
3361 elementOrder: is the order of elements
3362 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3368 return self.mesh.NbTrianglesOfOrder(elementOrder)
3370 def NbBiQuadTriangles(self):
3372 Return the number of biquadratic triangles in the mesh
3378 return self.mesh.NbBiQuadTriangles()
3380 def NbQuadrangles(self):
3382 Return the number of quadrangles in the mesh
3388 return self.mesh.NbQuadrangles()
3390 def NbQuadranglesOfOrder(self, elementOrder):
3392 Return the number of quadrangles with the given order in the mesh
3395 elementOrder: the order of elements
3396 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3402 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3404 def NbBiQuadQuadrangles(self):
3406 Return the number of biquadratic quadrangles in the mesh
3412 return self.mesh.NbBiQuadQuadrangles()
3414 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3416 Return the number of polygons of given order in the mesh
3419 elementOrder: the order of elements
3420 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3426 return self.mesh.NbPolygonsOfOrder(elementOrder)
3428 def NbVolumes(self):
3430 Return the number of volumes in the mesh
3436 return self.mesh.NbVolumes()
3439 def NbVolumesOfOrder(self, elementOrder):
3441 Return the number of volumes with the given order in the mesh
3444 elementOrder: the order of elements
3445 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3451 return self.mesh.NbVolumesOfOrder(elementOrder)
3455 Return the number of tetrahedrons in the mesh
3461 return self.mesh.NbTetras()
3463 def NbTetrasOfOrder(self, elementOrder):
3465 Return the number of tetrahedrons with the given order in the mesh
3468 elementOrder: the order of elements
3469 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3475 return self.mesh.NbTetrasOfOrder(elementOrder)
3479 Return the number of hexahedrons in the mesh
3485 return self.mesh.NbHexas()
3487 def NbHexasOfOrder(self, elementOrder):
3489 Return the number of hexahedrons with the given order in the mesh
3492 elementOrder: the order of elements
3493 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3499 return self.mesh.NbHexasOfOrder(elementOrder)
3501 def NbTriQuadraticHexas(self):
3503 Return the number of triquadratic hexahedrons in the mesh
3509 return self.mesh.NbTriQuadraticHexas()
3511 def NbPyramids(self):
3513 Return the number of pyramids in the mesh
3519 return self.mesh.NbPyramids()
3521 def NbPyramidsOfOrder(self, elementOrder):
3523 Return the number of pyramids with the given order in the mesh
3526 elementOrder: the order of elements
3527 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3533 return self.mesh.NbPyramidsOfOrder(elementOrder)
3537 Return the number of prisms in the mesh
3543 return self.mesh.NbPrisms()
3545 def NbPrismsOfOrder(self, elementOrder):
3547 Return the number of prisms with the given order in the mesh
3550 elementOrder: the order of elements
3551 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3557 return self.mesh.NbPrismsOfOrder(elementOrder)
3559 def NbHexagonalPrisms(self):
3561 Return the number of hexagonal prisms in the mesh
3567 return self.mesh.NbHexagonalPrisms()
3569 def NbPolyhedrons(self):
3571 Return the number of polyhedrons in the mesh
3577 return self.mesh.NbPolyhedrons()
3579 def NbSubMesh(self):
3581 Return the number of submeshes in the mesh
3587 return self.mesh.NbSubMesh()
3589 def GetElementsId(self):
3591 Return the list of all mesh elements IDs
3594 the list of integer values
3597 :meth:`GetElementsByType`
3600 return self.mesh.GetElementsId()
3602 def GetElementsByType(self, elementType):
3604 Return the list of IDs of mesh elements with the given type
3607 elementType (SMESH.ElementType): the required type of elements
3610 list of integer values
3613 return self.mesh.GetElementsByType(elementType)
3615 def GetNodesId(self):
3617 Return the list of mesh nodes IDs
3620 the list of integer values
3623 return self.mesh.GetNodesId()
3625 # Get the information about mesh elements:
3626 # ------------------------------------
3628 def GetElementType(self, id, iselem=True):
3630 Return the type of mesh element or node
3633 the value from :class:`SMESH.ElementType` enumeration.
3634 Return SMESH.ALL if element or node with the given ID does not exist
3637 return self.mesh.GetElementType(id, iselem)
3639 def GetElementGeomType(self, id):
3641 Return the geometric type of mesh element
3644 the value from :class:`SMESH.EntityType` enumeration.
3647 return self.mesh.GetElementGeomType(id)
3649 def GetElementShape(self, id):
3651 Return the shape type of mesh element
3654 the value from :class:`SMESH.GeometryType` enumeration.
3657 return self.mesh.GetElementShape(id)
3659 def GetSubMeshElementsId(self, Shape):
3661 Return the list of sub-mesh elements IDs
3664 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3665 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3668 list of integer values
3671 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3672 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3675 return self.mesh.GetSubMeshElementsId(ShapeID)
3677 def GetSubMeshNodesId(self, Shape, all):
3679 Return the list of sub-mesh nodes IDs
3682 Shape: a geom object (sub-shape).
3683 *Shape* must be the sub-shape of a :meth:`GetShape`
3684 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3687 list of integer values
3690 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3691 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3694 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3696 def GetSubMeshElementType(self, Shape):
3698 Return type of elements on given shape
3701 Shape: a geom object (sub-shape).
3702 *Shape* must be a sub-shape of a ShapeToMesh()
3705 :class:`SMESH.ElementType`
3708 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3709 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3712 return self.mesh.GetSubMeshElementType(ShapeID)
3716 Get the mesh description
3722 return self.mesh.Dump()
3725 # Get the information about nodes and elements of a mesh by its IDs:
3726 # -----------------------------------------------------------
3728 def GetNodeXYZ(self, id):
3730 Get XYZ coordinates of a node.
3731 If there is no node for the given ID - return an empty list
3734 list of float values
3737 return self.mesh.GetNodeXYZ(id)
3739 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3741 Return list of IDs of inverse elements for the given node.
3742 If there is no node for the given ID - return an empty list
3746 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3749 list of integer values
3752 return self.mesh.GetNodeInverseElements(id,elemType)
3754 def GetNodePosition(self,NodeID):
3756 Return the position of a node on the shape
3759 :class:`SMESH.NodePosition`
3762 return self.mesh.GetNodePosition(NodeID)
3764 def GetElementPosition(self,ElemID):
3766 Return the position of an element on the shape
3769 :class:`SMESH.ElementPosition`
3772 return self.mesh.GetElementPosition(ElemID)
3774 def GetShapeID(self, id):
3776 Return the ID of the shape, on which the given node was generated.
3779 an integer value > 0 or -1 if there is no node for the given
3780 ID or the node is not assigned to any geometry
3783 return self.mesh.GetShapeID(id)
3785 def GetShapeIDForElem(self,id):
3787 Return the ID of the shape, on which the given element was generated.
3790 an integer value > 0 or -1 if there is no element for the given
3791 ID or the element is not assigned to any geometry
3794 return self.mesh.GetShapeIDForElem(id)
3796 def GetElemNbNodes(self, id):
3798 Return the number of nodes of the given element
3801 an integer value > 0 or -1 if there is no element for the given ID
3804 return self.mesh.GetElemNbNodes(id)
3806 def GetElemNode(self, id, index):
3808 Return the node ID the given (zero based) index for the given element.
3810 * If there is no element for the given ID - return -1.
3811 * If there is no node for the given index - return -2.
3814 id (int): element ID
3815 index (int): node index within the element
3818 an integer value (ID)
3821 :meth:`GetElemNodes`
3824 return self.mesh.GetElemNode(id, index)
3826 def GetElemNodes(self, id):
3828 Return the IDs of nodes of the given element
3831 a list of integer values
3834 return self.mesh.GetElemNodes(id)
3836 def IsMediumNode(self, elementID, nodeID):
3838 Return true if the given node is the medium node in the given quadratic element
3841 return self.mesh.IsMediumNode(elementID, nodeID)
3843 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3845 Return true if the given node is the medium node in one of quadratic elements
3848 nodeID: ID of the node
3849 elementType: the type of elements to check a state of the node, either of
3850 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3853 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3855 def ElemNbEdges(self, id):
3857 Return the number of edges for the given element
3860 return self.mesh.ElemNbEdges(id)
3862 def ElemNbFaces(self, id):
3864 Return the number of faces for the given element
3867 return self.mesh.ElemNbFaces(id)
3869 def GetElemFaceNodes(self,elemId, faceIndex):
3871 Return nodes of given face (counted from zero) for given volumic element.
3874 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3876 def GetFaceNormal(self, faceId, normalized=False):
3878 Return three components of normal of given mesh face
3879 (or an empty array in KO case)
3882 return self.mesh.GetFaceNormal(faceId,normalized)
3884 def FindElementByNodes(self, nodes):
3886 Return an element based on all given nodes.
3889 return self.mesh.FindElementByNodes(nodes)
3891 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3893 Return elements including all given nodes.
3896 return self.mesh.GetElementsByNodes( nodes, elemType )
3898 def IsPoly(self, id):
3900 Return true if the given element is a polygon
3903 return self.mesh.IsPoly(id)
3905 def IsQuadratic(self, id):
3907 Return true if the given element is quadratic
3910 return self.mesh.IsQuadratic(id)
3912 def GetBallDiameter(self, id):
3914 Return diameter of a ball discrete element or zero in case of an invalid *id*
3917 return self.mesh.GetBallDiameter(id)
3919 def BaryCenter(self, id):
3921 Return XYZ coordinates of the barycenter of the given element.
3922 If there is no element for the given ID - return an empty list
3925 a list of three double values
3928 :meth:`smeshBuilder.GetGravityCenter`
3931 return self.mesh.BaryCenter(id)
3933 def GetIdsFromFilter(self, filter, meshParts=[] ):
3935 Pass mesh elements through the given filter and return IDs of fitting elements
3938 filter: :class:`SMESH.Filter`
3939 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3945 :meth:`SMESH.Filter.GetIDs`
3946 :meth:`SMESH.Filter.GetElementsIdFromParts`
3949 filter.SetMesh( self.mesh )
3952 if isinstance( meshParts, Mesh ):
3953 filter.SetMesh( meshParts.GetMesh() )
3954 return theFilter.GetIDs()
3955 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3956 meshParts = [ meshParts ]
3957 return filter.GetElementsIdFromParts( meshParts )
3959 return filter.GetIDs()
3961 # Get mesh measurements information:
3962 # ------------------------------------
3964 def GetFreeBorders(self):
3966 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3967 Return a list of special structures (borders).
3970 a list of :class:`SMESH.FreeEdges.Border`
3973 aFilterMgr = self.smeshpyD.CreateFilterManager()
3974 aPredicate = aFilterMgr.CreateFreeEdges()
3975 aPredicate.SetMesh(self.mesh)
3976 aBorders = aPredicate.GetBorders()
3977 aFilterMgr.UnRegister()
3980 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3982 Get minimum distance between two nodes, elements or distance to the origin
3985 id1: first node/element id
3986 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3987 isElem1: *True* if *id1* is element id, *False* if it is node id
3988 isElem2: *True* if *id2* is element id, *False* if it is node id
3991 minimum distance value
3993 :meth:`GetMinDistance`
3996 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3997 return aMeasure.value
3999 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4001 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4004 id1: first node/element id
4005 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4006 isElem1: *True* if *id1* is element id, *False* if it is node id
4007 isElem2: *True* if *id2* is element id, *False* if it is node id
4010 :class:`SMESH.Measure` structure
4016 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4018 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4021 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4023 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4028 aMeasurements = self.smeshpyD.CreateMeasurements()
4029 aMeasure = aMeasurements.MinDistance(id1, id2)
4030 genObjUnRegister([aMeasurements,id1, id2])
4033 def BoundingBox(self, objects=None, isElem=False):
4035 Get bounding box of the specified object(s)
4038 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4039 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4040 *False* specifies that *objects* are nodes
4043 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4046 :meth:`GetBoundingBox()`
4049 result = self.GetBoundingBox(objects, isElem)
4053 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4056 def GetBoundingBox(self, objects=None, isElem=False):
4058 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4061 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4062 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4063 False means that *objects* are nodes
4066 :class:`SMESH.Measure` structure
4069 :meth:`BoundingBox()`
4073 objects = [self.mesh]
4074 elif isinstance(objects, tuple):
4075 objects = list(objects)
4076 if not isinstance(objects, list):
4078 if len(objects) > 0 and isinstance(objects[0], int):
4081 unRegister = genObjUnRegister()
4083 if isinstance(o, Mesh):
4084 srclist.append(o.mesh)
4085 elif hasattr(o, "_narrow"):
4086 src = o._narrow(SMESH.SMESH_IDSource)
4087 if src: srclist.append(src)
4089 elif isinstance(o, list):
4091 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4093 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4094 unRegister.set( srclist[-1] )
4097 aMeasurements = self.smeshpyD.CreateMeasurements()
4098 unRegister.set( aMeasurements )
4099 aMeasure = aMeasurements.BoundingBox(srclist)
4102 # Mesh edition (SMESH_MeshEditor functionality):
4103 # ---------------------------------------------
4105 def RemoveElements(self, IDsOfElements):
4107 Remove the elements from the mesh by ids
4110 IDsOfElements: is a list of ids of elements to remove
4116 This operation can create gaps in numeration of elements.
4117 Call :meth:`RenumberElements` to remove the gaps.
4120 return self.editor.RemoveElements(IDsOfElements)
4122 def RemoveNodes(self, IDsOfNodes):
4124 Remove nodes from mesh by ids
4127 IDsOfNodes: is a list of ids of nodes to remove
4133 This operation can create gaps in numeration of nodes.
4134 Call :meth:`RenumberElements` to remove the gaps.
4137 return self.editor.RemoveNodes(IDsOfNodes)
4139 def RemoveNodeWithReconnection(self, nodeID ):
4141 Remove a node along with changing surrounding faces to cover a hole.
4144 nodeID: ID of node to remove
4147 return self.editor.RemoveNodeWithReconnection( nodeID )
4149 def RemoveOrphanNodes(self):
4151 Remove all orphan (free) nodes from mesh
4154 number of the removed nodes
4157 This operation can create gaps in numeration of nodes.
4158 Call :meth:`RenumberElements` to remove the gaps.
4161 return self.editor.RemoveOrphanNodes()
4163 def AddNode(self, x, y, z):
4165 Add a node to the mesh by coordinates
4171 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4172 if hasVars: self.mesh.SetParameters(Parameters)
4173 return self.editor.AddNode( x, y, z)
4175 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4177 Create a 0D element on a node with given number.
4180 IDOfNode: the ID of node for creation of the element.
4181 DuplicateElements: to add one more 0D element to a node or not
4184 ID of the new 0D element
4187 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4189 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4191 Create 0D elements on all nodes of the given elements except those
4192 nodes on which a 0D element already exists.
4195 theObject: an object on whose nodes 0D elements will be created.
4196 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4197 theGroupName: optional name of a group to add 0D elements created
4198 and/or found on nodes of *theObject*.
4199 DuplicateElements: to add one more 0D element to a node or not
4202 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4203 IDs of new and/or found 0D elements. IDs of 0D elements
4204 can be retrieved from the returned object by
4205 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4208 unRegister = genObjUnRegister()
4209 if isinstance( theObject, Mesh ):
4210 theObject = theObject.GetMesh()
4211 elif isinstance( theObject, list ):
4212 theObject = self.GetIDSource( theObject, SMESH.ALL )
4213 unRegister.set( theObject )
4214 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4216 def AddBall(self, IDOfNode, diameter):
4218 Create a ball element on a node with given ID.
4221 IDOfNode: the ID of node for creation of the element.
4222 diameter: the bal diameter.
4225 ID of the new ball element
4228 return self.editor.AddBall( IDOfNode, diameter )
4230 def AddEdge(self, IDsOfNodes):
4232 Create a linear or quadratic edge (this is determined
4233 by the number of given nodes).
4236 IDsOfNodes: list of node IDs for creation of the element.
4237 The order of nodes in this list should correspond to
4238 the :ref:`connectivity convention <connectivity_page>`.
4244 return self.editor.AddEdge(IDsOfNodes)
4246 def AddFace(self, IDsOfNodes):
4248 Create a linear or quadratic face (this is determined
4249 by the number of given nodes).
4252 IDsOfNodes: list of node IDs for creation of the element.
4253 The order of nodes in this list should correspond to
4254 the :ref:`connectivity convention <connectivity_page>`.
4260 return self.editor.AddFace(IDsOfNodes)
4262 def AddPolygonalFace(self, IdsOfNodes):
4264 Add a polygonal face defined by a list of node IDs
4267 IdsOfNodes: the list of node IDs for creation of the element.
4273 return self.editor.AddPolygonalFace(IdsOfNodes)
4275 def AddQuadPolygonalFace(self, IdsOfNodes):
4277 Add a quadratic polygonal face defined by a list of node IDs
4280 IdsOfNodes: the list of node IDs for creation of the element;
4281 corner nodes follow first.
4287 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4289 def AddVolume(self, IDsOfNodes):
4291 Create both simple and quadratic volume (this is determined
4292 by the number of given nodes).
4295 IDsOfNodes: list of node IDs for creation of the element.
4296 The order of nodes in this list should correspond to
4297 the :ref:`connectivity convention <connectivity_page>`.
4300 ID of the new volumic element
4303 return self.editor.AddVolume(IDsOfNodes)
4305 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4307 Create a volume of many faces, giving nodes for each face.
4310 IdsOfNodes: list of node IDs for volume creation, face by face.
4311 Quantities: list of integer values, Quantities[i]
4312 gives the quantity of nodes in face number i.
4315 ID of the new volumic element
4318 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4320 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4322 Create a volume of many faces, giving the IDs of the existing faces.
4325 The created volume will refer only to the nodes
4326 of the given faces, not to the faces themselves.
4329 IdsOfFaces: the list of face IDs for volume creation.
4332 ID of the new volumic element
4335 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4338 def SetNodeOnVertex(self, NodeID, Vertex):
4340 Bind a node to a vertex
4344 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4347 True if succeed else raises an exception
4350 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4351 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4355 self.editor.SetNodeOnVertex(NodeID, VertexID)
4356 except SALOME.SALOME_Exception as inst:
4357 raise ValueError(inst.details.text)
4361 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4363 Store the node position on an edge
4367 Edge: an edge (GEOM.GEOM_Object) or edge ID
4368 paramOnEdge: a parameter on the edge where the node is located
4371 True if succeed else raises an exception
4374 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4375 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4379 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4380 except SALOME.SALOME_Exception as inst:
4381 raise ValueError(inst.details.text)
4384 def SetNodeOnFace(self, NodeID, Face, u, v):
4386 Store node position on a face
4390 Face: a face (GEOM.GEOM_Object) or face ID
4391 u: U parameter on the face where the node is located
4392 v: V parameter on the face where the node is located
4395 True if succeed else raises an exception
4398 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4399 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4403 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4404 except SALOME.SALOME_Exception as inst:
4405 raise ValueError(inst.details.text)
4408 def SetNodeInVolume(self, NodeID, Solid):
4410 Bind a node to a solid
4414 Solid: a solid (GEOM.GEOM_Object) or solid ID
4417 True if succeed else raises an exception
4420 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4421 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4425 self.editor.SetNodeInVolume(NodeID, SolidID)
4426 except SALOME.SALOME_Exception as inst:
4427 raise ValueError(inst.details.text)
4430 def SetMeshElementOnShape(self, ElementID, Shape):
4432 Bind an element to a shape
4435 ElementID: an element ID
4436 Shape: a shape (GEOM.GEOM_Object) or shape ID
4439 True if succeed else raises an exception
4442 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4443 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4447 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4448 except SALOME.SALOME_Exception as inst:
4449 raise ValueError(inst.details.text)
4453 def MoveNode(self, NodeID, x, y, z):
4455 Move the node with the given id
4458 NodeID: the id of the node
4459 x: a new X coordinate
4460 y: a new Y coordinate
4461 z: a new Z coordinate
4464 True if succeed else False
4467 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4468 if hasVars: self.mesh.SetParameters(Parameters)
4469 return self.editor.MoveNode(NodeID, x, y, z)
4471 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4473 Find the node closest to a point and moves it to a point location
4476 x: the X coordinate of a point
4477 y: the Y coordinate of a point
4478 z: the Z coordinate of a point
4479 NodeID: if specified (>0), the node with this ID is moved,
4480 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4483 the ID of a moved node
4486 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4487 if hasVars: self.mesh.SetParameters(Parameters)
4488 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4490 def FindNodeClosestTo(self, x, y, z):
4492 Find the node closest to a point
4495 x: the X coordinate of a point
4496 y: the Y coordinate of a point
4497 z: the Z coordinate of a point
4503 return self.editor.FindNodeClosestTo(x, y, z)
4505 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4507 Find the elements where a point lays IN or ON
4510 x,y,z (float): coordinates of the point
4511 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4512 means elements of any type excluding nodes, discrete and 0D elements.
4513 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4516 list of IDs of found elements
4519 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4521 return self.editor.FindElementsByPoint(x, y, z, elementType)
4523 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4525 Project a point to a mesh object.
4526 Return ID of an element of given type where the given point is projected
4527 and coordinates of the projection point.
4528 In the case if nothing found, return -1 and []
4530 if isinstance( meshObject, Mesh ):
4531 meshObject = meshObject.GetMesh()
4533 meshObject = self.GetMesh()
4534 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4536 def GetPointState(self, x, y, z):
4538 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4539 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4540 UNKNOWN state means that either mesh is wrong or the analysis fails.
4543 return self.editor.GetPointState(x, y, z)
4545 def IsManifold(self):
4547 Check if a 2D mesh is manifold
4550 return self.editor.IsManifold()
4552 def IsCoherentOrientation2D(self):
4554 Check if orientation of 2D elements is coherent
4557 return self.editor.IsCoherentOrientation2D()
4559 def Get1DBranches( self, edges, startNode = 0 ):
4561 Partition given 1D elements into groups of contiguous edges.
4562 A node where number of meeting edges != 2 is a group end.
4563 An optional startNode is used to orient groups it belongs to.
4566 A list of edge groups and a list of corresponding node groups,
4567 where the group is a list of IDs of edges or nodes, like follows
4568 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4569 If a group is closed, the first and last nodes of the group are same.
4571 if isinstance( edges, Mesh ):
4572 edges = edges.GetMesh()
4573 unRegister = genObjUnRegister()
4574 if isinstance( edges, list ):
4575 edges = self.GetIDSource( edges, SMESH.EDGE )
4576 unRegister.set( edges )
4577 return self.editor.Get1DBranches( edges, startNode )
4579 def FindSharpEdges( self, angle, addExisting=False ):
4581 Return sharp edges of faces and non-manifold ones.
4582 Optionally add existing edges.
4585 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4586 addExisting: to return existing edges (1D elements) as well
4589 list of FaceEdge structures
4591 angle = ParseParameters( angle )[0]
4592 return self.editor.FindSharpEdges( angle, addExisting )
4594 def MeshToPassThroughAPoint(self, x, y, z):
4596 Find the node closest to a point and moves it to a point location
4599 x: the X coordinate of a point
4600 y: the Y coordinate of a point
4601 z: the Z coordinate of a point
4604 the ID of a moved node
4607 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4609 def InverseDiag(self, NodeID1, NodeID2):
4611 Replace two neighbour triangles sharing Node1-Node2 link
4612 with the triangles built on the same 4 nodes but having other common link.
4615 NodeID1: the ID of the first node
4616 NodeID2: the ID of the second node
4619 False if proper faces were not found
4621 return self.editor.InverseDiag(NodeID1, NodeID2)
4623 def DeleteDiag(self, NodeID1, NodeID2):
4625 Replace two neighbour triangles sharing *Node1-Node2* link
4626 with a quadrangle built on the same 4 nodes.
4629 NodeID1: ID of the first node
4630 NodeID2: ID of the second node
4633 False if proper faces were not found
4636 This operation can create gaps in numeration of elements.
4637 Call :meth:`RenumberElements` to remove the gaps.
4640 return self.editor.DeleteDiag(NodeID1, NodeID2)
4642 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4644 Replace each triangle bound by Node1-Node2 segment with
4645 two triangles by connecting a node made on the link with a node
4646 opposite to the link.
4649 Node1: ID of the first node
4650 Node2: ID of the second node
4651 position: location [0,1] of the new node on the segment
4653 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4655 def AddNodeOnFace(self, face, x, y, z):
4657 Split a face into triangles by adding a new node onto the face
4658 and connecting the new node with face nodes
4661 face: ID of the face
4662 x,y,z: coordinates of the new node
4664 return self.editor.AddNodeOnFace(face, x, y, z)
4666 def Reorient(self, IDsOfElements=None):
4668 Reorient elements by ids
4671 IDsOfElements: if undefined reorients all mesh elements
4674 True if succeed else False
4677 if IDsOfElements == None:
4678 IDsOfElements = self.GetElementsId()
4679 return self.editor.Reorient(IDsOfElements)
4681 def ReorientObject(self, theObject):
4683 Reorient all elements of the object
4686 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4689 True if succeed else False
4692 if ( isinstance( theObject, Mesh )):
4693 theObject = theObject.GetMesh()
4694 return self.editor.ReorientObject(theObject)
4696 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4698 Reorient faces contained in *the2DObject*.
4701 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4702 theDirection: a desired direction of normal of *theFace*.
4703 It can be either a GEOM vector or a list of coordinates [x,y,z].
4704 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4705 compared with theDirection. It can be either ID of face or a point
4706 by which the face will be found. The point can be given as either
4707 a GEOM vertex or a list of point coordinates.
4710 number of reoriented faces
4713 unRegister = genObjUnRegister()
4715 if isinstance( the2DObject, Mesh ):
4716 the2DObject = the2DObject.GetMesh()
4717 if isinstance( the2DObject, list ):
4718 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4719 unRegister.set( the2DObject )
4720 # check theDirection
4721 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4722 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4723 if isinstance( theDirection, list ):
4724 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4725 # prepare theFace and thePoint
4726 theFace = theFaceOrPoint
4727 thePoint = PointStruct(0,0,0)
4728 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4729 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4731 if isinstance( theFaceOrPoint, list ):
4732 thePoint = PointStruct( *theFaceOrPoint )
4734 if isinstance( theFaceOrPoint, PointStruct ):
4735 thePoint = theFaceOrPoint
4737 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4739 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4741 Reorient faces contained in a list of *objectFaces*
4742 equally to faces contained in a list of *referenceFaces*.
4745 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4746 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.
4749 number of reoriented faces.
4751 if not isinstance( objectFaces, list ):
4752 objectFaces = [ objectFaces ]
4753 for i,obj2D in enumerate( objectFaces ):
4754 if isinstance( obj2D, Mesh ):
4755 objectFaces[i] = obj2D.GetMesh()
4756 if not isinstance( referenceFaces, list ):
4757 referenceFaces = [ referenceFaces ]
4759 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4762 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4764 Reorient faces according to adjacent volumes.
4767 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4768 either IDs of faces or face groups.
4769 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4770 theOutsideNormal: to orient faces to have their normals
4771 pointing either *outside* or *inside* the adjacent volumes.
4774 number of reoriented faces.
4777 unRegister = genObjUnRegister()
4779 if not isinstance( the2DObject, list ):
4780 the2DObject = [ the2DObject ]
4781 elif the2DObject and isinstance( the2DObject[0], int ):
4782 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4783 unRegister.set( the2DObject )
4784 the2DObject = [ the2DObject ]
4785 for i,obj2D in enumerate( the2DObject ):
4786 if isinstance( obj2D, Mesh ):
4787 the2DObject[i] = obj2D.GetMesh()
4788 if isinstance( obj2D, list ):
4789 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4790 unRegister.set( the2DObject[i] )
4792 if isinstance( the3DObject, Mesh ):
4793 the3DObject = the3DObject.GetMesh()
4794 if isinstance( the3DObject, list ):
4795 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4796 unRegister.set( the3DObject )
4797 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4799 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4801 Fuse the neighbouring triangles into quadrangles.
4804 IDsOfElements: The triangles to be fused.
4805 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4806 applied to possible quadrangles to choose a neighbour to fuse with.
4807 Note that not all items of :class:`SMESH.FunctorType` corresponds
4808 to numerical functors.
4809 MaxAngle: is the maximum angle between element normals at which the fusion
4810 is still performed; theMaxAngle is measured in radians.
4811 Also it could be a name of variable which defines angle in degrees.
4814 True in case of success, False otherwise.
4817 This operation can create gaps in numeration of elements.
4818 Call :meth:`RenumberElements` to remove the gaps.
4821 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4822 self.mesh.SetParameters(Parameters)
4823 if not IDsOfElements:
4824 IDsOfElements = self.GetElementsId()
4825 Functor = self.smeshpyD.GetFunctor(theCriterion)
4826 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4828 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4830 Fuse the neighbouring triangles of the object into quadrangles
4833 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4834 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4835 applied to possible quadrangles to choose a neighbour to fuse with.
4836 Note that not all items of :class:`SMESH.FunctorType` corresponds
4837 to numerical functors.
4838 MaxAngle: a max angle between element normals at which the fusion
4839 is still performed; theMaxAngle is measured in radians.
4842 True in case of success, False otherwise.
4845 This operation can create gaps in numeration of elements.
4846 Call :meth:`RenumberElements` to remove the gaps.
4849 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4850 self.mesh.SetParameters(Parameters)
4851 if isinstance( theObject, Mesh ):
4852 theObject = theObject.GetMesh()
4853 Functor = self.smeshpyD.GetFunctor(theCriterion)
4854 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4856 def QuadToTri (self, IDsOfElements, theCriterion = None):
4858 Split quadrangles into triangles.
4861 IDsOfElements: the faces to be splitted.
4862 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4863 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4864 value, then quadrangles will be split by the smallest diagonal.
4865 Note that not all items of :class:`SMESH.FunctorType` corresponds
4866 to numerical functors.
4869 True in case of success, False otherwise.
4872 This operation can create gaps in numeration of elements.
4873 Call :meth:`RenumberElements` to remove the gaps.
4875 if IDsOfElements == []:
4876 IDsOfElements = self.GetElementsId()
4877 if theCriterion is None:
4878 theCriterion = FT_MaxElementLength2D
4879 Functor = self.smeshpyD.GetFunctor(theCriterion)
4880 return self.editor.QuadToTri(IDsOfElements, Functor)
4882 def QuadToTriObject (self, theObject, theCriterion = None):
4884 Split quadrangles into triangles.
4887 theObject: the object from which the list of elements is taken,
4888 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4889 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4890 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4891 value, then quadrangles will be split by the smallest diagonal.
4892 Note that not all items of :class:`SMESH.FunctorType` corresponds
4893 to numerical functors.
4896 True in case of success, False otherwise.
4899 This operation can create gaps in numeration of elements.
4900 Call :meth:`RenumberElements` to remove the gaps.
4902 if ( isinstance( theObject, Mesh )):
4903 theObject = theObject.GetMesh()
4904 if theCriterion is None:
4905 theCriterion = FT_MaxElementLength2D
4906 Functor = self.smeshpyD.GetFunctor(theCriterion)
4907 return self.editor.QuadToTriObject(theObject, Functor)
4909 def QuadTo4Tri (self, theElements=[]):
4911 Split each of given quadrangles into 4 triangles. A node is added at the center of
4915 theElements: the faces to be splitted. This can be either
4916 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4917 or a list of face IDs. By default all quadrangles are split
4920 This operation can create gaps in numeration of elements.
4921 Call :meth:`RenumberElements` to remove the gaps.
4923 unRegister = genObjUnRegister()
4924 if isinstance( theElements, Mesh ):
4925 theElements = theElements.mesh
4926 elif not theElements:
4927 theElements = self.mesh
4928 elif isinstance( theElements, list ):
4929 theElements = self.GetIDSource( theElements, SMESH.FACE )
4930 unRegister.set( theElements )
4931 return self.editor.QuadTo4Tri( theElements )
4933 def SplitQuad (self, IDsOfElements, Diag13):
4935 Split quadrangles into triangles.
4938 IDsOfElements: the faces to be splitted
4939 Diag13 (boolean): is used to choose a diagonal for splitting.
4942 True in case of success, False otherwise.
4945 This operation can create gaps in numeration of elements.
4946 Call :meth:`RenumberElements` to remove the gaps.
4948 if IDsOfElements == []:
4949 IDsOfElements = self.GetElementsId()
4950 return self.editor.SplitQuad(IDsOfElements, Diag13)
4952 def SplitQuadObject (self, theObject, Diag13):
4954 Split quadrangles into triangles.
4957 theObject: the object from which the list of elements is taken,
4958 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4959 Diag13 (boolean): is used to choose a diagonal for splitting.
4962 True in case of success, False otherwise.
4965 This operation can create gaps in numeration of elements.
4966 Call :meth:`RenumberElements` to remove the gaps.
4968 if ( isinstance( theObject, Mesh )):
4969 theObject = theObject.GetMesh()
4970 return self.editor.SplitQuadObject(theObject, Diag13)
4972 def BestSplit (self, IDOfQuad, theCriterion):
4974 Find a better splitting of the given quadrangle.
4977 IDOfQuad: the ID of the quadrangle to be splitted.
4978 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4979 choose a diagonal for splitting.
4980 Note that not all items of :class:`SMESH.FunctorType` corresponds
4981 to numerical functors.
4984 * 1 if 1-3 diagonal is better,
4985 * 2 if 2-4 diagonal is better,
4986 * 0 if error occurs.
4989 This operation can create gaps in numeration of elements.
4990 Call :meth:`RenumberElements` to remove the gaps.
4992 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4994 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4996 Split volumic elements into tetrahedrons
4999 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5000 method: flags passing splitting method:
5001 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5002 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5005 This operation can create gaps in numeration of elements.
5006 Call :meth:`RenumberElements` to remove the gaps.
5008 unRegister = genObjUnRegister()
5009 if isinstance( elems, Mesh ):
5010 elems = elems.GetMesh()
5011 if ( isinstance( elems, list )):
5012 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5013 unRegister.set( elems )
5014 self.editor.SplitVolumesIntoTetra(elems, method)
5017 def SplitBiQuadraticIntoLinear(self, elems=None):
5019 Split bi-quadratic elements into linear ones without creation of additional nodes:
5021 - bi-quadratic triangle will be split into 3 linear quadrangles;
5022 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5023 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5025 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5026 will be split in order to keep the mesh conformal.
5029 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5030 if None (default), all bi-quadratic elements will be split
5033 This operation can create gaps in numeration of elements.
5034 Call :meth:`RenumberElements` to remove the gaps.
5036 unRegister = genObjUnRegister()
5037 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5038 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5039 unRegister.set( elems )
5041 elems = [ self.GetMesh() ]
5042 if isinstance( elems, Mesh ):
5043 elems = [ elems.GetMesh() ]
5044 if not isinstance( elems, list ):
5046 self.editor.SplitBiQuadraticIntoLinear( elems )
5048 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5049 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5051 Split hexahedra into prisms
5054 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5055 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5056 gives a normal vector defining facets to split into triangles.
5057 *startHexPoint* can be either a triple of coordinates or a vertex.
5058 facetNormal: a normal to a facet to split into triangles of a
5059 hexahedron found by *startHexPoint*.
5060 *facetNormal* can be either a triple of coordinates or an edge.
5061 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5062 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5063 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5064 to *startHexPoint* are split, else *startHexPoint*
5065 is used to find the facet to split in all domains present in *elems*.
5068 This operation can create gaps in numeration of elements.
5069 Call :meth:`RenumberElements` to remove the gaps.
5072 unRegister = genObjUnRegister()
5073 if isinstance( elems, Mesh ):
5074 elems = elems.GetMesh()
5075 if ( isinstance( elems, list )):
5076 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5077 unRegister.set( elems )
5080 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5081 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5082 elif isinstance( startHexPoint, list ):
5083 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5086 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5087 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5088 elif isinstance( facetNormal, list ):
5089 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5092 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5094 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5096 def SplitQuadsNearTriangularFacets(self):
5098 Split quadrangle faces near triangular facets of volumes
5101 This operation can create gaps in numeration of elements.
5102 Call :meth:`RenumberElements` to remove the gaps.
5104 faces_array = self.GetElementsByType(SMESH.FACE)
5105 for face_id in faces_array:
5106 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5107 quad_nodes = self.mesh.GetElemNodes(face_id)
5108 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5109 isVolumeFound = False
5110 for node1_elem in node1_elems:
5111 if not isVolumeFound:
5112 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5113 nb_nodes = self.GetElemNbNodes(node1_elem)
5114 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5115 volume_elem = node1_elem
5116 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5117 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5118 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5119 isVolumeFound = True
5120 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5121 self.SplitQuad([face_id], False) # diagonal 2-4
5122 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5123 isVolumeFound = True
5124 self.SplitQuad([face_id], True) # diagonal 1-3
5125 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5126 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5127 isVolumeFound = True
5128 self.SplitQuad([face_id], True) # diagonal 1-3
5130 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5132 Split hexahedrons into tetrahedrons.
5134 This operation uses :doc:`pattern_mapping` functionality for splitting.
5137 theObject: the object from which the list of hexahedrons is taken;
5138 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5139 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5140 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5141 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5142 key-point will be mapped into *theNode001*-th node of each volume.
5143 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5146 True in case of success, False otherwise.
5149 This operation can create gaps in numeration of elements.
5150 Call :meth:`RenumberElements` to remove the gaps.
5158 # (0,0,1) 4.---------.7 * |
5165 # (0,0,0) 0.---------.3
5166 pattern_tetra = "!!! Nb of points: \n 8 \n\
5176 !!! Indices of points of 6 tetras: \n\
5184 pattern = self.smeshpyD.GetPattern()
5185 isDone = pattern.LoadFromFile(pattern_tetra)
5187 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5190 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5191 isDone = pattern.MakeMesh(self.mesh, False, False)
5192 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5194 # split quafrangle faces near triangular facets of volumes
5195 self.SplitQuadsNearTriangularFacets()
5199 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5201 Split hexahedrons into prisms.
5203 Uses the :doc:`pattern_mapping` functionality for splitting.
5206 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5207 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5208 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5209 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5210 will be mapped into the *theNode001* -th node of each volume.
5211 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5214 True in case of success, False otherwise.
5217 This operation can create gaps in numeration of elements.
5218 Call :meth:`RenumberElements` to remove the gaps.
5220 # Pattern: 5.---------.6
5225 # (0,0,1) 4.---------.7 |
5232 # (0,0,0) 0.---------.3
5233 pattern_prism = "!!! Nb of points: \n 8 \n\
5243 !!! Indices of points of 2 prisms: \n\
5247 pattern = self.smeshpyD.GetPattern()
5248 isDone = pattern.LoadFromFile(pattern_prism)
5250 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5253 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5254 isDone = pattern.MakeMesh(self.mesh, False, False)
5255 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5257 # Split quafrangle faces near triangular facets of volumes
5258 self.SplitQuadsNearTriangularFacets()
5262 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5263 MaxNbOfIterations, MaxAspectRatio, Method):
5268 IDsOfElements: the list if ids of elements to smooth
5269 IDsOfFixedNodes: the list of ids of fixed nodes.
5270 Note that nodes built on edges and boundary nodes are always fixed.
5271 MaxNbOfIterations: the maximum number of iterations
5272 MaxAspectRatio: varies in range [1.0, inf]
5273 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5274 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5277 True in case of success, False otherwise.
5280 if IDsOfElements == []:
5281 IDsOfElements = self.GetElementsId()
5282 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5283 self.mesh.SetParameters(Parameters)
5284 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5285 MaxNbOfIterations, MaxAspectRatio, Method)
5287 def SmoothObject(self, theObject, IDsOfFixedNodes,
5288 MaxNbOfIterations, MaxAspectRatio, Method):
5290 Smooth elements which belong to the given object
5293 theObject: the object to smooth
5294 IDsOfFixedNodes: the list of ids of fixed nodes.
5295 Note that nodes built on edges and boundary nodes are always fixed.
5296 MaxNbOfIterations: the maximum number of iterations
5297 MaxAspectRatio: varies in range [1.0, inf]
5298 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5299 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5302 True in case of success, False otherwise.
5305 if ( isinstance( theObject, Mesh )):
5306 theObject = theObject.GetMesh()
5307 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5308 MaxNbOfIterations, MaxAspectRatio, Method)
5310 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5311 MaxNbOfIterations, MaxAspectRatio, Method):
5313 Parametrically smooth the given elements
5316 IDsOfElements: the list if ids of elements to smooth
5317 IDsOfFixedNodes: the list of ids of fixed nodes.
5318 Note that nodes built on edges and boundary nodes are always fixed.
5319 MaxNbOfIterations: the maximum number of iterations
5320 MaxAspectRatio: varies in range [1.0, inf]
5321 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5322 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5325 True in case of success, False otherwise.
5328 if IDsOfElements == []:
5329 IDsOfElements = self.GetElementsId()
5330 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5331 self.mesh.SetParameters(Parameters)
5332 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5333 MaxNbOfIterations, MaxAspectRatio, Method)
5335 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5336 MaxNbOfIterations, MaxAspectRatio, Method):
5338 Parametrically smooth the elements which belong to the given object
5341 theObject: the object to smooth
5342 IDsOfFixedNodes: the list of ids of fixed nodes.
5343 Note that nodes built on edges and boundary nodes are always fixed.
5344 MaxNbOfIterations: the maximum number of iterations
5345 MaxAspectRatio: varies in range [1.0, inf]
5346 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5347 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5350 True in case of success, False otherwise.
5353 if ( isinstance( theObject, Mesh )):
5354 theObject = theObject.GetMesh()
5355 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5356 MaxNbOfIterations, MaxAspectRatio, Method)
5358 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5360 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5361 them with quadratic with the same id.
5364 theForce3d: method of new node creation:
5366 * False - the medium node lies at the geometrical entity from which the mesh element is built
5367 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5368 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5369 theToBiQuad: If True, converts the mesh to bi-quadratic
5372 :class:`SMESH.ComputeError` which can hold a warning
5375 If *theSubMesh* is provided, the mesh can become non-conformal
5378 This operation can create gaps in numeration of nodes or elements.
5379 Call :meth:`RenumberElements` to remove the gaps.
5382 if isinstance( theSubMesh, Mesh ):
5383 theSubMesh = theSubMesh.mesh
5385 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5388 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5390 self.editor.ConvertToQuadratic(theForce3d)
5391 error = self.editor.GetLastError()
5392 if error and error.comment:
5393 print(error.comment)
5396 def ConvertFromQuadratic(self, theSubMesh=None):
5398 Convert the mesh from quadratic to ordinary,
5399 deletes old quadratic elements,
5400 replacing them with ordinary mesh elements with the same id.
5403 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5406 If *theSubMesh* is provided, the mesh can become non-conformal
5409 This operation can create gaps in numeration of nodes or elements.
5410 Call :meth:`RenumberElements` to remove the gaps.
5414 self.editor.ConvertFromQuadraticObject(theSubMesh)
5416 return self.editor.ConvertFromQuadratic()
5418 def Make2DMeshFrom3D(self):
5420 Create 2D mesh as skin on boundary faces of a 3D mesh
5423 True if operation has been completed successfully, False otherwise
5426 return self.editor.Make2DMeshFrom3D()
5428 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5429 toCopyElements=False, toCopyExistingBondary=False):
5431 Create missing boundary elements
5434 elements: elements whose boundary is to be checked:
5435 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5436 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5437 dimension: defines type of boundary elements to create, either of
5438 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5439 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5440 groupName: a name of group to store created boundary elements in,
5441 "" means not to create the group
5442 meshName: a name of new mesh to store created boundary elements in,
5443 "" means not to create the new mesh
5444 toCopyElements: if True, the checked elements will be copied into
5445 the new mesh else only boundary elements will be copied into the new mesh
5446 toCopyExistingBondary: if True, not only new but also pre-existing
5447 boundary elements will be copied into the new mesh
5450 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5453 unRegister = genObjUnRegister()
5454 if isinstance( elements, Mesh ):
5455 elements = elements.GetMesh()
5456 if ( isinstance( elements, list )):
5457 elemType = SMESH.ALL
5458 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5459 elements = self.editor.MakeIDSource(elements, elemType)
5460 unRegister.set( elements )
5461 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5462 toCopyElements,toCopyExistingBondary)
5463 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5466 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5467 toCopyAll=False, groups=[]):
5469 Create missing boundary elements around either the whole mesh or
5473 dimension: defines type of boundary elements to create, either of
5474 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5475 groupName: a name of group to store all boundary elements in,
5476 "" means not to create the group
5477 meshName: a name of a new mesh, which is a copy of the initial
5478 mesh + created boundary elements; "" means not to create the new mesh
5479 toCopyAll: if True, the whole initial mesh will be copied into
5480 the new mesh else only boundary elements will be copied into the new mesh
5481 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5484 tuple( long, mesh, group )
5485 - long - number of added boundary elements
5486 - mesh - the :class:`Mesh` where elements were added to
5487 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5490 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5492 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5493 return nb, mesh, group
5495 def RenumberNodes(self):
5497 Renumber mesh nodes to remove unused node IDs
5499 self.editor.RenumberNodes()
5501 def RenumberElements(self):
5503 Renumber mesh elements to remove unused element IDs
5505 self.editor.RenumberElements()
5507 def _getIdSourceList(self, arg, idType, unRegister):
5509 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5511 if arg and isinstance( arg, list ):
5512 if isinstance( arg[0], int ):
5513 arg = self.GetIDSource( arg, idType )
5514 unRegister.set( arg )
5515 elif isinstance( arg[0], Mesh ):
5516 arg[0] = arg[0].GetMesh()
5517 elif isinstance( arg, Mesh ):
5519 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5523 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5524 MakeGroups=False, TotalAngle=False):
5526 Generate new elements by rotation of the given elements and nodes around the axis
5529 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5530 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5531 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5532 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5533 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5534 which defines angle in degrees
5535 NbOfSteps: the number of steps
5536 Tolerance: tolerance
5537 MakeGroups: forces the generation of new groups from existing ones
5538 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5539 of all steps, else - size of each step
5542 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5545 unRegister = genObjUnRegister()
5546 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5547 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5548 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5550 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5551 Axis = self.smeshpyD.GetAxisStruct( Axis )
5552 if isinstance( Axis, list ):
5553 Axis = SMESH.AxisStruct( *Axis )
5555 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5556 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5557 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5558 self.mesh.SetParameters(Parameters)
5559 if TotalAngle and NbOfSteps:
5560 AngleInRadians /= NbOfSteps
5561 return self.editor.RotationSweepObjects( nodes, edges, faces,
5562 Axis, AngleInRadians,
5563 NbOfSteps, Tolerance, MakeGroups)
5565 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5566 MakeGroups=False, TotalAngle=False):
5568 Generate new elements by rotation of the elements around the axis
5571 IDsOfElements: the list of ids of elements to sweep
5572 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5573 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5574 NbOfSteps: the number of steps
5575 Tolerance: tolerance
5576 MakeGroups: forces the generation of new groups from existing ones
5577 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5578 of all steps, else - size of each step
5581 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5584 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5585 AngleInRadians, NbOfSteps, Tolerance,
5586 MakeGroups, TotalAngle)
5588 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5589 MakeGroups=False, TotalAngle=False):
5591 Generate new elements by rotation of the elements of object around the axis
5592 theObject object which elements should be sweeped.
5593 It can be a mesh, a sub mesh or a group.
5596 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5597 AngleInRadians: the angle of Rotation
5598 NbOfSteps: number of steps
5599 Tolerance: tolerance
5600 MakeGroups: forces the generation of new groups from existing ones
5601 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5602 of all steps, else - size of each step
5605 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5608 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5609 AngleInRadians, NbOfSteps, Tolerance,
5610 MakeGroups, TotalAngle )
5612 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5613 MakeGroups=False, TotalAngle=False):
5615 Generate new elements by rotation of the elements of object around the axis
5616 theObject object which elements should be sweeped.
5617 It can be a mesh, a sub mesh or a group.
5620 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5621 AngleInRadians: the angle of Rotation
5622 NbOfSteps: number of steps
5623 Tolerance: tolerance
5624 MakeGroups: forces the generation of new groups from existing ones
5625 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5626 of all steps, else - size of each step
5629 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5630 empty list otherwise
5633 return self.RotationSweepObjects([],theObject,[], Axis,
5634 AngleInRadians, NbOfSteps, Tolerance,
5635 MakeGroups, TotalAngle)
5637 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5638 MakeGroups=False, TotalAngle=False):
5640 Generate new elements by rotation of the elements of object around the axis
5641 theObject object which elements should be sweeped.
5642 It can be a mesh, a sub mesh or a group.
5645 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5646 AngleInRadians: the angle of Rotation
5647 NbOfSteps: number of steps
5648 Tolerance: tolerance
5649 MakeGroups: forces the generation of new groups from existing ones
5650 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5651 of all steps, else - size of each step
5654 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5657 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5658 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5660 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5661 scaleFactors=[], linearVariation=False, basePoint=[],
5662 angles=[], anglesVariation=False):
5664 Generate new elements by extrusion of the given elements and nodes
5667 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5668 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5669 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5670 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5671 the direction and value of extrusion for one step (the total extrusion
5672 length will be NbOfSteps * ||StepVector||)
5673 NbOfSteps: the number of steps
5674 MakeGroups: forces the generation of new groups from existing ones
5675 scaleFactors: optional scale factors to apply during extrusion
5676 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5677 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5678 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5679 nodes and elements being extruded is used as the scaling center.
5682 - a list of tree components of the point or
5685 angles: list of angles in radians. Nodes at each extrusion step are rotated
5686 around *basePoint*, additionally to previous steps.
5687 anglesVariation: forces the computation of rotation angles as linear
5688 variation of the given *angles* along path steps
5690 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5692 Example: :ref:`tui_extrusion`
5694 unRegister = genObjUnRegister()
5695 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5696 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5697 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5699 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5700 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5701 if isinstance( StepVector, list ):
5702 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5704 if isinstance( basePoint, int):
5705 xyz = self.GetNodeXYZ( basePoint )
5707 raise RuntimeError("Invalid node ID: %s" % basePoint)
5709 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5710 basePoint = self.geompyD.PointCoordinates( basePoint )
5712 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5713 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5714 angles,angleParameters,hasVars = ParseAngles(angles)
5715 Parameters = StepVector.PS.parameters + var_separator + \
5716 Parameters + var_separator + \
5717 scaleParameters + var_separator + angleParameters
5718 self.mesh.SetParameters(Parameters)
5720 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5721 StepVector, NbOfSteps, MakeGroups,
5722 scaleFactors, linearVariation, basePoint,
5723 angles, anglesVariation )
5726 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5728 Generate new elements by extrusion of the elements with given ids
5731 IDsOfElements: the list of ids of elements or nodes for extrusion
5732 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5733 the direction and value of extrusion for one step (the total extrusion
5734 length will be NbOfSteps * ||StepVector||)
5735 NbOfSteps: the number of steps
5736 MakeGroups: forces the generation of new groups from existing ones
5737 IsNodes: is True if elements with given ids are nodes
5740 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5742 Example: :ref:`tui_extrusion`
5745 if IsNodes: n = IDsOfElements
5746 else : e,f, = IDsOfElements,IDsOfElements
5747 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5749 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5750 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5752 Generate new elements by extrusion along the normal to a discretized surface or wire
5755 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5756 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5757 StepSize: length of one extrusion step (the total extrusion
5758 length will be *NbOfSteps* *StepSize*).
5759 NbOfSteps: number of extrusion steps.
5760 ByAverageNormal: if True each node is translated by *StepSize*
5761 along the average of the normal vectors to the faces sharing the node;
5762 else each node is translated along the same average normal till
5763 intersection with the plane got by translation of the face sharing
5764 the node along its own normal by *StepSize*.
5765 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5766 for every node of *Elements*.
5767 MakeGroups: forces generation of new groups from existing ones.
5768 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5769 is not yet implemented. This parameter is used if *Elements* contains
5770 both faces and edges, i.e. *Elements* is a Mesh.
5773 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5774 empty list otherwise.
5775 Example: :ref:`tui_extrusion`
5778 unRegister = genObjUnRegister()
5779 if isinstance( Elements, Mesh ):
5780 Elements = [ Elements.GetMesh() ]
5781 if isinstance( Elements, list ):
5783 raise RuntimeError("Elements empty!")
5784 if isinstance( Elements[0], Mesh ):
5785 Elements = [ Elements[0].GetMesh() ]
5786 if isinstance( Elements[0], int ):
5787 Elements = self.GetIDSource( Elements, SMESH.ALL )
5788 unRegister.set( Elements )
5789 if not isinstance( Elements, list ):
5790 Elements = [ Elements ]
5791 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5792 self.mesh.SetParameters(Parameters)
5793 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5794 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5796 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5798 Generate new elements by extrusion of the elements or nodes which belong to the object
5801 theObject: the object whose elements or nodes should be processed.
5802 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5803 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5804 the direction and value of extrusion for one step (the total extrusion
5805 length will be NbOfSteps * ||StepVector||)
5806 NbOfSteps: the number of steps
5807 MakeGroups: forces the generation of new groups from existing ones
5808 IsNodes: is True if elements to extrude are nodes
5811 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5812 Example: :ref:`tui_extrusion`
5816 if IsNodes: n = theObject
5817 else : e,f, = theObject,theObject
5818 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5820 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5822 Generate new elements by extrusion of edges which belong to the object
5825 theObject: object whose 1D elements should be processed.
5826 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5827 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5828 the direction and value of extrusion for one step (the total extrusion
5829 length will be NbOfSteps * ||StepVector||)
5830 NbOfSteps: the number of steps
5831 MakeGroups: to generate new groups from existing ones
5834 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5835 Example: :ref:`tui_extrusion`
5838 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5840 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5842 Generate new elements by extrusion of faces which belong to the object
5845 theObject: object whose 2D elements should be processed.
5846 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5847 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5848 the direction and value of extrusion for one step (the total extrusion
5849 length will be NbOfSteps * ||StepVector||)
5850 NbOfSteps: the number of steps
5851 MakeGroups: forces the generation of new groups from existing ones
5854 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5855 Example: :ref:`tui_extrusion`
5858 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5860 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5861 ExtrFlags, SewTolerance, MakeGroups=False):
5863 Generate new elements by extrusion of the elements with given ids
5866 IDsOfElements: is ids of elements
5867 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5868 the direction and value of extrusion for one step (the total extrusion
5869 length will be NbOfSteps * ||StepVector||)
5870 NbOfSteps: the number of steps
5871 ExtrFlags: sets flags for extrusion
5872 SewTolerance: uses for comparing locations of nodes if flag
5873 EXTRUSION_FLAG_SEW is set
5874 MakeGroups: forces the generation of new groups from existing ones
5877 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5880 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5881 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5882 if isinstance( StepVector, list ):
5883 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5884 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5885 ExtrFlags, SewTolerance, MakeGroups)
5887 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5888 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5889 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5890 ScaleFactors=[], ScalesVariation=False):
5892 Generate new elements by extrusion of the given elements and nodes along the path.
5893 The path of extrusion must be a meshed edge.
5896 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5897 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5898 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5899 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5900 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
5901 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5902 HasAngles: not used obsolete
5903 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5904 around *basePoint*, additionally to previous steps.
5905 LinearVariation: forces the computation of rotation angles as linear
5906 variation of the given Angles along path steps
5907 HasRefPoint: allows using the reference point
5908 RefPoint: optional scaling and rotation center (mass center of the extruded
5909 elements by default). The User can specify any point as the Reference Point.
5910 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5911 MakeGroups: forces the generation of new groups from existing ones
5912 ScaleFactors: optional scale factors to apply during extrusion
5913 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5914 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5917 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5918 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5919 Example: :ref:`tui_extrusion_along_path`
5922 unRegister = genObjUnRegister()
5923 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5924 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5925 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5927 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5928 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5929 if isinstance( RefPoint, list ):
5930 if not RefPoint: RefPoint = [0,0,0]
5931 RefPoint = SMESH.PointStruct( *RefPoint )
5932 if isinstance( PathObject, Mesh ):
5933 PathObject = PathObject.GetMesh()
5934 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5935 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5936 Parameters = AnglesParameters + var_separator + \
5937 RefPoint.parameters + var_separator + ScalesParameters
5938 self.mesh.SetParameters(Parameters)
5939 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5940 PathObject, PathShape, NodeStart,
5941 HasAngles, Angles, LinearVariation,
5942 HasRefPoint, RefPoint, MakeGroups,
5943 ScaleFactors, ScalesVariation)
5945 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5946 HasAngles=False, Angles=[], LinearVariation=False,
5947 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5948 ElemType=SMESH.FACE):
5950 Generate new elements by extrusion of the given elements.
5951 The path of extrusion must be a meshed edge.
5954 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5955 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5956 NodeStart: the start node from Path. Defines the direction of extrusion
5957 HasAngles: not used obsolete
5958 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5959 around *basePoint*, additionally to previous steps.
5960 LinearVariation: forces the computation of rotation angles as linear
5961 variation of the given Angles along path steps
5962 HasRefPoint: allows using the reference point
5963 RefPoint: the reference point around which the elements are rotated (the mass
5964 center of the elements by default).
5965 The User can specify any point as the Reference Point.
5966 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5967 MakeGroups: forces the generation of new groups from existing ones
5968 ElemType: type of elements for extrusion (if param Base is a mesh)
5971 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5972 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5973 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5975 Example: :ref:`tui_extrusion_along_path`
5979 if ElemType == SMESH.NODE: n = Base
5980 if ElemType == SMESH.EDGE: e = Base
5981 if ElemType == SMESH.FACE: f = Base
5982 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5983 HasAngles, Angles, LinearVariation,
5984 HasRefPoint, RefPoint, MakeGroups)
5985 if MakeGroups: return gr,er
5988 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5989 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5990 MakeGroups=False, LinearVariation=False):
5992 Generate new elements by extrusion of the given elements.
5993 The path of extrusion must be a meshed edge.
5996 IDsOfElements: ids of elements
5997 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5998 PathShape: shape (edge) defines the sub-mesh for the path
5999 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6000 HasAngles: not used obsolete
6001 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6002 around *basePoint*, additionally to previous steps.
6003 HasRefPoint: allows using the reference point
6004 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6005 The User can specify any point as the Reference Point.
6006 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6007 MakeGroups: forces the generation of new groups from existing ones
6008 LinearVariation: forces the computation of rotation angles as linear
6009 variation of the given Angles along path steps
6012 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6013 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6014 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6015 Example: :ref:`tui_extrusion_along_path`
6018 if not IDsOfElements:
6019 IDsOfElements = [ self.GetMesh() ]
6020 n,e,f = [],IDsOfElements,IDsOfElements
6021 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6022 NodeStart, HasAngles, Angles,
6024 HasRefPoint, RefPoint, MakeGroups)
6025 if MakeGroups: return gr,er
6028 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6029 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6030 MakeGroups=False, LinearVariation=False):
6032 Generate new elements by extrusion of the elements which belong to the object.
6033 The path of extrusion must be a meshed edge.
6036 theObject: the object whose 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,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 ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6067 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6068 MakeGroups=False, LinearVariation=False):
6070 Generate new elements by extrusion of mesh segments which belong to the object.
6071 The path of extrusion must be a meshed edge.
6074 theObject: the object whose 1D 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 ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6105 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6106 MakeGroups=False, LinearVariation=False):
6108 Generate new elements by extrusion of faces which belong to the object.
6109 The path of extrusion must be a meshed edge.
6112 theObject: the object whose 2D elements should be processed.
6113 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6114 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6115 PathShape: shape (edge) defines the sub-mesh for the path
6116 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6117 HasAngles: not used obsolete
6118 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6119 around *basePoint*, additionally to previous steps.
6120 HasRefPoint: allows using the reference point
6121 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6122 The User can specify any point as the Reference Point.
6123 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6124 MakeGroups: forces the generation of new groups from existing ones
6125 LinearVariation: forces the computation of rotation angles as linear
6126 variation of the given Angles along path steps
6129 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6130 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6131 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6132 Example: :ref:`tui_extrusion_along_path`
6135 n,e,f = [],[],theObject
6136 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6137 HasAngles, Angles, LinearVariation,
6138 HasRefPoint, RefPoint, MakeGroups)
6139 if MakeGroups: return gr,er
6142 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6144 Create a symmetrical copy of mesh elements
6147 IDsOfElements: list of elements ids
6148 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6149 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6150 If the *Mirror* is a geom object this parameter is unnecessary
6151 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6152 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6155 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6158 if IDsOfElements == []:
6159 IDsOfElements = self.GetElementsId()
6160 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6161 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6162 theMirrorType = Mirror._mirrorType
6164 self.mesh.SetParameters(Mirror.parameters)
6165 if Copy and MakeGroups:
6166 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6167 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6170 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6172 Create a new mesh by a symmetrical copy of mesh elements
6175 IDsOfElements: the list of elements ids
6176 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6177 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6178 If the *Mirror* is a geom object this parameter is unnecessary
6179 MakeGroups: to generate new groups from existing ones
6180 NewMeshName: a name of the new mesh to create
6183 instance of class :class:`Mesh`
6186 if IDsOfElements == []:
6187 IDsOfElements = self.GetElementsId()
6188 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6189 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6190 theMirrorType = Mirror._mirrorType
6192 self.mesh.SetParameters(Mirror.parameters)
6193 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6194 MakeGroups, NewMeshName)
6195 return Mesh(self.smeshpyD,self.geompyD,mesh)
6197 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6199 Create a symmetrical copy of the object
6202 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6203 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6204 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6205 If the *Mirror* is a geom object this parameter is unnecessary
6206 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6207 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6210 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6213 if ( isinstance( theObject, Mesh )):
6214 theObject = theObject.GetMesh()
6215 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6216 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6217 theMirrorType = Mirror._mirrorType
6219 self.mesh.SetParameters(Mirror.parameters)
6220 if Copy and MakeGroups:
6221 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6222 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6225 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6227 Create a new mesh by a symmetrical copy of the object
6230 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6231 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6232 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6233 If the *Mirror* is a geom object this parameter is unnecessary
6234 MakeGroups: forces the generation of new groups from existing ones
6235 NewMeshName: the name of the new mesh to create
6238 instance of class :class:`Mesh`
6241 if ( isinstance( theObject, Mesh )):
6242 theObject = theObject.GetMesh()
6243 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6244 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6245 theMirrorType = Mirror._mirrorType
6247 self.mesh.SetParameters(Mirror.parameters)
6248 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6249 MakeGroups, NewMeshName)
6250 return Mesh( self.smeshpyD,self.geompyD,mesh )
6252 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6254 Translate the elements
6257 IDsOfElements: list of elements ids
6258 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6259 Copy: allows copying the translated elements
6260 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6263 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6266 if IDsOfElements == []:
6267 IDsOfElements = self.GetElementsId()
6268 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6269 Vector = self.smeshpyD.GetDirStruct(Vector)
6270 if isinstance( Vector, list ):
6271 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6272 self.mesh.SetParameters(Vector.PS.parameters)
6273 if Copy and MakeGroups:
6274 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6275 self.editor.Translate(IDsOfElements, Vector, Copy)
6278 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6280 Create a new mesh of translated elements
6283 IDsOfElements: list of elements ids
6284 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6285 MakeGroups: forces the generation of new groups from existing ones
6286 NewMeshName: the name of the newly created mesh
6289 instance of class :class:`Mesh`
6292 if IDsOfElements == []:
6293 IDsOfElements = self.GetElementsId()
6294 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6295 Vector = self.smeshpyD.GetDirStruct(Vector)
6296 if isinstance( Vector, list ):
6297 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6298 self.mesh.SetParameters(Vector.PS.parameters)
6299 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6300 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6302 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6304 Translate the object
6307 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6308 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6309 Copy: allows copying the translated elements
6310 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6313 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6316 if ( isinstance( theObject, Mesh )):
6317 theObject = theObject.GetMesh()
6318 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6319 Vector = self.smeshpyD.GetDirStruct(Vector)
6320 if isinstance( Vector, list ):
6321 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6322 self.mesh.SetParameters(Vector.PS.parameters)
6323 if Copy and MakeGroups:
6324 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6325 self.editor.TranslateObject(theObject, Vector, Copy)
6328 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6330 Create a new mesh from the translated object
6333 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6334 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6335 MakeGroups: forces the generation of new groups from existing ones
6336 NewMeshName: the name of the newly created mesh
6339 instance of class :class:`Mesh`
6342 if isinstance( theObject, Mesh ):
6343 theObject = theObject.GetMesh()
6344 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6345 Vector = self.smeshpyD.GetDirStruct(Vector)
6346 if isinstance( Vector, list ):
6347 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6348 self.mesh.SetParameters(Vector.PS.parameters)
6349 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6350 return Mesh( self.smeshpyD, self.geompyD, mesh )
6354 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6359 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6360 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6361 theScaleFact: list of 1-3 scale factors for axises
6362 Copy: allows copying the translated elements
6363 MakeGroups: forces the generation of new groups from existing
6367 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6368 empty list otherwise
6370 unRegister = genObjUnRegister()
6371 if ( isinstance( theObject, Mesh )):
6372 theObject = theObject.GetMesh()
6373 if ( isinstance( theObject, list )):
6374 theObject = self.GetIDSource(theObject, SMESH.ALL)
6375 unRegister.set( theObject )
6376 if ( isinstance( thePoint, list )):
6377 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6378 if ( isinstance( theScaleFact, float )):
6379 theScaleFact = [theScaleFact]
6380 if ( isinstance( theScaleFact, int )):
6381 theScaleFact = [ float(theScaleFact)]
6383 self.mesh.SetParameters(thePoint.parameters)
6385 if Copy and MakeGroups:
6386 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6387 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6390 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6392 Create a new mesh from the translated object
6395 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6396 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6397 theScaleFact: list of 1-3 scale factors for axises
6398 MakeGroups: forces the generation of new groups from existing ones
6399 NewMeshName: the name of the newly created mesh
6402 instance of class :class:`Mesh`
6404 unRegister = genObjUnRegister()
6405 if (isinstance(theObject, Mesh)):
6406 theObject = theObject.GetMesh()
6407 if ( isinstance( theObject, list )):
6408 theObject = self.GetIDSource(theObject,SMESH.ALL)
6409 unRegister.set( theObject )
6410 if ( isinstance( thePoint, list )):
6411 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6412 if ( isinstance( theScaleFact, float )):
6413 theScaleFact = [theScaleFact]
6414 if ( isinstance( theScaleFact, int )):
6415 theScaleFact = [ float(theScaleFact)]
6417 self.mesh.SetParameters(thePoint.parameters)
6418 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6419 MakeGroups, NewMeshName)
6420 return Mesh( self.smeshpyD, self.geompyD, mesh )
6424 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6429 IDsOfElements: list of elements ids
6430 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6431 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6432 Copy: allows copying the rotated elements
6433 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6436 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6440 if IDsOfElements == []:
6441 IDsOfElements = self.GetElementsId()
6442 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6443 Axis = self.smeshpyD.GetAxisStruct(Axis)
6444 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6445 Parameters = Axis.parameters + var_separator + Parameters
6446 self.mesh.SetParameters(Parameters)
6447 if Copy and MakeGroups:
6448 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6449 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6452 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6454 Create a new mesh of rotated elements
6457 IDsOfElements: list of element ids
6458 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6459 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6460 MakeGroups: forces the generation of new groups from existing ones
6461 NewMeshName: the name of the newly created mesh
6464 instance of class :class:`Mesh`
6467 if IDsOfElements == []:
6468 IDsOfElements = self.GetElementsId()
6469 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6470 Axis = self.smeshpyD.GetAxisStruct(Axis)
6471 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6472 Parameters = Axis.parameters + var_separator + Parameters
6473 self.mesh.SetParameters(Parameters)
6474 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6475 MakeGroups, NewMeshName)
6476 return Mesh( self.smeshpyD, self.geompyD, mesh )
6478 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6483 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6484 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6485 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6486 Copy: allows copying the rotated elements
6487 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6490 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6493 if (isinstance(theObject, Mesh)):
6494 theObject = theObject.GetMesh()
6495 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6496 Axis = self.smeshpyD.GetAxisStruct(Axis)
6497 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6498 Parameters = Axis.parameters + ":" + Parameters
6499 self.mesh.SetParameters(Parameters)
6500 if Copy and MakeGroups:
6501 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6502 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6505 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6507 Create a new mesh from the rotated object
6510 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6511 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6512 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6513 MakeGroups: forces the generation of new groups from existing ones
6514 NewMeshName: the name of the newly created mesh
6517 instance of class :class:`Mesh`
6520 if (isinstance( theObject, Mesh )):
6521 theObject = theObject.GetMesh()
6522 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6523 Axis = self.smeshpyD.GetAxisStruct(Axis)
6524 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6525 Parameters = Axis.parameters + ":" + Parameters
6526 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6527 MakeGroups, NewMeshName)
6528 self.mesh.SetParameters(Parameters)
6529 return Mesh( self.smeshpyD, self.geompyD, mesh )
6531 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6533 Create an offset mesh from the given 2D object
6536 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6537 theValue (float): signed offset size
6538 MakeGroups (boolean): forces the generation of new groups from existing ones
6539 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6540 False means to remove original elements.
6541 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6544 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6547 if isinstance( theObject, Mesh ):
6548 theObject = theObject.GetMesh()
6549 theValue,Parameters,hasVars = ParseParameters(Value)
6550 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6551 self.mesh.SetParameters(Parameters)
6553 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6556 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6558 Find groups of adjacent nodes within Tolerance.
6561 Tolerance (float): the value of tolerance
6562 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6563 corner and medium nodes in separate groups thus preventing
6564 their further merge.
6567 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6570 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6572 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6573 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6575 Find groups of adjacent nodes within Tolerance.
6578 Tolerance: the value of tolerance
6579 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6580 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6581 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6582 corner and medium nodes in separate groups thus preventing
6583 their further merge.
6586 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6589 unRegister = genObjUnRegister()
6590 if not isinstance( SubMeshOrGroup, list ):
6591 SubMeshOrGroup = [ SubMeshOrGroup ]
6592 for i,obj in enumerate( SubMeshOrGroup ):
6593 if isinstance( obj, Mesh ):
6594 SubMeshOrGroup = [ obj.GetMesh() ]
6596 if isinstance( obj, int ):
6597 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6598 unRegister.set( SubMeshOrGroup )
6601 if not isinstance( exceptNodes, list ):
6602 exceptNodes = [ exceptNodes ]
6603 if exceptNodes and isinstance( exceptNodes[0], int ):
6604 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6605 unRegister.set( exceptNodes )
6607 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6608 exceptNodes, SeparateCornerAndMediumNodes)
6610 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6615 GroupsOfNodes: a list of groups of nodes IDs for merging.
6616 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6617 in all elements and mesh groups by nodes 1 and 25 correspondingly
6618 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6619 If *NodesToKeep* does not include a node to keep for some group to merge,
6620 then the first node in the group is kept.
6621 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6625 This operation can create gaps in numeration of nodes or elements.
6626 Call :meth:`RenumberElements` to remove the gaps.
6628 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6630 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6632 Find the elements built on the same nodes.
6635 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6636 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6640 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6643 unRegister = genObjUnRegister()
6644 if MeshOrSubMeshOrGroup is None:
6645 MeshOrSubMeshOrGroup = [ self.mesh ]
6646 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6647 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6648 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6649 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6650 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6651 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6652 unRegister.set( MeshOrSubMeshOrGroup )
6653 for item in MeshOrSubMeshOrGroup:
6654 if isinstance( item, Mesh ):
6655 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6657 if not isinstance( exceptElements, list ):
6658 exceptElements = [ exceptElements ]
6659 if exceptElements and isinstance( exceptElements[0], int ):
6660 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6661 unRegister.set( exceptElements )
6663 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6665 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6667 Merge elements in each given group.
6670 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6671 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6672 replaced in all mesh groups by elements 1 and 25)
6673 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6674 If *ElementsToKeep* does not include an element to keep for some group to merge,
6675 then the first element in the group is kept.
6678 This operation can create gaps in numeration of elements.
6679 Call :meth:`RenumberElements` to remove the gaps.
6682 unRegister = genObjUnRegister()
6684 if not isinstance( ElementsToKeep, list ):
6685 ElementsToKeep = [ ElementsToKeep ]
6686 if isinstance( ElementsToKeep[0], int ):
6687 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6688 unRegister.set( ElementsToKeep )
6690 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6692 def MergeEqualElements(self):
6694 Leave one element and remove all other elements built on the same nodes.
6697 This operation can create gaps in numeration of elements.
6698 Call :meth:`RenumberElements` to remove the gaps.
6701 self.editor.MergeEqualElements()
6703 def FindFreeBorders(self, ClosedOnly=True):
6705 Returns all or only closed free borders
6708 list of SMESH.FreeBorder's
6711 return self.editor.FindFreeBorders( ClosedOnly )
6713 def FillHole(self, holeNodes, groupName=""):
6715 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6718 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6719 must describe all sequential nodes of the hole border. The first and the last
6720 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6721 groupName (string): name of a group to add new faces
6723 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6727 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6728 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6729 if not isinstance( holeNodes, SMESH.FreeBorder ):
6730 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6731 return self.editor.FillHole( holeNodes, groupName )
6733 def FindCoincidentFreeBorders (self, tolerance=0.):
6735 Return groups of FreeBorder's coincident within the given tolerance.
6738 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6739 size of elements adjacent to free borders being compared is used.
6742 SMESH.CoincidentFreeBorders structure
6745 return self.editor.FindCoincidentFreeBorders( tolerance )
6747 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6749 Sew FreeBorder's of each group
6752 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6753 where each enclosed list contains node IDs of a group of coincident free
6754 borders such that each consequent triple of IDs within a group describes
6755 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6756 last node of a border.
6757 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6758 groups of coincident free borders, each group including two borders.
6759 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6760 polygons if a node of opposite border falls on a face edge, else such
6761 faces are split into several ones.
6762 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6763 polyhedra if a node of opposite border falls on a volume edge, else such
6764 volumes, if any, remain intact and the mesh becomes non-conformal.
6767 a number of successfully sewed groups
6770 This operation can create gaps in numeration of nodes or elements.
6771 Call :meth:`RenumberElements` to remove the gaps.
6774 if freeBorders and isinstance( freeBorders, list ):
6775 # construct SMESH.CoincidentFreeBorders
6776 if isinstance( freeBorders[0], int ):
6777 freeBorders = [freeBorders]
6779 coincidentGroups = []
6780 for nodeList in freeBorders:
6781 if not nodeList or len( nodeList ) % 3:
6782 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6785 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6786 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6787 nodeList = nodeList[3:]
6789 coincidentGroups.append( group )
6791 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6793 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6795 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6796 FirstNodeID2, SecondNodeID2, LastNodeID2,
6797 CreatePolygons, CreatePolyedrs):
6802 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6805 This operation can create gaps in numeration of nodes or elements.
6806 Call :meth:`RenumberElements` to remove the gaps.
6809 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6810 FirstNodeID2, SecondNodeID2, LastNodeID2,
6811 CreatePolygons, CreatePolyedrs)
6813 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6814 FirstNodeID2, SecondNodeID2):
6816 Sew conform free borders
6819 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6822 This operation can create gaps in numeration of elements.
6823 Call :meth:`RenumberElements` to remove the gaps.
6826 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6827 FirstNodeID2, SecondNodeID2)
6829 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6830 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6835 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6838 This operation can create gaps in numeration of elements.
6839 Call :meth:`RenumberElements` to remove the gaps.
6842 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6843 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6845 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6846 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6847 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6849 Sew two sides of a mesh. The nodes belonging to Side1 are
6850 merged with the nodes of elements of Side2.
6851 The number of elements in theSide1 and in theSide2 must be
6852 equal and they should have similar nodal connectivity.
6853 The nodes to merge should belong to side borders and
6854 the first node should be linked to the second.
6857 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6860 This operation can create gaps in numeration of nodes.
6861 Call :meth:`RenumberElements` to remove the gaps.
6864 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6865 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6866 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6868 def ChangeElemNodes(self, ide, newIDs):
6870 Set new nodes for the given element. Number of nodes should be kept.
6877 False if the number of nodes does not correspond to the type of element
6880 return self.editor.ChangeElemNodes(ide, newIDs)
6882 def GetLastCreatedNodes(self):
6884 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6885 created, this method return the list of their IDs.
6886 If new nodes were not created - return empty list
6889 the list of integer values (can be empty)
6892 return self.editor.GetLastCreatedNodes()
6894 def GetLastCreatedElems(self):
6896 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6897 created this method return the list of their IDs.
6898 If new elements were not created - return empty list
6901 the list of integer values (can be empty)
6904 return self.editor.GetLastCreatedElems()
6906 def ClearLastCreated(self):
6908 Forget what nodes and elements were created by the last mesh edition operation
6911 self.editor.ClearLastCreated()
6913 def DoubleElements(self, theElements, theGroupName=""):
6915 Create duplicates of given elements, i.e. create new elements based on the
6916 same nodes as the given ones.
6919 theElements: container of elements to duplicate. It can be a
6920 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6921 or a list of element IDs. If *theElements* is
6922 a :class:`Mesh`, elements of highest dimension are duplicated
6923 theGroupName: a name of group to contain the generated elements.
6924 If a group with such a name already exists, the new elements
6925 are added to the existing group, else a new group is created.
6926 If *theGroupName* is empty, new elements are not added
6930 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6931 None if *theGroupName* == "".
6934 unRegister = genObjUnRegister()
6935 if isinstance( theElements, Mesh ):
6936 theElements = theElements.mesh
6937 elif isinstance( theElements, list ):
6938 theElements = self.GetIDSource( theElements, SMESH.ALL )
6939 unRegister.set( theElements )
6940 return self.editor.DoubleElements(theElements, theGroupName)
6942 def DoubleNodes(self, theNodes, theModifiedElems):
6944 Create a hole in a mesh by doubling the nodes of some particular elements
6947 theNodes: IDs of nodes to be doubled
6948 theModifiedElems: IDs of elements to be updated by the new (doubled)
6949 nodes. If list of element identifiers is empty then nodes are doubled but
6950 they not assigned to elements
6953 True if operation has been completed successfully, False otherwise
6956 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6958 def DoubleNode(self, theNodeId, theModifiedElems):
6960 Create a hole in a mesh by doubling the nodes of some particular elements.
6961 This method provided for convenience works as :meth:`DoubleNodes`.
6964 theNodeId: IDs of node to double
6965 theModifiedElems: IDs of elements to update
6968 True if operation has been completed successfully, False otherwise
6971 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6973 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6975 Create a hole in a mesh by doubling the nodes of some particular elements.
6976 This method provided for convenience works as :meth:`DoubleNodes`.
6979 theNodes: group of nodes to double.
6980 theModifiedElems: group of elements to update.
6981 theMakeGroup: forces the generation of a group containing new nodes.
6984 True or a created group if operation has been completed successfully,
6985 False or None otherwise
6989 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6990 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6992 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6994 Create a hole in a mesh by doubling the nodes of some particular elements.
6995 This method provided for convenience works as :meth:`DoubleNodes`.
6998 theNodes: list of groups of nodes to double.
6999 theModifiedElems: list of groups of elements to update.
7000 theMakeGroup: forces the generation of a group containing new nodes.
7003 True if operation has been completed successfully, False otherwise
7007 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7008 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7010 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7012 Create a hole in a mesh by doubling the nodes of some particular elements
7015 theElems: the list of elements (edges or faces) to replicate.
7016 The nodes for duplication could be found from these elements
7017 theNodesNot: list of nodes NOT to replicate
7018 theAffectedElems: the list of elements (cells and edges) to which the
7019 replicated nodes should be associated to
7022 True if operation has been completed successfully, False otherwise
7025 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7027 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7029 Create a hole in a mesh by doubling the nodes of some particular elements
7032 theElems: the list of elements (edges or faces) to replicate.
7033 The nodes for duplication could be found from these elements
7034 theNodesNot: list of nodes NOT to replicate
7035 theShape: shape to detect affected elements (element which geometric center
7036 located on or inside shape).
7037 The replicated nodes should be associated to affected elements.
7040 True if operation has been completed successfully, False otherwise
7043 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7045 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7046 theMakeGroup=False, theMakeNodeGroup=False):
7048 Create a hole in a mesh by doubling the nodes of some particular elements.
7049 This method provided for convenience works as :meth:`DoubleNodes`.
7052 theElems: group of of elements (edges or faces) to replicate.
7053 theNodesNot: group of nodes NOT to replicate.
7054 theAffectedElems: group of elements to which the replicated nodes
7055 should be associated to.
7056 theMakeGroup: forces the generation of a group containing new elements.
7057 theMakeNodeGroup: forces the generation of a group containing new nodes.
7060 True or created groups (one or two) if operation has been completed successfully,
7061 False or None otherwise
7064 if theMakeGroup or theMakeNodeGroup:
7065 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7067 theMakeGroup, theMakeNodeGroup)
7068 if theMakeGroup and theMakeNodeGroup:
7071 return twoGroups[ int(theMakeNodeGroup) ]
7072 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7074 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7076 Create a hole in a mesh by doubling the nodes of some particular elements.
7077 This method provided for convenience works as :meth:`DoubleNodes`.
7080 theElems: group of of elements (edges or faces) to replicate
7081 theNodesNot: group of nodes not to replicate
7082 theShape: shape to detect affected elements (element which geometric center
7083 located on or inside shape).
7084 The replicated nodes should be associated to affected elements
7087 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7089 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7090 theMakeGroup=False, theMakeNodeGroup=False):
7092 Create a hole in a mesh by doubling the nodes of some particular elements.
7093 This method provided for convenience works as :meth:`DoubleNodes`.
7096 theElems: list of groups of elements (edges or faces) to replicate
7097 theNodesNot: list of groups of nodes NOT to replicate
7098 theAffectedElems: group of elements to which the replicated nodes
7099 should be associated to
7100 theMakeGroup: forces generation of a group containing new elements.
7101 theMakeNodeGroup: forces generation of a group containing new nodes
7104 True or created groups (one or two) if operation has been completed successfully,
7105 False or None otherwise
7108 if theMakeGroup or theMakeNodeGroup:
7109 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7111 theMakeGroup, theMakeNodeGroup)
7112 if theMakeGroup and theMakeNodeGroup:
7115 return twoGroups[ int(theMakeNodeGroup) ]
7116 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7118 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7120 Create a hole in a mesh by doubling the nodes of some particular elements.
7121 This method provided for convenience works as :meth:`DoubleNodes`.
7124 theElems: list of groups of elements (edges or faces) to replicate
7125 theNodesNot: list of groups of nodes NOT to replicate
7126 theShape: shape to detect affected elements (element which geometric center
7127 located on or inside shape).
7128 The replicated nodes should be associated to affected elements
7131 True if operation has been completed successfully, False otherwise
7134 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7136 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7138 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7139 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7142 theElems: list of groups of nodes or elements (edges or faces) to replicate
7143 theNodesNot: list of groups of nodes NOT to replicate
7144 theShape: shape to detect affected elements (element which geometric center
7145 located on or inside shape).
7146 The replicated nodes should be associated to affected elements
7149 groups of affected elements in order: volumes, faces, edges
7152 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7154 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7157 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7158 The list of groups must describe a partition of the mesh volumes.
7159 The nodes of the internal faces at the boundaries of the groups are doubled.
7160 In option, the internal faces are replaced by flat elements.
7161 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7164 theDomains: list of groups of volumes
7165 createJointElems: if True, create the elements
7166 onAllBoundaries: if True, the nodes and elements are also created on
7167 the boundary between *theDomains* and the rest mesh
7170 True if operation has been completed successfully, False otherwise
7173 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7175 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7177 Double nodes on some external faces and create flat elements.
7178 Flat elements are mainly used by some types of mechanic calculations.
7180 Each group of the list must be constituted of faces.
7181 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7184 theGroupsOfFaces: list of groups of faces
7187 True if operation has been completed successfully, False otherwise
7190 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7192 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7194 Identify all the elements around a geom shape, get the faces delimiting the hole
7196 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7198 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7200 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7201 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7202 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7203 If there are several paths connecting a pair of points, the shortest path is
7204 selected by the module. Position of the cutting plane is defined by the two
7205 points and an optional vector lying on the plane specified by a PolySegment.
7206 By default the vector is defined by Mesh module as following. A middle point
7207 of the two given points is computed. The middle point is projected to the mesh.
7208 The vector goes from the middle point to the projection point. In case of planar
7209 mesh, the vector is normal to the mesh.
7211 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7214 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7215 groupName: optional name of a group where created mesh segments will be added.
7218 editor = self.editor
7220 editor = self.mesh.GetMeshEditPreviewer()
7221 segmentsRes = editor.MakePolyLine( segments, groupName )
7222 for i, seg in enumerate( segmentsRes ):
7223 segments[i].vector = seg.vector
7225 return editor.GetPreviewData()
7228 def MakeSlot(self, segmentGroup, width ):
7230 Create a slot of given width around given 1D elements lying on a triangle mesh.
7231 The slot is constructed by cutting faces by cylindrical surfaces made
7232 around each segment. Segments are expected to be created by MakePolyLine().
7235 FaceEdge's located at the slot boundary
7237 return self.editor.MakeSlot( segmentGroup, width )
7239 def GetFunctor(self, funcType ):
7241 Return a cached numerical functor by its type.
7244 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7245 Note that not all items correspond to numerical functors.
7248 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7251 fn = self.functors[ funcType._v ]
7253 fn = self.smeshpyD.GetFunctor(funcType)
7254 fn.SetMesh(self.mesh)
7255 self.functors[ funcType._v ] = fn
7258 def FunctorValue(self, funcType, elemId, isElem=True):
7260 Return value of a functor for a given element
7263 funcType: an item of :class:`SMESH.FunctorType` enum.
7264 elemId: element or node ID
7265 isElem: *elemId* is ID of element or node
7268 the functor value or zero in case of invalid arguments
7271 fn = self.GetFunctor( funcType )
7272 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7273 val = fn.GetValue(elemId)
7278 def GetLength(self, elemId=None):
7280 Get length of given 1D elements or of all 1D mesh elements
7283 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.
7286 Sum of lengths of given elements
7291 length = self.smeshpyD.GetLength(self)
7292 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7293 length = self.smeshpyD.GetLength(elemId)
7296 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7298 length += self.smeshpyD.GetLength(obj)
7299 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7300 unRegister = genObjUnRegister()
7301 obj = self.GetIDSource( elemId )
7302 unRegister.set( obj )
7303 length = self.smeshpyD.GetLength( obj )
7305 length = self.FunctorValue(SMESH.FT_Length, elemId)
7308 def GetArea(self, elemId=None):
7310 Get area of given 2D elements or of all 2D mesh elements
7313 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.
7316 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7321 area = self.smeshpyD.GetArea(self)
7322 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7323 area = self.smeshpyD.GetArea(elemId)
7326 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7328 area += self.smeshpyD.GetArea(obj)
7329 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7330 unRegister = genObjUnRegister()
7331 obj = self.GetIDSource( elemId )
7332 unRegister.set( obj )
7333 area = self.smeshpyD.GetArea( obj )
7335 area = self.FunctorValue(SMESH.FT_Area, elemId)
7338 def GetVolume(self, elemId=None):
7340 Get volume of given 3D elements or of all 3D mesh elements
7343 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.
7346 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7351 volume= self.smeshpyD.GetVolume(self)
7352 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7353 volume= self.smeshpyD.GetVolume(elemId)
7356 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7358 volume+= self.smeshpyD.GetVolume(obj)
7359 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7360 unRegister = genObjUnRegister()
7361 obj = self.GetIDSource( elemId )
7362 unRegister.set( obj )
7363 volume= self.smeshpyD.GetVolume( obj )
7365 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7368 def GetAngle(self, node1, node2, node3 ):
7370 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7373 node1,node2,node3: IDs of the three nodes
7376 Angle in radians [0,PI]. -1 if failure case.
7378 p1 = self.GetNodeXYZ( node1 )
7379 p2 = self.GetNodeXYZ( node2 )
7380 p3 = self.GetNodeXYZ( node3 )
7381 if p1 and p2 and p3:
7382 return self.smeshpyD.GetAngle( p1,p2,p3 )
7386 def GetMaxElementLength(self, elemId):
7388 Get maximum element length.
7391 elemId: mesh element ID
7394 element's maximum length value
7397 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7398 ftype = SMESH.FT_MaxElementLength3D
7400 ftype = SMESH.FT_MaxElementLength2D
7401 return self.FunctorValue(ftype, elemId)
7403 def GetAspectRatio(self, elemId):
7405 Get aspect ratio of 2D or 3D element.
7408 elemId: mesh element ID
7411 element's aspect ratio value
7414 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7415 ftype = SMESH.FT_AspectRatio3D
7417 ftype = SMESH.FT_AspectRatio
7418 return self.FunctorValue(ftype, elemId)
7420 def GetWarping(self, elemId):
7422 Get warping angle of 2D element.
7425 elemId: mesh element ID
7428 element's warping angle value
7431 return self.FunctorValue(SMESH.FT_Warping, elemId)
7433 def GetMinimumAngle(self, elemId):
7435 Get minimum angle of 2D element.
7438 elemId: mesh element ID
7441 element's minimum angle value
7444 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7446 def GetTaper(self, elemId):
7448 Get taper of 2D element.
7451 elemId: mesh element ID
7454 element's taper value
7457 return self.FunctorValue(SMESH.FT_Taper, elemId)
7459 def GetSkew(self, elemId):
7461 Get skew of 2D element.
7464 elemId: mesh element ID
7467 element's skew value
7470 return self.FunctorValue(SMESH.FT_Skew, elemId)
7472 def GetMinMax(self, funType, meshPart=None):
7474 Return minimal and maximal value of a given functor.
7477 funType (SMESH.FunctorType): a functor type.
7478 Note that not all items of :class:`SMESH.FunctorType` corresponds
7479 to numerical functors.
7480 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7486 unRegister = genObjUnRegister()
7487 if isinstance( meshPart, list ):
7488 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7489 unRegister.set( meshPart )
7490 if isinstance( meshPart, Mesh ):
7491 meshPart = meshPart.mesh
7492 fun = self.GetFunctor( funType )
7495 if hasattr( meshPart, "SetMesh" ):
7496 meshPart.SetMesh( self.mesh ) # set mesh to filter
7497 hist = fun.GetLocalHistogram( 1, False, meshPart )
7499 hist = fun.GetHistogram( 1, False )
7501 return hist[0].min, hist[0].max
7504 pass # end of Mesh class
7507 def _copy_netgen_param(dim, local_param, global_param):
7509 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7512 #TODO: Try to identify why we need to substract 1
7513 local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
7515 local_param.SetMaxSize(global_param.GetMaxSize())
7516 local_param.SetMinSize(global_param.GetMinSize())
7517 local_param.SetOptimize(global_param.GetOptimize())
7518 local_param.SetFineness(global_param.GetFineness())
7519 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7520 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7521 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7522 local_param.SetChordalError(global_param.GetChordalError())
7523 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7524 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7525 local_param.SetUseDelauney(global_param.GetUseDelauney())
7526 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7527 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7528 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7529 local_param.SetNbThreads(global_param.GetNbThreads())
7531 local_param.SetMaxSize(global_param.GetMaxSize())
7532 local_param.SetMinSize(global_param.GetMinSize())
7533 local_param.SetOptimize(global_param.GetOptimize())
7534 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7535 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7536 local_param.SetFineness(global_param.GetFineness())
7537 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7538 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7539 local_param.SetGrowthRate(global_param.GetGrowthRate())
7540 local_param.SetNbThreads(global_param.GetNbThreads())
7542 def _split_geom(geompyD, geom):
7544 Splitting geometry into n solids and a 2D/1D compound
7547 geompyD: geomBuilder instance
7548 geom: geometrical object for meshing
7551 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7552 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7557 for solid in object_solids:
7559 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7560 solids.append(solid)
7561 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7567 for isolid, solid in enumerate(solids):
7568 solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
7570 for face in solid_faces:
7573 geompyD.addToStudyInFather(solid, face,
7574 'Face_{}'.format(iface))
7576 # Creating submesh for edges 1D/2D part
7578 all_faces = geompyD.MakeCompound(faces)
7579 geompyD.addToStudy(all_faces, 'Compound_1')
7580 all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
7581 all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
7582 geompyD.addToStudy(all_faces, 'global2D')
7584 return all_faces, solids
7586 class ParallelismSettings:
7588 Defines the parameters for the parallelism of ParallelMesh
7590 def __init__(self, mesh):
7595 mesh: Instance of ParallelMesh
7597 if not(isinstance(mesh, ParallelMesh)):
7598 raise ValueError("mesh should be a ParallelMesh")
7602 def SetNbThreads(self, nbThreads):
7604 Set the number of threads for multithreading
7607 raise ValueError("Number of threads must be stricly greater than 1")
7609 self._mesh.mesh.SetNbThreads(nbThreads)
7611 def GetNbThreads(self):
7613 Get Number of threads
7615 return self._mesh.mesh.GetNbThreads()
7617 class ParallelMesh(Mesh):
7619 Surcharge on Mesh for parallel computation of a mesh
7621 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7623 Create a parallel mesh.
7626 smeshpyD: instance of smeshBuilder
7627 geompyD: instance of geomBuilder
7628 geom: geometrical object for meshing
7629 split_geom: If true will divide geometry on solids and 1D/2D
7630 coumpound and create the associated submeshes
7631 name: the name for the new mesh.
7634 an instance of class :class:`ParallelMesh`.
7637 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7638 raise ValueError("geom argument must be a geometry")
7640 # Splitting geometry into one geom containing 1D and 2D elements and a
7641 # list of 3D elements
7642 super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name, parallel=True)
7645 self._all_faces, self._solids = _split_geom(geompyD, geom)
7647 self.UseExistingSegments()
7648 self.UseExistingFaces()
7650 self._algo2d = self.Triangle(geom=self._all_faces, algo="NETGEN_2D")
7653 for solid_id, solid in enumerate(self._solids):
7654 name = "Solid_{}".format(solid_id)
7655 self.UseExistingSegments(geom=solid)
7656 self.UseExistingFaces(geom=solid)
7657 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7658 self._algo3d.append(algo3d)
7660 self._param = ParallelismSettings(self)
7663 def GetParallelismSettings(self):
7665 Return class to set parameters for the parallelism
7669 def AddGlobalHypothesis(self, hyp):
7671 Split hypothesis to apply it to all the submeshes:
7673 - each of the 3D solids
7676 hyp: a hypothesis to assign
7679 if not isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7680 raise ValueError("param must come from NETGENPlugin")
7682 param2d = self._algo2d.Parameters()
7683 _copy_netgen_param(2, param2d, hyp)
7685 for algo3d in self._algo3d:
7687 param3d = algo3d.Parameters()
7688 _copy_netgen_param(3, param3d, hyp)
7691 pass # End of ParallelMesh
7694 class meshProxy(SMESH._objref_SMESH_Mesh):
7696 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7697 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7699 def __init__(self,*args):
7700 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7701 def __deepcopy__(self, memo=None):
7702 new = self.__class__(self)
7704 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7705 if len( args ) == 3:
7706 args += SMESH.ALL_NODES, True
7707 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7708 def ExportToMEDX(self, *args): # function removed
7709 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7710 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7711 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7712 def ExportToMED(self, *args): # function removed
7713 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7714 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7716 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7718 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7719 def ExportPartToMED(self, *args): # 'version' parameter removed
7720 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7721 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7722 def ExportMED(self, *args): # signature of method changed
7723 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7725 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7727 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7728 def ExportUNV(self, *args): # renumber arg added
7729 if len( args ) == 1:
7731 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7732 def ExportDAT(self, *args): # renumber arg added
7733 if len( args ) == 1:
7735 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7737 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7740 class submeshProxy(SMESH._objref_SMESH_subMesh):
7743 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7745 def __init__(self,*args):
7746 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7748 def __deepcopy__(self, memo=None):
7749 new = self.__class__(self)
7752 def Compute(self,refresh=False):
7754 Compute the sub-mesh and return the status of the computation
7757 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7762 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7763 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7767 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7769 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7771 if salome.sg.hasDesktop():
7772 if refresh: salome.sg.updateObjBrowser()
7777 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7780 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7782 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7783 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7786 def __init__(self,*args):
7787 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7789 def __getattr__(self, name ): # method called if an attribute not found
7790 if not self.mesh: # look for name() method in Mesh class
7791 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7792 if hasattr( self.mesh, name ):
7793 return getattr( self.mesh, name )
7794 if name == "ExtrusionAlongPathObjX":
7795 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7796 print("meshEditor: attribute '%s' NOT FOUND" % name)
7798 def __deepcopy__(self, memo=None):
7799 new = self.__class__(self)
7801 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7802 if len( args ) == 1: args += False,
7803 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7804 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7805 if len( args ) == 2: args += False,
7806 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7807 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7808 if len( args ) == 1:
7809 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7810 NodesToKeep = args[1]
7811 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7812 unRegister = genObjUnRegister()
7814 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7815 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7816 if not isinstance( NodesToKeep, list ):
7817 NodesToKeep = [ NodesToKeep ]
7818 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7820 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7822 class Pattern(SMESH._objref_SMESH_Pattern):
7824 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7825 variables in some methods
7828 def LoadFromFile(self, patternTextOrFile ):
7829 text = patternTextOrFile
7830 if os.path.exists( text ):
7831 text = open( patternTextOrFile ).read()
7833 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7835 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7836 decrFun = lambda i: i-1
7837 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7838 theMesh.SetParameters(Parameters)
7839 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7841 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7842 decrFun = lambda i: i-1
7843 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7844 theMesh.SetParameters(Parameters)
7845 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7847 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7848 if isinstance( mesh, Mesh ):
7849 mesh = mesh.GetMesh()
7850 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7852 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7854 Registering the new proxy for Pattern
7859 Private class used to bind methods creating algorithms to the class Mesh
7862 def __init__(self, method):
7864 self.defaultAlgoType = ""
7865 self.algoTypeToClass = {}
7866 self.method = method
7868 def add(self, algoClass):
7870 Store a python class of algorithm
7872 if inspect.isclass(algoClass) and \
7873 hasattr( algoClass, "algoType"):
7874 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7875 if not self.defaultAlgoType and \
7876 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7877 self.defaultAlgoType = algoClass.algoType
7878 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7880 def copy(self, mesh):
7882 Create a copy of self and assign mesh to the copy
7885 other = algoCreator( self.method )
7886 other.defaultAlgoType = self.defaultAlgoType
7887 other.algoTypeToClass = self.algoTypeToClass
7891 def __call__(self,algo="",geom=0,*args):
7893 Create an instance of algorithm
7897 if isinstance( algo, str ):
7899 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7900 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7905 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7907 elif not algoType and isinstance( geom, str ):
7912 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7914 elif isinstance( arg, str ) and not algoType:
7917 import traceback, sys
7918 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7919 sys.stderr.write( msg + '\n' )
7920 tb = traceback.extract_stack(None,2)
7921 traceback.print_list( [tb[0]] )
7923 algoType = self.defaultAlgoType
7924 if not algoType and self.algoTypeToClass:
7925 algoType = sorted( self.algoTypeToClass.keys() )[0]
7926 if algoType in self.algoTypeToClass:
7927 #print("Create algo",algoType)
7928 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7929 raise RuntimeError( "No class found for algo type %s" % algoType)
7932 class hypMethodWrapper:
7934 Private class used to substitute and store variable parameters of hypotheses.
7937 def __init__(self, hyp, method):
7939 self.method = method
7940 #print("REBIND:", method.__name__)
7943 def __call__(self,*args):
7945 call a method of hypothesis with calling SetVarParameter() before
7949 return self.method( self.hyp, *args ) # hypothesis method with no args
7951 #print("MethWrapper.__call__", self.method.__name__, args)
7953 parsed = ParseParameters(*args) # replace variables with their values
7954 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7955 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7956 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7957 # maybe there is a replaced string arg which is not variable
7958 result = self.method( self.hyp, *args )
7959 except ValueError as detail: # raised by ParseParameters()
7961 result = self.method( self.hyp, *args )
7962 except omniORB.CORBA.BAD_PARAM:
7963 raise ValueError(detail) # wrong variable name
7968 class genObjUnRegister:
7970 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7973 def __init__(self, genObj=None):
7974 self.genObjList = []
7978 def set(self, genObj):
7979 "Store one or a list of of SALOME.GenericObj'es"
7980 if isinstance( genObj, list ):
7981 self.genObjList.extend( genObj )
7983 self.genObjList.append( genObj )
7987 for genObj in self.genObjList:
7988 if genObj and hasattr( genObj, "UnRegister" ):
7991 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7993 Bind methods creating mesher plug-ins to the Mesh class
7996 # print("pluginName: ", pluginName)
7997 pluginBuilderName = pluginName + "Builder"
7999 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8000 except Exception as e:
8001 from salome_utils import verbose
8002 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8004 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8005 plugin = eval( pluginBuilderName )
8006 # print(" plugin:" , str(plugin))
8008 # add methods creating algorithms to Mesh
8009 for k in dir( plugin ):
8010 if k[0] == '_': continue
8011 algo = getattr( plugin, k )
8012 #print(" algo:", str(algo))
8013 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8014 #print(" meshMethod:" , str(algo.meshMethod))
8015 if not hasattr( Mesh, algo.meshMethod ):
8016 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8018 _mmethod = getattr( Mesh, algo.meshMethod )
8019 if hasattr( _mmethod, "add" ):