1 # Copyright (C) 2007-2023 CEA, EDF, 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()
1236 elif theCriterion == FT_ScaledJacobian:
1237 functor = aFilterMgr.CreateScaledJacobian()
1239 print("Error: given parameter is not numerical functor type.")
1240 aFilterMgr.UnRegister()
1243 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1248 theHType (string): mesh hypothesis type
1249 theLibName (string): mesh plug-in library name
1252 created hypothesis instance
1254 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1256 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1259 # wrap hypothesis methods
1260 for meth_name in dir( hyp.__class__ ):
1261 if not meth_name.startswith("Get") and \
1262 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1263 method = getattr ( hyp.__class__, meth_name )
1264 if callable(method):
1265 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1269 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1271 Create hypothesis initialized according to parameters
1274 hypType (string): hypothesis type
1275 libName (string): plug-in library name
1276 mesh: optional mesh by which a hypotheses can initialize self
1277 shape: optional geometry by size of which a hypotheses can initialize self
1278 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1281 created hypothesis instance
1283 if isinstance( mesh, Mesh ):
1284 mesh = mesh.GetMesh()
1285 if isinstance( initParams, (bool,int)):
1286 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1287 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1288 mesh, shape, initParams )
1290 def GetMeshInfo(self, obj):
1292 Get the mesh statistic.
1295 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1298 if isinstance( obj, Mesh ):
1301 if hasattr(obj, "GetMeshInfo"):
1302 values = obj.GetMeshInfo()
1303 for i in range(SMESH.Entity_Last._v):
1304 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1308 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1310 Get minimum distance between two objects
1312 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1313 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1316 src1 (SMESH.SMESH_IDSource): first source object
1317 src2 (SMESH.SMESH_IDSource): second source object
1318 id1 (int): node/element id from the first source
1319 id2 (int): node/element id from the second (or first) source
1320 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1321 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1324 minimum distance value
1327 :meth:`GetMinDistance`
1330 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1334 result = result.value
1337 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1339 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1341 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1342 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1345 src1 (SMESH.SMESH_IDSource): first source object
1346 src2 (SMESH.SMESH_IDSource): second source object
1347 id1 (int): node/element id from the first source
1348 id2 (int): node/element id from the second (or first) source
1349 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1350 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1353 :class:`SMESH.Measure` structure or None if input data is invalid
1358 if isinstance(src1, Mesh): src1 = src1.mesh
1359 if isinstance(src2, Mesh): src2 = src2.mesh
1360 if src2 is None and id2 != 0: src2 = src1
1361 if not hasattr(src1, "_narrow"): return None
1362 src1 = src1._narrow(SMESH.SMESH_IDSource)
1363 if not src1: return None
1364 unRegister = genObjUnRegister()
1367 e = m.GetMeshEditor()
1369 src1 = e.MakeIDSource([id1], SMESH.FACE)
1371 src1 = e.MakeIDSource([id1], SMESH.NODE)
1372 unRegister.set( src1 )
1374 if hasattr(src2, "_narrow"):
1375 src2 = src2._narrow(SMESH.SMESH_IDSource)
1376 if src2 and id2 != 0:
1378 e = m.GetMeshEditor()
1380 src2 = e.MakeIDSource([id2], SMESH.FACE)
1382 src2 = e.MakeIDSource([id2], SMESH.NODE)
1383 unRegister.set( src2 )
1386 aMeasurements = self.CreateMeasurements()
1387 unRegister.set( aMeasurements )
1388 result = aMeasurements.MinDistance(src1, src2)
1391 def BoundingBox(self, objects):
1393 Get bounding box of the specified object(s)
1396 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1399 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1402 :meth:`GetBoundingBox`
1405 result = self.GetBoundingBox(objects)
1409 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1412 def GetBoundingBox(self, objects):
1414 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1417 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1420 :class:`SMESH.Measure` structure
1426 if isinstance(objects, tuple):
1427 objects = list(objects)
1428 if not isinstance(objects, list):
1432 if isinstance(o, Mesh):
1433 srclist.append(o.mesh)
1434 elif hasattr(o, "_narrow"):
1435 src = o._narrow(SMESH.SMESH_IDSource)
1436 if src: srclist.append(src)
1439 aMeasurements = self.CreateMeasurements()
1440 result = aMeasurements.BoundingBox(srclist)
1441 aMeasurements.UnRegister()
1444 def GetLength(self, obj):
1446 Get sum of lengths of all 1D elements in the mesh object.
1449 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1452 sum of lengths of all 1D elements
1455 if isinstance(obj, Mesh): obj = obj.mesh
1456 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1457 aMeasurements = self.CreateMeasurements()
1458 value = aMeasurements.Length(obj)
1459 aMeasurements.UnRegister()
1462 def GetArea(self, obj):
1464 Get sum of areas of all 2D elements in the mesh object.
1467 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1470 sum of areas of all 2D elements
1473 if isinstance(obj, Mesh): obj = obj.mesh
1474 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1475 aMeasurements = self.CreateMeasurements()
1476 value = aMeasurements.Area(obj)
1477 aMeasurements.UnRegister()
1480 def GetVolume(self, obj):
1482 Get sum of volumes of all 3D elements in the mesh object.
1485 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1488 sum of volumes of all 3D elements
1491 if isinstance(obj, Mesh): obj = obj.mesh
1492 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1493 aMeasurements = self.CreateMeasurements()
1494 value = aMeasurements.Volume(obj)
1495 aMeasurements.UnRegister()
1498 def GetGravityCenter(self, obj):
1500 Get gravity center of all nodes of a mesh object.
1503 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1506 Three components of the gravity center (x,y,z)
1509 :meth:`Mesh.BaryCenter`
1511 if isinstance(obj, Mesh): obj = obj.mesh
1512 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1513 aMeasurements = self.CreateMeasurements()
1514 pointStruct = aMeasurements.GravityCenter(obj)
1515 aMeasurements.UnRegister()
1516 return pointStruct.x, pointStruct.y, pointStruct.z
1518 def GetAngle(self, p1, p2, p3 ):
1520 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1523 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1529 if isinstance( p1, list ): p1 = PointStruct(*p1)
1530 if isinstance( p2, list ): p2 = PointStruct(*p2)
1531 if isinstance( p3, list ): p3 = PointStruct(*p3)
1533 aMeasurements = self.CreateMeasurements()
1534 angle = aMeasurements.Angle(p1,p2,p3)
1535 aMeasurements.UnRegister()
1540 pass # end of class smeshBuilder
1543 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1544 """Registering the new proxy for SMESH.SMESH_Gen"""
1547 def New( instance=None, instanceGeom=None):
1549 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1550 interface to create or load meshes.
1555 salome.salome_init()
1556 from salome.smesh import smeshBuilder
1557 smesh = smeshBuilder.New()
1560 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1561 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1563 :class:`smeshBuilder` instance
1568 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1570 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1575 smeshInst = smeshBuilder()
1576 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1577 smeshInst.init_smesh(instanceGeom)
1581 # Public class: Mesh
1582 # ==================
1585 class Mesh(metaclass = MeshMeta):
1587 This class allows defining and managing a mesh.
1588 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1589 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1590 new nodes and elements and by changing the existing entities), to get information
1591 about a mesh and to export a mesh in different formats.
1598 def __init__(self, smeshpyD, geompyD, obj=0, name=0, parallel=False):
1603 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1604 sets the GUI name of this mesh to *name*.
1607 smeshpyD: an instance of smeshBuilder class
1608 geompyD: an instance of geomBuilder class
1609 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1610 name: Study name of the mesh
1613 self.smeshpyD = smeshpyD
1614 self.geompyD = geompyD
1619 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1622 # publish geom of mesh (issue 0021122)
1623 if not self.geom.GetStudyEntry():
1627 geo_name = name + " shape"
1629 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1630 geompyD.addToStudy( self.geom, geo_name )
1631 if parallel and isinstance(self, ParallelMesh):
1632 self.SetMesh( self.smeshpyD.CreateParallelMesh(self.geom) )
1634 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1636 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1639 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1641 self.smeshpyD.SetName(self.mesh, name)
1643 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1646 self.geom = self.mesh.GetShapeToMesh()
1648 self.editor = self.mesh.GetMeshEditor()
1649 self.functors = [None] * SMESH.FT_Undefined._v
1651 # set self to algoCreator's
1652 for attrName in dir(self):
1653 attr = getattr( self, attrName )
1654 if isinstance( attr, algoCreator ):
1655 setattr( self, attrName, attr.copy( self ))
1662 Destructor. Clean-up resources
1665 #self.mesh.UnRegister()
1669 def SetMesh(self, theMesh):
1671 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1674 theMesh: a :class:`SMESH.SMESH_Mesh` object
1676 # do not call Register() as this prevents mesh servant deletion at closing study
1677 #if self.mesh: self.mesh.UnRegister()
1680 #self.mesh.Register()
1681 self.geom = self.mesh.GetShapeToMesh()
1685 if salome.sg.hasDesktop():
1686 so = salome.ObjectToSObject( self.geom )
1687 comp = so.GetFatherComponent()
1688 if comp.ComponentDataType() == "SHAPERSTUDY":
1689 import shaperBuilder
1690 self.geompyD = shaperBuilder.New()
1693 if not self.geompyD:
1694 self.geompyD = self.geom.GetGen()
1699 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1702 a :class:`SMESH.SMESH_Mesh` object
1707 def GetEngine(self):
1709 Return a smeshBuilder instance created this mesh
1711 return self.smeshpyD
1713 def GetGeomEngine(self):
1715 Return a geomBuilder instance
1721 Get the name of the mesh
1724 the name of the mesh as a string
1727 name = GetName(self.GetMesh())
1730 def SetName(self, name):
1732 Set a name to the mesh
1735 name: a new name of the mesh
1738 self.smeshpyD.SetName(self.GetMesh(), name)
1740 def GetSubMesh(self, geom, name):
1742 Get a sub-mesh object associated to a *geom* geometrical object.
1745 geom: a geometrical object (shape)
1746 name: a name for the sub-mesh in the Object Browser
1749 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1750 which lies on the given shape
1753 A sub-mesh is implicitly created when a sub-shape is specified at
1754 creating an algorithm, for example::
1756 algo1D = mesh.Segment(geom=Edge_1)
1758 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1759 The created sub-mesh can be retrieved from the algorithm::
1761 submesh = algo1D.GetSubMesh()
1764 AssureGeomPublished( self, geom, name )
1765 submesh = self.mesh.GetSubMesh( geom, name )
1770 Return the shape associated to the mesh
1778 def SetShape(self, geom):
1780 Associate the given shape to the mesh (entails the recreation of the mesh)
1783 geom: the shape to be meshed (GEOM_Object)
1786 self.mesh = self.smeshpyD.CreateMesh(geom)
1788 def HasShapeToMesh(self):
1790 Return ``True`` if this mesh is based on geometry
1792 return self.mesh.HasShapeToMesh()
1796 Load mesh from the study after opening the study
1800 def IsReadyToCompute(self, theSubObject):
1802 Return true if the hypotheses are defined well
1805 theSubObject: a sub-shape of a mesh shape
1811 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1813 def GetAlgoState(self, theSubObject):
1815 Return errors of hypotheses definition.
1816 The list of errors is empty if everything is OK.
1819 theSubObject: a sub-shape of a mesh shape
1825 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1827 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1829 Return a geometrical object on which the given element was built.
1830 The returned geometrical object, if not nil, is either found in the
1831 study or published by this method with the given name
1834 theElementID: the id of the mesh element
1835 theGeomName: the user-defined name of the geometrical object
1838 GEOM.GEOM_Object instance
1841 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1843 def MeshDimension(self):
1845 Return the mesh dimension depending on the dimension of the underlying shape
1846 or, if the mesh is not based on any shape, basing on deimension of elements
1849 mesh dimension as an integer value [0,3]
1852 if self.mesh.HasShapeToMesh():
1853 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1854 if len( shells ) > 0 :
1856 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1858 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1863 if self.NbVolumes() > 0: return 3
1864 if self.NbFaces() > 0: return 2
1865 if self.NbEdges() > 0: return 1
1868 def Evaluate(self, geom=0):
1870 Evaluate size of prospective mesh on a shape
1873 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1874 To know predicted number of e.g. edges, inquire it this way::
1876 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1879 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1881 geom = self.mesh.GetShapeToMesh()
1884 return self.smeshpyD.Evaluate(self.mesh, geom)
1886 def Compute(self, geom=0, discardModifs=False, refresh=False):
1888 Compute the mesh and return the status of the computation
1891 geom: geomtrical shape on which mesh data should be computed
1892 discardModifs: if True and the mesh has been edited since
1893 a last total re-compute and that may prevent successful partial re-compute,
1894 then the mesh is cleaned before Compute()
1895 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1901 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1902 geom = self.mesh.GetShapeToMesh()
1905 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1907 ok = self.smeshpyD.Compute(self.mesh, geom)
1908 except SALOME.SALOME_Exception as ex:
1909 print("Mesh computation failed, exception caught:")
1910 print(" ", ex.details.text)
1913 print("Mesh computation failed, exception caught:")
1914 traceback.print_exc()
1918 # Treat compute errors
1919 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1921 for err in computeErrors:
1922 if self.mesh.HasShapeToMesh():
1923 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1925 stdErrors = ["OK", #COMPERR_OK
1926 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1927 "std::exception", #COMPERR_STD_EXCEPTION
1928 "OCC exception", #COMPERR_OCC_EXCEPTION
1929 "..", #COMPERR_SLM_EXCEPTION
1930 "Unknown exception", #COMPERR_EXCEPTION
1931 "Memory allocation problem", #COMPERR_MEMORY_PB
1932 "Algorithm failed", #COMPERR_ALGO_FAILED
1933 "Unexpected geometry", #COMPERR_BAD_SHAPE
1934 "Warning", #COMPERR_WARNING
1935 "Computation cancelled",#COMPERR_CANCELED
1936 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1938 if err.code < len(stdErrors): errText = stdErrors[err.code]
1940 errText = "code %s" % -err.code
1941 if errText: errText += ". "
1942 errText += err.comment
1943 if allReasons: allReasons += "\n"
1945 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1947 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1951 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1953 if err.isGlobalAlgo:
1961 reason = '%s %sD algorithm is missing' % (glob, dim)
1962 elif err.state == HYP_MISSING:
1963 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1964 % (glob, dim, name, dim))
1965 elif err.state == HYP_NOTCONFORM:
1966 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1967 elif err.state == HYP_BAD_PARAMETER:
1968 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1969 % ( glob, dim, name ))
1970 elif err.state == HYP_BAD_GEOMETRY:
1971 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1972 'geometry' % ( glob, dim, name ))
1973 elif err.state == HYP_HIDDEN_ALGO:
1974 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1975 'algorithm of upper dimension generating %sD mesh'
1976 % ( glob, dim, name, glob, dim ))
1978 reason = ("For unknown reason. "
1979 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1981 if allReasons: allReasons += "\n"
1982 allReasons += "- " + reason
1984 if not ok or allReasons != "":
1985 msg = '"' + GetName(self.mesh) + '"'
1986 if ok: msg += " has been computed with warnings"
1987 else: msg += " has not been computed"
1988 if allReasons != "": msg += ":"
1994 if salome.sg.hasDesktop():
1995 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1996 if refresh: salome.sg.updateObjBrowser()
2000 def GetComputeErrors(self, shape=0 ):
2002 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2006 shape = self.mesh.GetShapeToMesh()
2007 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2009 def GetSubShapeName(self, subShapeID ):
2011 Return a name of a sub-shape by its ID.
2012 Possible variants (for *subShapeID* == 3):
2014 - **"Face_12"** - published sub-shape
2015 - **FACE #3** - not published sub-shape
2016 - **sub-shape #3** - invalid sub-shape ID
2017 - **#3** - error in this function
2020 subShapeID: a unique ID of a sub-shape
2023 a string describing the sub-shape
2027 if not self.mesh.HasShapeToMesh():
2031 mainIOR = salome.orb.object_to_string( self.GetShape() )
2033 mainSO = s.FindObjectIOR(mainIOR)
2036 shapeText = '"%s"' % mainSO.GetName()
2037 subIt = s.NewChildIterator(mainSO)
2039 subSO = subIt.Value()
2041 obj = subSO.GetObject()
2042 if not obj: continue
2043 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2046 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2049 if ids == subShapeID:
2050 shapeText = '"%s"' % subSO.GetName()
2053 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2055 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2057 shapeText = 'sub-shape #%s' % (subShapeID)
2059 shapeText = "#%s" % (subShapeID)
2062 def GetFailedShapes(self, publish=False):
2064 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2065 error of an algorithm
2068 publish: if *True*, the returned groups will be published in the study
2071 a list of GEOM groups each named after a failed algorithm
2076 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2077 for err in computeErrors:
2078 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2079 if not shape: continue
2080 if err.algoName in algo2shapes:
2081 algo2shapes[ err.algoName ].append( shape )
2083 algo2shapes[ err.algoName ] = [ shape ]
2087 for algoName, shapes in list(algo2shapes.items()):
2089 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2090 otherTypeShapes = []
2092 group = self.geompyD.CreateGroup( self.geom, groupType )
2093 for shape in shapes:
2094 if shape.GetShapeType() == shapes[0].GetShapeType():
2095 sameTypeShapes.append( shape )
2097 otherTypeShapes.append( shape )
2098 self.geompyD.UnionList( group, sameTypeShapes )
2100 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2102 group.SetName( algoName )
2103 groups.append( group )
2104 shapes = otherTypeShapes
2107 for group in groups:
2108 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2111 def GetMeshOrder(self):
2113 Return sub-mesh objects list in meshing order
2116 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2119 return self.mesh.GetMeshOrder()
2121 def SetMeshOrder(self, submeshes):
2123 Set priority of sub-meshes. It works in two ways:
2125 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2126 *several dimensions*, it sets the order in which the sub-meshes are computed.
2127 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2128 when looking for meshing parameters to apply to a sub-shape. To impose the
2129 order in which sub-meshes with uni-dimensional algorithms are computed,
2130 call **submesh.Compute()** in a desired order.
2133 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2135 Warning: the method is for setting the order for all sub-meshes at once:
2136 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2139 return self.mesh.SetMeshOrder(submeshes)
2141 def Clear(self, refresh=False):
2143 Remove all nodes and elements generated on geometry. Imported elements remain.
2146 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2150 if ( salome.sg.hasDesktop() ):
2151 if refresh: salome.sg.updateObjBrowser()
2153 def ClearSubMesh(self, geomId, refresh=False):
2155 Remove all nodes and elements of indicated shape
2158 geomId: the ID of a sub-shape to remove elements on
2159 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2162 self.mesh.ClearSubMesh(geomId)
2163 if salome.sg.hasDesktop():
2164 if refresh: salome.sg.updateObjBrowser()
2166 def AutomaticTetrahedralization(self, fineness=0):
2168 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2171 fineness: [0.0,1.0] defines mesh fineness
2177 dim = self.MeshDimension()
2179 self.RemoveGlobalHypotheses()
2180 self.Segment().AutomaticLength(fineness)
2182 self.Triangle().LengthFromEdges()
2187 return self.Compute()
2189 def AutomaticHexahedralization(self, fineness=0):
2191 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2194 fineness: [0.0, 1.0] defines mesh fineness
2200 dim = self.MeshDimension()
2201 # assign the hypotheses
2202 self.RemoveGlobalHypotheses()
2203 self.Segment().AutomaticLength(fineness)
2210 return self.Compute()
2212 def AddHypothesis(self, hyp, geom=0):
2217 hyp: a hypothesis to assign
2218 geom: a subhape of mesh geometry
2221 :class:`SMESH.Hypothesis_Status`
2224 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2225 hyp, geom = geom, hyp
2226 if isinstance( hyp, Mesh_Algorithm ):
2227 hyp = hyp.GetAlgorithm()
2232 geom = self.mesh.GetShapeToMesh()
2235 if self.mesh.HasShapeToMesh():
2236 hyp_type = hyp.GetName()
2237 lib_name = hyp.GetLibName()
2238 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2239 # if checkAll and geom:
2240 # checkAll = geom.GetType() == 37
2242 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2244 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2245 status = self.mesh.AddHypothesis(geom, hyp)
2247 status = HYP_BAD_GEOMETRY, ""
2248 hyp_name = GetName( hyp )
2251 geom_name = geom.GetName()
2252 isAlgo = hyp._narrow( SMESH_Algo )
2253 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2256 def IsUsedHypothesis(self, hyp, geom):
2258 Return True if an algorithm or hypothesis is assigned to a given shape
2261 hyp: an algorithm or hypothesis to check
2262 geom: a subhape of mesh geometry
2268 if not hyp: # or not geom
2270 if isinstance( hyp, Mesh_Algorithm ):
2271 hyp = hyp.GetAlgorithm()
2273 hyps = self.GetHypothesisList(geom)
2275 if h.GetId() == hyp.GetId():
2279 def RemoveHypothesis(self, hyp, geom=0):
2281 Unassign a hypothesis
2284 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2285 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2288 :class:`SMESH.Hypothesis_Status`
2293 if isinstance( hyp, Mesh_Algorithm ):
2294 hyp = hyp.GetAlgorithm()
2300 if self.IsUsedHypothesis( hyp, shape ):
2301 return self.mesh.RemoveHypothesis( shape, hyp )
2302 hypName = GetName( hyp )
2303 geoName = GetName( shape )
2304 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2307 def GetHypothesisList(self, geom):
2309 Get the list of hypotheses added on a geometry
2312 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2315 the sequence of :class:`SMESH.SMESH_Hypothesis`
2318 return self.mesh.GetHypothesisList( geom )
2320 def RemoveGlobalHypotheses(self):
2322 Remove all global hypotheses
2325 current_hyps = self.mesh.GetHypothesisList( self.geom )
2326 for hyp in current_hyps:
2327 self.mesh.RemoveHypothesis( self.geom, hyp )
2331 def ExportMEDCoupling(self, *args, **kwargs):
2333 Export the mesh in a memory representation.
2336 auto_groups (boolean): parameter for creating/not creating
2337 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2338 the typical use is auto_groups=False.
2339 overwrite (boolean): parameter for overwriting/not overwriting the file
2340 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2341 to export instead of the mesh
2342 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2344 - 1D if all mesh nodes lie on OX coordinate axis, or
2345 - 2D if all mesh nodes lie on XOY coordinate plane, or
2346 - 3D in the rest cases.
2348 If *autoDimension* is *False*, the space dimension is always 3.
2349 fields: list of GEOM fields defined on the shape to mesh.
2350 geomAssocFields: each character of this string means a need to export a
2351 corresponding field; correspondence between fields and characters
2354 - 'v' stands for "_vertices_" field;
2355 - 'e' stands for "_edges_" field;
2356 - 'f' stands for "_faces_" field;
2357 - 's' stands for "_solids_" field.
2359 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2360 close to zero within a given tolerance, the coordinate is set to zero.
2361 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2362 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2364 auto_groups = args[0] if len(args) > 0 else False
2365 meshPart = args[1] if len(args) > 1 else None
2366 autoDimension = args[2] if len(args) > 2 else True
2367 fields = args[3] if len(args) > 3 else []
2368 geomAssocFields = args[4] if len(args) > 4 else ''
2369 z_tolerance = args[5] if len(args) > 5 else -1.
2370 saveNumbers = args[6] if len(args) > 6 else True
2371 # process keywords arguments
2372 auto_groups = kwargs.get("auto_groups", auto_groups)
2373 meshPart = kwargs.get("meshPart", meshPart)
2374 autoDimension = kwargs.get("autoDimension", autoDimension)
2375 fields = kwargs.get("fields", fields)
2376 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2377 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2378 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2380 # invoke engine's function
2381 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2382 unRegister = genObjUnRegister()
2383 if isinstance( meshPart, list ):
2384 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2385 unRegister.set( meshPart )
2387 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2388 self.mesh.SetParameters(Parameters)
2390 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2391 fields, geomAssocFields, z_tolerance,
2394 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2395 return medcoupling.MEDFileData.New(dab)
2397 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2399 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2400 return medcoupling.MEDFileMesh.New(dab)
2402 def ExportMED(self, *args, **kwargs):
2404 Export the mesh in a file in MED format
2405 allowing to overwrite the file if it exists or add the exported data to its contents
2408 fileName: is the file name
2409 auto_groups (boolean): parameter for creating/not creating
2410 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2411 the typical use is auto_groups=False.
2412 version (int): define the version (xy, where version is x.y.z) of MED file format.
2413 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2414 The rules of compatibility to write a mesh in an older version than
2415 the current version depend on the current version. For instance,
2416 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2417 or 3.2.1 or 3.3.1 formats.
2418 If the version is equal to -1, the version is not changed (default).
2419 overwrite (boolean): parameter for overwriting/not overwriting the file
2420 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2421 to export instead of the mesh
2422 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2424 - 1D if all mesh nodes lie on OX coordinate axis, or
2425 - 2D if all mesh nodes lie on XOY coordinate plane, or
2426 - 3D in the rest cases.
2428 If *autoDimension* is *False*, the space dimension is always 3.
2429 fields: list of GEOM fields defined on the shape to mesh.
2430 geomAssocFields: each character of this string means a need to export a
2431 corresponding field; correspondence between fields and characters
2434 - 'v' stands for "_vertices_" field;
2435 - 'e' stands for "_edges_" field;
2436 - 'f' stands for "_faces_" field;
2437 - 's' stands for "_solids_" field.
2439 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2440 close to zero within a given tolerance, the coordinate is set to zero.
2441 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2442 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2444 # process positional arguments
2445 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2447 auto_groups = args[1] if len(args) > 1 else False
2448 version = args[2] if len(args) > 2 else -1
2449 overwrite = args[3] if len(args) > 3 else True
2450 meshPart = args[4] if len(args) > 4 else None
2451 autoDimension = args[5] if len(args) > 5 else True
2452 fields = args[6] if len(args) > 6 else []
2453 geomAssocFields = args[7] if len(args) > 7 else ''
2454 z_tolerance = args[8] if len(args) > 8 else -1.
2455 saveNumbers = args[9] if len(args) > 9 else True
2456 # process keywords arguments
2457 auto_groups = kwargs.get("auto_groups", auto_groups)
2458 version = kwargs.get("version", version)
2459 version = kwargs.get("minor", version)
2460 overwrite = kwargs.get("overwrite", overwrite)
2461 meshPart = kwargs.get("meshPart", meshPart)
2462 autoDimension = kwargs.get("autoDimension", autoDimension)
2463 fields = kwargs.get("fields", fields)
2464 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2465 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2466 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2468 if isinstance( meshPart, Mesh):
2469 meshPart = meshPart.GetMesh()
2471 # invoke engine's function
2472 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2473 unRegister = genObjUnRegister()
2474 if isinstance( meshPart, list ):
2475 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2476 unRegister.set( meshPart )
2478 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2479 self.mesh.SetParameters(Parameters)
2481 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2482 version, overwrite, autoDimension,
2483 fields, geomAssocFields, z_tolerance, saveNumbers )
2485 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2487 def ExportDAT(self, f, meshPart=None, renumber=True):
2489 Export the mesh in a file in DAT format
2493 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2494 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2497 if meshPart or not renumber:
2498 unRegister = genObjUnRegister()
2499 if isinstance( meshPart, list ):
2500 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2501 unRegister.set( meshPart )
2502 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2504 self.mesh.ExportDAT( f, renumber )
2506 def ExportUNV(self, f, meshPart=None, renumber=True):
2508 Export the mesh in a file in UNV format
2512 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2513 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2516 if meshPart or not renumber:
2517 unRegister = genObjUnRegister()
2518 if isinstance( meshPart, list ):
2519 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2520 unRegister.set( meshPart )
2521 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2523 self.mesh.ExportUNV( f, renumber )
2525 def ExportSTL(self, f, ascii=1, meshPart=None):
2527 Export the mesh in a file in STL format
2531 ascii: defines the file encoding
2532 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2536 unRegister = genObjUnRegister()
2537 if isinstance( meshPart, list ):
2538 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2539 unRegister.set( meshPart )
2540 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2542 self.mesh.ExportSTL(f, ascii)
2544 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2546 Export the mesh in a file in CGNS format
2550 overwrite: boolean parameter for overwriting/not overwriting the file
2551 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2552 groupElemsByType: if True all elements of same entity type are exported at ones,
2553 else elements are exported in order of their IDs which can cause creation
2554 of multiple cgns sections
2557 unRegister = genObjUnRegister()
2558 if isinstance( meshPart, list ):
2559 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2560 unRegister.set( meshPart )
2561 if isinstance( meshPart, Mesh ):
2562 meshPart = meshPart.mesh
2564 meshPart = self.mesh
2565 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2567 def ExportGMF(self, f, meshPart=None):
2569 Export the mesh in a file in GMF format.
2570 GMF files must have .mesh extension for the ASCII format and .meshb for
2571 the bynary format. Other extensions are not allowed.
2575 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2578 unRegister = genObjUnRegister()
2579 if isinstance( meshPart, list ):
2580 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2581 unRegister.set( meshPart )
2582 if isinstance( meshPart, Mesh ):
2583 meshPart = meshPart.mesh
2585 meshPart = self.mesh
2586 self.mesh.ExportGMF(meshPart, f, True)
2588 def ExportToMED(self, *args, **kwargs):
2590 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2591 Export the mesh in a file in MED format
2592 allowing to overwrite the file if it exists or add the exported data to its contents
2595 fileName: the file name
2596 opt (boolean): parameter for creating/not creating
2597 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2598 overwrite: boolean parameter for overwriting/not overwriting the file
2599 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2601 - 1D if all mesh nodes lie on OX coordinate axis, or
2602 - 2D if all mesh nodes lie on XOY coordinate plane, or
2603 - 3D in the rest cases.
2605 If **autoDimension** is *False*, the space dimension is always 3.
2608 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2609 # process positional arguments
2610 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2612 auto_groups = args[1] if len(args) > 1 else False
2613 overwrite = args[2] if len(args) > 2 else True
2614 autoDimension = args[3] if len(args) > 3 else True
2615 # process keywords arguments
2616 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2617 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2618 overwrite = kwargs.get("overwrite", overwrite)
2619 autoDimension = kwargs.get("autoDimension", autoDimension)
2621 # invoke engine's function
2622 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2624 def ExportToMEDX(self, *args, **kwargs):
2626 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2627 Export the mesh in a file in MED format
2630 fileName: the file name
2631 opt (boolean): parameter for creating/not creating
2632 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2633 overwrite: boolean parameter for overwriting/not overwriting the file
2634 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2636 - 1D if all mesh nodes lie on OX coordinate axis, or
2637 - 2D if all mesh nodes lie on XOY coordinate plane, or
2638 - 3D in the rest cases.
2640 If **autoDimension** is *False*, the space dimension is always 3.
2643 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2644 # process positional arguments
2645 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2647 auto_groups = args[1] if len(args) > 1 else False
2648 overwrite = args[2] if len(args) > 2 else True
2649 autoDimension = args[3] if len(args) > 3 else True
2650 # process keywords arguments
2651 auto_groups = kwargs.get("auto_groups", auto_groups)
2652 overwrite = kwargs.get("overwrite", overwrite)
2653 autoDimension = kwargs.get("autoDimension", autoDimension)
2655 # invoke engine's function
2656 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2660 def Append(self, meshes, uniteIdenticalGroups = True,
2661 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2663 Append given meshes into this mesh.
2664 All groups of input meshes will be created in this mesh.
2667 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2668 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2669 mergeNodesAndElements: if True, equal nodes and elements are merged
2670 mergeTolerance: tolerance for merging nodes
2671 allGroups: forces creation of groups corresponding to every input mesh
2673 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2674 mergeNodesAndElements, mergeTolerance, allGroups,
2675 meshToAppendTo = self.GetMesh() )
2677 # Operations with groups:
2678 # ----------------------
2679 def CreateEmptyGroup(self, elementType, name):
2681 Create an empty standalone mesh group
2684 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2685 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2686 name: the name of the mesh group
2689 :class:`SMESH.SMESH_Group`
2692 return self.mesh.CreateGroup(elementType, name)
2694 def Group(self, grp, name=""):
2696 Create a mesh group based on the geometric object *grp*
2697 and give it a *name*.
2698 If *name* is not defined the name of the geometric group is used
2701 Works like :meth:`GroupOnGeom`.
2704 grp: a geometric group, a vertex, an edge, a face or a solid
2705 name: the name of the mesh group
2708 :class:`SMESH.SMESH_GroupOnGeom`
2711 return self.GroupOnGeom(grp, name)
2713 def GroupOnGeom(self, grp, name="", typ=None):
2715 Create a mesh group based on the geometrical object *grp*
2716 and give it a *name*.
2717 if *name* is not defined the name of the geometric group is used
2720 grp: a geometrical group, a vertex, an edge, a face or a solid
2721 name: the name of the mesh group
2722 typ: the type of elements in the group; either of
2723 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2724 automatically detected by the type of the geometry
2727 :class:`SMESH.SMESH_GroupOnGeom`
2730 AssureGeomPublished( self, grp, name )
2732 name = grp.GetName()
2734 typ = self._groupTypeFromShape( grp )
2735 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2737 def _groupTypeFromShape( self, shape ):
2739 Pivate method to get a type of group on geometry
2741 tgeo = str(shape.GetShapeType())
2742 if tgeo == "VERTEX":
2744 elif tgeo == "EDGE" or tgeo == "WIRE":
2746 elif tgeo == "FACE" or tgeo == "SHELL":
2748 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2750 elif tgeo == "COMPOUND":
2752 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2754 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2755 # simplification of access in geomBuilder: omniORB.registerObjref
2756 from SHAPERSTUDY_utils import getEngine
2759 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2761 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2762 return self._groupTypeFromShape( sub[0] )
2764 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2767 def GroupOnFilter(self, typ, name, filter):
2769 Create a mesh group with given *name* based on the *filter*.
2770 It is a special type of group dynamically updating it's contents during
2774 typ: the type of elements in the group; either of
2775 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2776 name: the name of the mesh group
2777 filter (SMESH.Filter): the filter defining group contents
2780 :class:`SMESH.SMESH_GroupOnFilter`
2783 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2785 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2787 Create a mesh group by the given ids of elements
2790 groupName: the name of the mesh group
2791 elementType: the type of elements in the group; either of
2792 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2793 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2796 :class:`SMESH.SMESH_Group`
2799 group = self.mesh.CreateGroup(elementType, groupName)
2800 if isinstance( elemIDs, Mesh ):
2801 elemIDs = elemIDs.GetMesh()
2802 if hasattr( elemIDs, "GetIDs" ):
2803 if hasattr( elemIDs, "SetMesh" ):
2804 elemIDs.SetMesh( self.GetMesh() )
2805 group.AddFrom( elemIDs )
2813 CritType=FT_Undefined,
2816 UnaryOp=FT_Undefined,
2819 Create a mesh group by the given conditions
2822 groupName: the name of the mesh group
2823 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2824 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2825 Note that the items starting from FT_LessThan are not suitable for CritType.
2826 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2827 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2828 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2829 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2830 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2833 :class:`SMESH.SMESH_GroupOnFilter`
2836 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2837 group = self.MakeGroupByCriterion(groupName, aCriterion)
2840 def MakeGroupByCriterion(self, groupName, Criterion):
2842 Create a mesh group by the given criterion
2845 groupName: the name of the mesh group
2846 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2849 :class:`SMESH.SMESH_GroupOnFilter`
2852 :meth:`smeshBuilder.GetCriterion`
2855 return self.MakeGroupByCriteria( groupName, [Criterion] )
2857 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2859 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2862 groupName: the name of the mesh group
2863 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2864 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2867 :class:`SMESH.SMESH_GroupOnFilter`
2870 :meth:`smeshBuilder.GetCriterion`
2873 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2874 group = self.MakeGroupByFilter(groupName, aFilter)
2877 def MakeGroupByFilter(self, groupName, theFilter):
2879 Create a mesh group by the given filter
2882 groupName (string): the name of the mesh group
2883 theFilter (SMESH.Filter): the filter
2886 :class:`SMESH.SMESH_GroupOnFilter`
2889 :meth:`smeshBuilder.GetFilter`
2892 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2893 #theFilter.SetMesh( self.mesh )
2894 #group.AddFrom( theFilter )
2895 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2898 def RemoveGroup(self, group):
2903 group (SMESH.SMESH_GroupBase): group to remove
2906 self.mesh.RemoveGroup(group)
2908 def RemoveGroupWithContents(self, group):
2910 Remove a group with its contents
2913 group (SMESH.SMESH_GroupBase): group to remove
2916 This operation can create gaps in numeration of nodes or elements.
2917 Call :meth:`RenumberElements` to remove the gaps.
2920 self.mesh.RemoveGroupWithContents(group)
2922 def GetGroups(self, elemType = SMESH.ALL):
2924 Get the list of groups existing in the mesh in the order of creation
2925 (starting from the oldest one)
2928 elemType (SMESH.ElementType): type of elements the groups contain;
2929 by default groups of elements of all types are returned
2932 a list of :class:`SMESH.SMESH_GroupBase`
2935 groups = self.mesh.GetGroups()
2936 if elemType == SMESH.ALL:
2940 if g.GetType() == elemType:
2941 typedGroups.append( g )
2948 Get the number of groups existing in the mesh
2951 the quantity of groups as an integer value
2954 return self.mesh.NbGroups()
2956 def GetGroupNames(self):
2958 Get the list of names of groups existing in the mesh
2964 groups = self.GetGroups()
2966 for group in groups:
2967 names.append(group.GetName())
2970 def GetGroupByName(self, name, elemType = None):
2972 Find groups by name and type
2975 name (string): name of the group of interest
2976 elemType (SMESH.ElementType): type of elements the groups contain;
2977 by default one group of any type is returned;
2978 if elemType == SMESH.ALL then all groups of any type are returned
2981 a list of :class:`SMESH.SMESH_GroupBase`
2985 for group in self.GetGroups():
2986 if group.GetName() == name:
2987 if elemType is None:
2989 if ( elemType == SMESH.ALL or
2990 group.GetType() == elemType ):
2991 groups.append( group )
2994 def UnionGroups(self, group1, group2, name):
2996 Produce a union of two groups.
2997 A new group is created. All mesh elements that are
2998 present in the initial groups are added to the new one
3001 group1 (SMESH.SMESH_GroupBase): a group
3002 group2 (SMESH.SMESH_GroupBase): another group
3005 instance of :class:`SMESH.SMESH_Group`
3008 return self.mesh.UnionGroups(group1, group2, name)
3010 def UnionListOfGroups(self, groups, name):
3012 Produce a union list of groups.
3013 New group is created. All mesh elements that are present in
3014 initial groups are added to the new one
3017 groups: list of :class:`SMESH.SMESH_GroupBase`
3020 instance of :class:`SMESH.SMESH_Group`
3022 return self.mesh.UnionListOfGroups(groups, name)
3024 def IntersectGroups(self, group1, group2, name):
3026 Prodice an intersection of two groups.
3027 A new group is created. All mesh elements that are common
3028 for the two initial groups are added to the new one.
3031 group1 (SMESH.SMESH_GroupBase): a group
3032 group2 (SMESH.SMESH_GroupBase): another group
3035 instance of :class:`SMESH.SMESH_Group`
3038 return self.mesh.IntersectGroups(group1, group2, name)
3040 def IntersectListOfGroups(self, groups, name):
3042 Produce an intersection of groups.
3043 New group is created. All mesh elements that are present in all
3044 initial groups simultaneously are added to the new one
3047 groups: a list of :class:`SMESH.SMESH_GroupBase`
3050 instance of :class:`SMESH.SMESH_Group`
3052 return self.mesh.IntersectListOfGroups(groups, name)
3054 def CutGroups(self, main_group, tool_group, name):
3056 Produce a cut of two groups.
3057 A new group is created. All mesh elements that are present in
3058 the main group but are not present in the tool group are added to the new one
3061 main_group (SMESH.SMESH_GroupBase): a group to cut from
3062 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3065 an instance of :class:`SMESH.SMESH_Group`
3068 return self.mesh.CutGroups(main_group, tool_group, name)
3070 def CutListOfGroups(self, main_groups, tool_groups, name):
3072 Produce a cut of groups.
3073 A new group is created. All mesh elements that are present in main groups
3074 but do not present in tool groups are added to the new one
3077 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3078 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3081 an instance of :class:`SMESH.SMESH_Group`
3084 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3086 def CreateDimGroup(self, groups, elemType, name,
3087 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3089 Create a standalone group of entities basing on nodes of other groups.
3092 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3093 elemType: a type of elements to include to the new group; either of
3094 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3095 name: a name of the new group.
3096 nbCommonNodes: a criterion of inclusion of an element to the new group
3097 basing on number of element nodes common with reference *groups*.
3098 Meaning of possible values are:
3100 - SMESH.ALL_NODES - include if all nodes are common,
3101 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3102 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3103 - SMEHS.MAJORITY - include if half of nodes or more are common.
3104 underlyingOnly: if *True* (default), an element is included to the
3105 new group provided that it is based on nodes of an element of *groups*;
3106 in this case the reference *groups* are supposed to be of higher dimension
3107 than *elemType*, which can be useful for example to get all faces lying on
3108 volumes of the reference *groups*.
3111 an instance of :class:`SMESH.SMESH_Group`
3114 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3116 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3118 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3120 Distribute all faces of the mesh among groups using sharp edges and optionally
3121 existing 1D elements as group boundaries.
3124 sharpAngle: edge is considered sharp if an angle between normals of
3125 adjacent faces is more than \a sharpAngle in degrees.
3126 createEdges (boolean): to create 1D elements for detected sharp edges.
3127 useExistingEdges (boolean): to use existing edges as group boundaries
3129 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3131 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3132 self.mesh.SetParameters(Parameters)
3133 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3135 def ConvertToStandalone(self, group):
3137 Convert group on geom into standalone group
3140 return self.mesh.ConvertToStandalone(group)
3142 # Get some info about mesh:
3143 # ------------------------
3145 def GetLog(self, clearAfterGet):
3147 Return the log of nodes and elements added or removed
3148 since the previous clear of the log.
3151 clearAfterGet: log is emptied after Get (safe if concurrents access)
3154 list of SMESH.log_block structures { commandType, number, coords, indexes }
3157 return self.mesh.GetLog(clearAfterGet)
3161 Clear the log of nodes and elements added or removed since the previous
3162 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3165 self.mesh.ClearLog()
3167 def SetAutoColor(self, theAutoColor):
3169 Toggle auto color mode on the object.
3170 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3173 theAutoColor (boolean): the flag which toggles auto color mode.
3176 self.mesh.SetAutoColor(theAutoColor)
3178 def GetAutoColor(self):
3180 Get flag of object auto color mode.
3186 return self.mesh.GetAutoColor()
3193 integer value, which is the internal Id of the mesh
3196 return self.mesh.GetId()
3198 def HasDuplicatedGroupNamesMED(self):
3200 Check the group names for duplications.
3201 Consider the maximum group name length stored in MED file.
3207 return self.mesh.HasDuplicatedGroupNamesMED()
3209 def GetMeshEditor(self):
3211 Obtain the mesh editor tool
3214 an instance of :class:`SMESH.SMESH_MeshEditor`
3219 def GetIDSource(self, ids, elemType = SMESH.ALL):
3221 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3222 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3226 elemType: type of elements; this parameter is used to distinguish
3227 IDs of nodes from IDs of elements; by default ids are treated as
3228 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3231 an instance of :class:`SMESH.SMESH_IDSource`
3234 call UnRegister() for the returned object as soon as it is no more useful::
3236 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3237 mesh.DoSomething( idSrc )
3241 if isinstance( ids, int ):
3243 return self.editor.MakeIDSource(ids, elemType)
3246 # Get information about mesh contents:
3247 # ------------------------------------
3249 def GetMeshInfo(self, obj = None):
3251 Get the mesh statistic.
3254 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3257 if not obj: obj = self.mesh
3258 return self.smeshpyD.GetMeshInfo(obj)
3262 Return the number of nodes in the mesh
3268 return self.mesh.NbNodes()
3270 def NbElements(self):
3272 Return the number of elements in the mesh
3278 return self.mesh.NbElements()
3280 def Nb0DElements(self):
3282 Return the number of 0d elements in the mesh
3288 return self.mesh.Nb0DElements()
3292 Return the number of ball discrete elements in the mesh
3298 return self.mesh.NbBalls()
3302 Return the number of edges in the mesh
3308 return self.mesh.NbEdges()
3310 def NbEdgesOfOrder(self, elementOrder):
3312 Return the number of edges with the given order in the mesh
3315 elementOrder: the order of elements
3316 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322 return self.mesh.NbEdgesOfOrder(elementOrder)
3326 Return the number of faces in the mesh
3332 return self.mesh.NbFaces()
3334 def NbFacesOfOrder(self, elementOrder):
3336 Return the number of faces with the given order in the mesh
3339 elementOrder: the order of elements
3340 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346 return self.mesh.NbFacesOfOrder(elementOrder)
3348 def NbTriangles(self):
3350 Return the number of triangles in the mesh
3356 return self.mesh.NbTriangles()
3358 def NbTrianglesOfOrder(self, elementOrder):
3360 Return the number of triangles with the given order in the mesh
3363 elementOrder: is the order of elements
3364 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370 return self.mesh.NbTrianglesOfOrder(elementOrder)
3372 def NbBiQuadTriangles(self):
3374 Return the number of biquadratic triangles in the mesh
3380 return self.mesh.NbBiQuadTriangles()
3382 def NbQuadrangles(self):
3384 Return the number of quadrangles in the mesh
3390 return self.mesh.NbQuadrangles()
3392 def NbQuadranglesOfOrder(self, elementOrder):
3394 Return the number of quadrangles with the given order in the mesh
3397 elementOrder: the order of elements
3398 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3404 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3406 def NbBiQuadQuadrangles(self):
3408 Return the number of biquadratic quadrangles in the mesh
3414 return self.mesh.NbBiQuadQuadrangles()
3416 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3418 Return the number of polygons of given order in the mesh
3421 elementOrder: the order of elements
3422 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428 return self.mesh.NbPolygonsOfOrder(elementOrder)
3430 def NbVolumes(self):
3432 Return the number of volumes in the mesh
3438 return self.mesh.NbVolumes()
3441 def NbVolumesOfOrder(self, elementOrder):
3443 Return the number of volumes with the given order in the mesh
3446 elementOrder: the order of elements
3447 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3453 return self.mesh.NbVolumesOfOrder(elementOrder)
3457 Return the number of tetrahedrons in the mesh
3463 return self.mesh.NbTetras()
3465 def NbTetrasOfOrder(self, elementOrder):
3467 Return the number of tetrahedrons with the given order in the mesh
3470 elementOrder: the order of elements
3471 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3477 return self.mesh.NbTetrasOfOrder(elementOrder)
3481 Return the number of hexahedrons in the mesh
3487 return self.mesh.NbHexas()
3489 def NbHexasOfOrder(self, elementOrder):
3491 Return the number of hexahedrons with the given order in the mesh
3494 elementOrder: the order of elements
3495 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3501 return self.mesh.NbHexasOfOrder(elementOrder)
3503 def NbTriQuadraticHexas(self):
3505 Return the number of triquadratic hexahedrons in the mesh
3511 return self.mesh.NbTriQuadraticHexas()
3513 def NbPyramids(self):
3515 Return the number of pyramids in the mesh
3521 return self.mesh.NbPyramids()
3523 def NbPyramidsOfOrder(self, elementOrder):
3525 Return the number of pyramids with the given order in the mesh
3528 elementOrder: the order of elements
3529 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3535 return self.mesh.NbPyramidsOfOrder(elementOrder)
3539 Return the number of prisms in the mesh
3545 return self.mesh.NbPrisms()
3547 def NbPrismsOfOrder(self, elementOrder):
3549 Return the number of prisms with the given order in the mesh
3552 elementOrder: the order of elements
3553 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3559 return self.mesh.NbPrismsOfOrder(elementOrder)
3561 def NbHexagonalPrisms(self):
3563 Return the number of hexagonal prisms in the mesh
3569 return self.mesh.NbHexagonalPrisms()
3571 def NbPolyhedrons(self):
3573 Return the number of polyhedrons in the mesh
3579 return self.mesh.NbPolyhedrons()
3581 def NbSubMesh(self):
3583 Return the number of submeshes in the mesh
3589 return self.mesh.NbSubMesh()
3591 def GetElementsId(self):
3593 Return the list of all mesh elements IDs
3596 the list of integer values
3599 :meth:`GetElementsByType`
3602 return self.mesh.GetElementsId()
3604 def GetElementsByType(self, elementType):
3606 Return the list of IDs of mesh elements with the given type
3609 elementType (SMESH.ElementType): the required type of elements
3612 list of integer values
3615 return self.mesh.GetElementsByType(elementType)
3617 def GetNodesId(self):
3619 Return the list of mesh nodes IDs
3622 the list of integer values
3625 return self.mesh.GetNodesId()
3627 # Get the information about mesh elements:
3628 # ------------------------------------
3630 def GetElementType(self, id, iselem=True):
3632 Return the type of mesh element or node
3635 the value from :class:`SMESH.ElementType` enumeration.
3636 Return SMESH.ALL if element or node with the given ID does not exist
3639 return self.mesh.GetElementType(id, iselem)
3641 def GetElementGeomType(self, id):
3643 Return the geometric type of mesh element
3646 the value from :class:`SMESH.EntityType` enumeration.
3649 return self.mesh.GetElementGeomType(id)
3651 def GetElementShape(self, id):
3653 Return the shape type of mesh element
3656 the value from :class:`SMESH.GeometryType` enumeration.
3659 return self.mesh.GetElementShape(id)
3661 def GetSubMeshElementsId(self, Shape):
3663 Return the list of sub-mesh elements IDs
3666 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3667 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3670 list of integer values
3673 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3674 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3677 return self.mesh.GetSubMeshElementsId(ShapeID)
3679 def GetSubMeshNodesId(self, Shape, all):
3681 Return the list of sub-mesh nodes IDs
3684 Shape: a geom object (sub-shape).
3685 *Shape* must be the sub-shape of a :meth:`GetShape`
3686 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3689 list of integer values
3692 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3693 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3696 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3698 def GetSubMeshElementType(self, Shape):
3700 Return type of elements on given shape
3703 Shape: a geom object (sub-shape).
3704 *Shape* must be a sub-shape of a ShapeToMesh()
3707 :class:`SMESH.ElementType`
3710 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3711 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3714 return self.mesh.GetSubMeshElementType(ShapeID)
3718 Get the mesh description
3724 return self.mesh.Dump()
3727 # Get the information about nodes and elements of a mesh by its IDs:
3728 # -----------------------------------------------------------
3730 def GetNodeXYZ(self, id):
3732 Get XYZ coordinates of a node.
3733 If there is no node for the given ID - return an empty list
3736 list of float values
3739 return self.mesh.GetNodeXYZ(id)
3741 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3743 Return list of IDs of inverse elements for the given node.
3744 If there is no node for the given ID - return an empty list
3748 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3751 list of integer values
3754 return self.mesh.GetNodeInverseElements(id,elemType)
3756 def GetNodePosition(self,NodeID):
3758 Return the position of a node on the shape
3761 :class:`SMESH.NodePosition`
3764 return self.mesh.GetNodePosition(NodeID)
3766 def GetElementPosition(self,ElemID):
3768 Return the position of an element on the shape
3771 :class:`SMESH.ElementPosition`
3774 return self.mesh.GetElementPosition(ElemID)
3776 def GetShapeID(self, id):
3778 Return the ID of the shape, on which the given node was generated.
3781 an integer value > 0 or -1 if there is no node for the given
3782 ID or the node is not assigned to any geometry
3785 return self.mesh.GetShapeID(id)
3787 def GetShapeIDForElem(self,id):
3789 Return the ID of the shape, on which the given element was generated.
3792 an integer value > 0 or -1 if there is no element for the given
3793 ID or the element is not assigned to any geometry
3796 return self.mesh.GetShapeIDForElem(id)
3798 def GetElemNbNodes(self, id):
3800 Return the number of nodes of the given element
3803 an integer value > 0 or -1 if there is no element for the given ID
3806 return self.mesh.GetElemNbNodes(id)
3808 def GetElemNode(self, id, index):
3810 Return the node ID the given (zero based) index for the given element.
3812 * If there is no element for the given ID - return -1.
3813 * If there is no node for the given index - return -2.
3816 id (int): element ID
3817 index (int): node index within the element
3820 an integer value (ID)
3823 :meth:`GetElemNodes`
3826 return self.mesh.GetElemNode(id, index)
3828 def GetElemNodes(self, id):
3830 Return the IDs of nodes of the given element
3833 a list of integer values
3836 return self.mesh.GetElemNodes(id)
3838 def IsMediumNode(self, elementID, nodeID):
3840 Return true if the given node is the medium node in the given quadratic element
3843 return self.mesh.IsMediumNode(elementID, nodeID)
3845 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3847 Return true if the given node is the medium node in one of quadratic elements
3850 nodeID: ID of the node
3851 elementType: the type of elements to check a state of the node, either of
3852 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3855 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3857 def ElemNbEdges(self, id):
3859 Return the number of edges for the given element
3862 return self.mesh.ElemNbEdges(id)
3864 def ElemNbFaces(self, id):
3866 Return the number of faces for the given element
3869 return self.mesh.ElemNbFaces(id)
3871 def GetElemFaceNodes(self,elemId, faceIndex):
3873 Return nodes of given face (counted from zero) for given volumic element.
3876 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3878 def GetFaceNormal(self, faceId, normalized=False):
3880 Return three components of normal of given mesh face
3881 (or an empty array in KO case)
3884 return self.mesh.GetFaceNormal(faceId,normalized)
3886 def FindElementByNodes(self, nodes):
3888 Return an element based on all given nodes.
3891 return self.mesh.FindElementByNodes(nodes)
3893 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3895 Return elements including all given nodes.
3898 return self.mesh.GetElementsByNodes( nodes, elemType )
3900 def IsPoly(self, id):
3902 Return true if the given element is a polygon
3905 return self.mesh.IsPoly(id)
3907 def IsQuadratic(self, id):
3909 Return true if the given element is quadratic
3912 return self.mesh.IsQuadratic(id)
3914 def GetBallDiameter(self, id):
3916 Return diameter of a ball discrete element or zero in case of an invalid *id*
3919 return self.mesh.GetBallDiameter(id)
3921 def BaryCenter(self, id):
3923 Return XYZ coordinates of the barycenter of the given element.
3924 If there is no element for the given ID - return an empty list
3927 a list of three double values
3930 :meth:`smeshBuilder.GetGravityCenter`
3933 return self.mesh.BaryCenter(id)
3935 def GetIdsFromFilter(self, filter, meshParts=[] ):
3937 Pass mesh elements through the given filter and return IDs of fitting elements
3940 filter: :class:`SMESH.Filter`
3941 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3947 :meth:`SMESH.Filter.GetIDs`
3948 :meth:`SMESH.Filter.GetElementsIdFromParts`
3951 filter.SetMesh( self.mesh )
3954 if isinstance( meshParts, Mesh ):
3955 filter.SetMesh( meshParts.GetMesh() )
3956 return theFilter.GetIDs()
3957 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3958 meshParts = [ meshParts ]
3959 return filter.GetElementsIdFromParts( meshParts )
3961 return filter.GetIDs()
3963 # Get mesh measurements information:
3964 # ------------------------------------
3966 def GetFreeBorders(self):
3968 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3969 Return a list of special structures (borders).
3972 a list of :class:`SMESH.FreeEdges.Border`
3975 aFilterMgr = self.smeshpyD.CreateFilterManager()
3976 aPredicate = aFilterMgr.CreateFreeEdges()
3977 aPredicate.SetMesh(self.mesh)
3978 aBorders = aPredicate.GetBorders()
3979 aFilterMgr.UnRegister()
3982 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3984 Get minimum distance between two nodes, elements or distance to the origin
3987 id1: first node/element id
3988 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3989 isElem1: *True* if *id1* is element id, *False* if it is node id
3990 isElem2: *True* if *id2* is element id, *False* if it is node id
3993 minimum distance value
3995 :meth:`GetMinDistance`
3998 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3999 return aMeasure.value
4001 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4003 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4006 id1: first node/element id
4007 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4008 isElem1: *True* if *id1* is element id, *False* if it is node id
4009 isElem2: *True* if *id2* is element id, *False* if it is node id
4012 :class:`SMESH.Measure` structure
4018 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4020 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4023 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4025 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4030 aMeasurements = self.smeshpyD.CreateMeasurements()
4031 aMeasure = aMeasurements.MinDistance(id1, id2)
4032 genObjUnRegister([aMeasurements,id1, id2])
4035 def BoundingBox(self, objects=None, isElem=False):
4037 Get bounding box of the specified object(s)
4040 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4041 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4042 *False* specifies that *objects* are nodes
4045 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4048 :meth:`GetBoundingBox()`
4051 result = self.GetBoundingBox(objects, isElem)
4055 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4058 def GetBoundingBox(self, objects=None, isElem=False):
4060 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4063 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4064 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4065 False means that *objects* are nodes
4068 :class:`SMESH.Measure` structure
4071 :meth:`BoundingBox()`
4075 objects = [self.mesh]
4076 elif isinstance(objects, tuple):
4077 objects = list(objects)
4078 if not isinstance(objects, list):
4080 if len(objects) > 0 and isinstance(objects[0], int):
4083 unRegister = genObjUnRegister()
4085 if isinstance(o, Mesh):
4086 srclist.append(o.mesh)
4087 elif hasattr(o, "_narrow"):
4088 src = o._narrow(SMESH.SMESH_IDSource)
4089 if src: srclist.append(src)
4091 elif isinstance(o, list):
4093 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4095 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4096 unRegister.set( srclist[-1] )
4099 aMeasurements = self.smeshpyD.CreateMeasurements()
4100 unRegister.set( aMeasurements )
4101 aMeasure = aMeasurements.BoundingBox(srclist)
4104 # Mesh edition (SMESH_MeshEditor functionality):
4105 # ---------------------------------------------
4107 def RemoveElements(self, IDsOfElements):
4109 Remove the elements from the mesh by ids
4112 IDsOfElements: is a list of ids of elements to remove
4118 This operation can create gaps in numeration of elements.
4119 Call :meth:`RenumberElements` to remove the gaps.
4122 return self.editor.RemoveElements(IDsOfElements)
4124 def RemoveNodes(self, IDsOfNodes):
4126 Remove nodes from mesh by ids
4129 IDsOfNodes: is a list of ids of nodes to remove
4135 This operation can create gaps in numeration of nodes.
4136 Call :meth:`RenumberElements` to remove the gaps.
4139 return self.editor.RemoveNodes(IDsOfNodes)
4141 def RemoveNodeWithReconnection(self, nodeID ):
4143 Remove a node along with changing surrounding faces to cover a hole.
4146 nodeID: ID of node to remove
4149 return self.editor.RemoveNodeWithReconnection( nodeID )
4151 def RemoveOrphanNodes(self):
4153 Remove all orphan (free) nodes from mesh
4156 number of the removed nodes
4159 This operation can create gaps in numeration of nodes.
4160 Call :meth:`RenumberElements` to remove the gaps.
4163 return self.editor.RemoveOrphanNodes()
4165 def AddNode(self, x, y, z):
4167 Add a node to the mesh by coordinates
4173 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4174 if hasVars: self.mesh.SetParameters(Parameters)
4175 return self.editor.AddNode( x, y, z)
4177 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4179 Create a 0D element on a node with given number.
4182 IDOfNode: the ID of node for creation of the element.
4183 DuplicateElements: to add one more 0D element to a node or not
4186 ID of the new 0D element
4189 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4191 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4193 Create 0D elements on all nodes of the given elements except those
4194 nodes on which a 0D element already exists.
4197 theObject: an object on whose nodes 0D elements will be created.
4198 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4199 theGroupName: optional name of a group to add 0D elements created
4200 and/or found on nodes of *theObject*.
4201 DuplicateElements: to add one more 0D element to a node or not
4204 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4205 IDs of new and/or found 0D elements. IDs of 0D elements
4206 can be retrieved from the returned object by
4207 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4210 unRegister = genObjUnRegister()
4211 if isinstance( theObject, Mesh ):
4212 theObject = theObject.GetMesh()
4213 elif isinstance( theObject, list ):
4214 theObject = self.GetIDSource( theObject, SMESH.ALL )
4215 unRegister.set( theObject )
4216 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4218 def AddBall(self, IDOfNode, diameter):
4220 Create a ball element on a node with given ID.
4223 IDOfNode: the ID of node for creation of the element.
4224 diameter: the bal diameter.
4227 ID of the new ball element
4230 return self.editor.AddBall( IDOfNode, diameter )
4232 def AddEdge(self, IDsOfNodes):
4234 Create a linear or quadratic edge (this is determined
4235 by the number of given nodes).
4238 IDsOfNodes: list of node IDs for creation of the element.
4239 The order of nodes in this list should correspond to
4240 the :ref:`connectivity convention <connectivity_page>`.
4246 return self.editor.AddEdge(IDsOfNodes)
4248 def AddFace(self, IDsOfNodes):
4250 Create a linear or quadratic face (this is determined
4251 by the number of given nodes).
4254 IDsOfNodes: list of node IDs for creation of the element.
4255 The order of nodes in this list should correspond to
4256 the :ref:`connectivity convention <connectivity_page>`.
4262 return self.editor.AddFace(IDsOfNodes)
4264 def AddPolygonalFace(self, IdsOfNodes):
4266 Add a polygonal face defined by a list of node IDs
4269 IdsOfNodes: the list of node IDs for creation of the element.
4275 return self.editor.AddPolygonalFace(IdsOfNodes)
4277 def AddQuadPolygonalFace(self, IdsOfNodes):
4279 Add a quadratic polygonal face defined by a list of node IDs
4282 IdsOfNodes: the list of node IDs for creation of the element;
4283 corner nodes follow first.
4289 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4291 def AddVolume(self, IDsOfNodes):
4293 Create both simple and quadratic volume (this is determined
4294 by the number of given nodes).
4297 IDsOfNodes: list of node IDs for creation of the element.
4298 The order of nodes in this list should correspond to
4299 the :ref:`connectivity convention <connectivity_page>`.
4302 ID of the new volumic element
4305 return self.editor.AddVolume(IDsOfNodes)
4307 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4309 Create a volume of many faces, giving nodes for each face.
4312 IdsOfNodes: list of node IDs for volume creation, face by face.
4313 Quantities: list of integer values, Quantities[i]
4314 gives the quantity of nodes in face number i.
4317 ID of the new volumic element
4320 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4322 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4324 Create a volume of many faces, giving the IDs of the existing faces.
4327 The created volume will refer only to the nodes
4328 of the given faces, not to the faces themselves.
4331 IdsOfFaces: the list of face IDs for volume creation.
4334 ID of the new volumic element
4337 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4340 def SetNodeOnVertex(self, NodeID, Vertex):
4342 Bind a node to a vertex
4346 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4349 True if succeed else raises an exception
4352 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4353 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4357 self.editor.SetNodeOnVertex(NodeID, VertexID)
4358 except SALOME.SALOME_Exception as inst:
4359 raise ValueError(inst.details.text)
4363 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4365 Store the node position on an edge
4369 Edge: an edge (GEOM.GEOM_Object) or edge ID
4370 paramOnEdge: a parameter on the edge where the node is located
4373 True if succeed else raises an exception
4376 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4377 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4381 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4382 except SALOME.SALOME_Exception as inst:
4383 raise ValueError(inst.details.text)
4386 def SetNodeOnFace(self, NodeID, Face, u, v):
4388 Store node position on a face
4392 Face: a face (GEOM.GEOM_Object) or face ID
4393 u: U parameter on the face where the node is located
4394 v: V parameter on the face where the node is located
4397 True if succeed else raises an exception
4400 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4401 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4405 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4406 except SALOME.SALOME_Exception as inst:
4407 raise ValueError(inst.details.text)
4410 def SetNodeInVolume(self, NodeID, Solid):
4412 Bind a node to a solid
4416 Solid: a solid (GEOM.GEOM_Object) or solid ID
4419 True if succeed else raises an exception
4422 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4423 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4427 self.editor.SetNodeInVolume(NodeID, SolidID)
4428 except SALOME.SALOME_Exception as inst:
4429 raise ValueError(inst.details.text)
4432 def SetMeshElementOnShape(self, ElementID, Shape):
4434 Bind an element to a shape
4437 ElementID: an element ID
4438 Shape: a shape (GEOM.GEOM_Object) or shape ID
4441 True if succeed else raises an exception
4444 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4445 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4449 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4450 except SALOME.SALOME_Exception as inst:
4451 raise ValueError(inst.details.text)
4455 def MoveNode(self, NodeID, x, y, z):
4457 Move the node with the given id
4460 NodeID: the id of the node
4461 x: a new X coordinate
4462 y: a new Y coordinate
4463 z: a new Z coordinate
4466 True if succeed else False
4469 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4470 if hasVars: self.mesh.SetParameters(Parameters)
4471 return self.editor.MoveNode(NodeID, x, y, z)
4473 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4475 Find the node closest to a point and moves it to a point location
4478 x: the X coordinate of a point
4479 y: the Y coordinate of a point
4480 z: the Z coordinate of a point
4481 NodeID: if specified (>0), the node with this ID is moved,
4482 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4485 the ID of a moved node
4488 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4489 if hasVars: self.mesh.SetParameters(Parameters)
4490 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4492 def FindNodeClosestTo(self, x, y, z):
4494 Find the node closest to a point
4497 x: the X coordinate of a point
4498 y: the Y coordinate of a point
4499 z: the Z coordinate of a point
4505 return self.editor.FindNodeClosestTo(x, y, z)
4507 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4509 Find the elements where a point lays IN or ON
4512 x,y,z (float): coordinates of the point
4513 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4514 means elements of any type excluding nodes, discrete and 0D elements.
4515 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4518 list of IDs of found elements
4521 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4523 return self.editor.FindElementsByPoint(x, y, z, elementType)
4525 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4527 Project a point to a mesh object.
4528 Return ID of an element of given type where the given point is projected
4529 and coordinates of the projection point.
4530 In the case if nothing found, return -1 and []
4532 if isinstance( meshObject, Mesh ):
4533 meshObject = meshObject.GetMesh()
4535 meshObject = self.GetMesh()
4536 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4538 def GetPointState(self, x, y, z):
4540 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4541 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4542 UNKNOWN state means that either mesh is wrong or the analysis fails.
4545 return self.editor.GetPointState(x, y, z)
4547 def IsManifold(self):
4549 Check if a 2D mesh is manifold
4552 return self.editor.IsManifold()
4554 def IsCoherentOrientation2D(self):
4556 Check if orientation of 2D elements is coherent
4559 return self.editor.IsCoherentOrientation2D()
4561 def Get1DBranches( self, edges, startNode = 0 ):
4563 Partition given 1D elements into groups of contiguous edges.
4564 A node where number of meeting edges != 2 is a group end.
4565 An optional startNode is used to orient groups it belongs to.
4568 A list of edge groups and a list of corresponding node groups,
4569 where the group is a list of IDs of edges or nodes, like follows
4570 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4571 If a group is closed, the first and last nodes of the group are same.
4573 if isinstance( edges, Mesh ):
4574 edges = edges.GetMesh()
4575 unRegister = genObjUnRegister()
4576 if isinstance( edges, list ):
4577 edges = self.GetIDSource( edges, SMESH.EDGE )
4578 unRegister.set( edges )
4579 return self.editor.Get1DBranches( edges, startNode )
4581 def FindSharpEdges( self, angle, addExisting=False ):
4583 Return sharp edges of faces and non-manifold ones.
4584 Optionally add existing edges.
4587 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4588 addExisting: to return existing edges (1D elements) as well
4591 list of FaceEdge structures
4593 angle = ParseParameters( angle )[0]
4594 return self.editor.FindSharpEdges( angle, addExisting )
4596 def MeshToPassThroughAPoint(self, x, y, z):
4598 Find the node closest to a point and moves it to a point location
4601 x: the X coordinate of a point
4602 y: the Y coordinate of a point
4603 z: the Z coordinate of a point
4606 the ID of a moved node
4609 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4611 def InverseDiag(self, NodeID1, NodeID2):
4613 Replace two neighbour triangles sharing Node1-Node2 link
4614 with the triangles built on the same 4 nodes but having other common link.
4617 NodeID1: the ID of the first node
4618 NodeID2: the ID of the second node
4621 False if proper faces were not found
4623 return self.editor.InverseDiag(NodeID1, NodeID2)
4625 def DeleteDiag(self, NodeID1, NodeID2):
4627 Replace two neighbour triangles sharing *Node1-Node2* link
4628 with a quadrangle built on the same 4 nodes.
4631 NodeID1: ID of the first node
4632 NodeID2: ID of the second node
4635 False if proper faces were not found
4638 This operation can create gaps in numeration of elements.
4639 Call :meth:`RenumberElements` to remove the gaps.
4642 return self.editor.DeleteDiag(NodeID1, NodeID2)
4644 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4646 Replace each triangle bound by Node1-Node2 segment with
4647 two triangles by connecting a node made on the link with a node
4648 opposite to the link.
4651 Node1: ID of the first node
4652 Node2: ID of the second node
4653 position: location [0,1] of the new node on the segment
4655 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4657 def AddNodeOnFace(self, face, x, y, z):
4659 Split a face into triangles by adding a new node onto the face
4660 and connecting the new node with face nodes
4663 face: ID of the face
4664 x,y,z: coordinates of the new node
4666 return self.editor.AddNodeOnFace(face, x, y, z)
4668 def Reorient(self, IDsOfElements=None):
4670 Reorient elements by ids
4673 IDsOfElements: if undefined reorients all mesh elements
4676 True if succeed else False
4679 if IDsOfElements == None:
4680 IDsOfElements = self.GetElementsId()
4681 return self.editor.Reorient(IDsOfElements)
4683 def ReorientObject(self, theObject):
4685 Reorient all elements of the object
4688 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4691 True if succeed else False
4694 if ( isinstance( theObject, Mesh )):
4695 theObject = theObject.GetMesh()
4696 return self.editor.ReorientObject(theObject)
4698 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4700 Reorient faces contained in *the2DObject*.
4703 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4704 theDirection: a desired direction of normal of *theFace*.
4705 It can be either a GEOM vector or a list of coordinates [x,y,z].
4706 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4707 compared with theDirection. It can be either ID of face or a point
4708 by which the face will be found. The point can be given as either
4709 a GEOM vertex or a list of point coordinates.
4712 number of reoriented faces
4715 unRegister = genObjUnRegister()
4717 if isinstance( the2DObject, Mesh ):
4718 the2DObject = the2DObject.GetMesh()
4719 if isinstance( the2DObject, list ):
4720 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4721 unRegister.set( the2DObject )
4722 # check theDirection
4723 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4724 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4725 if isinstance( theDirection, list ):
4726 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4727 # prepare theFace and thePoint
4728 theFace = theFaceOrPoint
4729 thePoint = PointStruct(0,0,0)
4730 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4731 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4733 if isinstance( theFaceOrPoint, list ):
4734 thePoint = PointStruct( *theFaceOrPoint )
4736 if isinstance( theFaceOrPoint, PointStruct ):
4737 thePoint = theFaceOrPoint
4739 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4741 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4743 Reorient faces contained in a list of *objectFaces*
4744 equally to faces contained in a list of *referenceFaces*.
4747 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4748 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.
4751 number of reoriented faces.
4753 if not isinstance( objectFaces, list ):
4754 objectFaces = [ objectFaces ]
4755 for i,obj2D in enumerate( objectFaces ):
4756 if isinstance( obj2D, Mesh ):
4757 objectFaces[i] = obj2D.GetMesh()
4758 if not isinstance( referenceFaces, list ):
4759 referenceFaces = [ referenceFaces ]
4761 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4764 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4766 Reorient faces according to adjacent volumes.
4769 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4770 either IDs of faces or face groups.
4771 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4772 theOutsideNormal: to orient faces to have their normals
4773 pointing either *outside* or *inside* the adjacent volumes.
4776 number of reoriented faces.
4779 unRegister = genObjUnRegister()
4781 if not isinstance( the2DObject, list ):
4782 the2DObject = [ the2DObject ]
4783 elif the2DObject and isinstance( the2DObject[0], int ):
4784 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4785 unRegister.set( the2DObject )
4786 the2DObject = [ the2DObject ]
4787 for i,obj2D in enumerate( the2DObject ):
4788 if isinstance( obj2D, Mesh ):
4789 the2DObject[i] = obj2D.GetMesh()
4790 if isinstance( obj2D, list ):
4791 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4792 unRegister.set( the2DObject[i] )
4794 if isinstance( the3DObject, Mesh ):
4795 the3DObject = the3DObject.GetMesh()
4796 if isinstance( the3DObject, list ):
4797 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4798 unRegister.set( the3DObject )
4799 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4801 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4803 Fuse the neighbouring triangles into quadrangles.
4806 IDsOfElements: The triangles to be fused.
4807 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4808 applied to possible quadrangles to choose a neighbour to fuse with.
4809 Note that not all items of :class:`SMESH.FunctorType` corresponds
4810 to numerical functors.
4811 MaxAngle: is the maximum angle between element normals at which the fusion
4812 is still performed; theMaxAngle is measured in radians.
4813 Also it could be a name of variable which defines angle in degrees.
4816 True in case of success, False otherwise.
4819 This operation can create gaps in numeration of elements.
4820 Call :meth:`RenumberElements` to remove the gaps.
4823 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4824 self.mesh.SetParameters(Parameters)
4825 if not IDsOfElements:
4826 IDsOfElements = self.GetElementsId()
4827 Functor = self.smeshpyD.GetFunctor(theCriterion)
4828 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4830 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4832 Fuse the neighbouring triangles of the object into quadrangles
4835 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4836 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4837 applied to possible quadrangles to choose a neighbour to fuse with.
4838 Note that not all items of :class:`SMESH.FunctorType` corresponds
4839 to numerical functors.
4840 MaxAngle: a max angle between element normals at which the fusion
4841 is still performed; theMaxAngle is measured in radians.
4844 True in case of success, False otherwise.
4847 This operation can create gaps in numeration of elements.
4848 Call :meth:`RenumberElements` to remove the gaps.
4851 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4852 self.mesh.SetParameters(Parameters)
4853 if isinstance( theObject, Mesh ):
4854 theObject = theObject.GetMesh()
4855 Functor = self.smeshpyD.GetFunctor(theCriterion)
4856 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4858 def QuadToTri (self, IDsOfElements, theCriterion = None):
4860 Split quadrangles into triangles.
4863 IDsOfElements: the faces to be splitted.
4864 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4865 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4866 value, then quadrangles will be split by the smallest diagonal.
4867 Note that not all items of :class:`SMESH.FunctorType` corresponds
4868 to numerical functors.
4871 True in case of success, False otherwise.
4874 This operation can create gaps in numeration of elements.
4875 Call :meth:`RenumberElements` to remove the gaps.
4877 if IDsOfElements == []:
4878 IDsOfElements = self.GetElementsId()
4879 if theCriterion is None:
4880 theCriterion = FT_MaxElementLength2D
4881 Functor = self.smeshpyD.GetFunctor(theCriterion)
4882 return self.editor.QuadToTri(IDsOfElements, Functor)
4884 def QuadToTriObject (self, theObject, theCriterion = None):
4886 Split quadrangles into triangles.
4889 theObject: the object from which the list of elements is taken,
4890 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4891 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4892 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4893 value, then quadrangles will be split by the smallest diagonal.
4894 Note that not all items of :class:`SMESH.FunctorType` corresponds
4895 to numerical functors.
4898 True in case of success, False otherwise.
4901 This operation can create gaps in numeration of elements.
4902 Call :meth:`RenumberElements` to remove the gaps.
4904 if ( isinstance( theObject, Mesh )):
4905 theObject = theObject.GetMesh()
4906 if theCriterion is None:
4907 theCriterion = FT_MaxElementLength2D
4908 Functor = self.smeshpyD.GetFunctor(theCriterion)
4909 return self.editor.QuadToTriObject(theObject, Functor)
4911 def QuadTo4Tri (self, theElements=[]):
4913 Split each of given quadrangles into 4 triangles. A node is added at the center of
4917 theElements: the faces to be splitted. This can be either
4918 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4919 or a list of face IDs. By default all quadrangles are split
4922 This operation can create gaps in numeration of elements.
4923 Call :meth:`RenumberElements` to remove the gaps.
4925 unRegister = genObjUnRegister()
4926 if isinstance( theElements, Mesh ):
4927 theElements = theElements.mesh
4928 elif not theElements:
4929 theElements = self.mesh
4930 elif isinstance( theElements, list ):
4931 theElements = self.GetIDSource( theElements, SMESH.FACE )
4932 unRegister.set( theElements )
4933 return self.editor.QuadTo4Tri( theElements )
4935 def SplitQuad (self, IDsOfElements, Diag13):
4937 Split quadrangles into triangles.
4940 IDsOfElements: the faces to be splitted
4941 Diag13 (boolean): is used to choose a diagonal for splitting.
4944 True in case of success, False otherwise.
4947 This operation can create gaps in numeration of elements.
4948 Call :meth:`RenumberElements` to remove the gaps.
4950 if IDsOfElements == []:
4951 IDsOfElements = self.GetElementsId()
4952 return self.editor.SplitQuad(IDsOfElements, Diag13)
4954 def SplitQuadObject (self, theObject, Diag13):
4956 Split quadrangles into triangles.
4959 theObject: the object from which the list of elements is taken,
4960 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4961 Diag13 (boolean): is used to choose a diagonal for splitting.
4964 True in case of success, False otherwise.
4967 This operation can create gaps in numeration of elements.
4968 Call :meth:`RenumberElements` to remove the gaps.
4970 if ( isinstance( theObject, Mesh )):
4971 theObject = theObject.GetMesh()
4972 return self.editor.SplitQuadObject(theObject, Diag13)
4974 def BestSplit (self, IDOfQuad, theCriterion):
4976 Find a better splitting of the given quadrangle.
4979 IDOfQuad: the ID of the quadrangle to be splitted.
4980 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4981 choose a diagonal for splitting.
4982 Note that not all items of :class:`SMESH.FunctorType` corresponds
4983 to numerical functors.
4986 * 1 if 1-3 diagonal is better,
4987 * 2 if 2-4 diagonal is better,
4988 * 0 if error occurs.
4991 This operation can create gaps in numeration of elements.
4992 Call :meth:`RenumberElements` to remove the gaps.
4994 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4996 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4998 Split volumic elements into tetrahedrons
5001 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5002 method: flags passing splitting method:
5003 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5004 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5007 This operation can create gaps in numeration of elements.
5008 Call :meth:`RenumberElements` to remove the gaps.
5010 unRegister = genObjUnRegister()
5011 if isinstance( elems, Mesh ):
5012 elems = elems.GetMesh()
5013 if ( isinstance( elems, list )):
5014 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5015 unRegister.set( elems )
5016 self.editor.SplitVolumesIntoTetra(elems, method)
5019 def SplitBiQuadraticIntoLinear(self, elems=None):
5021 Split bi-quadratic elements into linear ones without creation of additional nodes:
5023 - bi-quadratic triangle will be split into 3 linear quadrangles;
5024 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5025 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5027 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5028 will be split in order to keep the mesh conformal.
5031 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5032 if None (default), all bi-quadratic elements will be split
5035 This operation can create gaps in numeration of elements.
5036 Call :meth:`RenumberElements` to remove the gaps.
5038 unRegister = genObjUnRegister()
5039 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5040 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5041 unRegister.set( elems )
5043 elems = [ self.GetMesh() ]
5044 if isinstance( elems, Mesh ):
5045 elems = [ elems.GetMesh() ]
5046 if not isinstance( elems, list ):
5048 self.editor.SplitBiQuadraticIntoLinear( elems )
5050 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5051 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5053 Split hexahedra into prisms
5056 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5057 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5058 gives a normal vector defining facets to split into triangles.
5059 *startHexPoint* can be either a triple of coordinates or a vertex.
5060 facetNormal: a normal to a facet to split into triangles of a
5061 hexahedron found by *startHexPoint*.
5062 *facetNormal* can be either a triple of coordinates or an edge.
5063 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5064 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5065 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5066 to *startHexPoint* are split, else *startHexPoint*
5067 is used to find the facet to split in all domains present in *elems*.
5070 This operation can create gaps in numeration of elements.
5071 Call :meth:`RenumberElements` to remove the gaps.
5074 unRegister = genObjUnRegister()
5075 if isinstance( elems, Mesh ):
5076 elems = elems.GetMesh()
5077 if ( isinstance( elems, list )):
5078 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5079 unRegister.set( elems )
5082 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5083 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5084 elif isinstance( startHexPoint, list ):
5085 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5088 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5089 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5090 elif isinstance( facetNormal, list ):
5091 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5094 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5096 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5098 def SplitQuadsNearTriangularFacets(self):
5100 Split quadrangle faces near triangular facets of volumes
5103 This operation can create gaps in numeration of elements.
5104 Call :meth:`RenumberElements` to remove the gaps.
5106 faces_array = self.GetElementsByType(SMESH.FACE)
5107 for face_id in faces_array:
5108 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5109 quad_nodes = self.mesh.GetElemNodes(face_id)
5110 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5111 isVolumeFound = False
5112 for node1_elem in node1_elems:
5113 if not isVolumeFound:
5114 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5115 nb_nodes = self.GetElemNbNodes(node1_elem)
5116 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5117 volume_elem = node1_elem
5118 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5119 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5120 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5121 isVolumeFound = True
5122 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5123 self.SplitQuad([face_id], False) # diagonal 2-4
5124 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5125 isVolumeFound = True
5126 self.SplitQuad([face_id], True) # diagonal 1-3
5127 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5128 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5129 isVolumeFound = True
5130 self.SplitQuad([face_id], True) # diagonal 1-3
5132 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5134 Split hexahedrons into tetrahedrons.
5136 This operation uses :doc:`pattern_mapping` functionality for splitting.
5139 theObject: the object from which the list of hexahedrons is taken;
5140 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5141 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5142 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5143 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5144 key-point will be mapped into *theNode001*-th node of each volume.
5145 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5148 True in case of success, False otherwise.
5151 This operation can create gaps in numeration of elements.
5152 Call :meth:`RenumberElements` to remove the gaps.
5160 # (0,0,1) 4.---------.7 * |
5167 # (0,0,0) 0.---------.3
5168 pattern_tetra = "!!! Nb of points: \n 8 \n\
5178 !!! Indices of points of 6 tetras: \n\
5186 pattern = self.smeshpyD.GetPattern()
5187 isDone = pattern.LoadFromFile(pattern_tetra)
5189 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5192 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5193 isDone = pattern.MakeMesh(self.mesh, False, False)
5194 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5196 # split quafrangle faces near triangular facets of volumes
5197 self.SplitQuadsNearTriangularFacets()
5201 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5203 Split hexahedrons into prisms.
5205 Uses the :doc:`pattern_mapping` functionality for splitting.
5208 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5209 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5210 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5211 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5212 will be mapped into the *theNode001* -th node of each volume.
5213 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5216 True in case of success, False otherwise.
5219 This operation can create gaps in numeration of elements.
5220 Call :meth:`RenumberElements` to remove the gaps.
5222 # Pattern: 5.---------.6
5227 # (0,0,1) 4.---------.7 |
5234 # (0,0,0) 0.---------.3
5235 pattern_prism = "!!! Nb of points: \n 8 \n\
5245 !!! Indices of points of 2 prisms: \n\
5249 pattern = self.smeshpyD.GetPattern()
5250 isDone = pattern.LoadFromFile(pattern_prism)
5252 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5255 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5256 isDone = pattern.MakeMesh(self.mesh, False, False)
5257 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5259 # Split quafrangle faces near triangular facets of volumes
5260 self.SplitQuadsNearTriangularFacets()
5264 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5265 MaxNbOfIterations, MaxAspectRatio, Method):
5270 IDsOfElements: the list if ids of elements to smooth
5271 IDsOfFixedNodes: the list of ids of fixed nodes.
5272 Note that nodes built on edges and boundary nodes are always fixed.
5273 MaxNbOfIterations: the maximum number of iterations
5274 MaxAspectRatio: varies in range [1.0, inf]
5275 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5276 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5279 True in case of success, False otherwise.
5282 if IDsOfElements == []:
5283 IDsOfElements = self.GetElementsId()
5284 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5285 self.mesh.SetParameters(Parameters)
5286 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5287 MaxNbOfIterations, MaxAspectRatio, Method)
5289 def SmoothObject(self, theObject, IDsOfFixedNodes,
5290 MaxNbOfIterations, MaxAspectRatio, Method):
5292 Smooth elements which belong to the given object
5295 theObject: the object to smooth
5296 IDsOfFixedNodes: the list of ids of fixed nodes.
5297 Note that nodes built on edges and boundary nodes are always fixed.
5298 MaxNbOfIterations: the maximum number of iterations
5299 MaxAspectRatio: varies in range [1.0, inf]
5300 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5301 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5304 True in case of success, False otherwise.
5307 if ( isinstance( theObject, Mesh )):
5308 theObject = theObject.GetMesh()
5309 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5310 MaxNbOfIterations, MaxAspectRatio, Method)
5312 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5313 MaxNbOfIterations, MaxAspectRatio, Method):
5315 Parametrically smooth the given elements
5318 IDsOfElements: the list if ids of elements to smooth
5319 IDsOfFixedNodes: the list of ids of fixed nodes.
5320 Note that nodes built on edges and boundary nodes are always fixed.
5321 MaxNbOfIterations: the maximum number of iterations
5322 MaxAspectRatio: varies in range [1.0, inf]
5323 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5324 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5327 True in case of success, False otherwise.
5330 if IDsOfElements == []:
5331 IDsOfElements = self.GetElementsId()
5332 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5333 self.mesh.SetParameters(Parameters)
5334 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5335 MaxNbOfIterations, MaxAspectRatio, Method)
5337 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5338 MaxNbOfIterations, MaxAspectRatio, Method):
5340 Parametrically smooth the elements which belong to the given object
5343 theObject: the object to smooth
5344 IDsOfFixedNodes: the list of ids of fixed nodes.
5345 Note that nodes built on edges and boundary nodes are always fixed.
5346 MaxNbOfIterations: the maximum number of iterations
5347 MaxAspectRatio: varies in range [1.0, inf]
5348 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5349 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5352 True in case of success, False otherwise.
5355 if ( isinstance( theObject, Mesh )):
5356 theObject = theObject.GetMesh()
5357 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5358 MaxNbOfIterations, MaxAspectRatio, Method)
5360 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5362 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5363 them with quadratic with the same id.
5366 theForce3d: method of new node creation:
5368 * False - the medium node lies at the geometrical entity from which the mesh element is built
5369 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5370 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5371 theToBiQuad: If True, converts the mesh to bi-quadratic
5374 :class:`SMESH.ComputeError` which can hold a warning
5377 If *theSubMesh* is provided, the mesh can become non-conformal
5380 This operation can create gaps in numeration of nodes or elements.
5381 Call :meth:`RenumberElements` to remove the gaps.
5384 if isinstance( theSubMesh, Mesh ):
5385 theSubMesh = theSubMesh.mesh
5387 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5390 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5392 self.editor.ConvertToQuadratic(theForce3d)
5393 error = self.editor.GetLastError()
5394 if error and error.comment:
5395 print(error.comment)
5398 def ConvertFromQuadratic(self, theSubMesh=None):
5400 Convert the mesh from quadratic to ordinary,
5401 deletes old quadratic elements,
5402 replacing them with ordinary mesh elements with the same id.
5405 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5408 If *theSubMesh* is provided, the mesh can become non-conformal
5411 This operation can create gaps in numeration of nodes or elements.
5412 Call :meth:`RenumberElements` to remove the gaps.
5416 self.editor.ConvertFromQuadraticObject(theSubMesh)
5418 return self.editor.ConvertFromQuadratic()
5420 def Make2DMeshFrom3D(self):
5422 Create 2D mesh as skin on boundary faces of a 3D mesh
5425 True if operation has been completed successfully, False otherwise
5428 return self.editor.Make2DMeshFrom3D()
5430 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5431 toCopyElements=False, toCopyExistingBondary=False):
5433 Create missing boundary elements
5436 elements: elements whose boundary is to be checked:
5437 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5438 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5439 dimension: defines type of boundary elements to create, either of
5440 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5441 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5442 groupName: a name of group to store created boundary elements in,
5443 "" means not to create the group
5444 meshName: a name of new mesh to store created boundary elements in,
5445 "" means not to create the new mesh
5446 toCopyElements: if True, the checked elements will be copied into
5447 the new mesh else only boundary elements will be copied into the new mesh
5448 toCopyExistingBondary: if True, not only new but also pre-existing
5449 boundary elements will be copied into the new mesh
5452 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5455 unRegister = genObjUnRegister()
5456 if isinstance( elements, Mesh ):
5457 elements = elements.GetMesh()
5458 if ( isinstance( elements, list )):
5459 elemType = SMESH.ALL
5460 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5461 elements = self.editor.MakeIDSource(elements, elemType)
5462 unRegister.set( elements )
5463 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5464 toCopyElements,toCopyExistingBondary)
5465 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5468 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5469 toCopyAll=False, groups=[]):
5471 Create missing boundary elements around either the whole mesh or
5475 dimension: defines type of boundary elements to create, either of
5476 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5477 groupName: a name of group to store all boundary elements in,
5478 "" means not to create the group
5479 meshName: a name of a new mesh, which is a copy of the initial
5480 mesh + created boundary elements; "" means not to create the new mesh
5481 toCopyAll: if True, the whole initial mesh will be copied into
5482 the new mesh else only boundary elements will be copied into the new mesh
5483 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5486 tuple( long, mesh, group )
5487 - long - number of added boundary elements
5488 - mesh - the :class:`Mesh` where elements were added to
5489 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5492 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5494 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5495 return nb, mesh, group
5497 def RenumberNodes(self):
5499 Renumber mesh nodes to remove unused node IDs
5501 self.editor.RenumberNodes()
5503 def RenumberElements(self):
5505 Renumber mesh elements to remove unused element IDs
5507 self.editor.RenumberElements()
5509 def _getIdSourceList(self, arg, idType, unRegister):
5511 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5513 if arg and isinstance( arg, list ):
5514 if isinstance( arg[0], int ):
5515 arg = self.GetIDSource( arg, idType )
5516 unRegister.set( arg )
5517 elif isinstance( arg[0], Mesh ):
5518 arg[0] = arg[0].GetMesh()
5519 elif isinstance( arg, Mesh ):
5521 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5525 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5526 MakeGroups=False, TotalAngle=False):
5528 Generate new elements by rotation of the given elements and nodes around the axis
5531 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5532 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5533 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5534 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5535 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5536 which defines angle in degrees
5537 NbOfSteps: the number of steps
5538 Tolerance: tolerance
5539 MakeGroups: forces the generation of new groups from existing ones
5540 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5541 of all steps, else - size of each step
5544 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5547 unRegister = genObjUnRegister()
5548 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5549 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5550 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5552 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5553 Axis = self.smeshpyD.GetAxisStruct( Axis )
5554 if isinstance( Axis, list ):
5555 Axis = SMESH.AxisStruct( *Axis )
5557 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5558 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5559 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5560 self.mesh.SetParameters(Parameters)
5561 if TotalAngle and NbOfSteps:
5562 AngleInRadians /= NbOfSteps
5563 return self.editor.RotationSweepObjects( nodes, edges, faces,
5564 Axis, AngleInRadians,
5565 NbOfSteps, Tolerance, MakeGroups)
5567 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5568 MakeGroups=False, TotalAngle=False):
5570 Generate new elements by rotation of the elements around the axis
5573 IDsOfElements: the list of ids of elements to sweep
5574 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5575 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5576 NbOfSteps: the number of steps
5577 Tolerance: tolerance
5578 MakeGroups: forces the generation of new groups from existing ones
5579 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5580 of all steps, else - size of each step
5583 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5586 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5587 AngleInRadians, NbOfSteps, Tolerance,
5588 MakeGroups, TotalAngle)
5590 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5591 MakeGroups=False, TotalAngle=False):
5593 Generate new elements by rotation of the elements of object around the axis
5594 theObject object which elements should be sweeped.
5595 It can be a mesh, a sub mesh or a group.
5598 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5599 AngleInRadians: the angle of Rotation
5600 NbOfSteps: number of steps
5601 Tolerance: tolerance
5602 MakeGroups: forces the generation of new groups from existing ones
5603 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5604 of all steps, else - size of each step
5607 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5610 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5611 AngleInRadians, NbOfSteps, Tolerance,
5612 MakeGroups, TotalAngle )
5614 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5615 MakeGroups=False, TotalAngle=False):
5617 Generate new elements by rotation of the elements of object around the axis
5618 theObject object which elements should be sweeped.
5619 It can be a mesh, a sub mesh or a group.
5622 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5623 AngleInRadians: the angle of Rotation
5624 NbOfSteps: number of steps
5625 Tolerance: tolerance
5626 MakeGroups: forces the generation of new groups from existing ones
5627 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5628 of all steps, else - size of each step
5631 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5632 empty list otherwise
5635 return self.RotationSweepObjects([],theObject,[], Axis,
5636 AngleInRadians, NbOfSteps, Tolerance,
5637 MakeGroups, TotalAngle)
5639 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5640 MakeGroups=False, TotalAngle=False):
5642 Generate new elements by rotation of the elements of object around the axis
5643 theObject object which elements should be sweeped.
5644 It can be a mesh, a sub mesh or a group.
5647 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5648 AngleInRadians: the angle of Rotation
5649 NbOfSteps: number of steps
5650 Tolerance: tolerance
5651 MakeGroups: forces the generation of new groups from existing ones
5652 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5653 of all steps, else - size of each step
5656 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5659 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5660 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5662 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5663 scaleFactors=[], linearVariation=False, basePoint=[],
5664 angles=[], anglesVariation=False):
5666 Generate new elements by extrusion of the given elements and nodes
5669 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5670 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5671 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5672 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5673 the direction and value of extrusion for one step (the total extrusion
5674 length will be NbOfSteps * ||StepVector||)
5675 NbOfSteps: the number of steps
5676 MakeGroups: forces the generation of new groups from existing ones
5677 scaleFactors: optional scale factors to apply during extrusion
5678 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5679 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5680 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5681 nodes and elements being extruded is used as the scaling center.
5684 - a list of tree components of the point or
5687 angles: list of angles in radians. Nodes at each extrusion step are rotated
5688 around *basePoint*, additionally to previous steps.
5689 anglesVariation: forces the computation of rotation angles as linear
5690 variation of the given *angles* along path steps
5692 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5694 Example: :ref:`tui_extrusion`
5696 unRegister = genObjUnRegister()
5697 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5698 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5699 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5701 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5702 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5703 if isinstance( StepVector, list ):
5704 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5706 if isinstance( basePoint, int):
5707 xyz = self.GetNodeXYZ( basePoint )
5709 raise RuntimeError("Invalid node ID: %s" % basePoint)
5711 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5712 basePoint = self.geompyD.PointCoordinates( basePoint )
5714 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5715 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5716 angles,angleParameters,hasVars = ParseAngles(angles)
5717 Parameters = StepVector.PS.parameters + var_separator + \
5718 Parameters + var_separator + \
5719 scaleParameters + var_separator + angleParameters
5720 self.mesh.SetParameters(Parameters)
5722 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5723 StepVector, NbOfSteps, MakeGroups,
5724 scaleFactors, linearVariation, basePoint,
5725 angles, anglesVariation )
5728 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5730 Generate new elements by extrusion of the elements with given ids
5733 IDsOfElements: the list of ids of elements or nodes for extrusion
5734 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5735 the direction and value of extrusion for one step (the total extrusion
5736 length will be NbOfSteps * ||StepVector||)
5737 NbOfSteps: the number of steps
5738 MakeGroups: forces the generation of new groups from existing ones
5739 IsNodes: is True if elements with given ids are nodes
5742 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5744 Example: :ref:`tui_extrusion`
5747 if IsNodes: n = IDsOfElements
5748 else : e,f, = IDsOfElements,IDsOfElements
5749 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5751 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5752 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5754 Generate new elements by extrusion along the normal to a discretized surface or wire
5757 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5758 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5759 StepSize: length of one extrusion step (the total extrusion
5760 length will be *NbOfSteps* *StepSize*).
5761 NbOfSteps: number of extrusion steps.
5762 ByAverageNormal: if True each node is translated by *StepSize*
5763 along the average of the normal vectors to the faces sharing the node;
5764 else each node is translated along the same average normal till
5765 intersection with the plane got by translation of the face sharing
5766 the node along its own normal by *StepSize*.
5767 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5768 for every node of *Elements*.
5769 MakeGroups: forces generation of new groups from existing ones.
5770 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5771 is not yet implemented. This parameter is used if *Elements* contains
5772 both faces and edges, i.e. *Elements* is a Mesh.
5775 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5776 empty list otherwise.
5777 Example: :ref:`tui_extrusion`
5780 unRegister = genObjUnRegister()
5781 if isinstance( Elements, Mesh ):
5782 Elements = [ Elements.GetMesh() ]
5783 if isinstance( Elements, list ):
5785 raise RuntimeError("Elements empty!")
5786 if isinstance( Elements[0], Mesh ):
5787 Elements = [ Elements[0].GetMesh() ]
5788 if isinstance( Elements[0], int ):
5789 Elements = self.GetIDSource( Elements, SMESH.ALL )
5790 unRegister.set( Elements )
5791 if not isinstance( Elements, list ):
5792 Elements = [ Elements ]
5793 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5794 self.mesh.SetParameters(Parameters)
5795 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5796 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5798 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5800 Generate new elements by extrusion of the elements or nodes which belong to the object
5803 theObject: the object whose elements or nodes should be processed.
5804 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5805 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5806 the direction and value of extrusion for one step (the total extrusion
5807 length will be NbOfSteps * ||StepVector||)
5808 NbOfSteps: the number of steps
5809 MakeGroups: forces the generation of new groups from existing ones
5810 IsNodes: is True if elements to extrude are nodes
5813 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5814 Example: :ref:`tui_extrusion`
5818 if IsNodes: n = theObject
5819 else : e,f, = theObject,theObject
5820 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5822 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5824 Generate new elements by extrusion of edges which belong to the object
5827 theObject: object whose 1D elements should be processed.
5828 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5829 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5830 the direction and value of extrusion for one step (the total extrusion
5831 length will be NbOfSteps * ||StepVector||)
5832 NbOfSteps: the number of steps
5833 MakeGroups: to generate new groups from existing ones
5836 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5837 Example: :ref:`tui_extrusion`
5840 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5842 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5844 Generate new elements by extrusion of faces which belong to the object
5847 theObject: object whose 2D elements should be processed.
5848 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5849 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5850 the direction and value of extrusion for one step (the total extrusion
5851 length will be NbOfSteps * ||StepVector||)
5852 NbOfSteps: the number of steps
5853 MakeGroups: forces the generation of new groups from existing ones
5856 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5857 Example: :ref:`tui_extrusion`
5860 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5862 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5863 ExtrFlags, SewTolerance, MakeGroups=False):
5865 Generate new elements by extrusion of the elements with given ids
5868 IDsOfElements: is ids of elements
5869 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5870 the direction and value of extrusion for one step (the total extrusion
5871 length will be NbOfSteps * ||StepVector||)
5872 NbOfSteps: the number of steps
5873 ExtrFlags: sets flags for extrusion
5874 SewTolerance: uses for comparing locations of nodes if flag
5875 EXTRUSION_FLAG_SEW is set
5876 MakeGroups: forces the generation of new groups from existing ones
5879 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5882 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5883 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5884 if isinstance( StepVector, list ):
5885 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5886 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5887 ExtrFlags, SewTolerance, MakeGroups)
5889 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5890 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5891 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5892 ScaleFactors=[], ScalesVariation=False):
5894 Generate new elements by extrusion of the given elements and nodes along the path.
5895 The path of extrusion must be a meshed edge.
5898 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5899 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5900 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5901 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5902 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
5903 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5904 HasAngles: not used obsolete
5905 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5906 around *basePoint*, additionally to previous steps.
5907 LinearVariation: forces the computation of rotation angles as linear
5908 variation of the given Angles along path steps
5909 HasRefPoint: allows using the reference point
5910 RefPoint: optional scaling and rotation center (mass center of the extruded
5911 elements by default). The User can specify any point as the Reference Point.
5912 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5913 MakeGroups: forces the generation of new groups from existing ones
5914 ScaleFactors: optional scale factors to apply during extrusion
5915 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5916 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5919 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5920 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5921 Example: :ref:`tui_extrusion_along_path`
5924 unRegister = genObjUnRegister()
5925 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5926 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5927 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5929 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5930 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5931 if isinstance( RefPoint, list ):
5932 if not RefPoint: RefPoint = [0,0,0]
5933 RefPoint = SMESH.PointStruct( *RefPoint )
5934 if isinstance( PathObject, Mesh ):
5935 PathObject = PathObject.GetMesh()
5936 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5937 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5938 Parameters = AnglesParameters + var_separator + \
5939 RefPoint.parameters + var_separator + ScalesParameters
5940 self.mesh.SetParameters(Parameters)
5941 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5942 PathObject, PathShape, NodeStart,
5943 HasAngles, Angles, LinearVariation,
5944 HasRefPoint, RefPoint, MakeGroups,
5945 ScaleFactors, ScalesVariation)
5947 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5948 HasAngles=False, Angles=[], LinearVariation=False,
5949 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5950 ElemType=SMESH.FACE):
5952 Generate new elements by extrusion of the given elements.
5953 The path of extrusion must be a meshed edge.
5956 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5957 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5958 NodeStart: the start node from Path. Defines the direction of extrusion
5959 HasAngles: not used obsolete
5960 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5961 around *basePoint*, additionally to previous steps.
5962 LinearVariation: forces the computation of rotation angles as linear
5963 variation of the given Angles along path steps
5964 HasRefPoint: allows using the reference point
5965 RefPoint: the reference point around which the elements are rotated (the mass
5966 center of the elements by default).
5967 The User can specify any point as the Reference Point.
5968 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5969 MakeGroups: forces the generation of new groups from existing ones
5970 ElemType: type of elements for extrusion (if param Base is a mesh)
5973 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5974 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5975 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5977 Example: :ref:`tui_extrusion_along_path`
5981 if ElemType == SMESH.NODE: n = Base
5982 if ElemType == SMESH.EDGE: e = Base
5983 if ElemType == SMESH.FACE: f = Base
5984 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5985 HasAngles, Angles, LinearVariation,
5986 HasRefPoint, RefPoint, MakeGroups)
5987 if MakeGroups: return gr,er
5990 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5991 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5992 MakeGroups=False, LinearVariation=False):
5994 Generate new elements by extrusion of the given elements.
5995 The path of extrusion must be a meshed edge.
5998 IDsOfElements: ids of elements
5999 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6000 PathShape: shape (edge) defines the sub-mesh for the path
6001 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6002 HasAngles: not used obsolete
6003 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6004 around *basePoint*, additionally to previous steps.
6005 HasRefPoint: allows using the reference point
6006 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6007 The User can specify any point as the Reference Point.
6008 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6009 MakeGroups: forces the generation of new groups from existing ones
6010 LinearVariation: forces the computation of rotation angles as linear
6011 variation of the given Angles along path steps
6014 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6015 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6016 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6017 Example: :ref:`tui_extrusion_along_path`
6020 if not IDsOfElements:
6021 IDsOfElements = [ self.GetMesh() ]
6022 n,e,f = [],IDsOfElements,IDsOfElements
6023 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6024 NodeStart, HasAngles, Angles,
6026 HasRefPoint, RefPoint, MakeGroups)
6027 if MakeGroups: return gr,er
6030 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6031 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6032 MakeGroups=False, LinearVariation=False):
6034 Generate new elements by extrusion of the elements which belong to the object.
6035 The path of extrusion must be a meshed edge.
6038 theObject: the object whose elements should be processed.
6039 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6040 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6041 PathShape: shape (edge) defines the sub-mesh for the path
6042 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6043 HasAngles: not used obsolete
6044 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6045 around *basePoint*, additionally to previous steps.
6046 HasRefPoint: allows using the reference point
6047 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6048 The User can specify any point as the Reference Point.
6049 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6050 MakeGroups: forces the generation of new groups from existing ones
6051 LinearVariation: forces the computation of rotation angles as linear
6052 variation of the given Angles along path steps
6055 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6056 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6057 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6058 Example: :ref:`tui_extrusion_along_path`
6061 n,e,f = [],theObject,theObject
6062 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6063 HasAngles, Angles, LinearVariation,
6064 HasRefPoint, RefPoint, MakeGroups)
6065 if MakeGroups: return gr,er
6068 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6069 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6070 MakeGroups=False, LinearVariation=False):
6072 Generate new elements by extrusion of mesh segments which belong to the object.
6073 The path of extrusion must be a meshed edge.
6076 theObject: the object whose 1D elements should be processed.
6077 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6078 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6079 PathShape: shape (edge) defines the sub-mesh for the path
6080 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6081 HasAngles: not used obsolete
6082 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6083 around *basePoint*, additionally to previous steps.
6084 HasRefPoint: allows using the reference point
6085 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6086 The User can specify any point as the Reference Point.
6087 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6088 MakeGroups: forces the generation of new groups from existing ones
6089 LinearVariation: forces the computation of rotation angles as linear
6090 variation of the given Angles along path steps
6093 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6094 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6095 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6096 Example: :ref:`tui_extrusion_along_path`
6099 n,e,f = [],theObject,[]
6100 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6101 HasAngles, Angles, LinearVariation,
6102 HasRefPoint, RefPoint, MakeGroups)
6103 if MakeGroups: return gr,er
6106 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6107 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6108 MakeGroups=False, LinearVariation=False):
6110 Generate new elements by extrusion of faces which belong to the object.
6111 The path of extrusion must be a meshed edge.
6114 theObject: the object whose 2D elements should be processed.
6115 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6116 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6117 PathShape: shape (edge) defines the sub-mesh for the path
6118 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6119 HasAngles: not used obsolete
6120 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6121 around *basePoint*, additionally to previous steps.
6122 HasRefPoint: allows using the reference point
6123 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6124 The User can specify any point as the Reference Point.
6125 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6126 MakeGroups: forces the generation of new groups from existing ones
6127 LinearVariation: forces the computation of rotation angles as linear
6128 variation of the given Angles along path steps
6131 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6132 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6133 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6134 Example: :ref:`tui_extrusion_along_path`
6137 n,e,f = [],[],theObject
6138 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6139 HasAngles, Angles, LinearVariation,
6140 HasRefPoint, RefPoint, MakeGroups)
6141 if MakeGroups: return gr,er
6144 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6146 Create a symmetrical copy of mesh elements
6149 IDsOfElements: list of elements ids
6150 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6151 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6152 If the *Mirror* is a geom object this parameter is unnecessary
6153 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6154 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6157 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6160 if IDsOfElements == []:
6161 IDsOfElements = self.GetElementsId()
6162 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6163 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6164 theMirrorType = Mirror._mirrorType
6166 self.mesh.SetParameters(Mirror.parameters)
6167 if Copy and MakeGroups:
6168 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6169 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6172 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6174 Create a new mesh by a symmetrical copy of mesh elements
6177 IDsOfElements: the list of elements ids
6178 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6179 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6180 If the *Mirror* is a geom object this parameter is unnecessary
6181 MakeGroups: to generate new groups from existing ones
6182 NewMeshName: a name of the new mesh to create
6185 instance of class :class:`Mesh`
6188 if IDsOfElements == []:
6189 IDsOfElements = self.GetElementsId()
6190 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6191 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6192 theMirrorType = Mirror._mirrorType
6194 self.mesh.SetParameters(Mirror.parameters)
6195 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6196 MakeGroups, NewMeshName)
6197 return Mesh(self.smeshpyD,self.geompyD,mesh)
6199 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6201 Create a symmetrical copy of the object
6204 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6205 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6206 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6207 If the *Mirror* is a geom object this parameter is unnecessary
6208 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6209 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6212 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6215 if ( isinstance( theObject, Mesh )):
6216 theObject = theObject.GetMesh()
6217 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6218 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6219 theMirrorType = Mirror._mirrorType
6221 self.mesh.SetParameters(Mirror.parameters)
6222 if Copy and MakeGroups:
6223 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6224 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6227 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6229 Create a new mesh by a symmetrical copy of the object
6232 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6233 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6234 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6235 If the *Mirror* is a geom object this parameter is unnecessary
6236 MakeGroups: forces the generation of new groups from existing ones
6237 NewMeshName: the name of the new mesh to create
6240 instance of class :class:`Mesh`
6243 if ( isinstance( theObject, Mesh )):
6244 theObject = theObject.GetMesh()
6245 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6246 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6247 theMirrorType = Mirror._mirrorType
6249 self.mesh.SetParameters(Mirror.parameters)
6250 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6251 MakeGroups, NewMeshName)
6252 return Mesh( self.smeshpyD,self.geompyD,mesh )
6254 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6256 Translate the elements
6259 IDsOfElements: list of elements ids
6260 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6261 Copy: allows copying the translated elements
6262 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6265 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6268 if IDsOfElements == []:
6269 IDsOfElements = self.GetElementsId()
6270 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6271 Vector = self.smeshpyD.GetDirStruct(Vector)
6272 if isinstance( Vector, list ):
6273 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6274 self.mesh.SetParameters(Vector.PS.parameters)
6275 if Copy and MakeGroups:
6276 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6277 self.editor.Translate(IDsOfElements, Vector, Copy)
6280 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6282 Create a new mesh of translated elements
6285 IDsOfElements: list of elements ids
6286 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6287 MakeGroups: forces the generation of new groups from existing ones
6288 NewMeshName: the name of the newly created mesh
6291 instance of class :class:`Mesh`
6294 if IDsOfElements == []:
6295 IDsOfElements = self.GetElementsId()
6296 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6297 Vector = self.smeshpyD.GetDirStruct(Vector)
6298 if isinstance( Vector, list ):
6299 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6300 self.mesh.SetParameters(Vector.PS.parameters)
6301 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6302 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6304 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6306 Translate the object
6309 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6310 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6311 Copy: allows copying the translated elements
6312 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6315 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6318 if ( isinstance( theObject, Mesh )):
6319 theObject = theObject.GetMesh()
6320 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6321 Vector = self.smeshpyD.GetDirStruct(Vector)
6322 if isinstance( Vector, list ):
6323 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6324 self.mesh.SetParameters(Vector.PS.parameters)
6325 if Copy and MakeGroups:
6326 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6327 self.editor.TranslateObject(theObject, Vector, Copy)
6330 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6332 Create a new mesh from the translated object
6335 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6336 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6337 MakeGroups: forces the generation of new groups from existing ones
6338 NewMeshName: the name of the newly created mesh
6341 instance of class :class:`Mesh`
6344 if isinstance( theObject, Mesh ):
6345 theObject = theObject.GetMesh()
6346 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6347 Vector = self.smeshpyD.GetDirStruct(Vector)
6348 if isinstance( Vector, list ):
6349 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6350 self.mesh.SetParameters(Vector.PS.parameters)
6351 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6352 return Mesh( self.smeshpyD, self.geompyD, mesh )
6356 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6361 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6362 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6363 theScaleFact: list of 1-3 scale factors for axises
6364 Copy: allows copying the translated elements
6365 MakeGroups: forces the generation of new groups from existing
6369 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6370 empty list otherwise
6372 unRegister = genObjUnRegister()
6373 if ( isinstance( theObject, Mesh )):
6374 theObject = theObject.GetMesh()
6375 if ( isinstance( theObject, list )):
6376 theObject = self.GetIDSource(theObject, SMESH.ALL)
6377 unRegister.set( theObject )
6378 if ( isinstance( thePoint, list )):
6379 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6380 if ( isinstance( theScaleFact, float )):
6381 theScaleFact = [theScaleFact]
6382 if ( isinstance( theScaleFact, int )):
6383 theScaleFact = [ float(theScaleFact)]
6385 self.mesh.SetParameters(thePoint.parameters)
6387 if Copy and MakeGroups:
6388 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6389 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6392 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6394 Create a new mesh from the translated object
6397 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6398 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6399 theScaleFact: list of 1-3 scale factors for axises
6400 MakeGroups: forces the generation of new groups from existing ones
6401 NewMeshName: the name of the newly created mesh
6404 instance of class :class:`Mesh`
6406 unRegister = genObjUnRegister()
6407 if (isinstance(theObject, Mesh)):
6408 theObject = theObject.GetMesh()
6409 if ( isinstance( theObject, list )):
6410 theObject = self.GetIDSource(theObject,SMESH.ALL)
6411 unRegister.set( theObject )
6412 if ( isinstance( thePoint, list )):
6413 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6414 if ( isinstance( theScaleFact, float )):
6415 theScaleFact = [theScaleFact]
6416 if ( isinstance( theScaleFact, int )):
6417 theScaleFact = [ float(theScaleFact)]
6419 self.mesh.SetParameters(thePoint.parameters)
6420 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6421 MakeGroups, NewMeshName)
6422 return Mesh( self.smeshpyD, self.geompyD, mesh )
6426 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6431 IDsOfElements: list of elements ids
6432 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6433 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6434 Copy: allows copying the rotated elements
6435 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6438 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6442 if IDsOfElements == []:
6443 IDsOfElements = self.GetElementsId()
6444 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6445 Axis = self.smeshpyD.GetAxisStruct(Axis)
6446 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6447 Parameters = Axis.parameters + var_separator + Parameters
6448 self.mesh.SetParameters(Parameters)
6449 if Copy and MakeGroups:
6450 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6451 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6454 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6456 Create a new mesh of rotated elements
6459 IDsOfElements: list of element ids
6460 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6461 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6462 MakeGroups: forces the generation of new groups from existing ones
6463 NewMeshName: the name of the newly created mesh
6466 instance of class :class:`Mesh`
6469 if IDsOfElements == []:
6470 IDsOfElements = self.GetElementsId()
6471 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6472 Axis = self.smeshpyD.GetAxisStruct(Axis)
6473 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6474 Parameters = Axis.parameters + var_separator + Parameters
6475 self.mesh.SetParameters(Parameters)
6476 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6477 MakeGroups, NewMeshName)
6478 return Mesh( self.smeshpyD, self.geompyD, mesh )
6480 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6485 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6486 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6487 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6488 Copy: allows copying the rotated elements
6489 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6492 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6495 if (isinstance(theObject, Mesh)):
6496 theObject = theObject.GetMesh()
6497 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6498 Axis = self.smeshpyD.GetAxisStruct(Axis)
6499 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6500 Parameters = Axis.parameters + ":" + Parameters
6501 self.mesh.SetParameters(Parameters)
6502 if Copy and MakeGroups:
6503 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6504 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6507 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6509 Create a new mesh from the rotated object
6512 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6513 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6514 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6515 MakeGroups: forces the generation of new groups from existing ones
6516 NewMeshName: the name of the newly created mesh
6519 instance of class :class:`Mesh`
6522 if (isinstance( theObject, Mesh )):
6523 theObject = theObject.GetMesh()
6524 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6525 Axis = self.smeshpyD.GetAxisStruct(Axis)
6526 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6527 Parameters = Axis.parameters + ":" + Parameters
6528 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6529 MakeGroups, NewMeshName)
6530 self.mesh.SetParameters(Parameters)
6531 return Mesh( self.smeshpyD, self.geompyD, mesh )
6533 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6535 Create an offset mesh from the given 2D object
6538 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6539 theValue (float): signed offset size
6540 MakeGroups (boolean): forces the generation of new groups from existing ones
6541 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6542 False means to remove original elements.
6543 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6546 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6549 if isinstance( theObject, Mesh ):
6550 theObject = theObject.GetMesh()
6551 theValue,Parameters,hasVars = ParseParameters(Value)
6552 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6553 self.mesh.SetParameters(Parameters)
6555 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6558 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6560 Find groups of adjacent nodes within Tolerance.
6563 Tolerance (float): the value of tolerance
6564 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6565 corner and medium nodes in separate groups thus preventing
6566 their further merge.
6569 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6572 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6574 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6575 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6577 Find groups of adjacent nodes within Tolerance.
6580 Tolerance: the value of tolerance
6581 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6582 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6583 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6584 corner and medium nodes in separate groups thus preventing
6585 their further merge.
6588 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6591 unRegister = genObjUnRegister()
6592 if not isinstance( SubMeshOrGroup, list ):
6593 SubMeshOrGroup = [ SubMeshOrGroup ]
6594 for i,obj in enumerate( SubMeshOrGroup ):
6595 if isinstance( obj, Mesh ):
6596 SubMeshOrGroup = [ obj.GetMesh() ]
6598 if isinstance( obj, int ):
6599 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6600 unRegister.set( SubMeshOrGroup )
6603 if not isinstance( exceptNodes, list ):
6604 exceptNodes = [ exceptNodes ]
6605 if exceptNodes and isinstance( exceptNodes[0], int ):
6606 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6607 unRegister.set( exceptNodes )
6609 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6610 exceptNodes, SeparateCornerAndMediumNodes)
6612 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6617 GroupsOfNodes: a list of groups of nodes IDs for merging.
6618 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6619 in all elements and mesh groups by nodes 1 and 25 correspondingly
6620 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6621 If *NodesToKeep* does not include a node to keep for some group to merge,
6622 then the first node in the group is kept.
6623 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6627 This operation can create gaps in numeration of nodes or elements.
6628 Call :meth:`RenumberElements` to remove the gaps.
6630 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6632 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6634 Find the elements built on the same nodes.
6637 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6638 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6642 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6645 unRegister = genObjUnRegister()
6646 if MeshOrSubMeshOrGroup is None:
6647 MeshOrSubMeshOrGroup = [ self.mesh ]
6648 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6649 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6650 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6651 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6652 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6653 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6654 unRegister.set( MeshOrSubMeshOrGroup )
6655 for item in MeshOrSubMeshOrGroup:
6656 if isinstance( item, Mesh ):
6657 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6659 if not isinstance( exceptElements, list ):
6660 exceptElements = [ exceptElements ]
6661 if exceptElements and isinstance( exceptElements[0], int ):
6662 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6663 unRegister.set( exceptElements )
6665 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6667 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6669 Merge elements in each given group.
6672 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6673 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6674 replaced in all mesh groups by elements 1 and 25)
6675 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6676 If *ElementsToKeep* does not include an element to keep for some group to merge,
6677 then the first element in the group is kept.
6680 This operation can create gaps in numeration of elements.
6681 Call :meth:`RenumberElements` to remove the gaps.
6684 unRegister = genObjUnRegister()
6686 if not isinstance( ElementsToKeep, list ):
6687 ElementsToKeep = [ ElementsToKeep ]
6688 if isinstance( ElementsToKeep[0], int ):
6689 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6690 unRegister.set( ElementsToKeep )
6692 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6694 def MergeEqualElements(self):
6696 Leave one element and remove all other elements built on the same nodes.
6699 This operation can create gaps in numeration of elements.
6700 Call :meth:`RenumberElements` to remove the gaps.
6703 self.editor.MergeEqualElements()
6705 def FindFreeBorders(self, ClosedOnly=True):
6707 Returns all or only closed free borders
6710 list of SMESH.FreeBorder's
6713 return self.editor.FindFreeBorders( ClosedOnly )
6715 def FillHole(self, holeNodes, groupName=""):
6717 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6720 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6721 must describe all sequential nodes of the hole border. The first and the last
6722 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6723 groupName (string): name of a group to add new faces
6725 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6729 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6730 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6731 if not isinstance( holeNodes, SMESH.FreeBorder ):
6732 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6733 return self.editor.FillHole( holeNodes, groupName )
6735 def FindCoincidentFreeBorders (self, tolerance=0.):
6737 Return groups of FreeBorder's coincident within the given tolerance.
6740 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6741 size of elements adjacent to free borders being compared is used.
6744 SMESH.CoincidentFreeBorders structure
6747 return self.editor.FindCoincidentFreeBorders( tolerance )
6749 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6751 Sew FreeBorder's of each group
6754 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6755 where each enclosed list contains node IDs of a group of coincident free
6756 borders such that each consequent triple of IDs within a group describes
6757 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6758 last node of a border.
6759 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6760 groups of coincident free borders, each group including two borders.
6761 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6762 polygons if a node of opposite border falls on a face edge, else such
6763 faces are split into several ones.
6764 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6765 polyhedra if a node of opposite border falls on a volume edge, else such
6766 volumes, if any, remain intact and the mesh becomes non-conformal.
6769 a number of successfully sewed groups
6772 This operation can create gaps in numeration of nodes or elements.
6773 Call :meth:`RenumberElements` to remove the gaps.
6776 if freeBorders and isinstance( freeBorders, list ):
6777 # construct SMESH.CoincidentFreeBorders
6778 if isinstance( freeBorders[0], int ):
6779 freeBorders = [freeBorders]
6781 coincidentGroups = []
6782 for nodeList in freeBorders:
6783 if not nodeList or len( nodeList ) % 3:
6784 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6787 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6788 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6789 nodeList = nodeList[3:]
6791 coincidentGroups.append( group )
6793 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6795 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6797 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6798 FirstNodeID2, SecondNodeID2, LastNodeID2,
6799 CreatePolygons, CreatePolyedrs):
6804 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6807 This operation can create gaps in numeration of nodes or elements.
6808 Call :meth:`RenumberElements` to remove the gaps.
6811 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6812 FirstNodeID2, SecondNodeID2, LastNodeID2,
6813 CreatePolygons, CreatePolyedrs)
6815 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6816 FirstNodeID2, SecondNodeID2):
6818 Sew conform free borders
6821 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6824 This operation can create gaps in numeration of elements.
6825 Call :meth:`RenumberElements` to remove the gaps.
6828 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6829 FirstNodeID2, SecondNodeID2)
6831 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6832 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6837 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6840 This operation can create gaps in numeration of elements.
6841 Call :meth:`RenumberElements` to remove the gaps.
6844 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6845 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6847 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6848 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6849 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6851 Sew two sides of a mesh. The nodes belonging to Side1 are
6852 merged with the nodes of elements of Side2.
6853 The number of elements in theSide1 and in theSide2 must be
6854 equal and they should have similar nodal connectivity.
6855 The nodes to merge should belong to side borders and
6856 the first node should be linked to the second.
6859 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6862 This operation can create gaps in numeration of nodes.
6863 Call :meth:`RenumberElements` to remove the gaps.
6866 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6867 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6868 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6870 def ChangeElemNodes(self, ide, newIDs):
6872 Set new nodes for the given element. Number of nodes should be kept.
6879 False if the number of nodes does not correspond to the type of element
6882 return self.editor.ChangeElemNodes(ide, newIDs)
6884 def GetLastCreatedNodes(self):
6886 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6887 created, this method return the list of their IDs.
6888 If new nodes were not created - return empty list
6891 the list of integer values (can be empty)
6894 return self.editor.GetLastCreatedNodes()
6896 def GetLastCreatedElems(self):
6898 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6899 created this method return the list of their IDs.
6900 If new elements were not created - return empty list
6903 the list of integer values (can be empty)
6906 return self.editor.GetLastCreatedElems()
6908 def ClearLastCreated(self):
6910 Forget what nodes and elements were created by the last mesh edition operation
6913 self.editor.ClearLastCreated()
6915 def DoubleElements(self, theElements, theGroupName=""):
6917 Create duplicates of given elements, i.e. create new elements based on the
6918 same nodes as the given ones.
6921 theElements: container of elements to duplicate. It can be a
6922 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6923 or a list of element IDs. If *theElements* is
6924 a :class:`Mesh`, elements of highest dimension are duplicated
6925 theGroupName: a name of group to contain the generated elements.
6926 If a group with such a name already exists, the new elements
6927 are added to the existing group, else a new group is created.
6928 If *theGroupName* is empty, new elements are not added
6932 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6933 None if *theGroupName* == "".
6936 unRegister = genObjUnRegister()
6937 if isinstance( theElements, Mesh ):
6938 theElements = theElements.mesh
6939 elif isinstance( theElements, list ):
6940 theElements = self.GetIDSource( theElements, SMESH.ALL )
6941 unRegister.set( theElements )
6942 return self.editor.DoubleElements(theElements, theGroupName)
6944 def DoubleNodes(self, theNodes, theModifiedElems):
6946 Create a hole in a mesh by doubling the nodes of some particular elements
6949 theNodes: IDs of nodes to be doubled
6950 theModifiedElems: IDs of elements to be updated by the new (doubled)
6951 nodes. If list of element identifiers is empty then nodes are doubled but
6952 they not assigned to elements
6955 True if operation has been completed successfully, False otherwise
6958 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6960 def DoubleNode(self, theNodeId, theModifiedElems):
6962 Create a hole in a mesh by doubling the nodes of some particular elements.
6963 This method provided for convenience works as :meth:`DoubleNodes`.
6966 theNodeId: IDs of node to double
6967 theModifiedElems: IDs of elements to update
6970 True if operation has been completed successfully, False otherwise
6973 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6975 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6977 Create a hole in a mesh by doubling the nodes of some particular elements.
6978 This method provided for convenience works as :meth:`DoubleNodes`.
6981 theNodes: group of nodes to double.
6982 theModifiedElems: group of elements to update.
6983 theMakeGroup: forces the generation of a group containing new nodes.
6986 True or a created group if operation has been completed successfully,
6987 False or None otherwise
6991 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6992 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6994 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6996 Create a hole in a mesh by doubling the nodes of some particular elements.
6997 This method provided for convenience works as :meth:`DoubleNodes`.
7000 theNodes: list of groups of nodes to double.
7001 theModifiedElems: list of groups of elements to update.
7002 theMakeGroup: forces the generation of a group containing new nodes.
7005 True if operation has been completed successfully, False otherwise
7009 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7010 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7012 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7014 Create a hole in a mesh by doubling the nodes of some particular elements
7017 theElems: the list of elements (edges or faces) to replicate.
7018 The nodes for duplication could be found from these elements
7019 theNodesNot: list of nodes NOT to replicate
7020 theAffectedElems: the list of elements (cells and edges) to which the
7021 replicated nodes should be associated to
7024 True if operation has been completed successfully, False otherwise
7027 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7029 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7031 Create a hole in a mesh by doubling the nodes of some particular elements
7034 theElems: the list of elements (edges or faces) to replicate.
7035 The nodes for duplication could be found from these elements
7036 theNodesNot: list of nodes NOT to replicate
7037 theShape: shape to detect affected elements (element which geometric center
7038 located on or inside shape).
7039 The replicated nodes should be associated to affected elements.
7042 True if operation has been completed successfully, False otherwise
7045 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7047 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7048 theMakeGroup=False, theMakeNodeGroup=False):
7050 Create a hole in a mesh by doubling the nodes of some particular elements.
7051 This method provided for convenience works as :meth:`DoubleNodes`.
7054 theElems: group of of elements (edges or faces) to replicate.
7055 theNodesNot: group of nodes NOT to replicate.
7056 theAffectedElems: group of elements to which the replicated nodes
7057 should be associated to.
7058 theMakeGroup: forces the generation of a group containing new elements.
7059 theMakeNodeGroup: forces the generation of a group containing new nodes.
7062 True or created groups (one or two) if operation has been completed successfully,
7063 False or None otherwise
7066 if theMakeGroup or theMakeNodeGroup:
7067 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7069 theMakeGroup, theMakeNodeGroup)
7070 if theMakeGroup and theMakeNodeGroup:
7073 return twoGroups[ int(theMakeNodeGroup) ]
7074 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7076 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7078 Create a hole in a mesh by doubling the nodes of some particular elements.
7079 This method provided for convenience works as :meth:`DoubleNodes`.
7082 theElems: group of of elements (edges or faces) to replicate
7083 theNodesNot: group of nodes not to replicate
7084 theShape: shape to detect affected elements (element which geometric center
7085 located on or inside shape).
7086 The replicated nodes should be associated to affected elements
7089 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7091 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7092 theMakeGroup=False, theMakeNodeGroup=False):
7094 Create a hole in a mesh by doubling the nodes of some particular elements.
7095 This method provided for convenience works as :meth:`DoubleNodes`.
7098 theElems: list of groups of elements (edges or faces) to replicate
7099 theNodesNot: list of groups of nodes NOT to replicate
7100 theAffectedElems: group of elements to which the replicated nodes
7101 should be associated to
7102 theMakeGroup: forces generation of a group containing new elements.
7103 theMakeNodeGroup: forces generation of a group containing new nodes
7106 True or created groups (one or two) if operation has been completed successfully,
7107 False or None otherwise
7110 if theMakeGroup or theMakeNodeGroup:
7111 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7113 theMakeGroup, theMakeNodeGroup)
7114 if theMakeGroup and theMakeNodeGroup:
7117 return twoGroups[ int(theMakeNodeGroup) ]
7118 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7120 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7122 Create a hole in a mesh by doubling the nodes of some particular elements.
7123 This method provided for convenience works as :meth:`DoubleNodes`.
7126 theElems: list of groups of elements (edges or faces) to replicate
7127 theNodesNot: list of groups of nodes NOT to replicate
7128 theShape: shape to detect affected elements (element which geometric center
7129 located on or inside shape).
7130 The replicated nodes should be associated to affected elements
7133 True if operation has been completed successfully, False otherwise
7136 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7138 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7140 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7141 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7144 theElems: list of groups of nodes or elements (edges or faces) to replicate
7145 theNodesNot: list of groups of nodes NOT to replicate
7146 theShape: shape to detect affected elements (element which geometric center
7147 located on or inside shape).
7148 The replicated nodes should be associated to affected elements
7151 groups of affected elements in order: volumes, faces, edges
7154 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7156 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7159 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7160 The list of groups must describe a partition of the mesh volumes.
7161 The nodes of the internal faces at the boundaries of the groups are doubled.
7162 In option, the internal faces are replaced by flat elements.
7163 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7166 theDomains: list of groups of volumes
7167 createJointElems: if True, create the elements
7168 onAllBoundaries: if True, the nodes and elements are also created on
7169 the boundary between *theDomains* and the rest mesh
7172 True if operation has been completed successfully, False otherwise
7175 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7177 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7179 Double nodes on some external faces and create flat elements.
7180 Flat elements are mainly used by some types of mechanic calculations.
7182 Each group of the list must be constituted of faces.
7183 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7186 theGroupsOfFaces: list of groups of faces
7189 True if operation has been completed successfully, False otherwise
7192 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7194 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7196 Identify all the elements around a geom shape, get the faces delimiting the hole
7198 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7200 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7202 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7203 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7204 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7205 If there are several paths connecting a pair of points, the shortest path is
7206 selected by the module. Position of the cutting plane is defined by the two
7207 points and an optional vector lying on the plane specified by a PolySegment.
7208 By default the vector is defined by Mesh module as following. A middle point
7209 of the two given points is computed. The middle point is projected to the mesh.
7210 The vector goes from the middle point to the projection point. In case of planar
7211 mesh, the vector is normal to the mesh.
7213 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7216 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7217 groupName: optional name of a group where created mesh segments will be added.
7220 editor = self.editor
7222 editor = self.mesh.GetMeshEditPreviewer()
7223 segmentsRes = editor.MakePolyLine( segments, groupName )
7224 for i, seg in enumerate( segmentsRes ):
7225 segments[i].vector = seg.vector
7227 return editor.GetPreviewData()
7230 def MakeSlot(self, segmentGroup, width ):
7232 Create a slot of given width around given 1D elements lying on a triangle mesh.
7233 The slot is constructed by cutting faces by cylindrical surfaces made
7234 around each segment. Segments are expected to be created by MakePolyLine().
7237 FaceEdge's located at the slot boundary
7239 return self.editor.MakeSlot( segmentGroup, width )
7241 def GetFunctor(self, funcType ):
7243 Return a cached numerical functor by its type.
7246 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7247 Note that not all items correspond to numerical functors.
7250 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7253 fn = self.functors[ funcType._v ]
7255 fn = self.smeshpyD.GetFunctor(funcType)
7256 fn.SetMesh(self.mesh)
7257 self.functors[ funcType._v ] = fn
7260 def FunctorValue(self, funcType, elemId, isElem=True):
7262 Return value of a functor for a given element
7265 funcType: an item of :class:`SMESH.FunctorType` enum.
7266 elemId: element or node ID
7267 isElem: *elemId* is ID of element or node
7270 the functor value or zero in case of invalid arguments
7273 fn = self.GetFunctor( funcType )
7274 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7275 val = fn.GetValue(elemId)
7280 def GetLength(self, elemId=None):
7282 Get length of given 1D elements or of all 1D mesh elements
7285 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.
7288 Sum of lengths of given elements
7293 length = self.smeshpyD.GetLength(self)
7294 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7295 length = self.smeshpyD.GetLength(elemId)
7298 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7300 length += self.smeshpyD.GetLength(obj)
7301 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7302 unRegister = genObjUnRegister()
7303 obj = self.GetIDSource( elemId )
7304 unRegister.set( obj )
7305 length = self.smeshpyD.GetLength( obj )
7307 length = self.FunctorValue(SMESH.FT_Length, elemId)
7310 def GetArea(self, elemId=None):
7312 Get area of given 2D elements or of all 2D mesh elements
7315 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.
7318 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7323 area = self.smeshpyD.GetArea(self)
7324 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7325 area = self.smeshpyD.GetArea(elemId)
7328 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7330 area += self.smeshpyD.GetArea(obj)
7331 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7332 unRegister = genObjUnRegister()
7333 obj = self.GetIDSource( elemId )
7334 unRegister.set( obj )
7335 area = self.smeshpyD.GetArea( obj )
7337 area = self.FunctorValue(SMESH.FT_Area, elemId)
7340 def GetVolume(self, elemId=None):
7342 Get volume of given 3D elements or of all 3D mesh elements
7345 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.
7348 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7353 volume= self.smeshpyD.GetVolume(self)
7354 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7355 volume= self.smeshpyD.GetVolume(elemId)
7358 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7360 volume+= self.smeshpyD.GetVolume(obj)
7361 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7362 unRegister = genObjUnRegister()
7363 obj = self.GetIDSource( elemId )
7364 unRegister.set( obj )
7365 volume= self.smeshpyD.GetVolume( obj )
7367 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7370 def GetAngle(self, node1, node2, node3 ):
7372 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7375 node1,node2,node3: IDs of the three nodes
7378 Angle in radians [0,PI]. -1 if failure case.
7380 p1 = self.GetNodeXYZ( node1 )
7381 p2 = self.GetNodeXYZ( node2 )
7382 p3 = self.GetNodeXYZ( node3 )
7383 if p1 and p2 and p3:
7384 return self.smeshpyD.GetAngle( p1,p2,p3 )
7388 def GetMaxElementLength(self, elemId):
7390 Get maximum element length.
7393 elemId: mesh element ID
7396 element's maximum length value
7399 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7400 ftype = SMESH.FT_MaxElementLength3D
7402 ftype = SMESH.FT_MaxElementLength2D
7403 return self.FunctorValue(ftype, elemId)
7405 def GetAspectRatio(self, elemId):
7407 Get aspect ratio of 2D or 3D element.
7410 elemId: mesh element ID
7413 element's aspect ratio value
7416 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7417 ftype = SMESH.FT_AspectRatio3D
7419 ftype = SMESH.FT_AspectRatio
7420 return self.FunctorValue(ftype, elemId)
7422 def GetWarping(self, elemId):
7424 Get warping angle of 2D element.
7427 elemId: mesh element ID
7430 element's warping angle value
7433 return self.FunctorValue(SMESH.FT_Warping, elemId)
7435 def GetMinimumAngle(self, elemId):
7437 Get minimum angle of 2D element.
7440 elemId: mesh element ID
7443 element's minimum angle value
7446 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7448 def GetTaper(self, elemId):
7450 Get taper of 2D element.
7453 elemId: mesh element ID
7456 element's taper value
7459 return self.FunctorValue(SMESH.FT_Taper, elemId)
7461 def GetSkew(self, elemId):
7463 Get skew of 2D element.
7466 elemId: mesh element ID
7469 element's skew value
7472 return self.FunctorValue(SMESH.FT_Skew, elemId)
7474 def GetScaledJacobian(self, elemId):
7476 Get the scaled jacobian of 3D element id
7479 elemId: mesh element ID
7485 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7487 def GetMinMax(self, funType, meshPart=None):
7489 Return minimal and maximal value of a given functor.
7492 funType (SMESH.FunctorType): a functor type.
7493 Note that not all items of :class:`SMESH.FunctorType` corresponds
7494 to numerical functors.
7495 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7501 unRegister = genObjUnRegister()
7502 if isinstance( meshPart, list ):
7503 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7504 unRegister.set( meshPart )
7505 if isinstance( meshPart, Mesh ):
7506 meshPart = meshPart.mesh
7507 fun = self.GetFunctor( funType )
7510 if hasattr( meshPart, "SetMesh" ):
7511 meshPart.SetMesh( self.mesh ) # set mesh to filter
7512 hist = fun.GetLocalHistogram( 1, False, meshPart )
7514 hist = fun.GetHistogram( 1, False )
7516 return hist[0].min, hist[0].max
7519 pass # end of Mesh class
7522 def _copy_netgen_param(dim, local_param, global_param):
7524 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7527 #TODO: Try to identify why we need to substract 1
7528 local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
7530 local_param.SetMaxSize(global_param.GetMaxSize())
7531 local_param.SetMinSize(global_param.GetMinSize())
7532 local_param.SetOptimize(global_param.GetOptimize())
7533 local_param.SetFineness(global_param.GetFineness())
7534 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7535 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7536 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7537 local_param.SetChordalError(global_param.GetChordalError())
7538 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7539 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7540 local_param.SetUseDelauney(global_param.GetUseDelauney())
7541 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7542 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7543 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7544 local_param.SetNbThreads(global_param.GetNbThreads())
7546 local_param.SetMaxSize(global_param.GetMaxSize())
7547 local_param.SetMinSize(global_param.GetMinSize())
7548 local_param.SetOptimize(global_param.GetOptimize())
7549 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7550 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7551 local_param.SetFineness(global_param.GetFineness())
7552 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7553 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7554 local_param.SetGrowthRate(global_param.GetGrowthRate())
7555 local_param.SetNbThreads(global_param.GetNbThreads())
7557 def _split_geom(geompyD, geom):
7559 Splitting geometry into n solids and a 2D/1D compound
7562 geompyD: geomBuilder instance
7563 geom: geometrical object for meshing
7566 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7567 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7572 for solid in object_solids:
7574 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7575 solids.append(solid)
7576 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7582 for isolid, solid in enumerate(solids):
7583 solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
7585 for face in solid_faces:
7588 geompyD.addToStudyInFather(solid, face,
7589 'Face_{}'.format(iface))
7591 # Creating submesh for edges 1D/2D part
7593 all_faces = geompyD.MakeCompound(faces)
7594 geompyD.addToStudy(all_faces, 'Compound_1')
7595 all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
7596 all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
7597 geompyD.addToStudy(all_faces, 'global2D')
7599 return all_faces, solids
7601 class ParallelismSettings:
7603 Defines the parameters for the parallelism of ParallelMesh
7605 def __init__(self, mesh):
7610 mesh: Instance of ParallelMesh
7612 if not(isinstance(mesh, ParallelMesh)):
7613 raise ValueError("mesh should be a ParallelMesh")
7617 def SetNbThreads(self, nbThreads):
7619 Set the number of threads for multithreading
7622 raise ValueError("Number of threads must be stricly greater than 1")
7624 self._mesh.mesh.SetNbThreads(nbThreads)
7626 def GetNbThreads(self):
7628 Get Number of threads
7630 return self._mesh.mesh.GetNbThreads()
7632 class ParallelMesh(Mesh):
7634 Surcharge on Mesh for parallel computation of a mesh
7636 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7638 Create a parallel mesh.
7641 smeshpyD: instance of smeshBuilder
7642 geompyD: instance of geomBuilder
7643 geom: geometrical object for meshing
7644 split_geom: If true will divide geometry on solids and 1D/2D
7645 coumpound and create the associated submeshes
7646 name: the name for the new mesh.
7649 an instance of class :class:`ParallelMesh`.
7652 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7653 raise ValueError("geom argument must be a geometry")
7655 # Splitting geometry into one geom containing 1D and 2D elements and a
7656 # list of 3D elements
7657 super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name, parallel=True)
7660 self._all_faces, self._solids = _split_geom(geompyD, geom)
7662 self.UseExistingSegments()
7663 self.UseExistingFaces()
7665 self._algo2d = self.Triangle(geom=self._all_faces, algo="NETGEN_2D")
7668 for solid_id, solid in enumerate(self._solids):
7669 name = "Solid_{}".format(solid_id)
7670 self.UseExistingSegments(geom=solid)
7671 self.UseExistingFaces(geom=solid)
7672 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7673 self._algo3d.append(algo3d)
7675 self._param = ParallelismSettings(self)
7678 def GetParallelismSettings(self):
7680 Return class to set parameters for the parallelism
7684 def AddGlobalHypothesis(self, hyp):
7686 Split hypothesis to apply it to all the submeshes:
7688 - each of the 3D solids
7691 hyp: a hypothesis to assign
7694 if not isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7695 raise ValueError("param must come from NETGENPlugin")
7697 param2d = self._algo2d.Parameters()
7698 _copy_netgen_param(2, param2d, hyp)
7700 for algo3d in self._algo3d:
7702 param3d = algo3d.Parameters()
7703 _copy_netgen_param(3, param3d, hyp)
7706 pass # End of ParallelMesh
7709 class meshProxy(SMESH._objref_SMESH_Mesh):
7711 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7712 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7714 def __init__(self,*args):
7715 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7716 def __deepcopy__(self, memo=None):
7717 new = self.__class__(self)
7719 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7720 if len( args ) == 3:
7721 args += SMESH.ALL_NODES, True
7722 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7723 def ExportToMEDX(self, *args): # function removed
7724 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7725 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7726 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7727 def ExportToMED(self, *args): # function removed
7728 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7729 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7731 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7733 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7734 def ExportPartToMED(self, *args): # 'version' parameter removed
7735 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7736 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7737 def ExportMED(self, *args): # signature of method changed
7738 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7740 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7742 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7743 def ExportUNV(self, *args): # renumber arg added
7744 if len( args ) == 1:
7746 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7747 def ExportDAT(self, *args): # renumber arg added
7748 if len( args ) == 1:
7750 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7752 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7755 class submeshProxy(SMESH._objref_SMESH_subMesh):
7758 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7760 def __init__(self,*args):
7761 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7763 def __deepcopy__(self, memo=None):
7764 new = self.__class__(self)
7767 def Compute(self,refresh=False):
7769 Compute the sub-mesh and return the status of the computation
7772 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7777 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7778 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7782 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7784 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7786 if salome.sg.hasDesktop():
7787 if refresh: salome.sg.updateObjBrowser()
7792 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7795 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7797 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7798 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7801 def __init__(self,*args):
7802 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7804 def __getattr__(self, name ): # method called if an attribute not found
7805 if not self.mesh: # look for name() method in Mesh class
7806 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7807 if hasattr( self.mesh, name ):
7808 return getattr( self.mesh, name )
7809 if name == "ExtrusionAlongPathObjX":
7810 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7811 print("meshEditor: attribute '%s' NOT FOUND" % name)
7813 def __deepcopy__(self, memo=None):
7814 new = self.__class__(self)
7816 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7817 if len( args ) == 1: args += False,
7818 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7819 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7820 if len( args ) == 2: args += False,
7821 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7822 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7823 if len( args ) == 1:
7824 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7825 NodesToKeep = args[1]
7826 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7827 unRegister = genObjUnRegister()
7829 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7830 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7831 if not isinstance( NodesToKeep, list ):
7832 NodesToKeep = [ NodesToKeep ]
7833 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7835 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7837 class Pattern(SMESH._objref_SMESH_Pattern):
7839 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7840 variables in some methods
7843 def LoadFromFile(self, patternTextOrFile ):
7844 text = patternTextOrFile
7845 if os.path.exists( text ):
7846 text = open( patternTextOrFile ).read()
7848 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7850 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7851 decrFun = lambda i: i-1
7852 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7853 theMesh.SetParameters(Parameters)
7854 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7856 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7857 decrFun = lambda i: i-1
7858 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7859 theMesh.SetParameters(Parameters)
7860 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7862 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7863 if isinstance( mesh, Mesh ):
7864 mesh = mesh.GetMesh()
7865 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7867 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7869 Registering the new proxy for Pattern
7874 Private class used to bind methods creating algorithms to the class Mesh
7877 def __init__(self, method):
7879 self.defaultAlgoType = ""
7880 self.algoTypeToClass = {}
7881 self.method = method
7883 def add(self, algoClass):
7885 Store a python class of algorithm
7887 if inspect.isclass(algoClass) and \
7888 hasattr( algoClass, "algoType"):
7889 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7890 if not self.defaultAlgoType and \
7891 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7892 self.defaultAlgoType = algoClass.algoType
7893 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7895 def copy(self, mesh):
7897 Create a copy of self and assign mesh to the copy
7900 other = algoCreator( self.method )
7901 other.defaultAlgoType = self.defaultAlgoType
7902 other.algoTypeToClass = self.algoTypeToClass
7906 def __call__(self,algo="",geom=0,*args):
7908 Create an instance of algorithm
7912 if isinstance( algo, str ):
7914 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7915 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7920 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7922 elif not algoType and isinstance( geom, str ):
7927 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7929 elif isinstance( arg, str ) and not algoType:
7932 import traceback, sys
7933 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7934 sys.stderr.write( msg + '\n' )
7935 tb = traceback.extract_stack(None,2)
7936 traceback.print_list( [tb[0]] )
7938 algoType = self.defaultAlgoType
7939 if not algoType and self.algoTypeToClass:
7940 algoType = sorted( self.algoTypeToClass.keys() )[0]
7941 if algoType in self.algoTypeToClass:
7942 #print("Create algo",algoType)
7943 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7944 raise RuntimeError( "No class found for algo type %s" % algoType)
7947 class hypMethodWrapper:
7949 Private class used to substitute and store variable parameters of hypotheses.
7952 def __init__(self, hyp, method):
7954 self.method = method
7955 #print("REBIND:", method.__name__)
7958 def __call__(self,*args):
7960 call a method of hypothesis with calling SetVarParameter() before
7964 return self.method( self.hyp, *args ) # hypothesis method with no args
7966 #print("MethWrapper.__call__", self.method.__name__, args)
7968 parsed = ParseParameters(*args) # replace variables with their values
7969 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7970 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7971 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7972 # maybe there is a replaced string arg which is not variable
7973 result = self.method( self.hyp, *args )
7974 except ValueError as detail: # raised by ParseParameters()
7976 result = self.method( self.hyp, *args )
7977 except omniORB.CORBA.BAD_PARAM:
7978 raise ValueError(detail) # wrong variable name
7983 class genObjUnRegister:
7985 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7988 def __init__(self, genObj=None):
7989 self.genObjList = []
7993 def set(self, genObj):
7994 "Store one or a list of of SALOME.GenericObj'es"
7995 if isinstance( genObj, list ):
7996 self.genObjList.extend( genObj )
7998 self.genObjList.append( genObj )
8002 for genObj in self.genObjList:
8003 if genObj and hasattr( genObj, "UnRegister" ):
8006 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8008 Bind methods creating mesher plug-ins to the Mesh class
8011 # print("pluginName: ", pluginName)
8012 pluginBuilderName = pluginName + "Builder"
8014 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8015 except Exception as e:
8016 from salome_utils import verbose
8017 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8019 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8020 plugin = eval( pluginBuilderName )
8021 # print(" plugin:" , str(plugin))
8023 # add methods creating algorithms to Mesh
8024 for k in dir( plugin ):
8025 if k[0] == '_': continue
8026 algo = getattr( plugin, k )
8027 #print(" algo:", str(algo))
8028 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8029 #print(" meshMethod:" , str(algo.meshMethod))
8030 if not hasattr( Mesh, algo.meshMethod ):
8031 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8033 _mmethod = getattr( Mesh, algo.meshMethod )
8034 if hasattr( _mmethod, "add" ):