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 mymesh = self.smeshpyD.CreateParallelMesh(self.geom)
1633 mymesh2 = mymesh._narrow(SMESH._objref_SMESH_Mesh)
1634 self.SetMesh( mymesh )
1636 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1638 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1641 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1643 self.smeshpyD.SetName(self.mesh, name)
1645 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1648 self.geom = self.mesh.GetShapeToMesh()
1650 self.editor = self.mesh.GetMeshEditor()
1651 self.functors = [None] * SMESH.FT_Undefined._v
1653 # set self to algoCreator's
1654 for attrName in dir(self):
1655 attr = getattr( self, attrName )
1656 if isinstance( attr, algoCreator ):
1657 setattr( self, attrName, attr.copy( self ))
1664 Destructor. Clean-up resources
1667 #self.mesh.UnRegister()
1671 def SetMesh(self, theMesh):
1673 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1676 theMesh: a :class:`SMESH.SMESH_Mesh` object
1678 # do not call Register() as this prevents mesh servant deletion at closing study
1679 #if self.mesh: self.mesh.UnRegister()
1682 #self.mesh.Register()
1683 self.geom = self.mesh.GetShapeToMesh()
1687 if salome.sg.hasDesktop():
1688 so = salome.ObjectToSObject( self.geom )
1689 comp = so.GetFatherComponent()
1690 if comp.ComponentDataType() == "SHAPERSTUDY":
1691 import shaperBuilder
1692 self.geompyD = shaperBuilder.New()
1695 if not self.geompyD:
1696 self.geompyD = self.geom.GetGen()
1701 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1704 a :class:`SMESH.SMESH_Mesh` object
1709 def GetEngine(self):
1711 Return a smeshBuilder instance created this mesh
1713 return self.smeshpyD
1715 def GetGeomEngine(self):
1717 Return a geomBuilder instance
1723 Get the name of the mesh
1726 the name of the mesh as a string
1729 name = GetName(self.GetMesh())
1732 def SetName(self, name):
1734 Set a name to the mesh
1737 name: a new name of the mesh
1740 self.smeshpyD.SetName(self.GetMesh(), name)
1742 def GetSubMesh(self, geom, name):
1744 Get a sub-mesh object associated to a *geom* geometrical object.
1747 geom: a geometrical object (shape)
1748 name: a name for the sub-mesh in the Object Browser
1751 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1752 which lies on the given shape
1755 A sub-mesh is implicitly created when a sub-shape is specified at
1756 creating an algorithm, for example::
1758 algo1D = mesh.Segment(geom=Edge_1)
1760 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1761 The created sub-mesh can be retrieved from the algorithm::
1763 submesh = algo1D.GetSubMesh()
1766 AssureGeomPublished( self, geom, name )
1767 submesh = self.mesh.GetSubMesh( geom, name )
1772 Return the shape associated to the mesh
1780 def SetShape(self, geom):
1782 Associate the given shape to the mesh (entails the recreation of the mesh)
1785 geom: the shape to be meshed (GEOM_Object)
1788 self.mesh = self.smeshpyD.CreateMesh(geom)
1790 def HasShapeToMesh(self):
1792 Return ``True`` if this mesh is based on geometry
1794 return self.mesh.HasShapeToMesh()
1798 Load mesh from the study after opening the study
1802 def IsReadyToCompute(self, theSubObject):
1804 Return true if the hypotheses are defined well
1807 theSubObject: a sub-shape of a mesh shape
1813 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1815 def GetAlgoState(self, theSubObject):
1817 Return errors of hypotheses definition.
1818 The list of errors is empty if everything is OK.
1821 theSubObject: a sub-shape of a mesh shape
1827 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1829 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1831 Return a geometrical object on which the given element was built.
1832 The returned geometrical object, if not nil, is either found in the
1833 study or published by this method with the given name
1836 theElementID: the id of the mesh element
1837 theGeomName: the user-defined name of the geometrical object
1840 GEOM.GEOM_Object instance
1843 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1845 def MeshDimension(self):
1847 Return the mesh dimension depending on the dimension of the underlying shape
1848 or, if the mesh is not based on any shape, basing on deimension of elements
1851 mesh dimension as an integer value [0,3]
1854 if self.mesh.HasShapeToMesh():
1855 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1856 if len( shells ) > 0 :
1858 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1860 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1865 if self.NbVolumes() > 0: return 3
1866 if self.NbFaces() > 0: return 2
1867 if self.NbEdges() > 0: return 1
1870 def Evaluate(self, geom=0):
1872 Evaluate size of prospective mesh on a shape
1875 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1876 To know predicted number of e.g. edges, inquire it this way::
1878 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1881 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1883 geom = self.mesh.GetShapeToMesh()
1886 return self.smeshpyD.Evaluate(self.mesh, geom)
1888 def Compute(self, geom=0, discardModifs=False, refresh=False):
1890 Compute the mesh and return the status of the computation
1893 geom: geomtrical shape on which mesh data should be computed
1894 discardModifs: if True and the mesh has been edited since
1895 a last total re-compute and that may prevent successful partial re-compute,
1896 then the mesh is cleaned before Compute()
1897 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1903 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1904 geom = self.mesh.GetShapeToMesh()
1907 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1909 ok = self.smeshpyD.Compute(self.mesh, geom)
1910 except SALOME.SALOME_Exception as ex:
1911 print("Mesh computation failed, exception caught:")
1912 print(" ", ex.details.text)
1915 print("Mesh computation failed, exception caught:")
1916 traceback.print_exc()
1920 # Treat compute errors
1921 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1923 for err in computeErrors:
1924 if self.mesh.HasShapeToMesh():
1925 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1927 stdErrors = ["OK", #COMPERR_OK
1928 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1929 "std::exception", #COMPERR_STD_EXCEPTION
1930 "OCC exception", #COMPERR_OCC_EXCEPTION
1931 "..", #COMPERR_SLM_EXCEPTION
1932 "Unknown exception", #COMPERR_EXCEPTION
1933 "Memory allocation problem", #COMPERR_MEMORY_PB
1934 "Algorithm failed", #COMPERR_ALGO_FAILED
1935 "Unexpected geometry", #COMPERR_BAD_SHAPE
1936 "Warning", #COMPERR_WARNING
1937 "Computation cancelled",#COMPERR_CANCELED
1938 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1940 if err.code < len(stdErrors): errText = stdErrors[err.code]
1942 errText = "code %s" % -err.code
1943 if errText: errText += ". "
1944 errText += err.comment
1945 if allReasons: allReasons += "\n"
1947 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1949 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1953 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1955 if err.isGlobalAlgo:
1963 reason = '%s %sD algorithm is missing' % (glob, dim)
1964 elif err.state == HYP_MISSING:
1965 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1966 % (glob, dim, name, dim))
1967 elif err.state == HYP_NOTCONFORM:
1968 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1969 elif err.state == HYP_BAD_PARAMETER:
1970 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1971 % ( glob, dim, name ))
1972 elif err.state == HYP_BAD_GEOMETRY:
1973 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1974 'geometry' % ( glob, dim, name ))
1975 elif err.state == HYP_HIDDEN_ALGO:
1976 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1977 'algorithm of upper dimension generating %sD mesh'
1978 % ( glob, dim, name, glob, dim ))
1980 reason = ("For unknown reason. "
1981 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1983 if allReasons: allReasons += "\n"
1984 allReasons += "- " + reason
1986 if not ok or allReasons != "":
1987 msg = '"' + GetName(self.mesh) + '"'
1988 if ok: msg += " has been computed with warnings"
1989 else: msg += " has not been computed"
1990 if allReasons != "": msg += ":"
1996 if salome.sg.hasDesktop():
1997 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1998 if refresh: salome.sg.updateObjBrowser()
2002 def GetComputeErrors(self, shape=0 ):
2004 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2008 shape = self.mesh.GetShapeToMesh()
2009 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2011 def GetSubShapeName(self, subShapeID ):
2013 Return a name of a sub-shape by its ID.
2014 Possible variants (for *subShapeID* == 3):
2016 - **"Face_12"** - published sub-shape
2017 - **FACE #3** - not published sub-shape
2018 - **sub-shape #3** - invalid sub-shape ID
2019 - **#3** - error in this function
2022 subShapeID: a unique ID of a sub-shape
2025 a string describing the sub-shape
2029 if not self.mesh.HasShapeToMesh():
2033 mainIOR = salome.orb.object_to_string( self.GetShape() )
2035 mainSO = s.FindObjectIOR(mainIOR)
2038 shapeText = '"%s"' % mainSO.GetName()
2039 subIt = s.NewChildIterator(mainSO)
2041 subSO = subIt.Value()
2043 obj = subSO.GetObject()
2044 if not obj: continue
2045 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2048 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2051 if ids == subShapeID:
2052 shapeText = '"%s"' % subSO.GetName()
2055 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2057 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2059 shapeText = 'sub-shape #%s' % (subShapeID)
2061 shapeText = "#%s" % (subShapeID)
2064 def GetFailedShapes(self, publish=False):
2066 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2067 error of an algorithm
2070 publish: if *True*, the returned groups will be published in the study
2073 a list of GEOM groups each named after a failed algorithm
2078 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2079 for err in computeErrors:
2080 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2081 if not shape: continue
2082 if err.algoName in algo2shapes:
2083 algo2shapes[ err.algoName ].append( shape )
2085 algo2shapes[ err.algoName ] = [ shape ]
2089 for algoName, shapes in list(algo2shapes.items()):
2091 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2092 otherTypeShapes = []
2094 group = self.geompyD.CreateGroup( self.geom, groupType )
2095 for shape in shapes:
2096 if shape.GetShapeType() == shapes[0].GetShapeType():
2097 sameTypeShapes.append( shape )
2099 otherTypeShapes.append( shape )
2100 self.geompyD.UnionList( group, sameTypeShapes )
2102 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2104 group.SetName( algoName )
2105 groups.append( group )
2106 shapes = otherTypeShapes
2109 for group in groups:
2110 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2113 def GetMeshOrder(self):
2115 Return sub-mesh objects list in meshing order
2118 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2121 return self.mesh.GetMeshOrder()
2123 def SetMeshOrder(self, submeshes):
2125 Set priority of sub-meshes. It works in two ways:
2127 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2128 *several dimensions*, it sets the order in which the sub-meshes are computed.
2129 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2130 when looking for meshing parameters to apply to a sub-shape. To impose the
2131 order in which sub-meshes with uni-dimensional algorithms are computed,
2132 call **submesh.Compute()** in a desired order.
2135 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2137 Warning: the method is for setting the order for all sub-meshes at once:
2138 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2141 return self.mesh.SetMeshOrder(submeshes)
2143 def Clear(self, refresh=False):
2145 Remove all nodes and elements generated on geometry. Imported elements remain.
2148 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2152 if ( salome.sg.hasDesktop() ):
2153 if refresh: salome.sg.updateObjBrowser()
2155 def ClearSubMesh(self, geomId, refresh=False):
2157 Remove all nodes and elements of indicated shape
2160 geomId: the ID of a sub-shape to remove elements on
2161 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2164 self.mesh.ClearSubMesh(geomId)
2165 if salome.sg.hasDesktop():
2166 if refresh: salome.sg.updateObjBrowser()
2168 def AutomaticTetrahedralization(self, fineness=0):
2170 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2173 fineness: [0.0,1.0] defines mesh fineness
2179 dim = self.MeshDimension()
2181 self.RemoveGlobalHypotheses()
2182 self.Segment().AutomaticLength(fineness)
2184 self.Triangle().LengthFromEdges()
2189 return self.Compute()
2191 def AutomaticHexahedralization(self, fineness=0):
2193 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2196 fineness: [0.0, 1.0] defines mesh fineness
2202 dim = self.MeshDimension()
2203 # assign the hypotheses
2204 self.RemoveGlobalHypotheses()
2205 self.Segment().AutomaticLength(fineness)
2212 return self.Compute()
2214 def AddHypothesis(self, hyp, geom=0):
2219 hyp: a hypothesis to assign
2220 geom: a subhape of mesh geometry
2223 :class:`SMESH.Hypothesis_Status`
2226 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2227 hyp, geom = geom, hyp
2228 if isinstance( hyp, Mesh_Algorithm ):
2229 hyp = hyp.GetAlgorithm()
2234 geom = self.mesh.GetShapeToMesh()
2237 if self.mesh.HasShapeToMesh():
2238 hyp_type = hyp.GetName()
2239 lib_name = hyp.GetLibName()
2240 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2241 # if checkAll and geom:
2242 # checkAll = geom.GetType() == 37
2244 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2246 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2247 status = self.mesh.AddHypothesis(geom, hyp)
2249 status = HYP_BAD_GEOMETRY, ""
2250 hyp_name = GetName( hyp )
2253 geom_name = geom.GetName()
2254 isAlgo = hyp._narrow( SMESH_Algo )
2255 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2258 def IsUsedHypothesis(self, hyp, geom):
2260 Return True if an algorithm or hypothesis is assigned to a given shape
2263 hyp: an algorithm or hypothesis to check
2264 geom: a subhape of mesh geometry
2270 if not hyp: # or not geom
2272 if isinstance( hyp, Mesh_Algorithm ):
2273 hyp = hyp.GetAlgorithm()
2275 hyps = self.GetHypothesisList(geom)
2277 if h.GetId() == hyp.GetId():
2281 def RemoveHypothesis(self, hyp, geom=0):
2283 Unassign a hypothesis
2286 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2287 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2290 :class:`SMESH.Hypothesis_Status`
2295 if isinstance( hyp, Mesh_Algorithm ):
2296 hyp = hyp.GetAlgorithm()
2302 if self.IsUsedHypothesis( hyp, shape ):
2303 return self.mesh.RemoveHypothesis( shape, hyp )
2304 hypName = GetName( hyp )
2305 geoName = GetName( shape )
2306 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2309 def GetHypothesisList(self, geom):
2311 Get the list of hypotheses added on a geometry
2314 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2317 the sequence of :class:`SMESH.SMESH_Hypothesis`
2320 return self.mesh.GetHypothesisList( geom )
2322 def RemoveGlobalHypotheses(self):
2324 Remove all global hypotheses
2327 current_hyps = self.mesh.GetHypothesisList( self.geom )
2328 for hyp in current_hyps:
2329 self.mesh.RemoveHypothesis( self.geom, hyp )
2333 def ExportMEDCoupling(self, *args, **kwargs):
2335 Export the mesh in a memory representation.
2338 auto_groups (boolean): parameter for creating/not creating
2339 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2340 the typical use is auto_groups=False.
2341 overwrite (boolean): parameter for overwriting/not overwriting the file
2342 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2343 to export instead of the mesh
2344 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2346 - 1D if all mesh nodes lie on OX coordinate axis, or
2347 - 2D if all mesh nodes lie on XOY coordinate plane, or
2348 - 3D in the rest cases.
2350 If *autoDimension* is *False*, the space dimension is always 3.
2351 fields: list of GEOM fields defined on the shape to mesh.
2352 geomAssocFields: each character of this string means a need to export a
2353 corresponding field; correspondence between fields and characters
2356 - 'v' stands for "_vertices_" field;
2357 - 'e' stands for "_edges_" field;
2358 - 'f' stands for "_faces_" field;
2359 - 's' stands for "_solids_" field.
2361 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2362 close to zero within a given tolerance, the coordinate is set to zero.
2363 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2364 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2366 auto_groups = args[0] if len(args) > 0 else False
2367 meshPart = args[1] if len(args) > 1 else None
2368 autoDimension = args[2] if len(args) > 2 else True
2369 fields = args[3] if len(args) > 3 else []
2370 geomAssocFields = args[4] if len(args) > 4 else ''
2371 z_tolerance = args[5] if len(args) > 5 else -1.
2372 saveNumbers = args[6] if len(args) > 6 else True
2373 # process keywords arguments
2374 auto_groups = kwargs.get("auto_groups", auto_groups)
2375 meshPart = kwargs.get("meshPart", meshPart)
2376 autoDimension = kwargs.get("autoDimension", autoDimension)
2377 fields = kwargs.get("fields", fields)
2378 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2379 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2380 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2382 # invoke engine's function
2383 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2384 unRegister = genObjUnRegister()
2385 if isinstance( meshPart, list ):
2386 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2387 unRegister.set( meshPart )
2389 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2390 self.mesh.SetParameters(Parameters)
2392 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2393 fields, geomAssocFields, z_tolerance,
2396 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2397 return medcoupling.MEDFileData.New(dab)
2399 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2401 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2402 return medcoupling.MEDFileMesh.New(dab)
2404 def ExportMED(self, *args, **kwargs):
2406 Export the mesh in a file in MED format
2407 allowing to overwrite the file if it exists or add the exported data to its contents
2410 fileName: is the file name
2411 auto_groups (boolean): parameter for creating/not creating
2412 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2413 the typical use is auto_groups=False.
2414 version (int): define the version (xy, where version is x.y.z) of MED file format.
2415 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2416 The rules of compatibility to write a mesh in an older version than
2417 the current version depend on the current version. For instance,
2418 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2419 or 3.2.1 or 3.3.1 formats.
2420 If the version is equal to -1, the version is not changed (default).
2421 overwrite (boolean): parameter for overwriting/not overwriting the file
2422 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2423 to export instead of the mesh
2424 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2426 - 1D if all mesh nodes lie on OX coordinate axis, or
2427 - 2D if all mesh nodes lie on XOY coordinate plane, or
2428 - 3D in the rest cases.
2430 If *autoDimension* is *False*, the space dimension is always 3.
2431 fields: list of GEOM fields defined on the shape to mesh.
2432 geomAssocFields: each character of this string means a need to export a
2433 corresponding field; correspondence between fields and characters
2436 - 'v' stands for "_vertices_" field;
2437 - 'e' stands for "_edges_" field;
2438 - 'f' stands for "_faces_" field;
2439 - 's' stands for "_solids_" field.
2441 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2442 close to zero within a given tolerance, the coordinate is set to zero.
2443 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2444 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2446 # process positional arguments
2447 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2449 auto_groups = args[1] if len(args) > 1 else False
2450 version = args[2] if len(args) > 2 else -1
2451 overwrite = args[3] if len(args) > 3 else True
2452 meshPart = args[4] if len(args) > 4 else None
2453 autoDimension = args[5] if len(args) > 5 else True
2454 fields = args[6] if len(args) > 6 else []
2455 geomAssocFields = args[7] if len(args) > 7 else ''
2456 z_tolerance = args[8] if len(args) > 8 else -1.
2457 saveNumbers = args[9] if len(args) > 9 else True
2458 # process keywords arguments
2459 auto_groups = kwargs.get("auto_groups", auto_groups)
2460 version = kwargs.get("version", version)
2461 version = kwargs.get("minor", version)
2462 overwrite = kwargs.get("overwrite", overwrite)
2463 meshPart = kwargs.get("meshPart", meshPart)
2464 autoDimension = kwargs.get("autoDimension", autoDimension)
2465 fields = kwargs.get("fields", fields)
2466 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2467 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2468 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2470 if isinstance( meshPart, Mesh):
2471 meshPart = meshPart.GetMesh()
2473 # invoke engine's function
2474 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2475 unRegister = genObjUnRegister()
2476 if isinstance( meshPart, list ):
2477 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2478 unRegister.set( meshPart )
2480 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2481 self.mesh.SetParameters(Parameters)
2483 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2484 version, overwrite, autoDimension,
2485 fields, geomAssocFields, z_tolerance, saveNumbers )
2487 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2489 def ExportDAT(self, f, meshPart=None, renumber=True):
2491 Export the mesh in a file in DAT format
2495 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2496 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2499 if meshPart or not renumber:
2500 unRegister = genObjUnRegister()
2501 if isinstance( meshPart, list ):
2502 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2503 unRegister.set( meshPart )
2504 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2506 self.mesh.ExportDAT( f, renumber )
2508 def ExportUNV(self, f, meshPart=None, renumber=True):
2510 Export the mesh in a file in UNV format
2514 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2515 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2518 if meshPart or not renumber:
2519 unRegister = genObjUnRegister()
2520 if isinstance( meshPart, list ):
2521 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2522 unRegister.set( meshPart )
2523 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2525 self.mesh.ExportUNV( f, renumber )
2527 def ExportSTL(self, f, ascii=1, meshPart=None):
2529 Export the mesh in a file in STL format
2533 ascii: defines the file encoding
2534 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538 unRegister = genObjUnRegister()
2539 if isinstance( meshPart, list ):
2540 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2541 unRegister.set( meshPart )
2542 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2544 self.mesh.ExportSTL(f, ascii)
2546 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2548 Export the mesh in a file in CGNS format
2552 overwrite: boolean parameter for overwriting/not overwriting the file
2553 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2554 groupElemsByType: if True all elements of same entity type are exported at ones,
2555 else elements are exported in order of their IDs which can cause creation
2556 of multiple cgns sections
2559 unRegister = genObjUnRegister()
2560 if isinstance( meshPart, list ):
2561 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2562 unRegister.set( meshPart )
2563 if isinstance( meshPart, Mesh ):
2564 meshPart = meshPart.mesh
2566 meshPart = self.mesh
2567 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2569 def ExportGMF(self, f, meshPart=None):
2571 Export the mesh in a file in GMF format.
2572 GMF files must have .mesh extension for the ASCII format and .meshb for
2573 the bynary format. Other extensions are not allowed.
2577 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2580 unRegister = genObjUnRegister()
2581 if isinstance( meshPart, list ):
2582 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2583 unRegister.set( meshPart )
2584 if isinstance( meshPart, Mesh ):
2585 meshPart = meshPart.mesh
2587 meshPart = self.mesh
2588 self.mesh.ExportGMF(meshPart, f, True)
2590 def ExportToMED(self, *args, **kwargs):
2592 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2593 Export the mesh in a file in MED format
2594 allowing to overwrite the file if it exists or add the exported data to its contents
2597 fileName: the file name
2598 opt (boolean): parameter for creating/not creating
2599 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2600 overwrite: boolean parameter for overwriting/not overwriting the file
2601 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2603 - 1D if all mesh nodes lie on OX coordinate axis, or
2604 - 2D if all mesh nodes lie on XOY coordinate plane, or
2605 - 3D in the rest cases.
2607 If **autoDimension** is *False*, the space dimension is always 3.
2610 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2611 # process positional arguments
2612 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2614 auto_groups = args[1] if len(args) > 1 else False
2615 overwrite = args[2] if len(args) > 2 else True
2616 autoDimension = args[3] if len(args) > 3 else True
2617 # process keywords arguments
2618 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2619 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2620 overwrite = kwargs.get("overwrite", overwrite)
2621 autoDimension = kwargs.get("autoDimension", autoDimension)
2623 # invoke engine's function
2624 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2626 def ExportToMEDX(self, *args, **kwargs):
2628 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2629 Export the mesh in a file in MED format
2632 fileName: the file name
2633 opt (boolean): parameter for creating/not creating
2634 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2635 overwrite: boolean parameter for overwriting/not overwriting the file
2636 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2638 - 1D if all mesh nodes lie on OX coordinate axis, or
2639 - 2D if all mesh nodes lie on XOY coordinate plane, or
2640 - 3D in the rest cases.
2642 If **autoDimension** is *False*, the space dimension is always 3.
2645 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2646 # process positional arguments
2647 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2649 auto_groups = args[1] if len(args) > 1 else False
2650 overwrite = args[2] if len(args) > 2 else True
2651 autoDimension = args[3] if len(args) > 3 else True
2652 # process keywords arguments
2653 auto_groups = kwargs.get("auto_groups", auto_groups)
2654 overwrite = kwargs.get("overwrite", overwrite)
2655 autoDimension = kwargs.get("autoDimension", autoDimension)
2657 # invoke engine's function
2658 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2662 def Append(self, meshes, uniteIdenticalGroups = True,
2663 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2665 Append given meshes into this mesh.
2666 All groups of input meshes will be created in this mesh.
2669 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2670 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2671 mergeNodesAndElements: if True, equal nodes and elements are merged
2672 mergeTolerance: tolerance for merging nodes
2673 allGroups: forces creation of groups corresponding to every input mesh
2675 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2676 mergeNodesAndElements, mergeTolerance, allGroups,
2677 meshToAppendTo = self.GetMesh() )
2679 # Operations with groups:
2680 # ----------------------
2681 def CreateEmptyGroup(self, elementType, name):
2683 Create an empty standalone mesh group
2686 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2687 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2688 name: the name of the mesh group
2691 :class:`SMESH.SMESH_Group`
2694 return self.mesh.CreateGroup(elementType, name)
2696 def Group(self, grp, name=""):
2698 Create a mesh group based on the geometric object *grp*
2699 and give it a *name*.
2700 If *name* is not defined the name of the geometric group is used
2703 Works like :meth:`GroupOnGeom`.
2706 grp: a geometric group, a vertex, an edge, a face or a solid
2707 name: the name of the mesh group
2710 :class:`SMESH.SMESH_GroupOnGeom`
2713 return self.GroupOnGeom(grp, name)
2715 def GroupOnGeom(self, grp, name="", typ=None):
2717 Create a mesh group based on the geometrical object *grp*
2718 and give it a *name*.
2719 if *name* is not defined the name of the geometric group is used
2722 grp: a geometrical group, a vertex, an edge, a face or a solid
2723 name: the name of the mesh group
2724 typ: the type of elements in the group; either of
2725 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2726 automatically detected by the type of the geometry
2729 :class:`SMESH.SMESH_GroupOnGeom`
2732 AssureGeomPublished( self, grp, name )
2734 name = grp.GetName()
2736 typ = self._groupTypeFromShape( grp )
2737 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2739 def _groupTypeFromShape( self, shape ):
2741 Pivate method to get a type of group on geometry
2743 tgeo = str(shape.GetShapeType())
2744 if tgeo == "VERTEX":
2746 elif tgeo == "EDGE" or tgeo == "WIRE":
2748 elif tgeo == "FACE" or tgeo == "SHELL":
2750 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2752 elif tgeo == "COMPOUND":
2754 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2756 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2757 # simplification of access in geomBuilder: omniORB.registerObjref
2758 from SHAPERSTUDY_utils import getEngine
2761 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2763 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2764 return self._groupTypeFromShape( sub[0] )
2766 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2769 def GroupOnFilter(self, typ, name, filter):
2771 Create a mesh group with given *name* based on the *filter*.
2772 It is a special type of group dynamically updating it's contents during
2776 typ: the type of elements in the group; either of
2777 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2778 name: the name of the mesh group
2779 filter (SMESH.Filter): the filter defining group contents
2782 :class:`SMESH.SMESH_GroupOnFilter`
2785 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2787 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2789 Create a mesh group by the given ids of elements
2792 groupName: the name of the mesh group
2793 elementType: the type of elements in the group; either of
2794 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2795 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2798 :class:`SMESH.SMESH_Group`
2801 group = self.mesh.CreateGroup(elementType, groupName)
2802 if isinstance( elemIDs, Mesh ):
2803 elemIDs = elemIDs.GetMesh()
2804 if hasattr( elemIDs, "GetIDs" ):
2805 if hasattr( elemIDs, "SetMesh" ):
2806 elemIDs.SetMesh( self.GetMesh() )
2807 group.AddFrom( elemIDs )
2815 CritType=FT_Undefined,
2818 UnaryOp=FT_Undefined,
2821 Create a mesh group by the given conditions
2824 groupName: the name of the mesh group
2825 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2826 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2827 Note that the items starting from FT_LessThan are not suitable for CritType.
2828 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2829 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2830 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2831 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2832 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2835 :class:`SMESH.SMESH_GroupOnFilter`
2838 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2839 group = self.MakeGroupByCriterion(groupName, aCriterion)
2842 def MakeGroupByCriterion(self, groupName, Criterion):
2844 Create a mesh group by the given criterion
2847 groupName: the name of the mesh group
2848 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2851 :class:`SMESH.SMESH_GroupOnFilter`
2854 :meth:`smeshBuilder.GetCriterion`
2857 return self.MakeGroupByCriteria( groupName, [Criterion] )
2859 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2861 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2864 groupName: the name of the mesh group
2865 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2866 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2869 :class:`SMESH.SMESH_GroupOnFilter`
2872 :meth:`smeshBuilder.GetCriterion`
2875 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2876 group = self.MakeGroupByFilter(groupName, aFilter)
2879 def MakeGroupByFilter(self, groupName, theFilter):
2881 Create a mesh group by the given filter
2884 groupName (string): the name of the mesh group
2885 theFilter (SMESH.Filter): the filter
2888 :class:`SMESH.SMESH_GroupOnFilter`
2891 :meth:`smeshBuilder.GetFilter`
2894 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2895 #theFilter.SetMesh( self.mesh )
2896 #group.AddFrom( theFilter )
2897 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2900 def RemoveGroup(self, group):
2905 group (SMESH.SMESH_GroupBase): group to remove
2908 self.mesh.RemoveGroup(group)
2910 def RemoveGroupWithContents(self, group):
2912 Remove a group with its contents
2915 group (SMESH.SMESH_GroupBase): group to remove
2918 This operation can create gaps in numeration of nodes or elements.
2919 Call :meth:`RenumberElements` to remove the gaps.
2922 self.mesh.RemoveGroupWithContents(group)
2924 def GetGroups(self, elemType = SMESH.ALL):
2926 Get the list of groups existing in the mesh in the order of creation
2927 (starting from the oldest one)
2930 elemType (SMESH.ElementType): type of elements the groups contain;
2931 by default groups of elements of all types are returned
2934 a list of :class:`SMESH.SMESH_GroupBase`
2937 groups = self.mesh.GetGroups()
2938 if elemType == SMESH.ALL:
2942 if g.GetType() == elemType:
2943 typedGroups.append( g )
2950 Get the number of groups existing in the mesh
2953 the quantity of groups as an integer value
2956 return self.mesh.NbGroups()
2958 def GetGroupNames(self):
2960 Get the list of names of groups existing in the mesh
2966 groups = self.GetGroups()
2968 for group in groups:
2969 names.append(group.GetName())
2972 def GetGroupByName(self, name, elemType = None):
2974 Find groups by name and type
2977 name (string): name of the group of interest
2978 elemType (SMESH.ElementType): type of elements the groups contain;
2979 by default one group of any type is returned;
2980 if elemType == SMESH.ALL then all groups of any type are returned
2983 a list of :class:`SMESH.SMESH_GroupBase`
2987 for group in self.GetGroups():
2988 if group.GetName() == name:
2989 if elemType is None:
2991 if ( elemType == SMESH.ALL or
2992 group.GetType() == elemType ):
2993 groups.append( group )
2996 def UnionGroups(self, group1, group2, name):
2998 Produce a union of two groups.
2999 A new group is created. All mesh elements that are
3000 present in the initial groups are added to the new one
3003 group1 (SMESH.SMESH_GroupBase): a group
3004 group2 (SMESH.SMESH_GroupBase): another group
3007 instance of :class:`SMESH.SMESH_Group`
3010 return self.mesh.UnionGroups(group1, group2, name)
3012 def UnionListOfGroups(self, groups, name):
3014 Produce a union list of groups.
3015 New group is created. All mesh elements that are present in
3016 initial groups are added to the new one
3019 groups: list of :class:`SMESH.SMESH_GroupBase`
3022 instance of :class:`SMESH.SMESH_Group`
3024 return self.mesh.UnionListOfGroups(groups, name)
3026 def IntersectGroups(self, group1, group2, name):
3028 Prodice an intersection of two groups.
3029 A new group is created. All mesh elements that are common
3030 for the two initial groups are added to the new one.
3033 group1 (SMESH.SMESH_GroupBase): a group
3034 group2 (SMESH.SMESH_GroupBase): another group
3037 instance of :class:`SMESH.SMESH_Group`
3040 return self.mesh.IntersectGroups(group1, group2, name)
3042 def IntersectListOfGroups(self, groups, name):
3044 Produce an intersection of groups.
3045 New group is created. All mesh elements that are present in all
3046 initial groups simultaneously are added to the new one
3049 groups: a list of :class:`SMESH.SMESH_GroupBase`
3052 instance of :class:`SMESH.SMESH_Group`
3054 return self.mesh.IntersectListOfGroups(groups, name)
3056 def CutGroups(self, main_group, tool_group, name):
3058 Produce a cut of two groups.
3059 A new group is created. All mesh elements that are present in
3060 the main group but are not present in the tool group are added to the new one
3063 main_group (SMESH.SMESH_GroupBase): a group to cut from
3064 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3067 an instance of :class:`SMESH.SMESH_Group`
3070 return self.mesh.CutGroups(main_group, tool_group, name)
3072 def CutListOfGroups(self, main_groups, tool_groups, name):
3074 Produce a cut of groups.
3075 A new group is created. All mesh elements that are present in main groups
3076 but do not present in tool groups are added to the new one
3079 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3080 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3083 an instance of :class:`SMESH.SMESH_Group`
3086 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3088 def CreateDimGroup(self, groups, elemType, name,
3089 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3091 Create a standalone group of entities basing on nodes of other groups.
3094 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3095 elemType: a type of elements to include to the new group; either of
3096 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3097 name: a name of the new group.
3098 nbCommonNodes: a criterion of inclusion of an element to the new group
3099 basing on number of element nodes common with reference *groups*.
3100 Meaning of possible values are:
3102 - SMESH.ALL_NODES - include if all nodes are common,
3103 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3104 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3105 - SMEHS.MAJORITY - include if half of nodes or more are common.
3106 underlyingOnly: if *True* (default), an element is included to the
3107 new group provided that it is based on nodes of an element of *groups*;
3108 in this case the reference *groups* are supposed to be of higher dimension
3109 than *elemType*, which can be useful for example to get all faces lying on
3110 volumes of the reference *groups*.
3113 an instance of :class:`SMESH.SMESH_Group`
3116 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3118 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3120 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3122 Distribute all faces of the mesh among groups using sharp edges and optionally
3123 existing 1D elements as group boundaries.
3126 sharpAngle: edge is considered sharp if an angle between normals of
3127 adjacent faces is more than \a sharpAngle in degrees.
3128 createEdges (boolean): to create 1D elements for detected sharp edges.
3129 useExistingEdges (boolean): to use existing edges as group boundaries
3131 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3133 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3134 self.mesh.SetParameters(Parameters)
3135 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3137 def ConvertToStandalone(self, group):
3139 Convert group on geom into standalone group
3142 return self.mesh.ConvertToStandalone(group)
3144 # Get some info about mesh:
3145 # ------------------------
3147 def GetLog(self, clearAfterGet):
3149 Return the log of nodes and elements added or removed
3150 since the previous clear of the log.
3153 clearAfterGet: log is emptied after Get (safe if concurrents access)
3156 list of SMESH.log_block structures { commandType, number, coords, indexes }
3159 return self.mesh.GetLog(clearAfterGet)
3163 Clear the log of nodes and elements added or removed since the previous
3164 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3167 self.mesh.ClearLog()
3169 def SetAutoColor(self, theAutoColor):
3171 Toggle auto color mode on the object.
3172 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3175 theAutoColor (boolean): the flag which toggles auto color mode.
3178 self.mesh.SetAutoColor(theAutoColor)
3180 def GetAutoColor(self):
3182 Get flag of object auto color mode.
3188 return self.mesh.GetAutoColor()
3195 integer value, which is the internal Id of the mesh
3198 return self.mesh.GetId()
3200 def HasDuplicatedGroupNamesMED(self):
3202 Check the group names for duplications.
3203 Consider the maximum group name length stored in MED file.
3209 return self.mesh.HasDuplicatedGroupNamesMED()
3211 def GetMeshEditor(self):
3213 Obtain the mesh editor tool
3216 an instance of :class:`SMESH.SMESH_MeshEditor`
3221 def GetIDSource(self, ids, elemType = SMESH.ALL):
3223 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3224 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3228 elemType: type of elements; this parameter is used to distinguish
3229 IDs of nodes from IDs of elements; by default ids are treated as
3230 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3233 an instance of :class:`SMESH.SMESH_IDSource`
3236 call UnRegister() for the returned object as soon as it is no more useful::
3238 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3239 mesh.DoSomething( idSrc )
3243 if isinstance( ids, int ):
3245 return self.editor.MakeIDSource(ids, elemType)
3248 # Get information about mesh contents:
3249 # ------------------------------------
3251 def GetMeshInfo(self, obj = None):
3253 Get the mesh statistic.
3256 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3259 if not obj: obj = self.mesh
3260 return self.smeshpyD.GetMeshInfo(obj)
3264 Return the number of nodes in the mesh
3270 return self.mesh.NbNodes()
3272 def NbElements(self):
3274 Return the number of elements in the mesh
3280 return self.mesh.NbElements()
3282 def Nb0DElements(self):
3284 Return the number of 0d elements in the mesh
3290 return self.mesh.Nb0DElements()
3294 Return the number of ball discrete elements in the mesh
3300 return self.mesh.NbBalls()
3304 Return the number of edges in the mesh
3310 return self.mesh.NbEdges()
3312 def NbEdgesOfOrder(self, elementOrder):
3314 Return the number of edges with the given order in the mesh
3317 elementOrder: the order of elements
3318 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3324 return self.mesh.NbEdgesOfOrder(elementOrder)
3328 Return the number of faces in the mesh
3334 return self.mesh.NbFaces()
3336 def NbFacesOfOrder(self, elementOrder):
3338 Return the number of faces with the given order in the mesh
3341 elementOrder: the order of elements
3342 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3348 return self.mesh.NbFacesOfOrder(elementOrder)
3350 def NbTriangles(self):
3352 Return the number of triangles in the mesh
3358 return self.mesh.NbTriangles()
3360 def NbTrianglesOfOrder(self, elementOrder):
3362 Return the number of triangles with the given order in the mesh
3365 elementOrder: is the order of elements
3366 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3372 return self.mesh.NbTrianglesOfOrder(elementOrder)
3374 def NbBiQuadTriangles(self):
3376 Return the number of biquadratic triangles in the mesh
3382 return self.mesh.NbBiQuadTriangles()
3384 def NbQuadrangles(self):
3386 Return the number of quadrangles in the mesh
3392 return self.mesh.NbQuadrangles()
3394 def NbQuadranglesOfOrder(self, elementOrder):
3396 Return the number of quadrangles with the given order in the mesh
3399 elementOrder: the order of elements
3400 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3406 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3408 def NbBiQuadQuadrangles(self):
3410 Return the number of biquadratic quadrangles in the mesh
3416 return self.mesh.NbBiQuadQuadrangles()
3418 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3420 Return the number of polygons of given order in the mesh
3423 elementOrder: the order of elements
3424 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3430 return self.mesh.NbPolygonsOfOrder(elementOrder)
3432 def NbVolumes(self):
3434 Return the number of volumes in the mesh
3440 return self.mesh.NbVolumes()
3443 def NbVolumesOfOrder(self, elementOrder):
3445 Return the number of volumes with the given order in the mesh
3448 elementOrder: the order of elements
3449 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3455 return self.mesh.NbVolumesOfOrder(elementOrder)
3459 Return the number of tetrahedrons in the mesh
3465 return self.mesh.NbTetras()
3467 def NbTetrasOfOrder(self, elementOrder):
3469 Return the number of tetrahedrons with the given order in the mesh
3472 elementOrder: the order of elements
3473 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3479 return self.mesh.NbTetrasOfOrder(elementOrder)
3483 Return the number of hexahedrons in the mesh
3489 return self.mesh.NbHexas()
3491 def NbHexasOfOrder(self, elementOrder):
3493 Return the number of hexahedrons with the given order in the mesh
3496 elementOrder: the order of elements
3497 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3503 return self.mesh.NbHexasOfOrder(elementOrder)
3505 def NbTriQuadraticHexas(self):
3507 Return the number of triquadratic hexahedrons in the mesh
3513 return self.mesh.NbTriQuadraticHexas()
3515 def NbPyramids(self):
3517 Return the number of pyramids in the mesh
3523 return self.mesh.NbPyramids()
3525 def NbPyramidsOfOrder(self, elementOrder):
3527 Return the number of pyramids with the given order in the mesh
3530 elementOrder: the order of elements
3531 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3537 return self.mesh.NbPyramidsOfOrder(elementOrder)
3541 Return the number of prisms in the mesh
3547 return self.mesh.NbPrisms()
3549 def NbPrismsOfOrder(self, elementOrder):
3551 Return the number of prisms with the given order in the mesh
3554 elementOrder: the order of elements
3555 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3561 return self.mesh.NbPrismsOfOrder(elementOrder)
3563 def NbHexagonalPrisms(self):
3565 Return the number of hexagonal prisms in the mesh
3571 return self.mesh.NbHexagonalPrisms()
3573 def NbPolyhedrons(self):
3575 Return the number of polyhedrons in the mesh
3581 return self.mesh.NbPolyhedrons()
3583 def NbSubMesh(self):
3585 Return the number of submeshes in the mesh
3591 return self.mesh.NbSubMesh()
3593 def GetElementsId(self):
3595 Return the list of all mesh elements IDs
3598 the list of integer values
3601 :meth:`GetElementsByType`
3604 return self.mesh.GetElementsId()
3606 def GetElementsByType(self, elementType):
3608 Return the list of IDs of mesh elements with the given type
3611 elementType (SMESH.ElementType): the required type of elements
3614 list of integer values
3617 return self.mesh.GetElementsByType(elementType)
3619 def GetNodesId(self):
3621 Return the list of mesh nodes IDs
3624 the list of integer values
3627 return self.mesh.GetNodesId()
3629 # Get the information about mesh elements:
3630 # ------------------------------------
3632 def GetElementType(self, id, iselem=True):
3634 Return the type of mesh element or node
3637 the value from :class:`SMESH.ElementType` enumeration.
3638 Return SMESH.ALL if element or node with the given ID does not exist
3641 return self.mesh.GetElementType(id, iselem)
3643 def GetElementGeomType(self, id):
3645 Return the geometric type of mesh element
3648 the value from :class:`SMESH.EntityType` enumeration.
3651 return self.mesh.GetElementGeomType(id)
3653 def GetElementShape(self, id):
3655 Return the shape type of mesh element
3658 the value from :class:`SMESH.GeometryType` enumeration.
3661 return self.mesh.GetElementShape(id)
3663 def GetSubMeshElementsId(self, Shape):
3665 Return the list of sub-mesh elements IDs
3668 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3669 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3672 list of integer values
3675 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3676 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3679 return self.mesh.GetSubMeshElementsId(ShapeID)
3681 def GetSubMeshNodesId(self, Shape, all):
3683 Return the list of sub-mesh nodes IDs
3686 Shape: a geom object (sub-shape).
3687 *Shape* must be the sub-shape of a :meth:`GetShape`
3688 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3691 list of integer values
3694 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3695 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3698 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3700 def GetSubMeshElementType(self, Shape):
3702 Return type of elements on given shape
3705 Shape: a geom object (sub-shape).
3706 *Shape* must be a sub-shape of a ShapeToMesh()
3709 :class:`SMESH.ElementType`
3712 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3713 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3716 return self.mesh.GetSubMeshElementType(ShapeID)
3720 Get the mesh description
3726 return self.mesh.Dump()
3729 # Get the information about nodes and elements of a mesh by its IDs:
3730 # -----------------------------------------------------------
3732 def GetNodeXYZ(self, id):
3734 Get XYZ coordinates of a node.
3735 If there is no node for the given ID - return an empty list
3738 list of float values
3741 return self.mesh.GetNodeXYZ(id)
3743 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3745 Return list of IDs of inverse elements for the given node.
3746 If there is no node for the given ID - return an empty list
3750 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3753 list of integer values
3756 return self.mesh.GetNodeInverseElements(id,elemType)
3758 def GetNodePosition(self,NodeID):
3760 Return the position of a node on the shape
3763 :class:`SMESH.NodePosition`
3766 return self.mesh.GetNodePosition(NodeID)
3768 def GetElementPosition(self,ElemID):
3770 Return the position of an element on the shape
3773 :class:`SMESH.ElementPosition`
3776 return self.mesh.GetElementPosition(ElemID)
3778 def GetShapeID(self, id):
3780 Return the ID of the shape, on which the given node was generated.
3783 an integer value > 0 or -1 if there is no node for the given
3784 ID or the node is not assigned to any geometry
3787 return self.mesh.GetShapeID(id)
3789 def GetShapeIDForElem(self,id):
3791 Return the ID of the shape, on which the given element was generated.
3794 an integer value > 0 or -1 if there is no element for the given
3795 ID or the element is not assigned to any geometry
3798 return self.mesh.GetShapeIDForElem(id)
3800 def GetElemNbNodes(self, id):
3802 Return the number of nodes of the given element
3805 an integer value > 0 or -1 if there is no element for the given ID
3808 return self.mesh.GetElemNbNodes(id)
3810 def GetElemNode(self, id, index):
3812 Return the node ID the given (zero based) index for the given element.
3814 * If there is no element for the given ID - return -1.
3815 * If there is no node for the given index - return -2.
3818 id (int): element ID
3819 index (int): node index within the element
3822 an integer value (ID)
3825 :meth:`GetElemNodes`
3828 return self.mesh.GetElemNode(id, index)
3830 def GetElemNodes(self, id):
3832 Return the IDs of nodes of the given element
3835 a list of integer values
3838 return self.mesh.GetElemNodes(id)
3840 def IsMediumNode(self, elementID, nodeID):
3842 Return true if the given node is the medium node in the given quadratic element
3845 return self.mesh.IsMediumNode(elementID, nodeID)
3847 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3849 Return true if the given node is the medium node in one of quadratic elements
3852 nodeID: ID of the node
3853 elementType: the type of elements to check a state of the node, either of
3854 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3857 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3859 def ElemNbEdges(self, id):
3861 Return the number of edges for the given element
3864 return self.mesh.ElemNbEdges(id)
3866 def ElemNbFaces(self, id):
3868 Return the number of faces for the given element
3871 return self.mesh.ElemNbFaces(id)
3873 def GetElemFaceNodes(self,elemId, faceIndex):
3875 Return nodes of given face (counted from zero) for given volumic element.
3878 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3880 def GetFaceNormal(self, faceId, normalized=False):
3882 Return three components of normal of given mesh face
3883 (or an empty array in KO case)
3886 return self.mesh.GetFaceNormal(faceId,normalized)
3888 def FindElementByNodes(self, nodes):
3890 Return an element based on all given nodes.
3893 return self.mesh.FindElementByNodes(nodes)
3895 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3897 Return elements including all given nodes.
3900 return self.mesh.GetElementsByNodes( nodes, elemType )
3902 def IsPoly(self, id):
3904 Return true if the given element is a polygon
3907 return self.mesh.IsPoly(id)
3909 def IsQuadratic(self, id):
3911 Return true if the given element is quadratic
3914 return self.mesh.IsQuadratic(id)
3916 def GetBallDiameter(self, id):
3918 Return diameter of a ball discrete element or zero in case of an invalid *id*
3921 return self.mesh.GetBallDiameter(id)
3923 def BaryCenter(self, id):
3925 Return XYZ coordinates of the barycenter of the given element.
3926 If there is no element for the given ID - return an empty list
3929 a list of three double values
3932 :meth:`smeshBuilder.GetGravityCenter`
3935 return self.mesh.BaryCenter(id)
3937 def GetIdsFromFilter(self, filter, meshParts=[] ):
3939 Pass mesh elements through the given filter and return IDs of fitting elements
3942 filter: :class:`SMESH.Filter`
3943 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3949 :meth:`SMESH.Filter.GetIDs`
3950 :meth:`SMESH.Filter.GetElementsIdFromParts`
3953 filter.SetMesh( self.mesh )
3956 if isinstance( meshParts, Mesh ):
3957 filter.SetMesh( meshParts.GetMesh() )
3958 return theFilter.GetIDs()
3959 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3960 meshParts = [ meshParts ]
3961 return filter.GetElementsIdFromParts( meshParts )
3963 return filter.GetIDs()
3965 # Get mesh measurements information:
3966 # ------------------------------------
3968 def GetFreeBorders(self):
3970 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3971 Return a list of special structures (borders).
3974 a list of :class:`SMESH.FreeEdges.Border`
3977 aFilterMgr = self.smeshpyD.CreateFilterManager()
3978 aPredicate = aFilterMgr.CreateFreeEdges()
3979 aPredicate.SetMesh(self.mesh)
3980 aBorders = aPredicate.GetBorders()
3981 aFilterMgr.UnRegister()
3984 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3986 Get minimum distance between two nodes, elements or distance to the origin
3989 id1: first node/element id
3990 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3991 isElem1: *True* if *id1* is element id, *False* if it is node id
3992 isElem2: *True* if *id2* is element id, *False* if it is node id
3995 minimum distance value
3997 :meth:`GetMinDistance`
4000 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4001 return aMeasure.value
4003 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4005 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4008 id1: first node/element id
4009 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4010 isElem1: *True* if *id1* is element id, *False* if it is node id
4011 isElem2: *True* if *id2* is element id, *False* if it is node id
4014 :class:`SMESH.Measure` structure
4020 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4022 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4025 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4027 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4032 aMeasurements = self.smeshpyD.CreateMeasurements()
4033 aMeasure = aMeasurements.MinDistance(id1, id2)
4034 genObjUnRegister([aMeasurements,id1, id2])
4037 def BoundingBox(self, objects=None, isElem=False):
4039 Get bounding box of the specified object(s)
4042 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4043 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4044 *False* specifies that *objects* are nodes
4047 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4050 :meth:`GetBoundingBox()`
4053 result = self.GetBoundingBox(objects, isElem)
4057 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4060 def GetBoundingBox(self, objects=None, isElem=False):
4062 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4065 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4066 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4067 False means that *objects* are nodes
4070 :class:`SMESH.Measure` structure
4073 :meth:`BoundingBox()`
4077 objects = [self.mesh]
4078 elif isinstance(objects, tuple):
4079 objects = list(objects)
4080 if not isinstance(objects, list):
4082 if len(objects) > 0 and isinstance(objects[0], int):
4085 unRegister = genObjUnRegister()
4087 if isinstance(o, Mesh):
4088 srclist.append(o.mesh)
4089 elif hasattr(o, "_narrow"):
4090 src = o._narrow(SMESH.SMESH_IDSource)
4091 if src: srclist.append(src)
4093 elif isinstance(o, list):
4095 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4097 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4098 unRegister.set( srclist[-1] )
4101 aMeasurements = self.smeshpyD.CreateMeasurements()
4102 unRegister.set( aMeasurements )
4103 aMeasure = aMeasurements.BoundingBox(srclist)
4106 # Mesh edition (SMESH_MeshEditor functionality):
4107 # ---------------------------------------------
4109 def RemoveElements(self, IDsOfElements):
4111 Remove the elements from the mesh by ids
4114 IDsOfElements: is a list of ids of elements to remove
4120 This operation can create gaps in numeration of elements.
4121 Call :meth:`RenumberElements` to remove the gaps.
4124 return self.editor.RemoveElements(IDsOfElements)
4126 def RemoveNodes(self, IDsOfNodes):
4128 Remove nodes from mesh by ids
4131 IDsOfNodes: is a list of ids of nodes to remove
4137 This operation can create gaps in numeration of nodes.
4138 Call :meth:`RenumberElements` to remove the gaps.
4141 return self.editor.RemoveNodes(IDsOfNodes)
4143 def RemoveNodeWithReconnection(self, nodeID ):
4145 Remove a node along with changing surrounding faces to cover a hole.
4148 nodeID: ID of node to remove
4151 return self.editor.RemoveNodeWithReconnection( nodeID )
4153 def RemoveOrphanNodes(self):
4155 Remove all orphan (free) nodes from mesh
4158 number of the removed nodes
4161 This operation can create gaps in numeration of nodes.
4162 Call :meth:`RenumberElements` to remove the gaps.
4165 return self.editor.RemoveOrphanNodes()
4167 def AddNode(self, x, y, z):
4169 Add a node to the mesh by coordinates
4175 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4176 if hasVars: self.mesh.SetParameters(Parameters)
4177 return self.editor.AddNode( x, y, z)
4179 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4181 Create a 0D element on a node with given number.
4184 IDOfNode: the ID of node for creation of the element.
4185 DuplicateElements: to add one more 0D element to a node or not
4188 ID of the new 0D element
4191 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4193 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4195 Create 0D elements on all nodes of the given elements except those
4196 nodes on which a 0D element already exists.
4199 theObject: an object on whose nodes 0D elements will be created.
4200 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4201 theGroupName: optional name of a group to add 0D elements created
4202 and/or found on nodes of *theObject*.
4203 DuplicateElements: to add one more 0D element to a node or not
4206 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4207 IDs of new and/or found 0D elements. IDs of 0D elements
4208 can be retrieved from the returned object by
4209 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4212 unRegister = genObjUnRegister()
4213 if isinstance( theObject, Mesh ):
4214 theObject = theObject.GetMesh()
4215 elif isinstance( theObject, list ):
4216 theObject = self.GetIDSource( theObject, SMESH.ALL )
4217 unRegister.set( theObject )
4218 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4220 def AddBall(self, IDOfNode, diameter):
4222 Create a ball element on a node with given ID.
4225 IDOfNode: the ID of node for creation of the element.
4226 diameter: the bal diameter.
4229 ID of the new ball element
4232 return self.editor.AddBall( IDOfNode, diameter )
4234 def AddEdge(self, IDsOfNodes):
4236 Create a linear or quadratic edge (this is determined
4237 by the number of given nodes).
4240 IDsOfNodes: list of node IDs for creation of the element.
4241 The order of nodes in this list should correspond to
4242 the :ref:`connectivity convention <connectivity_page>`.
4248 return self.editor.AddEdge(IDsOfNodes)
4250 def AddFace(self, IDsOfNodes):
4252 Create a linear or quadratic face (this is determined
4253 by the number of given nodes).
4256 IDsOfNodes: list of node IDs for creation of the element.
4257 The order of nodes in this list should correspond to
4258 the :ref:`connectivity convention <connectivity_page>`.
4264 return self.editor.AddFace(IDsOfNodes)
4266 def AddPolygonalFace(self, IdsOfNodes):
4268 Add a polygonal face defined by a list of node IDs
4271 IdsOfNodes: the list of node IDs for creation of the element.
4277 return self.editor.AddPolygonalFace(IdsOfNodes)
4279 def AddQuadPolygonalFace(self, IdsOfNodes):
4281 Add a quadratic polygonal face defined by a list of node IDs
4284 IdsOfNodes: the list of node IDs for creation of the element;
4285 corner nodes follow first.
4291 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4293 def AddVolume(self, IDsOfNodes):
4295 Create both simple and quadratic volume (this is determined
4296 by the number of given nodes).
4299 IDsOfNodes: list of node IDs for creation of the element.
4300 The order of nodes in this list should correspond to
4301 the :ref:`connectivity convention <connectivity_page>`.
4304 ID of the new volumic element
4307 return self.editor.AddVolume(IDsOfNodes)
4309 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4311 Create a volume of many faces, giving nodes for each face.
4314 IdsOfNodes: list of node IDs for volume creation, face by face.
4315 Quantities: list of integer values, Quantities[i]
4316 gives the quantity of nodes in face number i.
4319 ID of the new volumic element
4322 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4324 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4326 Create a volume of many faces, giving the IDs of the existing faces.
4329 The created volume will refer only to the nodes
4330 of the given faces, not to the faces themselves.
4333 IdsOfFaces: the list of face IDs for volume creation.
4336 ID of the new volumic element
4339 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4342 def SetNodeOnVertex(self, NodeID, Vertex):
4344 Bind a node to a vertex
4348 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4351 True if succeed else raises an exception
4354 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4355 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4359 self.editor.SetNodeOnVertex(NodeID, VertexID)
4360 except SALOME.SALOME_Exception as inst:
4361 raise ValueError(inst.details.text)
4365 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4367 Store the node position on an edge
4371 Edge: an edge (GEOM.GEOM_Object) or edge ID
4372 paramOnEdge: a parameter on the edge where the node is located
4375 True if succeed else raises an exception
4378 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4379 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4383 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4384 except SALOME.SALOME_Exception as inst:
4385 raise ValueError(inst.details.text)
4388 def SetNodeOnFace(self, NodeID, Face, u, v):
4390 Store node position on a face
4394 Face: a face (GEOM.GEOM_Object) or face ID
4395 u: U parameter on the face where the node is located
4396 v: V parameter on the face where the node is located
4399 True if succeed else raises an exception
4402 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4403 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4407 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4408 except SALOME.SALOME_Exception as inst:
4409 raise ValueError(inst.details.text)
4412 def SetNodeInVolume(self, NodeID, Solid):
4414 Bind a node to a solid
4418 Solid: a solid (GEOM.GEOM_Object) or solid ID
4421 True if succeed else raises an exception
4424 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4425 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4429 self.editor.SetNodeInVolume(NodeID, SolidID)
4430 except SALOME.SALOME_Exception as inst:
4431 raise ValueError(inst.details.text)
4434 def SetMeshElementOnShape(self, ElementID, Shape):
4436 Bind an element to a shape
4439 ElementID: an element ID
4440 Shape: a shape (GEOM.GEOM_Object) or shape ID
4443 True if succeed else raises an exception
4446 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4447 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4451 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4452 except SALOME.SALOME_Exception as inst:
4453 raise ValueError(inst.details.text)
4457 def MoveNode(self, NodeID, x, y, z):
4459 Move the node with the given id
4462 NodeID: the id of the node
4463 x: a new X coordinate
4464 y: a new Y coordinate
4465 z: a new Z coordinate
4468 True if succeed else False
4471 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4472 if hasVars: self.mesh.SetParameters(Parameters)
4473 return self.editor.MoveNode(NodeID, x, y, z)
4475 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4477 Find the node closest to a point and moves it to a point location
4480 x: the X coordinate of a point
4481 y: the Y coordinate of a point
4482 z: the Z coordinate of a point
4483 NodeID: if specified (>0), the node with this ID is moved,
4484 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4487 the ID of a moved node
4490 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4491 if hasVars: self.mesh.SetParameters(Parameters)
4492 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4494 def FindNodeClosestTo(self, x, y, z):
4496 Find the node closest to a point
4499 x: the X coordinate of a point
4500 y: the Y coordinate of a point
4501 z: the Z coordinate of a point
4507 return self.editor.FindNodeClosestTo(x, y, z)
4509 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4511 Find the elements where a point lays IN or ON
4514 x,y,z (float): coordinates of the point
4515 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4516 means elements of any type excluding nodes, discrete and 0D elements.
4517 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4520 list of IDs of found elements
4523 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4525 return self.editor.FindElementsByPoint(x, y, z, elementType)
4527 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4529 Project a point to a mesh object.
4530 Return ID of an element of given type where the given point is projected
4531 and coordinates of the projection point.
4532 In the case if nothing found, return -1 and []
4534 if isinstance( meshObject, Mesh ):
4535 meshObject = meshObject.GetMesh()
4537 meshObject = self.GetMesh()
4538 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4540 def GetPointState(self, x, y, z):
4542 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4543 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4544 UNKNOWN state means that either mesh is wrong or the analysis fails.
4547 return self.editor.GetPointState(x, y, z)
4549 def IsManifold(self):
4551 Check if a 2D mesh is manifold
4554 return self.editor.IsManifold()
4556 def IsCoherentOrientation2D(self):
4558 Check if orientation of 2D elements is coherent
4561 return self.editor.IsCoherentOrientation2D()
4563 def Get1DBranches( self, edges, startNode = 0 ):
4565 Partition given 1D elements into groups of contiguous edges.
4566 A node where number of meeting edges != 2 is a group end.
4567 An optional startNode is used to orient groups it belongs to.
4570 A list of edge groups and a list of corresponding node groups,
4571 where the group is a list of IDs of edges or nodes, like follows
4572 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4573 If a group is closed, the first and last nodes of the group are same.
4575 if isinstance( edges, Mesh ):
4576 edges = edges.GetMesh()
4577 unRegister = genObjUnRegister()
4578 if isinstance( edges, list ):
4579 edges = self.GetIDSource( edges, SMESH.EDGE )
4580 unRegister.set( edges )
4581 return self.editor.Get1DBranches( edges, startNode )
4583 def FindSharpEdges( self, angle, addExisting=False ):
4585 Return sharp edges of faces and non-manifold ones.
4586 Optionally add existing edges.
4589 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4590 addExisting: to return existing edges (1D elements) as well
4593 list of FaceEdge structures
4595 angle = ParseParameters( angle )[0]
4596 return self.editor.FindSharpEdges( angle, addExisting )
4598 def MeshToPassThroughAPoint(self, x, y, z):
4600 Find the node closest to a point and moves it to a point location
4603 x: the X coordinate of a point
4604 y: the Y coordinate of a point
4605 z: the Z coordinate of a point
4608 the ID of a moved node
4611 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4613 def InverseDiag(self, NodeID1, NodeID2):
4615 Replace two neighbour triangles sharing Node1-Node2 link
4616 with the triangles built on the same 4 nodes but having other common link.
4619 NodeID1: the ID of the first node
4620 NodeID2: the ID of the second node
4623 False if proper faces were not found
4625 return self.editor.InverseDiag(NodeID1, NodeID2)
4627 def DeleteDiag(self, NodeID1, NodeID2):
4629 Replace two neighbour triangles sharing *Node1-Node2* link
4630 with a quadrangle built on the same 4 nodes.
4633 NodeID1: ID of the first node
4634 NodeID2: ID of the second node
4637 False if proper faces were not found
4640 This operation can create gaps in numeration of elements.
4641 Call :meth:`RenumberElements` to remove the gaps.
4644 return self.editor.DeleteDiag(NodeID1, NodeID2)
4646 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4648 Replace each triangle bound by Node1-Node2 segment with
4649 two triangles by connecting a node made on the link with a node
4650 opposite to the link.
4653 Node1: ID of the first node
4654 Node2: ID of the second node
4655 position: location [0,1] of the new node on the segment
4657 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4659 def AddNodeOnFace(self, face, x, y, z):
4661 Split a face into triangles by adding a new node onto the face
4662 and connecting the new node with face nodes
4665 face: ID of the face
4666 x,y,z: coordinates of the new node
4668 return self.editor.AddNodeOnFace(face, x, y, z)
4670 def Reorient(self, IDsOfElements=None):
4672 Reorient elements by ids
4675 IDsOfElements: if undefined reorients all mesh elements
4678 True if succeed else False
4681 if IDsOfElements == None:
4682 IDsOfElements = self.GetElementsId()
4683 return self.editor.Reorient(IDsOfElements)
4685 def ReorientObject(self, theObject):
4687 Reorient all elements of the object
4690 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4693 True if succeed else False
4696 if ( isinstance( theObject, Mesh )):
4697 theObject = theObject.GetMesh()
4698 return self.editor.ReorientObject(theObject)
4700 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4702 Reorient faces contained in *the2DObject*.
4705 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4706 theDirection: a desired direction of normal of *theFace*.
4707 It can be either a GEOM vector or a list of coordinates [x,y,z].
4708 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4709 compared with theDirection. It can be either ID of face or a point
4710 by which the face will be found. The point can be given as either
4711 a GEOM vertex or a list of point coordinates.
4714 number of reoriented faces
4717 unRegister = genObjUnRegister()
4719 if isinstance( the2DObject, Mesh ):
4720 the2DObject = the2DObject.GetMesh()
4721 if isinstance( the2DObject, list ):
4722 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4723 unRegister.set( the2DObject )
4724 # check theDirection
4725 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4726 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4727 if isinstance( theDirection, list ):
4728 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4729 # prepare theFace and thePoint
4730 theFace = theFaceOrPoint
4731 thePoint = PointStruct(0,0,0)
4732 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4733 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4735 if isinstance( theFaceOrPoint, list ):
4736 thePoint = PointStruct( *theFaceOrPoint )
4738 if isinstance( theFaceOrPoint, PointStruct ):
4739 thePoint = theFaceOrPoint
4741 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4743 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4745 Reorient faces contained in a list of *objectFaces*
4746 equally to faces contained in a list of *referenceFaces*.
4749 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4750 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.
4753 number of reoriented faces.
4755 if not isinstance( objectFaces, list ):
4756 objectFaces = [ objectFaces ]
4757 for i,obj2D in enumerate( objectFaces ):
4758 if isinstance( obj2D, Mesh ):
4759 objectFaces[i] = obj2D.GetMesh()
4760 if not isinstance( referenceFaces, list ):
4761 referenceFaces = [ referenceFaces ]
4763 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4766 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4768 Reorient faces according to adjacent volumes.
4771 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4772 either IDs of faces or face groups.
4773 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4774 theOutsideNormal: to orient faces to have their normals
4775 pointing either *outside* or *inside* the adjacent volumes.
4778 number of reoriented faces.
4781 unRegister = genObjUnRegister()
4783 if not isinstance( the2DObject, list ):
4784 the2DObject = [ the2DObject ]
4785 elif the2DObject and isinstance( the2DObject[0], int ):
4786 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4787 unRegister.set( the2DObject )
4788 the2DObject = [ the2DObject ]
4789 for i,obj2D in enumerate( the2DObject ):
4790 if isinstance( obj2D, Mesh ):
4791 the2DObject[i] = obj2D.GetMesh()
4792 if isinstance( obj2D, list ):
4793 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4794 unRegister.set( the2DObject[i] )
4796 if isinstance( the3DObject, Mesh ):
4797 the3DObject = the3DObject.GetMesh()
4798 if isinstance( the3DObject, list ):
4799 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4800 unRegister.set( the3DObject )
4801 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4803 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4805 Fuse the neighbouring triangles into quadrangles.
4808 IDsOfElements: The triangles to be fused.
4809 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4810 applied to possible quadrangles to choose a neighbour to fuse with.
4811 Note that not all items of :class:`SMESH.FunctorType` corresponds
4812 to numerical functors.
4813 MaxAngle: is the maximum angle between element normals at which the fusion
4814 is still performed; theMaxAngle is measured in radians.
4815 Also it could be a name of variable which defines angle in degrees.
4818 True in case of success, False otherwise.
4821 This operation can create gaps in numeration of elements.
4822 Call :meth:`RenumberElements` to remove the gaps.
4825 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4826 self.mesh.SetParameters(Parameters)
4827 if not IDsOfElements:
4828 IDsOfElements = self.GetElementsId()
4829 Functor = self.smeshpyD.GetFunctor(theCriterion)
4830 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4832 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4834 Fuse the neighbouring triangles of the object into quadrangles
4837 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4838 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4839 applied to possible quadrangles to choose a neighbour to fuse with.
4840 Note that not all items of :class:`SMESH.FunctorType` corresponds
4841 to numerical functors.
4842 MaxAngle: a max angle between element normals at which the fusion
4843 is still performed; theMaxAngle is measured in radians.
4846 True in case of success, False otherwise.
4849 This operation can create gaps in numeration of elements.
4850 Call :meth:`RenumberElements` to remove the gaps.
4853 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4854 self.mesh.SetParameters(Parameters)
4855 if isinstance( theObject, Mesh ):
4856 theObject = theObject.GetMesh()
4857 Functor = self.smeshpyD.GetFunctor(theCriterion)
4858 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4860 def QuadToTri (self, IDsOfElements, theCriterion = None):
4862 Split quadrangles into triangles.
4865 IDsOfElements: the faces to be splitted.
4866 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4867 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4868 value, then quadrangles will be split by the smallest diagonal.
4869 Note that not all items of :class:`SMESH.FunctorType` corresponds
4870 to numerical functors.
4873 True in case of success, False otherwise.
4876 This operation can create gaps in numeration of elements.
4877 Call :meth:`RenumberElements` to remove the gaps.
4879 if IDsOfElements == []:
4880 IDsOfElements = self.GetElementsId()
4881 if theCriterion is None:
4882 theCriterion = FT_MaxElementLength2D
4883 Functor = self.smeshpyD.GetFunctor(theCriterion)
4884 return self.editor.QuadToTri(IDsOfElements, Functor)
4886 def QuadToTriObject (self, theObject, theCriterion = None):
4888 Split quadrangles into triangles.
4891 theObject: the object from which the list of elements is taken,
4892 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4893 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4894 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4895 value, then quadrangles will be split by the smallest diagonal.
4896 Note that not all items of :class:`SMESH.FunctorType` corresponds
4897 to numerical functors.
4900 True in case of success, False otherwise.
4903 This operation can create gaps in numeration of elements.
4904 Call :meth:`RenumberElements` to remove the gaps.
4906 if ( isinstance( theObject, Mesh )):
4907 theObject = theObject.GetMesh()
4908 if theCriterion is None:
4909 theCriterion = FT_MaxElementLength2D
4910 Functor = self.smeshpyD.GetFunctor(theCriterion)
4911 return self.editor.QuadToTriObject(theObject, Functor)
4913 def QuadTo4Tri (self, theElements=[]):
4915 Split each of given quadrangles into 4 triangles. A node is added at the center of
4919 theElements: the faces to be splitted. This can be either
4920 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4921 or a list of face IDs. By default all quadrangles are split
4924 This operation can create gaps in numeration of elements.
4925 Call :meth:`RenumberElements` to remove the gaps.
4927 unRegister = genObjUnRegister()
4928 if isinstance( theElements, Mesh ):
4929 theElements = theElements.mesh
4930 elif not theElements:
4931 theElements = self.mesh
4932 elif isinstance( theElements, list ):
4933 theElements = self.GetIDSource( theElements, SMESH.FACE )
4934 unRegister.set( theElements )
4935 return self.editor.QuadTo4Tri( theElements )
4937 def SplitQuad (self, IDsOfElements, Diag13):
4939 Split quadrangles into triangles.
4942 IDsOfElements: the faces to be splitted
4943 Diag13 (boolean): is used to choose a diagonal for splitting.
4946 True in case of success, False otherwise.
4949 This operation can create gaps in numeration of elements.
4950 Call :meth:`RenumberElements` to remove the gaps.
4952 if IDsOfElements == []:
4953 IDsOfElements = self.GetElementsId()
4954 return self.editor.SplitQuad(IDsOfElements, Diag13)
4956 def SplitQuadObject (self, theObject, Diag13):
4958 Split quadrangles into triangles.
4961 theObject: the object from which the list of elements is taken,
4962 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4963 Diag13 (boolean): is used to choose a diagonal for splitting.
4966 True in case of success, False otherwise.
4969 This operation can create gaps in numeration of elements.
4970 Call :meth:`RenumberElements` to remove the gaps.
4972 if ( isinstance( theObject, Mesh )):
4973 theObject = theObject.GetMesh()
4974 return self.editor.SplitQuadObject(theObject, Diag13)
4976 def BestSplit (self, IDOfQuad, theCriterion):
4978 Find a better splitting of the given quadrangle.
4981 IDOfQuad: the ID of the quadrangle to be splitted.
4982 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4983 choose a diagonal for splitting.
4984 Note that not all items of :class:`SMESH.FunctorType` corresponds
4985 to numerical functors.
4988 * 1 if 1-3 diagonal is better,
4989 * 2 if 2-4 diagonal is better,
4990 * 0 if error occurs.
4993 This operation can create gaps in numeration of elements.
4994 Call :meth:`RenumberElements` to remove the gaps.
4996 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4998 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5000 Split volumic elements into tetrahedrons
5003 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5004 method: flags passing splitting method:
5005 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5006 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5009 This operation can create gaps in numeration of elements.
5010 Call :meth:`RenumberElements` to remove the gaps.
5012 unRegister = genObjUnRegister()
5013 if isinstance( elems, Mesh ):
5014 elems = elems.GetMesh()
5015 if ( isinstance( elems, list )):
5016 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5017 unRegister.set( elems )
5018 self.editor.SplitVolumesIntoTetra(elems, method)
5021 def SplitBiQuadraticIntoLinear(self, elems=None):
5023 Split bi-quadratic elements into linear ones without creation of additional nodes:
5025 - bi-quadratic triangle will be split into 3 linear quadrangles;
5026 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5027 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5029 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5030 will be split in order to keep the mesh conformal.
5033 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5034 if None (default), all bi-quadratic elements will be split
5037 This operation can create gaps in numeration of elements.
5038 Call :meth:`RenumberElements` to remove the gaps.
5040 unRegister = genObjUnRegister()
5041 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5042 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5043 unRegister.set( elems )
5045 elems = [ self.GetMesh() ]
5046 if isinstance( elems, Mesh ):
5047 elems = [ elems.GetMesh() ]
5048 if not isinstance( elems, list ):
5050 self.editor.SplitBiQuadraticIntoLinear( elems )
5052 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5053 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5055 Split hexahedra into prisms
5058 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5059 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5060 gives a normal vector defining facets to split into triangles.
5061 *startHexPoint* can be either a triple of coordinates or a vertex.
5062 facetNormal: a normal to a facet to split into triangles of a
5063 hexahedron found by *startHexPoint*.
5064 *facetNormal* can be either a triple of coordinates or an edge.
5065 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5066 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5067 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5068 to *startHexPoint* are split, else *startHexPoint*
5069 is used to find the facet to split in all domains present in *elems*.
5072 This operation can create gaps in numeration of elements.
5073 Call :meth:`RenumberElements` to remove the gaps.
5076 unRegister = genObjUnRegister()
5077 if isinstance( elems, Mesh ):
5078 elems = elems.GetMesh()
5079 if ( isinstance( elems, list )):
5080 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5081 unRegister.set( elems )
5084 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5085 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5086 elif isinstance( startHexPoint, list ):
5087 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5090 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5091 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5092 elif isinstance( facetNormal, list ):
5093 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5096 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5098 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5100 def SplitQuadsNearTriangularFacets(self):
5102 Split quadrangle faces near triangular facets of volumes
5105 This operation can create gaps in numeration of elements.
5106 Call :meth:`RenumberElements` to remove the gaps.
5108 faces_array = self.GetElementsByType(SMESH.FACE)
5109 for face_id in faces_array:
5110 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5111 quad_nodes = self.mesh.GetElemNodes(face_id)
5112 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5113 isVolumeFound = False
5114 for node1_elem in node1_elems:
5115 if not isVolumeFound:
5116 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5117 nb_nodes = self.GetElemNbNodes(node1_elem)
5118 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5119 volume_elem = node1_elem
5120 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5121 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5122 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5123 isVolumeFound = True
5124 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5125 self.SplitQuad([face_id], False) # diagonal 2-4
5126 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5127 isVolumeFound = True
5128 self.SplitQuad([face_id], True) # diagonal 1-3
5129 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5130 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5131 isVolumeFound = True
5132 self.SplitQuad([face_id], True) # diagonal 1-3
5134 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5136 Split hexahedrons into tetrahedrons.
5138 This operation uses :doc:`pattern_mapping` functionality for splitting.
5141 theObject: the object from which the list of hexahedrons is taken;
5142 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5143 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5144 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5145 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5146 key-point will be mapped into *theNode001*-th node of each volume.
5147 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5150 True in case of success, False otherwise.
5153 This operation can create gaps in numeration of elements.
5154 Call :meth:`RenumberElements` to remove the gaps.
5162 # (0,0,1) 4.---------.7 * |
5169 # (0,0,0) 0.---------.3
5170 pattern_tetra = "!!! Nb of points: \n 8 \n\
5180 !!! Indices of points of 6 tetras: \n\
5188 pattern = self.smeshpyD.GetPattern()
5189 isDone = pattern.LoadFromFile(pattern_tetra)
5191 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5194 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5195 isDone = pattern.MakeMesh(self.mesh, False, False)
5196 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5198 # split quafrangle faces near triangular facets of volumes
5199 self.SplitQuadsNearTriangularFacets()
5203 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5205 Split hexahedrons into prisms.
5207 Uses the :doc:`pattern_mapping` functionality for splitting.
5210 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5211 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5212 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5213 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5214 will be mapped into the *theNode001* -th node of each volume.
5215 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5218 True in case of success, False otherwise.
5221 This operation can create gaps in numeration of elements.
5222 Call :meth:`RenumberElements` to remove the gaps.
5224 # Pattern: 5.---------.6
5229 # (0,0,1) 4.---------.7 |
5236 # (0,0,0) 0.---------.3
5237 pattern_prism = "!!! Nb of points: \n 8 \n\
5247 !!! Indices of points of 2 prisms: \n\
5251 pattern = self.smeshpyD.GetPattern()
5252 isDone = pattern.LoadFromFile(pattern_prism)
5254 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5257 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5258 isDone = pattern.MakeMesh(self.mesh, False, False)
5259 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5261 # Split quafrangle faces near triangular facets of volumes
5262 self.SplitQuadsNearTriangularFacets()
5266 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5267 MaxNbOfIterations, MaxAspectRatio, Method):
5272 IDsOfElements: the list if ids of elements to smooth
5273 IDsOfFixedNodes: the list of ids of fixed nodes.
5274 Note that nodes built on edges and boundary nodes are always fixed.
5275 MaxNbOfIterations: the maximum number of iterations
5276 MaxAspectRatio: varies in range [1.0, inf]
5277 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5278 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5281 True in case of success, False otherwise.
5284 if IDsOfElements == []:
5285 IDsOfElements = self.GetElementsId()
5286 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5287 self.mesh.SetParameters(Parameters)
5288 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5289 MaxNbOfIterations, MaxAspectRatio, Method)
5291 def SmoothObject(self, theObject, IDsOfFixedNodes,
5292 MaxNbOfIterations, MaxAspectRatio, Method):
5294 Smooth elements which belong to the given object
5297 theObject: the object to smooth
5298 IDsOfFixedNodes: the list of ids of fixed nodes.
5299 Note that nodes built on edges and boundary nodes are always fixed.
5300 MaxNbOfIterations: the maximum number of iterations
5301 MaxAspectRatio: varies in range [1.0, inf]
5302 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5303 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5306 True in case of success, False otherwise.
5309 if ( isinstance( theObject, Mesh )):
5310 theObject = theObject.GetMesh()
5311 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5312 MaxNbOfIterations, MaxAspectRatio, Method)
5314 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5315 MaxNbOfIterations, MaxAspectRatio, Method):
5317 Parametrically smooth the given elements
5320 IDsOfElements: the list if ids of elements to smooth
5321 IDsOfFixedNodes: the list of ids of fixed nodes.
5322 Note that nodes built on edges and boundary nodes are always fixed.
5323 MaxNbOfIterations: the maximum number of iterations
5324 MaxAspectRatio: varies in range [1.0, inf]
5325 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5326 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5329 True in case of success, False otherwise.
5332 if IDsOfElements == []:
5333 IDsOfElements = self.GetElementsId()
5334 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5335 self.mesh.SetParameters(Parameters)
5336 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5337 MaxNbOfIterations, MaxAspectRatio, Method)
5339 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5340 MaxNbOfIterations, MaxAspectRatio, Method):
5342 Parametrically smooth the elements which belong to the given object
5345 theObject: the object to smooth
5346 IDsOfFixedNodes: the list of ids of fixed nodes.
5347 Note that nodes built on edges and boundary nodes are always fixed.
5348 MaxNbOfIterations: the maximum number of iterations
5349 MaxAspectRatio: varies in range [1.0, inf]
5350 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5351 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5354 True in case of success, False otherwise.
5357 if ( isinstance( theObject, Mesh )):
5358 theObject = theObject.GetMesh()
5359 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5360 MaxNbOfIterations, MaxAspectRatio, Method)
5362 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5364 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5365 them with quadratic with the same id.
5368 theForce3d: method of new node creation:
5370 * False - the medium node lies at the geometrical entity from which the mesh element is built
5371 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5372 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5373 theToBiQuad: If True, converts the mesh to bi-quadratic
5376 :class:`SMESH.ComputeError` which can hold a warning
5379 If *theSubMesh* is provided, the mesh can become non-conformal
5382 This operation can create gaps in numeration of nodes or elements.
5383 Call :meth:`RenumberElements` to remove the gaps.
5386 if isinstance( theSubMesh, Mesh ):
5387 theSubMesh = theSubMesh.mesh
5389 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5392 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5394 self.editor.ConvertToQuadratic(theForce3d)
5395 error = self.editor.GetLastError()
5396 if error and error.comment:
5397 print(error.comment)
5400 def ConvertFromQuadratic(self, theSubMesh=None):
5402 Convert the mesh from quadratic to ordinary,
5403 deletes old quadratic elements,
5404 replacing them with ordinary mesh elements with the same id.
5407 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5410 If *theSubMesh* is provided, the mesh can become non-conformal
5413 This operation can create gaps in numeration of nodes or elements.
5414 Call :meth:`RenumberElements` to remove the gaps.
5418 self.editor.ConvertFromQuadraticObject(theSubMesh)
5420 return self.editor.ConvertFromQuadratic()
5422 def Make2DMeshFrom3D(self):
5424 Create 2D mesh as skin on boundary faces of a 3D mesh
5427 True if operation has been completed successfully, False otherwise
5430 return self.editor.Make2DMeshFrom3D()
5432 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5433 toCopyElements=False, toCopyExistingBondary=False):
5435 Create missing boundary elements
5438 elements: elements whose boundary is to be checked:
5439 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5440 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5441 dimension: defines type of boundary elements to create, either of
5442 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5443 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5444 groupName: a name of group to store created boundary elements in,
5445 "" means not to create the group
5446 meshName: a name of new mesh to store created boundary elements in,
5447 "" means not to create the new mesh
5448 toCopyElements: if True, the checked elements will be copied into
5449 the new mesh else only boundary elements will be copied into the new mesh
5450 toCopyExistingBondary: if True, not only new but also pre-existing
5451 boundary elements will be copied into the new mesh
5454 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5457 unRegister = genObjUnRegister()
5458 if isinstance( elements, Mesh ):
5459 elements = elements.GetMesh()
5460 if ( isinstance( elements, list )):
5461 elemType = SMESH.ALL
5462 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5463 elements = self.editor.MakeIDSource(elements, elemType)
5464 unRegister.set( elements )
5465 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5466 toCopyElements,toCopyExistingBondary)
5467 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5470 def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
5472 Create boundary elements around the whole mesh or groups of elements
5475 groupName: a name of group to store all boundary elements in,
5476 "" means not to create the group
5477 meshName: a name of a new mesh, which is a copy of the initial
5478 mesh + created boundary elements; "" means not to create the new mesh
5479 toCopyAll: if True, the whole initial mesh will be copied into
5480 the new mesh else only boundary elements will be copied into the new mesh
5481 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5484 tuple( long, mesh, group )
5485 - long - number of added boundary elements
5486 - mesh - the :class:`Mesh` where elements were added to
5487 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5489 dimension=SMESH.BND_2DFROM3D
5490 toCreateAllElements = True # create all boundary elements in the mesh
5491 nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
5492 toCopyAll,toCreateAllElements,groups)
5493 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5494 return nb, mesh, group
5496 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5497 toCopyAll=False, groups=[]):
5499 Create missing boundary elements around either the whole mesh or
5503 dimension: defines type of boundary elements to create, either of
5504 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5505 groupName: a name of group to store all boundary elements in,
5506 "" means not to create the group
5507 meshName: a name of a new mesh, which is a copy of the initial
5508 mesh + created boundary elements; "" means not to create the new mesh
5509 toCopyAll: if True, the whole initial mesh will be copied into
5510 the new mesh else only boundary elements will be copied into the new mesh
5511 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5514 tuple( long, mesh, group )
5515 - long - number of added boundary elements
5516 - mesh - the :class:`Mesh` where elements were added to
5517 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5519 toCreateAllElements = False # create only elements in the boundary of the solid
5520 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5521 toCopyAll,toCreateAllElements,groups)
5522 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5523 return nb, mesh, group
5525 def RenumberNodes(self):
5527 Renumber mesh nodes to remove unused node IDs
5529 self.editor.RenumberNodes()
5531 def RenumberElements(self):
5533 Renumber mesh elements to remove unused element IDs
5535 self.editor.RenumberElements()
5537 def _getIdSourceList(self, arg, idType, unRegister):
5539 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5541 if arg and isinstance( arg, list ):
5542 if isinstance( arg[0], int ):
5543 arg = self.GetIDSource( arg, idType )
5544 unRegister.set( arg )
5545 elif isinstance( arg[0], Mesh ):
5546 arg[0] = arg[0].GetMesh()
5547 elif isinstance( arg, Mesh ):
5549 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5553 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5554 MakeGroups=False, TotalAngle=False):
5556 Generate new elements by rotation of the given elements and nodes around the axis
5559 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5560 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5561 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5562 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5563 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5564 which defines angle in degrees
5565 NbOfSteps: the number of steps
5566 Tolerance: tolerance
5567 MakeGroups: forces the generation of new groups from existing ones
5568 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5569 of all steps, else - size of each step
5572 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5575 unRegister = genObjUnRegister()
5576 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5577 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5578 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5580 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5581 Axis = self.smeshpyD.GetAxisStruct( Axis )
5582 if isinstance( Axis, list ):
5583 Axis = SMESH.AxisStruct( *Axis )
5585 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5586 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5587 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5588 self.mesh.SetParameters(Parameters)
5589 if TotalAngle and NbOfSteps:
5590 AngleInRadians /= NbOfSteps
5591 return self.editor.RotationSweepObjects( nodes, edges, faces,
5592 Axis, AngleInRadians,
5593 NbOfSteps, Tolerance, MakeGroups)
5595 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5596 MakeGroups=False, TotalAngle=False):
5598 Generate new elements by rotation of the elements around the axis
5601 IDsOfElements: the list of ids of elements to sweep
5602 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5603 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5604 NbOfSteps: the number of steps
5605 Tolerance: tolerance
5606 MakeGroups: forces the generation of new groups from existing ones
5607 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5608 of all steps, else - size of each step
5611 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5614 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5615 AngleInRadians, NbOfSteps, Tolerance,
5616 MakeGroups, TotalAngle)
5618 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5619 MakeGroups=False, TotalAngle=False):
5621 Generate new elements by rotation of the elements of object around the axis
5622 theObject object which elements should be sweeped.
5623 It can be a mesh, a sub mesh or a group.
5626 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5627 AngleInRadians: the angle of Rotation
5628 NbOfSteps: number of steps
5629 Tolerance: tolerance
5630 MakeGroups: forces the generation of new groups from existing ones
5631 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5632 of all steps, else - size of each step
5635 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5638 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5639 AngleInRadians, NbOfSteps, Tolerance,
5640 MakeGroups, TotalAngle )
5642 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5643 MakeGroups=False, TotalAngle=False):
5645 Generate new elements by rotation of the elements of object around the axis
5646 theObject object which elements should be sweeped.
5647 It can be a mesh, a sub mesh or a group.
5650 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5651 AngleInRadians: the angle of Rotation
5652 NbOfSteps: number of steps
5653 Tolerance: tolerance
5654 MakeGroups: forces the generation of new groups from existing ones
5655 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5656 of all steps, else - size of each step
5659 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5660 empty list otherwise
5663 return self.RotationSweepObjects([],theObject,[], Axis,
5664 AngleInRadians, NbOfSteps, Tolerance,
5665 MakeGroups, TotalAngle)
5667 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5668 MakeGroups=False, TotalAngle=False):
5670 Generate new elements by rotation of the elements of object around the axis
5671 theObject object which elements should be sweeped.
5672 It can be a mesh, a sub mesh or a group.
5675 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5676 AngleInRadians: the angle of Rotation
5677 NbOfSteps: number of steps
5678 Tolerance: tolerance
5679 MakeGroups: forces the generation of new groups from existing ones
5680 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5681 of all steps, else - size of each step
5684 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5687 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5688 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5690 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5691 scaleFactors=[], linearVariation=False, basePoint=[],
5692 angles=[], anglesVariation=False):
5694 Generate new elements by extrusion of the given elements and nodes
5697 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5698 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5699 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5700 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5701 the direction and value of extrusion for one step (the total extrusion
5702 length will be NbOfSteps * ||StepVector||)
5703 NbOfSteps: the number of steps
5704 MakeGroups: forces the generation of new groups from existing ones
5705 scaleFactors: optional scale factors to apply during extrusion
5706 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5707 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5708 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5709 nodes and elements being extruded is used as the scaling center.
5712 - a list of tree components of the point or
5715 angles: list of angles in radians. Nodes at each extrusion step are rotated
5716 around *basePoint*, additionally to previous steps.
5717 anglesVariation: forces the computation of rotation angles as linear
5718 variation of the given *angles* along path steps
5720 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5722 Example: :ref:`tui_extrusion`
5724 unRegister = genObjUnRegister()
5725 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5726 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5727 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5729 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5730 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5731 if isinstance( StepVector, list ):
5732 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5734 if isinstance( basePoint, int):
5735 xyz = self.GetNodeXYZ( basePoint )
5737 raise RuntimeError("Invalid node ID: %s" % basePoint)
5739 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5740 basePoint = self.geompyD.PointCoordinates( basePoint )
5742 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5743 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5744 angles,angleParameters,hasVars = ParseAngles(angles)
5745 Parameters = StepVector.PS.parameters + var_separator + \
5746 Parameters + var_separator + \
5747 scaleParameters + var_separator + angleParameters
5748 self.mesh.SetParameters(Parameters)
5750 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5751 StepVector, NbOfSteps, MakeGroups,
5752 scaleFactors, linearVariation, basePoint,
5753 angles, anglesVariation )
5756 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5758 Generate new elements by extrusion of the elements with given ids
5761 IDsOfElements: the list of ids of elements or nodes for extrusion
5762 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5763 the direction and value of extrusion for one step (the total extrusion
5764 length will be NbOfSteps * ||StepVector||)
5765 NbOfSteps: the number of steps
5766 MakeGroups: forces the generation of new groups from existing ones
5767 IsNodes: is True if elements with given ids are nodes
5770 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5772 Example: :ref:`tui_extrusion`
5775 if IsNodes: n = IDsOfElements
5776 else : e,f, = IDsOfElements,IDsOfElements
5777 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5779 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5780 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5782 Generate new elements by extrusion along the normal to a discretized surface or wire
5785 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5786 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5787 StepSize: length of one extrusion step (the total extrusion
5788 length will be *NbOfSteps* *StepSize*).
5789 NbOfSteps: number of extrusion steps.
5790 ByAverageNormal: if True each node is translated by *StepSize*
5791 along the average of the normal vectors to the faces sharing the node;
5792 else each node is translated along the same average normal till
5793 intersection with the plane got by translation of the face sharing
5794 the node along its own normal by *StepSize*.
5795 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5796 for every node of *Elements*.
5797 MakeGroups: forces generation of new groups from existing ones.
5798 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5799 is not yet implemented. This parameter is used if *Elements* contains
5800 both faces and edges, i.e. *Elements* is a Mesh.
5803 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5804 empty list otherwise.
5805 Example: :ref:`tui_extrusion`
5808 unRegister = genObjUnRegister()
5809 if isinstance( Elements, Mesh ):
5810 Elements = [ Elements.GetMesh() ]
5811 if isinstance( Elements, list ):
5813 raise RuntimeError("Elements empty!")
5814 if isinstance( Elements[0], Mesh ):
5815 Elements = [ Elements[0].GetMesh() ]
5816 if isinstance( Elements[0], int ):
5817 Elements = self.GetIDSource( Elements, SMESH.ALL )
5818 unRegister.set( Elements )
5819 if not isinstance( Elements, list ):
5820 Elements = [ Elements ]
5821 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5822 self.mesh.SetParameters(Parameters)
5823 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5824 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5826 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5828 Generate new elements by extrusion of the elements or nodes which belong to the object
5831 theObject: the object whose elements or nodes should be processed.
5832 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5833 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5834 the direction and value of extrusion for one step (the total extrusion
5835 length will be NbOfSteps * ||StepVector||)
5836 NbOfSteps: the number of steps
5837 MakeGroups: forces the generation of new groups from existing ones
5838 IsNodes: is True if elements to extrude are nodes
5841 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5842 Example: :ref:`tui_extrusion`
5846 if IsNodes: n = theObject
5847 else : e,f, = theObject,theObject
5848 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5850 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5852 Generate new elements by extrusion of edges which belong to the object
5855 theObject: object whose 1D elements should be processed.
5856 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5857 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5858 the direction and value of extrusion for one step (the total extrusion
5859 length will be NbOfSteps * ||StepVector||)
5860 NbOfSteps: the number of steps
5861 MakeGroups: to generate new groups from existing ones
5864 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5865 Example: :ref:`tui_extrusion`
5868 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5870 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5872 Generate new elements by extrusion of faces which belong to the object
5875 theObject: object whose 2D elements should be processed.
5876 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5877 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5878 the direction and value of extrusion for one step (the total extrusion
5879 length will be NbOfSteps * ||StepVector||)
5880 NbOfSteps: the number of steps
5881 MakeGroups: forces the generation of new groups from existing ones
5884 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5885 Example: :ref:`tui_extrusion`
5888 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5890 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5891 ExtrFlags, SewTolerance, MakeGroups=False):
5893 Generate new elements by extrusion of the elements with given ids
5896 IDsOfElements: is ids of elements
5897 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5898 the direction and value of extrusion for one step (the total extrusion
5899 length will be NbOfSteps * ||StepVector||)
5900 NbOfSteps: the number of steps
5901 ExtrFlags: sets flags for extrusion
5902 SewTolerance: uses for comparing locations of nodes if flag
5903 EXTRUSION_FLAG_SEW is set
5904 MakeGroups: forces the generation of new groups from existing ones
5907 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5910 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5911 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5912 if isinstance( StepVector, list ):
5913 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5914 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5915 ExtrFlags, SewTolerance, MakeGroups)
5917 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5918 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5919 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5920 ScaleFactors=[], ScalesVariation=False):
5922 Generate new elements by extrusion of the given elements and nodes along the path.
5923 The path of extrusion must be a meshed edge.
5926 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5927 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5928 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5929 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5930 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
5931 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5932 HasAngles: not used obsolete
5933 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5934 around *basePoint*, additionally to previous steps.
5935 LinearVariation: forces the computation of rotation angles as linear
5936 variation of the given Angles along path steps
5937 HasRefPoint: allows using the reference point
5938 RefPoint: optional scaling and rotation center (mass center of the extruded
5939 elements by default). The User can specify any point as the Reference Point.
5940 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5941 MakeGroups: forces the generation of new groups from existing ones
5942 ScaleFactors: optional scale factors to apply during extrusion
5943 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5944 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5947 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5948 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5949 Example: :ref:`tui_extrusion_along_path`
5952 unRegister = genObjUnRegister()
5953 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5954 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5955 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5957 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5958 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5959 if isinstance( RefPoint, list ):
5960 if not RefPoint: RefPoint = [0,0,0]
5961 RefPoint = SMESH.PointStruct( *RefPoint )
5962 if isinstance( PathObject, Mesh ):
5963 PathObject = PathObject.GetMesh()
5964 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5965 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5966 Parameters = AnglesParameters + var_separator + \
5967 RefPoint.parameters + var_separator + ScalesParameters
5968 self.mesh.SetParameters(Parameters)
5969 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5970 PathObject, PathShape, NodeStart,
5971 HasAngles, Angles, LinearVariation,
5972 HasRefPoint, RefPoint, MakeGroups,
5973 ScaleFactors, ScalesVariation)
5975 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5976 HasAngles=False, Angles=[], LinearVariation=False,
5977 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5978 ElemType=SMESH.FACE):
5980 Generate new elements by extrusion of the given elements.
5981 The path of extrusion must be a meshed edge.
5984 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5985 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5986 NodeStart: the start node from Path. Defines the direction of extrusion
5987 HasAngles: not used obsolete
5988 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5989 around *basePoint*, additionally to previous steps.
5990 LinearVariation: forces the computation of rotation angles as linear
5991 variation of the given Angles along path steps
5992 HasRefPoint: allows using the reference point
5993 RefPoint: the reference point around which the elements are rotated (the mass
5994 center of the elements by default).
5995 The User can specify any point as the Reference Point.
5996 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5997 MakeGroups: forces the generation of new groups from existing ones
5998 ElemType: type of elements for extrusion (if param Base is a mesh)
6001 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6002 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6003 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6005 Example: :ref:`tui_extrusion_along_path`
6009 if ElemType == SMESH.NODE: n = Base
6010 if ElemType == SMESH.EDGE: e = Base
6011 if ElemType == SMESH.FACE: f = Base
6012 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
6013 HasAngles, Angles, LinearVariation,
6014 HasRefPoint, RefPoint, MakeGroups)
6015 if MakeGroups: return gr,er
6018 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
6019 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6020 MakeGroups=False, LinearVariation=False):
6022 Generate new elements by extrusion of the given elements.
6023 The path of extrusion must be a meshed edge.
6026 IDsOfElements: ids of elements
6027 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6028 PathShape: shape (edge) defines the sub-mesh for the path
6029 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6030 HasAngles: not used obsolete
6031 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6032 around *basePoint*, additionally to previous steps.
6033 HasRefPoint: allows using the reference point
6034 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6035 The User can specify any point as the Reference Point.
6036 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6037 MakeGroups: forces the generation of new groups from existing ones
6038 LinearVariation: forces the computation of rotation angles as linear
6039 variation of the given Angles along path steps
6042 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6043 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6044 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6045 Example: :ref:`tui_extrusion_along_path`
6048 if not IDsOfElements:
6049 IDsOfElements = [ self.GetMesh() ]
6050 n,e,f = [],IDsOfElements,IDsOfElements
6051 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6052 NodeStart, HasAngles, Angles,
6054 HasRefPoint, RefPoint, MakeGroups)
6055 if MakeGroups: return gr,er
6058 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6059 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6060 MakeGroups=False, LinearVariation=False):
6062 Generate new elements by extrusion of the elements which belong to the object.
6063 The path of extrusion must be a meshed edge.
6066 theObject: the object whose elements should be processed.
6067 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6068 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6069 PathShape: shape (edge) defines the sub-mesh for the path
6070 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6071 HasAngles: not used obsolete
6072 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6073 around *basePoint*, additionally to previous steps.
6074 HasRefPoint: allows using the reference point
6075 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6076 The User can specify any point as the Reference Point.
6077 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6078 MakeGroups: forces the generation of new groups from existing ones
6079 LinearVariation: forces the computation of rotation angles as linear
6080 variation of the given Angles along path steps
6083 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6084 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6085 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6086 Example: :ref:`tui_extrusion_along_path`
6089 n,e,f = [],theObject,theObject
6090 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6091 HasAngles, Angles, LinearVariation,
6092 HasRefPoint, RefPoint, MakeGroups)
6093 if MakeGroups: return gr,er
6096 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6097 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6098 MakeGroups=False, LinearVariation=False):
6100 Generate new elements by extrusion of mesh segments which belong to the object.
6101 The path of extrusion must be a meshed edge.
6104 theObject: the object whose 1D elements should be processed.
6105 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6106 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6107 PathShape: shape (edge) defines the sub-mesh for the path
6108 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6109 HasAngles: not used obsolete
6110 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6111 around *basePoint*, additionally to previous steps.
6112 HasRefPoint: allows using the reference point
6113 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6114 The User can specify any point as the Reference Point.
6115 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6116 MakeGroups: forces the generation of new groups from existing ones
6117 LinearVariation: forces the computation of rotation angles as linear
6118 variation of the given Angles along path steps
6121 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6122 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6123 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6124 Example: :ref:`tui_extrusion_along_path`
6127 n,e,f = [],theObject,[]
6128 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6129 HasAngles, Angles, LinearVariation,
6130 HasRefPoint, RefPoint, MakeGroups)
6131 if MakeGroups: return gr,er
6134 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6135 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6136 MakeGroups=False, LinearVariation=False):
6138 Generate new elements by extrusion of faces which belong to the object.
6139 The path of extrusion must be a meshed edge.
6142 theObject: the object whose 2D elements should be processed.
6143 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6144 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6145 PathShape: shape (edge) defines the sub-mesh for the path
6146 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6147 HasAngles: not used obsolete
6148 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6149 around *basePoint*, additionally to previous steps.
6150 HasRefPoint: allows using the reference point
6151 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6152 The User can specify any point as the Reference Point.
6153 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6154 MakeGroups: forces the generation of new groups from existing ones
6155 LinearVariation: forces the computation of rotation angles as linear
6156 variation of the given Angles along path steps
6159 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6160 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6161 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6162 Example: :ref:`tui_extrusion_along_path`
6165 n,e,f = [],[],theObject
6166 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6167 HasAngles, Angles, LinearVariation,
6168 HasRefPoint, RefPoint, MakeGroups)
6169 if MakeGroups: return gr,er
6172 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6174 Create a symmetrical copy of mesh elements
6177 IDsOfElements: 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 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6182 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6185 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
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 if Copy and MakeGroups:
6196 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6197 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6200 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6202 Create a new mesh by a symmetrical copy of mesh elements
6205 IDsOfElements: the list of elements ids
6206 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6207 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6208 If the *Mirror* is a geom object this parameter is unnecessary
6209 MakeGroups: to generate new groups from existing ones
6210 NewMeshName: a name of the new mesh to create
6213 instance of class :class:`Mesh`
6216 if IDsOfElements == []:
6217 IDsOfElements = self.GetElementsId()
6218 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6219 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6220 theMirrorType = Mirror._mirrorType
6222 self.mesh.SetParameters(Mirror.parameters)
6223 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6224 MakeGroups, NewMeshName)
6225 return Mesh(self.smeshpyD,self.geompyD,mesh)
6227 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6229 Create 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 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6237 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6240 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
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 if Copy and MakeGroups:
6251 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6252 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6255 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6257 Create a new mesh by a symmetrical copy of the object
6260 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6261 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6262 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6263 If the *Mirror* is a geom object this parameter is unnecessary
6264 MakeGroups: forces the generation of new groups from existing ones
6265 NewMeshName: the name of the new mesh to create
6268 instance of class :class:`Mesh`
6271 if ( isinstance( theObject, Mesh )):
6272 theObject = theObject.GetMesh()
6273 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6274 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6275 theMirrorType = Mirror._mirrorType
6277 self.mesh.SetParameters(Mirror.parameters)
6278 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6279 MakeGroups, NewMeshName)
6280 return Mesh( self.smeshpyD,self.geompyD,mesh )
6282 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6284 Translate the elements
6287 IDsOfElements: list of elements ids
6288 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6289 Copy: allows copying the translated elements
6290 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6293 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6296 if IDsOfElements == []:
6297 IDsOfElements = self.GetElementsId()
6298 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6299 Vector = self.smeshpyD.GetDirStruct(Vector)
6300 if isinstance( Vector, list ):
6301 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6302 self.mesh.SetParameters(Vector.PS.parameters)
6303 if Copy and MakeGroups:
6304 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6305 self.editor.Translate(IDsOfElements, Vector, Copy)
6308 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6310 Create a new mesh of translated elements
6313 IDsOfElements: list of elements ids
6314 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6315 MakeGroups: forces the generation of new groups from existing ones
6316 NewMeshName: the name of the newly created mesh
6319 instance of class :class:`Mesh`
6322 if IDsOfElements == []:
6323 IDsOfElements = self.GetElementsId()
6324 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6325 Vector = self.smeshpyD.GetDirStruct(Vector)
6326 if isinstance( Vector, list ):
6327 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6328 self.mesh.SetParameters(Vector.PS.parameters)
6329 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6330 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6332 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6334 Translate the object
6337 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6338 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6339 Copy: allows copying the translated elements
6340 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6343 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6346 if ( isinstance( theObject, Mesh )):
6347 theObject = theObject.GetMesh()
6348 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6349 Vector = self.smeshpyD.GetDirStruct(Vector)
6350 if isinstance( Vector, list ):
6351 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6352 self.mesh.SetParameters(Vector.PS.parameters)
6353 if Copy and MakeGroups:
6354 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6355 self.editor.TranslateObject(theObject, Vector, Copy)
6358 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6360 Create a new mesh from the translated object
6363 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6364 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6365 MakeGroups: forces the generation of new groups from existing ones
6366 NewMeshName: the name of the newly created mesh
6369 instance of class :class:`Mesh`
6372 if isinstance( theObject, Mesh ):
6373 theObject = theObject.GetMesh()
6374 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6375 Vector = self.smeshpyD.GetDirStruct(Vector)
6376 if isinstance( Vector, list ):
6377 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6378 self.mesh.SetParameters(Vector.PS.parameters)
6379 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6380 return Mesh( self.smeshpyD, self.geompyD, mesh )
6384 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6389 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6390 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6391 theScaleFact: list of 1-3 scale factors for axises
6392 Copy: allows copying the translated elements
6393 MakeGroups: forces the generation of new groups from existing
6397 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6398 empty list otherwise
6400 unRegister = genObjUnRegister()
6401 if ( isinstance( theObject, Mesh )):
6402 theObject = theObject.GetMesh()
6403 if ( isinstance( theObject, list )):
6404 theObject = self.GetIDSource(theObject, SMESH.ALL)
6405 unRegister.set( theObject )
6406 if ( isinstance( thePoint, list )):
6407 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6408 if ( isinstance( theScaleFact, float )):
6409 theScaleFact = [theScaleFact]
6410 if ( isinstance( theScaleFact, int )):
6411 theScaleFact = [ float(theScaleFact)]
6413 self.mesh.SetParameters(thePoint.parameters)
6415 if Copy and MakeGroups:
6416 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6417 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6420 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6422 Create a new mesh from the translated object
6425 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6426 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6427 theScaleFact: list of 1-3 scale factors for axises
6428 MakeGroups: forces the generation of new groups from existing ones
6429 NewMeshName: the name of the newly created mesh
6432 instance of class :class:`Mesh`
6434 unRegister = genObjUnRegister()
6435 if (isinstance(theObject, Mesh)):
6436 theObject = theObject.GetMesh()
6437 if ( isinstance( theObject, list )):
6438 theObject = self.GetIDSource(theObject,SMESH.ALL)
6439 unRegister.set( theObject )
6440 if ( isinstance( thePoint, list )):
6441 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6442 if ( isinstance( theScaleFact, float )):
6443 theScaleFact = [theScaleFact]
6444 if ( isinstance( theScaleFact, int )):
6445 theScaleFact = [ float(theScaleFact)]
6447 self.mesh.SetParameters(thePoint.parameters)
6448 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6449 MakeGroups, NewMeshName)
6450 return Mesh( self.smeshpyD, self.geompyD, mesh )
6454 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6459 IDsOfElements: list of elements 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 Copy: allows copying the rotated elements
6463 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6466 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6470 if IDsOfElements == []:
6471 IDsOfElements = self.GetElementsId()
6472 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6473 Axis = self.smeshpyD.GetAxisStruct(Axis)
6474 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6475 Parameters = Axis.parameters + var_separator + Parameters
6476 self.mesh.SetParameters(Parameters)
6477 if Copy and MakeGroups:
6478 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6479 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6482 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6484 Create a new mesh of rotated elements
6487 IDsOfElements: list of element ids
6488 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6489 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6490 MakeGroups: forces the generation of new groups from existing ones
6491 NewMeshName: the name of the newly created mesh
6494 instance of class :class:`Mesh`
6497 if IDsOfElements == []:
6498 IDsOfElements = self.GetElementsId()
6499 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6500 Axis = self.smeshpyD.GetAxisStruct(Axis)
6501 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6502 Parameters = Axis.parameters + var_separator + Parameters
6503 self.mesh.SetParameters(Parameters)
6504 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6505 MakeGroups, NewMeshName)
6506 return Mesh( self.smeshpyD, self.geompyD, mesh )
6508 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6513 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6514 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6515 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6516 Copy: allows copying the rotated elements
6517 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6520 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6523 if (isinstance(theObject, Mesh)):
6524 theObject = theObject.GetMesh()
6525 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6526 Axis = self.smeshpyD.GetAxisStruct(Axis)
6527 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6528 Parameters = Axis.parameters + ":" + Parameters
6529 self.mesh.SetParameters(Parameters)
6530 if Copy and MakeGroups:
6531 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6532 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6535 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6537 Create a new mesh from the rotated object
6540 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6541 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6542 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6543 MakeGroups: forces the generation of new groups from existing ones
6544 NewMeshName: the name of the newly created mesh
6547 instance of class :class:`Mesh`
6550 if (isinstance( theObject, Mesh )):
6551 theObject = theObject.GetMesh()
6552 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6553 Axis = self.smeshpyD.GetAxisStruct(Axis)
6554 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6555 Parameters = Axis.parameters + ":" + Parameters
6556 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6557 MakeGroups, NewMeshName)
6558 self.mesh.SetParameters(Parameters)
6559 return Mesh( self.smeshpyD, self.geompyD, mesh )
6561 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6563 Create an offset mesh from the given 2D object
6566 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6567 theValue (float): signed offset size
6568 MakeGroups (boolean): forces the generation of new groups from existing ones
6569 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6570 False means to remove original elements.
6571 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6574 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6577 if isinstance( theObject, Mesh ):
6578 theObject = theObject.GetMesh()
6579 theValue,Parameters,hasVars = ParseParameters(Value)
6580 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6581 self.mesh.SetParameters(Parameters)
6583 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6586 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6588 Find groups of adjacent nodes within Tolerance.
6591 Tolerance (float): the value of tolerance
6592 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6593 corner and medium nodes in separate groups thus preventing
6594 their further merge.
6597 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6600 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6602 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6603 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6605 Find groups of adjacent nodes within Tolerance.
6608 Tolerance: the value of tolerance
6609 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6610 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6611 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6612 corner and medium nodes in separate groups thus preventing
6613 their further merge.
6616 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6619 unRegister = genObjUnRegister()
6620 if not isinstance( SubMeshOrGroup, list ):
6621 SubMeshOrGroup = [ SubMeshOrGroup ]
6622 for i,obj in enumerate( SubMeshOrGroup ):
6623 if isinstance( obj, Mesh ):
6624 SubMeshOrGroup = [ obj.GetMesh() ]
6626 if isinstance( obj, int ):
6627 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6628 unRegister.set( SubMeshOrGroup )
6631 if not isinstance( exceptNodes, list ):
6632 exceptNodes = [ exceptNodes ]
6633 if exceptNodes and isinstance( exceptNodes[0], int ):
6634 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6635 unRegister.set( exceptNodes )
6637 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6638 exceptNodes, SeparateCornerAndMediumNodes)
6640 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6645 GroupsOfNodes: a list of groups of nodes IDs for merging.
6646 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6647 in all elements and mesh groups by nodes 1 and 25 correspondingly
6648 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6649 If *NodesToKeep* does not include a node to keep for some group to merge,
6650 then the first node in the group is kept.
6651 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6655 This operation can create gaps in numeration of nodes or elements.
6656 Call :meth:`RenumberElements` to remove the gaps.
6658 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6660 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6662 Find the elements built on the same nodes.
6665 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6666 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6670 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6673 unRegister = genObjUnRegister()
6674 if MeshOrSubMeshOrGroup is None:
6675 MeshOrSubMeshOrGroup = [ self.mesh ]
6676 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6677 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6678 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6679 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6680 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6681 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6682 unRegister.set( MeshOrSubMeshOrGroup )
6683 for item in MeshOrSubMeshOrGroup:
6684 if isinstance( item, Mesh ):
6685 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6687 if not isinstance( exceptElements, list ):
6688 exceptElements = [ exceptElements ]
6689 if exceptElements and isinstance( exceptElements[0], int ):
6690 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6691 unRegister.set( exceptElements )
6693 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6695 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6697 Merge elements in each given group.
6700 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6701 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6702 replaced in all mesh groups by elements 1 and 25)
6703 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6704 If *ElementsToKeep* does not include an element to keep for some group to merge,
6705 then the first element in the group is kept.
6708 This operation can create gaps in numeration of elements.
6709 Call :meth:`RenumberElements` to remove the gaps.
6712 unRegister = genObjUnRegister()
6714 if not isinstance( ElementsToKeep, list ):
6715 ElementsToKeep = [ ElementsToKeep ]
6716 if isinstance( ElementsToKeep[0], int ):
6717 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6718 unRegister.set( ElementsToKeep )
6720 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6722 def MergeEqualElements(self):
6724 Leave one element and remove all other elements built on the same nodes.
6727 This operation can create gaps in numeration of elements.
6728 Call :meth:`RenumberElements` to remove the gaps.
6731 self.editor.MergeEqualElements()
6733 def FindFreeBorders(self, ClosedOnly=True):
6735 Returns all or only closed free borders
6738 list of SMESH.FreeBorder's
6741 return self.editor.FindFreeBorders( ClosedOnly )
6743 def FillHole(self, holeNodes, groupName=""):
6745 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6748 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6749 must describe all sequential nodes of the hole border. The first and the last
6750 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6751 groupName (string): name of a group to add new faces
6753 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6757 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6758 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6759 if not isinstance( holeNodes, SMESH.FreeBorder ):
6760 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6761 return self.editor.FillHole( holeNodes, groupName )
6763 def FindCoincidentFreeBorders (self, tolerance=0.):
6765 Return groups of FreeBorder's coincident within the given tolerance.
6768 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6769 size of elements adjacent to free borders being compared is used.
6772 SMESH.CoincidentFreeBorders structure
6775 return self.editor.FindCoincidentFreeBorders( tolerance )
6777 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6779 Sew FreeBorder's of each group
6782 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6783 where each enclosed list contains node IDs of a group of coincident free
6784 borders such that each consequent triple of IDs within a group describes
6785 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6786 last node of a border.
6787 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6788 groups of coincident free borders, each group including two borders.
6789 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6790 polygons if a node of opposite border falls on a face edge, else such
6791 faces are split into several ones.
6792 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6793 polyhedra if a node of opposite border falls on a volume edge, else such
6794 volumes, if any, remain intact and the mesh becomes non-conformal.
6797 a number of successfully sewed groups
6800 This operation can create gaps in numeration of nodes or elements.
6801 Call :meth:`RenumberElements` to remove the gaps.
6804 if freeBorders and isinstance( freeBorders, list ):
6805 # construct SMESH.CoincidentFreeBorders
6806 if isinstance( freeBorders[0], int ):
6807 freeBorders = [freeBorders]
6809 coincidentGroups = []
6810 for nodeList in freeBorders:
6811 if not nodeList or len( nodeList ) % 3:
6812 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6815 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6816 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6817 nodeList = nodeList[3:]
6819 coincidentGroups.append( group )
6821 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6823 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6825 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6826 FirstNodeID2, SecondNodeID2, LastNodeID2,
6827 CreatePolygons, CreatePolyedrs):
6832 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6835 This operation can create gaps in numeration of nodes or elements.
6836 Call :meth:`RenumberElements` to remove the gaps.
6839 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6840 FirstNodeID2, SecondNodeID2, LastNodeID2,
6841 CreatePolygons, CreatePolyedrs)
6843 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6844 FirstNodeID2, SecondNodeID2):
6846 Sew conform free borders
6849 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6852 This operation can create gaps in numeration of elements.
6853 Call :meth:`RenumberElements` to remove the gaps.
6856 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6857 FirstNodeID2, SecondNodeID2)
6859 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6860 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6865 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6868 This operation can create gaps in numeration of elements.
6869 Call :meth:`RenumberElements` to remove the gaps.
6872 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6873 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6875 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6876 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6877 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6879 Sew two sides of a mesh. The nodes belonging to Side1 are
6880 merged with the nodes of elements of Side2.
6881 The number of elements in theSide1 and in theSide2 must be
6882 equal and they should have similar nodal connectivity.
6883 The nodes to merge should belong to side borders and
6884 the first node should be linked to the second.
6887 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6890 This operation can create gaps in numeration of nodes.
6891 Call :meth:`RenumberElements` to remove the gaps.
6894 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6895 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6896 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6898 def ChangeElemNodes(self, ide, newIDs):
6900 Set new nodes for the given element. Number of nodes should be kept.
6907 False if the number of nodes does not correspond to the type of element
6910 return self.editor.ChangeElemNodes(ide, newIDs)
6912 def GetLastCreatedNodes(self):
6914 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6915 created, this method return the list of their IDs.
6916 If new nodes were not created - return empty list
6919 the list of integer values (can be empty)
6922 return self.editor.GetLastCreatedNodes()
6924 def GetLastCreatedElems(self):
6926 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6927 created this method return the list of their IDs.
6928 If new elements were not created - return empty list
6931 the list of integer values (can be empty)
6934 return self.editor.GetLastCreatedElems()
6936 def ClearLastCreated(self):
6938 Forget what nodes and elements were created by the last mesh edition operation
6941 self.editor.ClearLastCreated()
6943 def DoubleElements(self, theElements, theGroupName=""):
6945 Create duplicates of given elements, i.e. create new elements based on the
6946 same nodes as the given ones.
6949 theElements: container of elements to duplicate. It can be a
6950 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6951 or a list of element IDs. If *theElements* is
6952 a :class:`Mesh`, elements of highest dimension are duplicated
6953 theGroupName: a name of group to contain the generated elements.
6954 If a group with such a name already exists, the new elements
6955 are added to the existing group, else a new group is created.
6956 If *theGroupName* is empty, new elements are not added
6960 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6961 None if *theGroupName* == "".
6964 unRegister = genObjUnRegister()
6965 if isinstance( theElements, Mesh ):
6966 theElements = theElements.mesh
6967 elif isinstance( theElements, list ):
6968 theElements = self.GetIDSource( theElements, SMESH.ALL )
6969 unRegister.set( theElements )
6970 return self.editor.DoubleElements(theElements, theGroupName)
6972 def DoubleNodes(self, theNodes, theModifiedElems):
6974 Create a hole in a mesh by doubling the nodes of some particular elements
6977 theNodes: IDs of nodes to be doubled
6978 theModifiedElems: IDs of elements to be updated by the new (doubled)
6979 nodes. If list of element identifiers is empty then nodes are doubled but
6980 they not assigned to elements
6983 True if operation has been completed successfully, False otherwise
6986 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6988 def DoubleNode(self, theNodeId, theModifiedElems):
6990 Create a hole in a mesh by doubling the nodes of some particular elements.
6991 This method provided for convenience works as :meth:`DoubleNodes`.
6994 theNodeId: IDs of node to double
6995 theModifiedElems: IDs of elements to update
6998 True if operation has been completed successfully, False otherwise
7001 return self.editor.DoubleNode(theNodeId, theModifiedElems)
7003 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
7005 Create a hole in a mesh by doubling the nodes of some particular elements.
7006 This method provided for convenience works as :meth:`DoubleNodes`.
7009 theNodes: group of nodes to double.
7010 theModifiedElems: group of elements to update.
7011 theMakeGroup: forces the generation of a group containing new nodes.
7014 True or a created group if operation has been completed successfully,
7015 False or None otherwise
7019 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
7020 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7022 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7024 Create a hole in a mesh by doubling the nodes of some particular elements.
7025 This method provided for convenience works as :meth:`DoubleNodes`.
7028 theNodes: list of groups of nodes to double.
7029 theModifiedElems: list of groups of elements to update.
7030 theMakeGroup: forces the generation of a group containing new nodes.
7033 True if operation has been completed successfully, False otherwise
7037 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7038 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7040 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7042 Create a hole in a mesh by doubling the nodes of some particular elements
7045 theElems: the list of elements (edges or faces) to replicate.
7046 The nodes for duplication could be found from these elements
7047 theNodesNot: list of nodes NOT to replicate
7048 theAffectedElems: the list of elements (cells and edges) to which the
7049 replicated nodes should be associated to
7052 True if operation has been completed successfully, False otherwise
7055 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7057 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7059 Create a hole in a mesh by doubling the nodes of some particular elements
7062 theElems: the list of elements (edges or faces) to replicate.
7063 The nodes for duplication could be found from these elements
7064 theNodesNot: list of nodes NOT to replicate
7065 theShape: shape to detect affected elements (element which geometric center
7066 located on or inside shape).
7067 The replicated nodes should be associated to affected elements.
7070 True if operation has been completed successfully, False otherwise
7073 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7075 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7076 theMakeGroup=False, theMakeNodeGroup=False):
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 theAffectedElems: group of elements to which the replicated nodes
7085 should be associated to.
7086 theMakeGroup: forces the generation of a group containing new elements.
7087 theMakeNodeGroup: forces the generation of a group containing new nodes.
7090 True or created groups (one or two) if operation has been completed successfully,
7091 False or None otherwise
7094 if theMakeGroup or theMakeNodeGroup:
7095 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7097 theMakeGroup, theMakeNodeGroup)
7098 if theMakeGroup and theMakeNodeGroup:
7101 return twoGroups[ int(theMakeNodeGroup) ]
7102 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7104 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7106 Create a hole in a mesh by doubling the nodes of some particular elements.
7107 This method provided for convenience works as :meth:`DoubleNodes`.
7110 theElems: group of of elements (edges or faces) to replicate
7111 theNodesNot: group of nodes not to replicate
7112 theShape: shape to detect affected elements (element which geometric center
7113 located on or inside shape).
7114 The replicated nodes should be associated to affected elements
7117 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7119 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7120 theMakeGroup=False, theMakeNodeGroup=False):
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 theAffectedElems: group of elements to which the replicated nodes
7129 should be associated to
7130 theMakeGroup: forces generation of a group containing new elements.
7131 theMakeNodeGroup: forces generation of a group containing new nodes
7134 True or created groups (one or two) if operation has been completed successfully,
7135 False or None otherwise
7138 if theMakeGroup or theMakeNodeGroup:
7139 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7141 theMakeGroup, theMakeNodeGroup)
7142 if theMakeGroup and theMakeNodeGroup:
7145 return twoGroups[ int(theMakeNodeGroup) ]
7146 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7148 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7150 Create a hole in a mesh by doubling the nodes of some particular elements.
7151 This method provided for convenience works as :meth:`DoubleNodes`.
7154 theElems: list of groups of elements (edges or faces) to replicate
7155 theNodesNot: list of groups of nodes NOT to replicate
7156 theShape: shape to detect affected elements (element which geometric center
7157 located on or inside shape).
7158 The replicated nodes should be associated to affected elements
7161 True if operation has been completed successfully, False otherwise
7164 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7166 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7168 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7169 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7172 theElems: list of groups of nodes or elements (edges or faces) to replicate
7173 theNodesNot: list of groups of nodes NOT to replicate
7174 theShape: shape to detect affected elements (element which geometric center
7175 located on or inside shape).
7176 The replicated nodes should be associated to affected elements
7179 groups of affected elements in order: volumes, faces, edges
7182 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7184 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7187 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7188 The list of groups must describe a partition of the mesh volumes.
7189 The nodes of the internal faces at the boundaries of the groups are doubled.
7190 In option, the internal faces are replaced by flat elements.
7191 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7194 theDomains: list of groups of volumes
7195 createJointElems: if True, create the elements
7196 onAllBoundaries: if True, the nodes and elements are also created on
7197 the boundary between *theDomains* and the rest mesh
7200 True if operation has been completed successfully, False otherwise
7203 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7205 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7207 Double nodes on some external faces and create flat elements.
7208 Flat elements are mainly used by some types of mechanic calculations.
7210 Each group of the list must be constituted of faces.
7211 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7214 theGroupsOfFaces: list of groups of faces
7217 True if operation has been completed successfully, False otherwise
7220 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7222 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7224 Identify all the elements around a geom shape, get the faces delimiting the hole
7226 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7228 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7230 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7231 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7232 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7233 If there are several paths connecting a pair of points, the shortest path is
7234 selected by the module. Position of the cutting plane is defined by the two
7235 points and an optional vector lying on the plane specified by a PolySegment.
7236 By default the vector is defined by Mesh module as following. A middle point
7237 of the two given points is computed. The middle point is projected to the mesh.
7238 The vector goes from the middle point to the projection point. In case of planar
7239 mesh, the vector is normal to the mesh.
7241 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7244 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7245 groupName: optional name of a group where created mesh segments will be added.
7248 editor = self.editor
7250 editor = self.mesh.GetMeshEditPreviewer()
7251 segmentsRes = editor.MakePolyLine( segments, groupName )
7252 for i, seg in enumerate( segmentsRes ):
7253 segments[i].vector = seg.vector
7255 return editor.GetPreviewData()
7258 def MakeSlot(self, segmentGroup, width ):
7260 Create a slot of given width around given 1D elements lying on a triangle mesh.
7261 The slot is constructed by cutting faces by cylindrical surfaces made
7262 around each segment. Segments are expected to be created by MakePolyLine().
7265 FaceEdge's located at the slot boundary
7267 return self.editor.MakeSlot( segmentGroup, width )
7269 def GetFunctor(self, funcType ):
7271 Return a cached numerical functor by its type.
7274 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7275 Note that not all items correspond to numerical functors.
7278 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7281 fn = self.functors[ funcType._v ]
7283 fn = self.smeshpyD.GetFunctor(funcType)
7284 fn.SetMesh(self.mesh)
7285 self.functors[ funcType._v ] = fn
7288 def FunctorValue(self, funcType, elemId, isElem=True):
7290 Return value of a functor for a given element
7293 funcType: an item of :class:`SMESH.FunctorType` enum.
7294 elemId: element or node ID
7295 isElem: *elemId* is ID of element or node
7298 the functor value or zero in case of invalid arguments
7301 fn = self.GetFunctor( funcType )
7302 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7303 val = fn.GetValue(elemId)
7308 def GetLength(self, elemId=None):
7310 Get length of given 1D elements or of all 1D mesh elements
7313 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
7316 Sum of lengths of given elements
7321 length = self.smeshpyD.GetLength(self)
7322 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7323 length = self.smeshpyD.GetLength(elemId)
7326 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7328 length += self.smeshpyD.GetLength(obj)
7329 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7330 unRegister = genObjUnRegister()
7331 obj = self.GetIDSource( elemId )
7332 unRegister.set( obj )
7333 length = self.smeshpyD.GetLength( obj )
7335 length = self.FunctorValue(SMESH.FT_Length, elemId)
7338 def GetArea(self, elemId=None):
7340 Get area of given 2D elements or of all 2D mesh elements
7343 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
7346 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7351 area = self.smeshpyD.GetArea(self)
7352 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7353 area = self.smeshpyD.GetArea(elemId)
7356 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7358 area += self.smeshpyD.GetArea(obj)
7359 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7360 unRegister = genObjUnRegister()
7361 obj = self.GetIDSource( elemId )
7362 unRegister.set( obj )
7363 area = self.smeshpyD.GetArea( obj )
7365 area = self.FunctorValue(SMESH.FT_Area, elemId)
7368 def GetVolume(self, elemId=None):
7370 Get volume of given 3D elements or of all 3D mesh elements
7373 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.
7376 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7381 volume= self.smeshpyD.GetVolume(self)
7382 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7383 volume= self.smeshpyD.GetVolume(elemId)
7386 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7388 volume+= self.smeshpyD.GetVolume(obj)
7389 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7390 unRegister = genObjUnRegister()
7391 obj = self.GetIDSource( elemId )
7392 unRegister.set( obj )
7393 volume= self.smeshpyD.GetVolume( obj )
7395 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7398 def GetAngle(self, node1, node2, node3 ):
7400 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7403 node1,node2,node3: IDs of the three nodes
7406 Angle in radians [0,PI]. -1 if failure case.
7408 p1 = self.GetNodeXYZ( node1 )
7409 p2 = self.GetNodeXYZ( node2 )
7410 p3 = self.GetNodeXYZ( node3 )
7411 if p1 and p2 and p3:
7412 return self.smeshpyD.GetAngle( p1,p2,p3 )
7416 def GetMaxElementLength(self, elemId):
7418 Get maximum element length.
7421 elemId: mesh element ID
7424 element's maximum length value
7427 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7428 ftype = SMESH.FT_MaxElementLength3D
7430 ftype = SMESH.FT_MaxElementLength2D
7431 return self.FunctorValue(ftype, elemId)
7433 def GetAspectRatio(self, elemId):
7435 Get aspect ratio of 2D or 3D element.
7438 elemId: mesh element ID
7441 element's aspect ratio value
7444 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7445 ftype = SMESH.FT_AspectRatio3D
7447 ftype = SMESH.FT_AspectRatio
7448 return self.FunctorValue(ftype, elemId)
7450 def GetWarping(self, elemId):
7452 Get warping angle of 2D element.
7455 elemId: mesh element ID
7458 element's warping angle value
7461 return self.FunctorValue(SMESH.FT_Warping, elemId)
7463 def GetMinimumAngle(self, elemId):
7465 Get minimum angle of 2D element.
7468 elemId: mesh element ID
7471 element's minimum angle value
7474 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7476 def GetTaper(self, elemId):
7478 Get taper of 2D element.
7481 elemId: mesh element ID
7484 element's taper value
7487 return self.FunctorValue(SMESH.FT_Taper, elemId)
7489 def GetSkew(self, elemId):
7491 Get skew of 2D element.
7494 elemId: mesh element ID
7497 element's skew value
7500 return self.FunctorValue(SMESH.FT_Skew, elemId)
7502 def GetScaledJacobian(self, elemId):
7504 Get the scaled jacobian of 3D element id
7507 elemId: mesh element ID
7513 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7515 def GetMinMax(self, funType, meshPart=None):
7517 Return minimal and maximal value of a given functor.
7520 funType (SMESH.FunctorType): a functor type.
7521 Note that not all items of :class:`SMESH.FunctorType` corresponds
7522 to numerical functors.
7523 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7529 unRegister = genObjUnRegister()
7530 if isinstance( meshPart, list ):
7531 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7532 unRegister.set( meshPart )
7533 if isinstance( meshPart, Mesh ):
7534 meshPart = meshPart.mesh
7535 fun = self.GetFunctor( funType )
7538 if hasattr( meshPart, "SetMesh" ):
7539 meshPart.SetMesh( self.mesh ) # set mesh to filter
7540 hist = fun.GetLocalHistogram( 1, False, meshPart )
7542 hist = fun.GetHistogram( 1, False )
7544 return hist[0].min, hist[0].max
7547 pass # end of Mesh class
7550 def _copy_netgen_param(dim, local_param, global_param):
7552 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7555 #TODO: Try to identify why we need to substract 1 to have same results
7556 local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
7558 local_param.SetMaxSize(global_param.GetMaxSize())
7559 local_param.SetMinSize(global_param.GetMinSize())
7560 local_param.SetOptimize(global_param.GetOptimize())
7561 local_param.SetFineness(global_param.GetFineness())
7562 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7563 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7564 #TODO: Why the 0.9 to have same results
7565 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7566 local_param.SetChordalError(global_param.GetChordalError())
7567 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7568 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7569 local_param.SetUseDelauney(global_param.GetUseDelauney())
7570 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7571 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7572 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7573 local_param.SetNbThreads(global_param.GetNbThreads())
7575 local_param.SetMaxSize(global_param.GetMaxSize())
7576 local_param.SetMinSize(global_param.GetMinSize())
7577 local_param.SetOptimize(global_param.GetOptimize())
7578 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7579 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7580 local_param.SetFineness(global_param.GetFineness())
7581 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7582 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7583 local_param.SetGrowthRate(global_param.GetGrowthRate())
7584 local_param.SetNbThreads(global_param.GetNbThreads())
7587 def _shaperstudy2geom(geompyD, shaper_obj):
7589 Convertion of shaper object to geom object
7592 geompyD: geomBuilder instance
7593 shaper_obj: Shaper study object
7600 #Writing shaperstudy object into a brep file
7601 fid, tmp_file = tempfile.mkstemp(suffix='.brep')
7602 with open(fid, 'wb') as f:
7603 f.write(shaper_obj.GetShapeStream())
7604 # Reimporting brep file into geom
7605 real_geom = geompyD.ImportBREP(tmp_file)
7611 def _split_geom(geompyD, geom):
7613 Splitting geometry into n solids and a 2D/1D compound
7616 geompyD: geomBuilder instance
7617 geom: geometrical object for meshing
7620 compound containing all the 1D,2D elements
7624 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7625 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7630 for solid in object_solids:
7632 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7633 solids.append(solid)
7634 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7640 for isolid, solid in enumerate(solids):
7641 solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
7643 for face in solid_faces:
7646 geompyD.addToStudyInFather(solid, face,
7647 'Face_{}'.format(iface))
7649 # Creating submesh for edges 1D/2D part
7650 all_faces = geompyD.MakeCompound(faces)
7651 geompyD.addToStudy(all_faces, 'Compound_1')
7652 all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
7653 all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
7654 geompyD.addToStudy(all_faces, 'global2D')
7656 return all_faces, solids
7659 MULTITHREAD, MULTINODE = range(2)
7660 class ParallelismSettings:
7662 Defines the parameters for the parallelism of ParallelMesh
7664 def __init__(self, mesh):
7669 mesh: Instance of ParallelMesh
7671 if not(isinstance(mesh, ParallelMesh)):
7672 raise ValueError("mesh should be a ParallelMesh")
7677 class MTParallelismSettings(ParallelismSettings):
7679 Defines the parameters for the parallelism of ParallelMesh using MultiThreading
7681 def __init__(self, mesh):
7682 ParallelismSettings.__init__(self, mesh)
7684 # Multithreading methods
7685 def SetNbThreads(self, nbThreads):
7686 """ Set the number of threads for multithread """
7688 raise ValueError("Number of threads must be stricly greater than 1")
7690 self._mesh.mesh.SetNbThreads(nbThreads)
7692 def GetNbThreads(self):
7693 """ Get Number of threads """
7694 return self._mesh.mesh.GetNbThreads()
7697 """ str conversion """
7698 string = "\nParameter for MultiThreading parallelism:\n"
7699 string += "NbThreads: {}\n".format(self.GetNbThreads())
7704 class MNParallelismSettings(ParallelismSettings):
7706 Defines the parameters for the parallelism of ParallelMesh using MultiNodal
7708 def __init__(self, mesh):
7709 ParallelismSettings.__init__(self, mesh)
7711 def GetResource(self):
7712 """ Get the resource on which to run """
7713 return self._mesh.mesh.GetResource()
7715 def SetResource(self, resource):
7716 """ Set the resource on which to run """
7717 self._mesh.mesh.SetResource(resource)
7719 def SetNbProc(self, nbProc):
7720 """ Set the number of Processor for multinode """
7722 raise ValueError("Number of Proc must be stricly greater than 1")
7723 self._mesh.mesh.SetNbProc(nbProc)
7725 def GetNbProc(self):
7726 """ Get Number of Processor """
7727 return self._mesh.mesh.GetNbProc()
7729 def SetNbProcPerNode(self, nbProcPerNode):
7730 """ Set the number of Processor Per Node for multinode """
7731 if nbProcPerNode < 1:
7732 raise ValueError("Number of Processor Per Node must be stricly greater than 1")
7734 self._mesh.mesh.SetNbProcPerNode(nbProcPerNode)
7736 def GetNbProcPerNode(self):
7737 """ Get Number of Processor Per Node """
7738 return self._mesh.mesh.GetNbProcPerNode()
7740 def SetNbNode(self, nbNode):
7741 """ Set the number of Node for multinode """
7743 raise ValueError("Number of Node must be stricly greater than 1")
7744 self._mesh.mesh.SetNbNode(nbNode)
7746 def GetNbNode(self):
7747 """ Get Number of Node """
7748 return self._mesh.mesh.GetNbNode()
7750 def SetWcKey(self, wcKey):
7751 """ Set the number of Node for multinode """
7752 self._mesh.mesh.SetWcKey(wcKey)
7755 """ Get Number of Node """
7756 return self._mesh.mesh.GetWcKey()
7759 """ str conversion """
7760 string = "\nParameter for MultiNode parallelism:\n"
7761 string += "Reource: {}\n".format(self.GetResource())
7762 string += "NbProc: {}\n".format(self.GetNbProc())
7763 string += "NbProcPerNode: {}\n".format(self.GetNbProcPerNode())
7764 string += "NbNode: {}\n".format(self.GetNbNode())
7765 string += "WcKey: {}\n".format(self.GetWcKey())
7770 class ParallelMesh(Mesh):
7772 Surcharge on Mesh for parallel computation of a mesh
7774 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7776 Create a parallel mesh.
7779 smeshpyD: instance of smeshBuilder
7780 geompyD: instance of geomBuilder
7781 geom: geometrical object for meshing
7782 split_geom: If true will divide geometry on solids and 1D/2D
7783 coumpound and create the associated submeshes
7784 name: the name for the new mesh.
7787 an instance of class :class:`ParallelMesh`.
7790 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7791 raise ValueError("geom argument must be a geometry")
7794 import shaperBuilder
7795 # If we have a shaper object converting it into geom (temporary solution)
7796 if isinstance(geom, SHAPERSTUDY.SHAPERSTUDY_ORB._objref_SHAPER_Object):
7797 geom_obj = _shaperstudy2geom(geompyD, geom)
7801 # Splitting geometry into one geom containing 1D and 2D elements and a
7802 # list of 3D elements
7803 super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom_obj, name, parallel=True)
7806 self._all_faces, self._solids = _split_geom(geompyD, geom_obj)
7809 self._algo2d = self.Triangle(geom=geom_obj, algo="NETGEN_2D")
7812 for solid_id, solid in enumerate(self._solids):
7813 name = "Solid_{}".format(solid_id)
7814 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7815 self._algo3d.append(algo3d)
7820 def GetNbSolids(self):
7822 Return the number of 3D solids
7824 return len(self._solids)
7826 def GetParallelismMethod(self):
7827 """ Get the parallelims method """
7828 return self.mesh.GetParallelismMethod()
7830 def SetParallelismMethod(self, method):
7831 """ Set the parallelims method """
7832 if method not in [MULTITHREAD , MULTINODE]:
7833 raise ValueError("Parallelism method can only be 0:MultiThread or 1:MultiNode")
7835 self.mesh.SetParallelismMethod(method)
7837 if method == MULTITHREAD:
7838 self._param = MTParallelismSettings(self)
7840 self._param = MNParallelismSettings(self)
7842 def GetParallelismSettings(self):
7844 Return class to set parameters for the parallelism
7846 if self._param is None:
7847 raise Exception("You need to set Parallelism method first (SetParallelismMethod)")
7850 def AddGlobalHypothesis(self, hyp):
7852 Split hypothesis to apply it to all the submeshes:
7854 - each of the 3D solids
7857 hyp: a hypothesis to assign
7860 if not isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7861 raise ValueError("param must come from NETGENPlugin")
7863 param2d = self._algo2d.Parameters()
7864 _copy_netgen_param(2, param2d, hyp)
7866 for algo3d in self._algo3d:
7868 param3d = algo3d.Parameters()
7869 _copy_netgen_param(3, param3d, hyp)
7872 pass # End of ParallelMesh
7874 class meshProxy(SMESH._objref_SMESH_Mesh):
7876 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7877 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7879 def __init__(self,*args):
7880 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7881 def __deepcopy__(self, memo=None):
7882 new = self.__class__(self)
7884 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7885 if len( args ) == 3:
7886 args += SMESH.ALL_NODES, True
7887 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7888 def ExportToMEDX(self, *args): # function removed
7889 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7890 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7891 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7892 def ExportToMED(self, *args): # function removed
7893 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7894 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7896 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7898 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7899 def ExportPartToMED(self, *args): # 'version' parameter removed
7900 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7901 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7902 def ExportMED(self, *args): # signature of method changed
7903 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7905 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7907 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7908 def ExportUNV(self, *args): # renumber arg added
7909 if len( args ) == 1:
7911 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7912 def ExportDAT(self, *args): # renumber arg added
7913 if len( args ) == 1:
7915 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7917 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7920 class parallelMeshProxy(SMESH._objref_SMESH_ParallelMesh):
7921 def __init__(self,*args):
7922 SMESH._objref_SMESH_ParallelMesh.__init__(self,*args)
7923 def __deepcopy__(self, memo=None):
7924 new = self.__class__(self)
7926 omniORB.registerObjref(SMESH._objref_SMESH_ParallelMesh._NP_RepositoryId, parallelMeshProxy)
7930 class submeshProxy(SMESH._objref_SMESH_subMesh):
7933 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7935 def __init__(self,*args):
7936 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7938 def __deepcopy__(self, memo=None):
7939 new = self.__class__(self)
7942 def Compute(self,refresh=False):
7944 Compute the sub-mesh and return the status of the computation
7947 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7952 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7953 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7957 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7959 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7961 if salome.sg.hasDesktop():
7962 if refresh: salome.sg.updateObjBrowser()
7967 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7970 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7972 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7973 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7976 def __init__(self,*args):
7977 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7979 def __getattr__(self, name ): # method called if an attribute not found
7980 if not self.mesh: # look for name() method in Mesh class
7981 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7982 if hasattr( self.mesh, name ):
7983 return getattr( self.mesh, name )
7984 if name == "ExtrusionAlongPathObjX":
7985 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7986 print("meshEditor: attribute '%s' NOT FOUND" % name)
7988 def __deepcopy__(self, memo=None):
7989 new = self.__class__(self)
7991 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7992 if len( args ) == 1: args += False,
7993 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7994 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7995 if len( args ) == 2: args += False,
7996 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7997 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7998 if len( args ) == 1:
7999 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
8000 NodesToKeep = args[1]
8001 AvoidMakingHoles = args[2] if len( args ) == 3 else False
8002 unRegister = genObjUnRegister()
8004 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
8005 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
8006 if not isinstance( NodesToKeep, list ):
8007 NodesToKeep = [ NodesToKeep ]
8008 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
8010 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
8012 class Pattern(SMESH._objref_SMESH_Pattern):
8014 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
8015 variables in some methods
8018 def LoadFromFile(self, patternTextOrFile ):
8019 text = patternTextOrFile
8020 if os.path.exists( text ):
8021 text = open( patternTextOrFile ).read()
8023 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
8025 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
8026 decrFun = lambda i: i-1
8027 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
8028 theMesh.SetParameters(Parameters)
8029 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
8031 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
8032 decrFun = lambda i: i-1
8033 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
8034 theMesh.SetParameters(Parameters)
8035 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
8037 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
8038 if isinstance( mesh, Mesh ):
8039 mesh = mesh.GetMesh()
8040 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
8042 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
8044 Registering the new proxy for Pattern
8049 Private class used to bind methods creating algorithms to the class Mesh
8052 def __init__(self, method):
8054 self.defaultAlgoType = ""
8055 self.algoTypeToClass = {}
8056 self.method = method
8058 def add(self, algoClass):
8060 Store a python class of algorithm
8062 if inspect.isclass(algoClass) and \
8063 hasattr( algoClass, "algoType"):
8064 self.algoTypeToClass[ algoClass.algoType ] = algoClass
8065 if not self.defaultAlgoType and \
8066 hasattr( algoClass, "isDefault") and algoClass.isDefault:
8067 self.defaultAlgoType = algoClass.algoType
8068 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
8070 def copy(self, mesh):
8072 Create a copy of self and assign mesh to the copy
8075 other = algoCreator( self.method )
8076 other.defaultAlgoType = self.defaultAlgoType
8077 other.algoTypeToClass = self.algoTypeToClass
8081 def __call__(self,algo="",geom=0,*args):
8083 Create an instance of algorithm
8087 if isinstance( algo, str ):
8089 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
8090 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
8095 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
8097 elif not algoType and isinstance( geom, str ):
8102 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
8104 elif isinstance( arg, str ) and not algoType:
8107 import traceback, sys
8108 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
8109 sys.stderr.write( msg + '\n' )
8110 tb = traceback.extract_stack(None,2)
8111 traceback.print_list( [tb[0]] )
8113 algoType = self.defaultAlgoType
8114 if not algoType and self.algoTypeToClass:
8115 algoType = sorted( self.algoTypeToClass.keys() )[0]
8116 if algoType in self.algoTypeToClass:
8117 #print("Create algo",algoType)
8118 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
8119 raise RuntimeError( "No class found for algo type %s" % algoType)
8122 class hypMethodWrapper:
8124 Private class used to substitute and store variable parameters of hypotheses.
8127 def __init__(self, hyp, method):
8129 self.method = method
8130 #print("REBIND:", method.__name__)
8133 def __call__(self,*args):
8135 call a method of hypothesis with calling SetVarParameter() before
8139 return self.method( self.hyp, *args ) # hypothesis method with no args
8141 #print("MethWrapper.__call__", self.method.__name__, args)
8143 parsed = ParseParameters(*args) # replace variables with their values
8144 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
8145 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
8146 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
8147 # maybe there is a replaced string arg which is not variable
8148 result = self.method( self.hyp, *args )
8149 except ValueError as detail: # raised by ParseParameters()
8151 result = self.method( self.hyp, *args )
8152 except omniORB.CORBA.BAD_PARAM:
8153 raise ValueError(detail) # wrong variable name
8158 class genObjUnRegister:
8160 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
8163 def __init__(self, genObj=None):
8164 self.genObjList = []
8168 def set(self, genObj):
8169 "Store one or a list of of SALOME.GenericObj'es"
8170 if isinstance( genObj, list ):
8171 self.genObjList.extend( genObj )
8173 self.genObjList.append( genObj )
8177 for genObj in self.genObjList:
8178 if genObj and hasattr( genObj, "UnRegister" ):
8181 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8183 Bind methods creating mesher plug-ins to the Mesh class
8186 # print("pluginName: ", pluginName)
8187 pluginBuilderName = pluginName + "Builder"
8189 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8190 except Exception as e:
8191 from salome_utils import verbose
8192 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8194 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8195 plugin = eval( pluginBuilderName )
8196 # print(" plugin:" , str(plugin))
8198 # add methods creating algorithms to Mesh
8199 for k in dir( plugin ):
8200 if k[0] == '_': continue
8201 algo = getattr( plugin, k )
8202 #print(" algo:", str(algo))
8203 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8204 #print(" meshMethod:" , str(algo.meshMethod))
8205 if not hasattr( Mesh, algo.meshMethod ):
8206 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8208 _mmethod = getattr( Mesh, algo.meshMethod )
8209 if hasattr( _mmethod, "add" ):