1 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def EnumToLong(self,theItem):
480 Return a long value from enumeration
485 def ColorToString(self,c):
487 Convert SALOMEDS.Color to string.
488 To be used with filters.
491 c: color value (SALOMEDS.Color)
494 a string representation of the color.
498 if isinstance(c, SALOMEDS.Color):
499 val = "%s;%s;%s" % (c.R, c.G, c.B)
500 elif isinstance(c, str):
503 raise ValueError("Color value should be of string or SALOMEDS.Color type")
506 def GetPointStruct(self,theVertex):
508 Get :class:`SMESH.PointStruct` from vertex
511 theVertex (GEOM.GEOM_Object): vertex
514 :class:`SMESH.PointStruct`
517 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518 return PointStruct(x,y,z)
520 def GetDirStruct(self,theVector):
522 Get :class:`SMESH.DirStruct` from vector
525 theVector (GEOM.GEOM_Object): vector
528 :class:`SMESH.DirStruct`
531 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532 if(len(vertices) != 2):
533 print("Error: vector object is incorrect.")
535 p1 = self.geompyD.PointCoordinates(vertices[0])
536 p2 = self.geompyD.PointCoordinates(vertices[1])
537 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538 dirst = DirStruct(pnt)
541 def MakeDirStruct(self,x,y,z):
543 Make :class:`SMESH.DirStruct` from a triplet of floats
546 x,y,z (float): vector components
549 :class:`SMESH.DirStruct`
552 pnt = PointStruct(x,y,z)
553 return DirStruct(pnt)
555 def GetAxisStruct(self,theObj):
557 Get :class:`SMESH.AxisStruct` from a geometrical object
560 theObj (GEOM.GEOM_Object): line or plane
563 :class:`SMESH.AxisStruct`
566 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
569 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571 vertex1 = self.geompyD.PointCoordinates(vertex1)
572 vertex2 = self.geompyD.PointCoordinates(vertex2)
573 vertex3 = self.geompyD.PointCoordinates(vertex3)
574 vertex4 = self.geompyD.PointCoordinates(vertex4)
575 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577 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] ]
578 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580 elif len(edges) == 1:
581 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582 p1 = self.geompyD.PointCoordinates( vertex1 )
583 p2 = self.geompyD.PointCoordinates( vertex2 )
584 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586 elif theObj.GetShapeType() == GEOM.VERTEX:
587 x,y,z = self.geompyD.PointCoordinates( theObj )
588 axis = AxisStruct( x,y,z, 1,0,0,)
589 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
592 # From SMESH_Gen interface:
593 # ------------------------
595 def SetName(self, obj, name):
597 Set the given name to an object
600 obj: the object to rename
601 name: a new object name
604 if isinstance( obj, Mesh ):
606 elif isinstance( obj, Mesh_Algorithm ):
607 obj = obj.GetAlgorithm()
608 ior = salome.orb.object_to_string(obj)
609 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
611 def SetEmbeddedMode( self,theMode ):
616 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
618 def IsEmbeddedMode(self):
623 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
625 def UpdateStudy( self, geompyD = None ):
627 Update the current study. Calling UpdateStudy() allows to
628 update meshes at switching GEOM->SMESH
632 from salome.geom import geomBuilder
633 geompyD = geomBuilder.geom
635 geompyD = geomBuilder.New()
638 self.SetGeomEngine(geompyD)
639 SMESH._objref_SMESH_Gen.UpdateStudy(self)
640 sb = salome.myStudy.NewBuilder()
641 sc = salome.myStudy.FindComponent("SMESH")
643 sb.LoadWith(sc, self)
646 def SetEnablePublish( self, theIsEnablePublish ):
648 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649 switch **off** publishing in the Study of mesh objects.
651 #self.SetEnablePublish(theIsEnablePublish)
652 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
654 notebook = salome_notebook.NoteBook( theIsEnablePublish )
657 def CreateMeshesFromUNV( self,theFileName ):
659 Create a Mesh object importing data from the given UNV file
662 an instance of class :class:`Mesh`
665 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
669 def CreateMeshesFromMED( self,theFileName ):
671 Create a Mesh object(s) importing data from the given MED file
674 a tuple ( list of class :class:`Mesh` instances,
675 :class:`SMESH.DriverMED_ReadStatus` )
678 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680 return aMeshes, aStatus
682 def CreateMeshesFromSAUV( self,theFileName ):
684 Create a Mesh object(s) importing data from the given SAUV file
687 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
690 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692 return aMeshes, aStatus
694 def CreateMeshesFromSTL( self, theFileName ):
696 Create a Mesh object importing data from the given STL file
699 an instance of class :class:`Mesh`
702 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
706 def CreateMeshesFromCGNS( self, theFileName ):
708 Create Mesh objects importing data from the given CGNS file
711 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
714 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716 return aMeshes, aStatus
718 def CreateMeshesFromGMF( self, theFileName ):
720 Create a Mesh object importing data from the given GMF file.
721 GMF files must have .mesh extension for the ASCII format and .meshb for
725 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
728 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
731 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732 return Mesh(self, self.geompyD, aSmeshMesh), error
734 def Concatenate( self, meshes, uniteIdenticalGroups,
735 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736 name = "", meshToAppendTo = None):
738 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
739 All groups of input meshes will be present in the new mesh.
742 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744 mergeNodesAndElements: if True, equal nodes and elements are merged
745 mergeTolerance: tolerance for merging nodes
746 allGroups: forces creation of groups corresponding to every input mesh
747 name: name of a new mesh
748 meshToAppendTo a mesh to append all given meshes
751 an instance of class :class:`Mesh`
754 if not meshes: return None
755 for i,m in enumerate(meshes):
756 if isinstance(m, Mesh):
757 meshes[i] = m.GetMesh()
758 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
759 if hasattr(meshes[0], "SetParameters"):
760 meshes[0].SetParameters(Parameters)
762 meshes[0].GetMesh().SetParameters(Parameters)
763 if isinstance( meshToAppendTo, Mesh ):
764 meshToAppendTo = meshToAppendTo.GetMesh()
766 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
767 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
768 mergeTolerance,meshToAppendTo)
770 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
771 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
772 mergeTolerance,meshToAppendTo)
774 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
777 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
779 Create a mesh by copying a part of another mesh.
782 meshPart: a part of mesh to copy, either
783 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
784 To copy nodes or elements not forming any mesh object,
785 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
786 meshName: a name of the new mesh
787 toCopyGroups: to create in the new mesh groups the copied elements belongs to
788 toKeepIDs: to preserve order of the copied elements or not
791 an instance of class :class:`Mesh`
794 if isinstance( meshPart, Mesh ):
795 meshPart = meshPart.GetMesh()
796 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
797 return Mesh(self, self.geompyD, mesh)
799 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
800 toReuseHypotheses=True, toCopyElements=True):
802 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
803 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
804 To facilitate and speed up the operation, consider using
805 "Set presentation parameters and sub-shapes from arguments" option in
806 a dialog of geometrical operation used to create the new geometry.
809 sourceMesh: the mesh to copy definition of.
810 newGeom: the new geomtry.
811 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
812 toCopyGroups: to create groups in the new mesh.
813 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
814 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
817 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
818 *invalidEntries* are study entries of objects whose
819 counterparts are not found in the *newGeom*, followed by entries
820 of mesh sub-objects that are invalid because they depend on a not found
823 if isinstance( sourceMesh, Mesh ):
824 sourceMesh = sourceMesh.GetMesh()
826 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
827 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
831 return ( ok, Mesh(self, self.geompyD, newMesh),
832 newGroups, newSubMeshes, newHypotheses, invalidEntries )
834 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
836 Return IDs of sub-shapes
839 theMainObject (GEOM.GEOM_Object): a shape
840 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
842 the list of integer values
845 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
847 def GetPattern(self):
849 Create a pattern mapper.
852 an instance of :class:`SMESH.SMESH_Pattern`
854 :ref:`Example of Patterns usage <tui_pattern_mapping>`
857 return SMESH._objref_SMESH_Gen.GetPattern(self)
859 def SetBoundaryBoxSegmentation(self, nbSegments):
861 Set number of segments per diagonal of boundary box of geometry, by which
862 default segment length of appropriate 1D hypotheses is defined in GUI.
866 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
868 # Filtering. Auxiliary functions:
869 # ------------------------------
871 def GetEmptyCriterion(self):
873 Create an empty criterion
876 :class:`SMESH.Filter.Criterion`
879 Type = self.EnumToLong(FT_Undefined)
880 Compare = self.EnumToLong(FT_Undefined)
884 UnaryOp = self.EnumToLong(FT_Undefined)
885 BinaryOp = self.EnumToLong(FT_Undefined)
888 Precision = -1 ##@1e-07
889 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
890 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
892 def GetCriterion(self,elementType,
894 Compare = FT_EqualTo,
896 UnaryOp=FT_Undefined,
897 BinaryOp=FT_Undefined,
900 Create a criterion by the given parameters
901 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
904 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
905 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
906 Note that the items starting from FT_LessThan are not suitable for *CritType*.
907 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
908 Threshold: the threshold value (range of ids as string, shape, numeric)
909 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
910 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
912 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
913 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
916 :class:`SMESH.Filter.Criterion`
918 Example: :ref:`combining_filters`
921 if not CritType in SMESH.FunctorType._items:
922 raise TypeError("CritType should be of SMESH.FunctorType")
923 aCriterion = self.GetEmptyCriterion()
924 aCriterion.TypeOfElement = elementType
925 aCriterion.Type = self.EnumToLong(CritType)
926 aCriterion.Tolerance = Tolerance
928 aThreshold = Threshold
930 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
931 aCriterion.Compare = self.EnumToLong(Compare)
932 elif Compare == "=" or Compare == "==":
933 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
935 aCriterion.Compare = self.EnumToLong(FT_LessThan)
937 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
938 elif Compare != FT_Undefined:
939 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
942 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
943 FT_BelongToCylinder, FT_LyingOnGeom]:
944 # Check that Threshold is GEOM object
945 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
946 aCriterion.ThresholdStr = GetName(aThreshold)
947 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
948 if not aCriterion.ThresholdID:
949 name = aCriterion.ThresholdStr
951 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
952 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
953 # or a name of GEOM object
954 elif isinstance( aThreshold, str ):
955 aCriterion.ThresholdStr = aThreshold
957 raise TypeError("The Threshold should be a shape.")
958 if isinstance(UnaryOp,float):
959 aCriterion.Tolerance = UnaryOp
960 UnaryOp = FT_Undefined
962 elif CritType == FT_BelongToMeshGroup:
963 # Check that Threshold is a group
964 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
965 if aThreshold.GetType() != elementType:
966 raise ValueError("Group type mismatches Element type")
967 aCriterion.ThresholdStr = aThreshold.GetName()
968 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
969 study = salome.myStudy
971 so = study.FindObjectIOR( aCriterion.ThresholdID )
975 aCriterion.ThresholdID = entry
977 raise TypeError("The Threshold should be a Mesh Group")
978 elif CritType == FT_RangeOfIds:
979 # Check that Threshold is string
980 if isinstance(aThreshold, str):
981 aCriterion.ThresholdStr = aThreshold
983 raise TypeError("The Threshold should be a string.")
984 elif CritType == FT_CoplanarFaces:
985 # Check the Threshold
986 if isinstance(aThreshold, int):
987 aCriterion.ThresholdID = str(aThreshold)
988 elif isinstance(aThreshold, str):
991 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
992 aCriterion.ThresholdID = aThreshold
994 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
995 elif CritType == FT_ConnectedElements:
996 # Check the Threshold
997 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
998 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
999 if not aCriterion.ThresholdID:
1000 name = aThreshold.GetName()
1002 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1003 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1004 elif isinstance(aThreshold, int): # node id
1005 aCriterion.Threshold = aThreshold
1006 elif isinstance(aThreshold, list): # 3 point coordinates
1007 if len( aThreshold ) < 3:
1008 raise ValueError("too few point coordinates, must be 3")
1009 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1010 elif isinstance(aThreshold, str):
1011 if aThreshold.isdigit():
1012 aCriterion.Threshold = aThreshold # node id
1014 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1016 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1017 "or a list of point coordinates and not '%s'"%aThreshold)
1018 elif CritType == FT_ElemGeomType:
1019 # Check the Threshold
1021 aCriterion.Threshold = self.EnumToLong(aThreshold)
1022 assert( aThreshold in SMESH.GeometryType._items )
1024 if isinstance(aThreshold, int):
1025 aCriterion.Threshold = aThreshold
1027 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1030 elif CritType == FT_EntityType:
1031 # Check the Threshold
1033 aCriterion.Threshold = self.EnumToLong(aThreshold)
1034 assert( aThreshold in SMESH.EntityType._items )
1036 if isinstance(aThreshold, int):
1037 aCriterion.Threshold = aThreshold
1039 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1043 elif CritType == FT_GroupColor:
1044 # Check the Threshold
1046 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1048 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1050 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1051 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1052 FT_BareBorderFace, FT_BareBorderVolume,
1053 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1054 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1055 # At this point the Threshold is unnecessary
1056 if aThreshold == FT_LogicalNOT:
1057 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1058 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1059 aCriterion.BinaryOp = aThreshold
1063 aThreshold = float(aThreshold)
1064 aCriterion.Threshold = aThreshold
1066 raise TypeError("The Threshold should be a number.")
1069 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1070 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1072 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1073 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1075 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1076 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1078 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1079 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1083 def GetFilter(self,elementType,
1084 CritType=FT_Undefined,
1087 UnaryOp=FT_Undefined,
1091 Create a filter with the given parameters
1094 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1095 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1096 Note that the items starting from FT_LessThan are not suitable for CritType.
1097 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1098 Threshold: the threshold value (range of ids as string, shape, numeric)
1099 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1100 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1101 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1102 mesh: the mesh to initialize the filter with
1105 :class:`SMESH.Filter`
1108 See :doc:`Filters usage examples <tui_filters>`
1111 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1112 aFilterMgr = self.CreateFilterManager()
1113 aFilter = aFilterMgr.CreateFilter()
1115 aCriteria.append(aCriterion)
1116 aFilter.SetCriteria(aCriteria)
1118 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1119 else : aFilter.SetMesh( mesh )
1120 aFilterMgr.UnRegister()
1123 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1125 Create a filter from criteria
1128 criteria: a list of :class:`SMESH.Filter.Criterion`
1129 binOp: binary operator used when binary operator of criteria is undefined
1132 :class:`SMESH.Filter`
1135 See :doc:`Filters usage examples <tui_filters>`
1138 for i in range( len( criteria ) - 1 ):
1139 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1140 criteria[i].BinaryOp = self.EnumToLong( binOp )
1141 aFilterMgr = self.CreateFilterManager()
1142 aFilter = aFilterMgr.CreateFilter()
1143 aFilter.SetCriteria(criteria)
1144 aFilterMgr.UnRegister()
1147 def GetFunctor(self,theCriterion):
1149 Create a numerical functor by its type
1152 theCriterion (SMESH.FunctorType): functor type.
1153 Note that not all items correspond to numerical functors.
1156 :class:`SMESH.NumericalFunctor`
1159 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1161 aFilterMgr = self.CreateFilterManager()
1163 if theCriterion == FT_AspectRatio:
1164 functor = aFilterMgr.CreateAspectRatio()
1165 elif theCriterion == FT_AspectRatio3D:
1166 functor = aFilterMgr.CreateAspectRatio3D()
1167 elif theCriterion == FT_Warping:
1168 functor = aFilterMgr.CreateWarping()
1169 elif theCriterion == FT_MinimumAngle:
1170 functor = aFilterMgr.CreateMinimumAngle()
1171 elif theCriterion == FT_Taper:
1172 functor = aFilterMgr.CreateTaper()
1173 elif theCriterion == FT_Skew:
1174 functor = aFilterMgr.CreateSkew()
1175 elif theCriterion == FT_Area:
1176 functor = aFilterMgr.CreateArea()
1177 elif theCriterion == FT_Volume3D:
1178 functor = aFilterMgr.CreateVolume3D()
1179 elif theCriterion == FT_MaxElementLength2D:
1180 functor = aFilterMgr.CreateMaxElementLength2D()
1181 elif theCriterion == FT_MaxElementLength3D:
1182 functor = aFilterMgr.CreateMaxElementLength3D()
1183 elif theCriterion == FT_MultiConnection:
1184 functor = aFilterMgr.CreateMultiConnection()
1185 elif theCriterion == FT_MultiConnection2D:
1186 functor = aFilterMgr.CreateMultiConnection2D()
1187 elif theCriterion == FT_Length:
1188 functor = aFilterMgr.CreateLength()
1189 elif theCriterion == FT_Length2D:
1190 functor = aFilterMgr.CreateLength2D()
1191 elif theCriterion == FT_Deflection2D:
1192 functor = aFilterMgr.CreateDeflection2D()
1193 elif theCriterion == FT_NodeConnectivityNumber:
1194 functor = aFilterMgr.CreateNodeConnectivityNumber()
1195 elif theCriterion == FT_BallDiameter:
1196 functor = aFilterMgr.CreateBallDiameter()
1198 print("Error: given parameter is not numerical functor type.")
1199 aFilterMgr.UnRegister()
1202 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1207 theHType (string): mesh hypothesis type
1208 theLibName (string): mesh plug-in library name
1211 created hypothesis instance
1213 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1215 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1218 # wrap hypothesis methods
1219 for meth_name in dir( hyp.__class__ ):
1220 if not meth_name.startswith("Get") and \
1221 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1222 method = getattr ( hyp.__class__, meth_name )
1223 if callable(method):
1224 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1228 def GetMeshInfo(self, obj):
1230 Get the mesh statistic.
1231 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1232 an item of :class:`SMESH.EntityType`.
1235 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1238 if isinstance( obj, Mesh ):
1241 if hasattr(obj, "GetMeshInfo"):
1242 values = obj.GetMeshInfo()
1243 for i in range(SMESH.Entity_Last._v):
1244 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1248 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1250 Get minimum distance between two objects
1252 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1253 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1256 src1 (SMESH.SMESH_IDSource): first source object
1257 src2 (SMESH.SMESH_IDSource): second source object
1258 id1 (int): node/element id from the first source
1259 id2 (int): node/element id from the second (or first) source
1260 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1261 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1264 minimum distance value
1267 :meth:`GetMinDistance`
1270 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1274 result = result.value
1277 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1279 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1281 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1282 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1285 src1 (SMESH.SMESH_IDSource): first source object
1286 src2 (SMESH.SMESH_IDSource): second source object
1287 id1 (int): node/element id from the first source
1288 id2 (int): node/element id from the second (or first) source
1289 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1290 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1293 :class:`SMESH.Measure` structure or None if input data is invalid
1298 if isinstance(src1, Mesh): src1 = src1.mesh
1299 if isinstance(src2, Mesh): src2 = src2.mesh
1300 if src2 is None and id2 != 0: src2 = src1
1301 if not hasattr(src1, "_narrow"): return None
1302 src1 = src1._narrow(SMESH.SMESH_IDSource)
1303 if not src1: return None
1304 unRegister = genObjUnRegister()
1307 e = m.GetMeshEditor()
1309 src1 = e.MakeIDSource([id1], SMESH.FACE)
1311 src1 = e.MakeIDSource([id1], SMESH.NODE)
1312 unRegister.set( src1 )
1314 if hasattr(src2, "_narrow"):
1315 src2 = src2._narrow(SMESH.SMESH_IDSource)
1316 if src2 and id2 != 0:
1318 e = m.GetMeshEditor()
1320 src2 = e.MakeIDSource([id2], SMESH.FACE)
1322 src2 = e.MakeIDSource([id2], SMESH.NODE)
1323 unRegister.set( src2 )
1326 aMeasurements = self.CreateMeasurements()
1327 unRegister.set( aMeasurements )
1328 result = aMeasurements.MinDistance(src1, src2)
1331 def BoundingBox(self, objects):
1333 Get bounding box of the specified object(s)
1336 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1339 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1342 :meth:`GetBoundingBox`
1345 result = self.GetBoundingBox(objects)
1349 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1352 def GetBoundingBox(self, objects):
1354 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1357 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1360 :class:`SMESH.Measure` structure
1366 if isinstance(objects, tuple):
1367 objects = list(objects)
1368 if not isinstance(objects, list):
1372 if isinstance(o, Mesh):
1373 srclist.append(o.mesh)
1374 elif hasattr(o, "_narrow"):
1375 src = o._narrow(SMESH.SMESH_IDSource)
1376 if src: srclist.append(src)
1379 aMeasurements = self.CreateMeasurements()
1380 result = aMeasurements.BoundingBox(srclist)
1381 aMeasurements.UnRegister()
1384 def GetLength(self, obj):
1386 Get sum of lengths of all 1D elements in the mesh object.
1389 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1392 sum of lengths of all 1D elements
1395 if isinstance(obj, Mesh): obj = obj.mesh
1396 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1397 aMeasurements = self.CreateMeasurements()
1398 value = aMeasurements.Length(obj)
1399 aMeasurements.UnRegister()
1402 def GetArea(self, obj):
1404 Get sum of areas of all 2D elements in the mesh object.
1407 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1410 sum of areas of all 2D elements
1413 if isinstance(obj, Mesh): obj = obj.mesh
1414 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1415 aMeasurements = self.CreateMeasurements()
1416 value = aMeasurements.Area(obj)
1417 aMeasurements.UnRegister()
1420 def GetVolume(self, obj):
1422 Get sum of volumes of all 3D elements in the mesh object.
1425 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1428 sum of volumes of all 3D elements
1431 if isinstance(obj, Mesh): obj = obj.mesh
1432 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1433 aMeasurements = self.CreateMeasurements()
1434 value = aMeasurements.Volume(obj)
1435 aMeasurements.UnRegister()
1438 def GetGravityCenter(self, obj):
1440 Get gravity center of all nodes of a mesh object.
1443 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1446 Three components of the gravity center (x,y,z)
1449 :meth:`Mesh.BaryCenter`
1451 if isinstance(obj, Mesh): obj = obj.mesh
1452 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1453 aMeasurements = self.CreateMeasurements()
1454 pointStruct = aMeasurements.GravityCenter(obj)
1455 aMeasurements.UnRegister()
1456 return pointStruct.x, pointStruct.y, pointStruct.z
1458 def GetAngle(self, p1, p2, p3 ):
1460 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1463 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1469 if isinstance( p1, list ): p1 = PointStruct(*p1)
1470 if isinstance( p2, list ): p2 = PointStruct(*p2)
1471 if isinstance( p3, list ): p3 = PointStruct(*p3)
1473 aMeasurements = self.CreateMeasurements()
1474 angle = aMeasurements.Angle(p1,p2,p3)
1475 aMeasurements.UnRegister()
1480 pass # end of class smeshBuilder
1483 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1484 """Registering the new proxy for SMESH.SMESH_Gen"""
1487 def New( instance=None, instanceGeom=None):
1489 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1490 interface to create or load meshes.
1495 salome.salome_init()
1496 from salome.smesh import smeshBuilder
1497 smesh = smeshBuilder.New()
1500 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1501 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1503 :class:`smeshBuilder` instance
1508 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1510 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1515 smeshInst = smeshBuilder()
1516 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1517 smeshInst.init_smesh(instanceGeom)
1521 # Public class: Mesh
1522 # ==================
1525 class Mesh(metaclass = MeshMeta):
1527 This class allows defining and managing a mesh.
1528 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1529 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1530 new nodes and elements and by changing the existing entities), to get information
1531 about a mesh and to export a mesh in different formats.
1538 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1543 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1544 sets the GUI name of this mesh to *name*.
1547 smeshpyD: an instance of smeshBuilder class
1548 geompyD: an instance of geomBuilder class
1549 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1550 name: Study name of the mesh
1553 self.smeshpyD = smeshpyD
1554 self.geompyD = geompyD
1559 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1562 # publish geom of mesh (issue 0021122)
1563 if not self.geom.GetStudyEntry():
1567 geo_name = name + " shape"
1569 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1570 geompyD.addToStudy( self.geom, geo_name )
1571 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1573 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1576 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1578 self.smeshpyD.SetName(self.mesh, name)
1580 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1583 self.geom = self.mesh.GetShapeToMesh()
1585 self.editor = self.mesh.GetMeshEditor()
1586 self.functors = [None] * SMESH.FT_Undefined._v
1588 # set self to algoCreator's
1589 for attrName in dir(self):
1590 attr = getattr( self, attrName )
1591 if isinstance( attr, algoCreator ):
1592 setattr( self, attrName, attr.copy( self ))
1599 Destructor. Clean-up resources
1602 #self.mesh.UnRegister()
1606 def SetMesh(self, theMesh):
1608 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1611 theMesh: a :class:`SMESH.SMESH_Mesh` object
1615 # do not call Register() as this prevents mesh servant deletion at closing study
1616 #if self.mesh: self.mesh.UnRegister()
1619 #self.mesh.Register()
1620 self.geom = self.mesh.GetShapeToMesh()
1625 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1628 a :class:`SMESH.SMESH_Mesh` object
1633 def GetEngine(self):
1635 Return a smeshBuilder instance created this mesh
1637 return self.smeshpyD
1639 def GetGeomEngine(self):
1641 Return a geomBuilder instance
1647 Get the name of the mesh
1650 the name of the mesh as a string
1653 name = GetName(self.GetMesh())
1656 def SetName(self, name):
1658 Set a name to the mesh
1661 name: a new name of the mesh
1664 self.smeshpyD.SetName(self.GetMesh(), name)
1666 def GetSubMesh(self, geom, name):
1668 Get a sub-mesh object associated to a *geom* geometrical object.
1671 geom: a geometrical object (shape)
1672 name: a name for the sub-mesh in the Object Browser
1675 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1676 which lies on the given shape
1679 A sub-mesh is implicitly created when a sub-shape is specified at
1680 creating an algorithm, for example::
1682 algo1D = mesh.Segment(geom=Edge_1)
1684 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1685 The created sub-mesh can be retrieved from the algorithm::
1687 submesh = algo1D.GetSubMesh()
1690 AssureGeomPublished( self, geom, name )
1691 submesh = self.mesh.GetSubMesh( geom, name )
1696 Return the shape associated to the mesh
1704 def SetShape(self, geom):
1706 Associate the given shape to the mesh (entails the recreation of the mesh)
1709 geom: the shape to be meshed (GEOM_Object)
1712 self.mesh = self.smeshpyD.CreateMesh(geom)
1714 def HasShapeToMesh(self):
1716 Return ``True`` if this mesh is based on geometry
1718 return self.mesh.HasShapeToMesh()
1722 Load mesh from the study after opening the study
1726 def IsReadyToCompute(self, theSubObject):
1728 Return true if the hypotheses are defined well
1731 theSubObject: a sub-shape of a mesh shape
1737 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1739 def GetAlgoState(self, theSubObject):
1741 Return errors of hypotheses definition.
1742 The list of errors is empty if everything is OK.
1745 theSubObject: a sub-shape of a mesh shape
1751 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1753 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1755 Return a geometrical object on which the given element was built.
1756 The returned geometrical object, if not nil, is either found in the
1757 study or published by this method with the given name
1760 theElementID: the id of the mesh element
1761 theGeomName: the user-defined name of the geometrical object
1764 GEOM.GEOM_Object instance
1767 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1769 def MeshDimension(self):
1771 Return the mesh dimension depending on the dimension of the underlying shape
1772 or, if the mesh is not based on any shape, basing on deimension of elements
1775 mesh dimension as an integer value [0,3]
1778 if self.mesh.HasShapeToMesh():
1779 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1780 if len( shells ) > 0 :
1782 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1784 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1789 if self.NbVolumes() > 0: return 3
1790 if self.NbFaces() > 0: return 2
1791 if self.NbEdges() > 0: return 1
1794 def Evaluate(self, geom=0):
1796 Evaluate size of prospective mesh on a shape
1799 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1800 To know predicted number of e.g. edges, inquire it this way::
1802 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1805 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1807 geom = self.mesh.GetShapeToMesh()
1810 return self.smeshpyD.Evaluate(self.mesh, geom)
1813 def Compute(self, geom=0, discardModifs=False, refresh=False):
1815 Compute the mesh and return the status of the computation
1818 geom: geomtrical shape on which mesh data should be computed
1819 discardModifs: if True and the mesh has been edited since
1820 a last total re-compute and that may prevent successful partial re-compute,
1821 then the mesh is cleaned before Compute()
1822 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1828 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1830 geom = self.mesh.GetShapeToMesh()
1835 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1837 ok = self.smeshpyD.Compute(self.mesh, geom)
1838 except SALOME.SALOME_Exception as ex:
1839 print("Mesh computation failed, exception caught:")
1840 print(" ", ex.details.text)
1843 print("Mesh computation failed, exception caught:")
1844 traceback.print_exc()
1848 # Treat compute errors
1849 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1851 for err in computeErrors:
1852 if self.mesh.HasShapeToMesh():
1853 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1855 stdErrors = ["OK", #COMPERR_OK
1856 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1857 "std::exception", #COMPERR_STD_EXCEPTION
1858 "OCC exception", #COMPERR_OCC_EXCEPTION
1859 "..", #COMPERR_SLM_EXCEPTION
1860 "Unknown exception", #COMPERR_EXCEPTION
1861 "Memory allocation problem", #COMPERR_MEMORY_PB
1862 "Algorithm failed", #COMPERR_ALGO_FAILED
1863 "Unexpected geometry", #COMPERR_BAD_SHAPE
1864 "Warning", #COMPERR_WARNING
1865 "Computation cancelled",#COMPERR_CANCELED
1866 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1868 if err.code < len(stdErrors): errText = stdErrors[err.code]
1870 errText = "code %s" % -err.code
1871 if errText: errText += ". "
1872 errText += err.comment
1873 if allReasons: allReasons += "\n"
1875 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1877 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1881 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1883 if err.isGlobalAlgo:
1891 reason = '%s %sD algorithm is missing' % (glob, dim)
1892 elif err.state == HYP_MISSING:
1893 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1894 % (glob, dim, name, dim))
1895 elif err.state == HYP_NOTCONFORM:
1896 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1897 elif err.state == HYP_BAD_PARAMETER:
1898 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1899 % ( glob, dim, name ))
1900 elif err.state == HYP_BAD_GEOMETRY:
1901 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1902 'geometry' % ( glob, dim, name ))
1903 elif err.state == HYP_HIDDEN_ALGO:
1904 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1905 'algorithm of upper dimension generating %sD mesh'
1906 % ( glob, dim, name, glob, dim ))
1908 reason = ("For unknown reason. "
1909 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1911 if allReasons: allReasons += "\n"
1912 allReasons += "- " + reason
1914 if not ok or allReasons != "":
1915 msg = '"' + GetName(self.mesh) + '"'
1916 if ok: msg += " has been computed with warnings"
1917 else: msg += " has not been computed"
1918 if allReasons != "": msg += ":"
1923 if salome.sg.hasDesktop():
1924 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1925 if refresh: salome.sg.updateObjBrowser()
1929 def GetComputeErrors(self, shape=0 ):
1931 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1935 shape = self.mesh.GetShapeToMesh()
1936 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1938 def GetSubShapeName(self, subShapeID ):
1940 Return a name of a sub-shape by its ID.
1941 Possible variants (for *subShapeID* == 3):
1943 - **"Face_12"** - published sub-shape
1944 - **FACE #3** - not published sub-shape
1945 - **sub-shape #3** - invalid sub-shape ID
1946 - **#3** - error in this function
1949 subShapeID: a unique ID of a sub-shape
1952 a string describing the sub-shape
1956 if not self.mesh.HasShapeToMesh():
1960 mainIOR = salome.orb.object_to_string( self.GetShape() )
1962 mainSO = s.FindObjectIOR(mainIOR)
1965 shapeText = '"%s"' % mainSO.GetName()
1966 subIt = s.NewChildIterator(mainSO)
1968 subSO = subIt.Value()
1970 obj = subSO.GetObject()
1971 if not obj: continue
1972 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1975 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1978 if ids == subShapeID:
1979 shapeText = '"%s"' % subSO.GetName()
1982 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1984 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1986 shapeText = 'sub-shape #%s' % (subShapeID)
1988 shapeText = "#%s" % (subShapeID)
1991 def GetFailedShapes(self, publish=False):
1993 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1994 error of an algorithm
1997 publish: if *True*, the returned groups will be published in the study
2000 a list of GEOM groups each named after a failed algorithm
2005 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2006 for err in computeErrors:
2007 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2008 if not shape: continue
2009 if err.algoName in algo2shapes:
2010 algo2shapes[ err.algoName ].append( shape )
2012 algo2shapes[ err.algoName ] = [ shape ]
2016 for algoName, shapes in list(algo2shapes.items()):
2018 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2019 otherTypeShapes = []
2021 group = self.geompyD.CreateGroup( self.geom, groupType )
2022 for shape in shapes:
2023 if shape.GetShapeType() == shapes[0].GetShapeType():
2024 sameTypeShapes.append( shape )
2026 otherTypeShapes.append( shape )
2027 self.geompyD.UnionList( group, sameTypeShapes )
2029 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2031 group.SetName( algoName )
2032 groups.append( group )
2033 shapes = otherTypeShapes
2036 for group in groups:
2037 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2040 def GetMeshOrder(self):
2042 Return sub-mesh objects list in meshing order
2045 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2048 return self.mesh.GetMeshOrder()
2050 def SetMeshOrder(self, submeshes):
2052 Set order in which concurrent sub-meshes should be meshed
2055 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2058 return self.mesh.SetMeshOrder(submeshes)
2060 def Clear(self, refresh=False):
2062 Remove all nodes and elements generated on geometry. Imported elements remain.
2065 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2069 if ( salome.sg.hasDesktop() ):
2070 if refresh: salome.sg.updateObjBrowser()
2072 def ClearSubMesh(self, geomId, refresh=False):
2074 Remove all nodes and elements of indicated shape
2077 geomId: the ID of a sub-shape to remove elements on
2078 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2081 self.mesh.ClearSubMesh(geomId)
2082 if salome.sg.hasDesktop():
2083 if refresh: salome.sg.updateObjBrowser()
2085 def AutomaticTetrahedralization(self, fineness=0):
2087 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2090 fineness: [0.0,1.0] defines mesh fineness
2096 dim = self.MeshDimension()
2098 self.RemoveGlobalHypotheses()
2099 self.Segment().AutomaticLength(fineness)
2101 self.Triangle().LengthFromEdges()
2106 return self.Compute()
2108 def AutomaticHexahedralization(self, fineness=0):
2110 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2113 fineness: [0.0, 1.0] defines mesh fineness
2119 dim = self.MeshDimension()
2120 # assign the hypotheses
2121 self.RemoveGlobalHypotheses()
2122 self.Segment().AutomaticLength(fineness)
2129 return self.Compute()
2131 def AddHypothesis(self, hyp, geom=0):
2136 hyp: a hypothesis to assign
2137 geom: a subhape of mesh geometry
2140 :class:`SMESH.Hypothesis_Status`
2143 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2144 hyp, geom = geom, hyp
2145 if isinstance( hyp, Mesh_Algorithm ):
2146 hyp = hyp.GetAlgorithm()
2151 geom = self.mesh.GetShapeToMesh()
2154 if self.mesh.HasShapeToMesh():
2155 hyp_type = hyp.GetName()
2156 lib_name = hyp.GetLibName()
2157 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2158 # if checkAll and geom:
2159 # checkAll = geom.GetType() == 37
2161 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2163 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2164 status = self.mesh.AddHypothesis(geom, hyp)
2166 status = HYP_BAD_GEOMETRY, ""
2167 hyp_name = GetName( hyp )
2170 geom_name = geom.GetName()
2171 isAlgo = hyp._narrow( SMESH_Algo )
2172 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2175 def IsUsedHypothesis(self, hyp, geom):
2177 Return True if an algorithm or hypothesis is assigned to a given shape
2180 hyp: an algorithm or hypothesis to check
2181 geom: a subhape of mesh geometry
2187 if not hyp: # or not geom
2189 if isinstance( hyp, Mesh_Algorithm ):
2190 hyp = hyp.GetAlgorithm()
2192 hyps = self.GetHypothesisList(geom)
2194 if h.GetId() == hyp.GetId():
2198 def RemoveHypothesis(self, hyp, geom=0):
2200 Unassign a hypothesis
2203 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2204 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2207 :class:`SMESH.Hypothesis_Status`
2212 if isinstance( hyp, Mesh_Algorithm ):
2213 hyp = hyp.GetAlgorithm()
2219 if self.IsUsedHypothesis( hyp, shape ):
2220 return self.mesh.RemoveHypothesis( shape, hyp )
2221 hypName = GetName( hyp )
2222 geoName = GetName( shape )
2223 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2226 def GetHypothesisList(self, geom):
2228 Get the list of hypotheses added on a geometry
2231 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2234 the sequence of :class:`SMESH.SMESH_Hypothesis`
2237 return self.mesh.GetHypothesisList( geom )
2239 def RemoveGlobalHypotheses(self):
2241 Remove all global hypotheses
2244 current_hyps = self.mesh.GetHypothesisList( self.geom )
2245 for hyp in current_hyps:
2246 self.mesh.RemoveHypothesis( self.geom, hyp )
2249 def ExportMED(self, *args, **kwargs):
2251 Export the mesh in a file in MED format
2252 allowing to overwrite the file if it exists or add the exported data to its contents
2255 fileName: is the file name
2256 auto_groups (boolean): parameter for creating/not creating
2257 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2258 the typical use is auto_groups=False.
2259 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2260 The minor must be between 0 and the current minor version of MED file library.
2261 If minor is equal to -1, the minor version is not changed (default).
2262 The major version (x, where version is x.y.z) cannot be changed.
2263 overwrite (boolean): parameter for overwriting/not overwriting the file
2264 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2265 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2267 - 1D if all mesh nodes lie on OX coordinate axis, or
2268 - 2D if all mesh nodes lie on XOY coordinate plane, or
2269 - 3D in the rest cases.
2271 If *autoDimension* is *False*, the space dimension is always 3.
2272 fields: list of GEOM fields defined on the shape to mesh.
2273 geomAssocFields: each character of this string means a need to export a
2274 corresponding field; correspondence between fields and characters
2277 - 'v' stands for "_vertices_" field;
2278 - 'e' stands for "_edges_" field;
2279 - 'f' stands for "_faces_" field;
2280 - 's' stands for "_solids_" field.
2282 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2283 close to zero within a given tolerance, the coordinate is set to zero.
2284 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2286 # process positional arguments
2287 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2289 auto_groups = args[1] if len(args) > 1 else False
2290 minor = args[2] if len(args) > 2 else -1
2291 overwrite = args[3] if len(args) > 3 else True
2292 meshPart = args[4] if len(args) > 4 else None
2293 autoDimension = args[5] if len(args) > 5 else True
2294 fields = args[6] if len(args) > 6 else []
2295 geomAssocFields = args[7] if len(args) > 7 else ''
2296 z_tolerance = args[8] if len(args) > 8 else -1.
2297 # process keywords arguments
2298 auto_groups = kwargs.get("auto_groups", auto_groups)
2299 minor = kwargs.get("minor", minor)
2300 overwrite = kwargs.get("overwrite", overwrite)
2301 meshPart = kwargs.get("meshPart", meshPart)
2302 autoDimension = kwargs.get("autoDimension", autoDimension)
2303 fields = kwargs.get("fields", fields)
2304 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2305 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2307 # invoke engine's function
2308 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2309 unRegister = genObjUnRegister()
2310 if isinstance( meshPart, list ):
2311 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2312 unRegister.set( meshPart )
2314 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2315 self.mesh.SetParameters(Parameters)
2317 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2318 fields, geomAssocFields, z_tolerance)
2320 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2322 def ExportSAUV(self, f, auto_groups=0):
2324 Export the mesh in a file in SAUV format
2329 auto_groups: boolean parameter for creating/not creating
2330 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2331 the typical use is auto_groups=False.
2334 self.mesh.ExportSAUV(f, auto_groups)
2336 def ExportDAT(self, f, meshPart=None):
2338 Export the mesh in a file in DAT format
2342 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2346 unRegister = genObjUnRegister()
2347 if isinstance( meshPart, list ):
2348 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2349 unRegister.set( meshPart )
2350 self.mesh.ExportPartToDAT( meshPart, f )
2352 self.mesh.ExportDAT(f)
2354 def ExportUNV(self, f, meshPart=None):
2356 Export the mesh in a file in UNV format
2360 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2364 unRegister = genObjUnRegister()
2365 if isinstance( meshPart, list ):
2366 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2367 unRegister.set( meshPart )
2368 self.mesh.ExportPartToUNV( meshPart, f )
2370 self.mesh.ExportUNV(f)
2372 def ExportSTL(self, f, ascii=1, meshPart=None):
2374 Export the mesh in a file in STL format
2378 ascii: defines the file encoding
2379 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2383 unRegister = genObjUnRegister()
2384 if isinstance( meshPart, list ):
2385 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2386 unRegister.set( meshPart )
2387 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2389 self.mesh.ExportSTL(f, ascii)
2391 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2393 Export the mesh in a file in CGNS format
2397 overwrite: boolean parameter for overwriting/not overwriting the file
2398 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2399 groupElemsByType: if True all elements of same entity type are exported at ones,
2400 else elements are exported in order of their IDs which can cause creation
2401 of multiple cgns sections
2404 unRegister = genObjUnRegister()
2405 if isinstance( meshPart, list ):
2406 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2407 unRegister.set( meshPart )
2408 if isinstance( meshPart, Mesh ):
2409 meshPart = meshPart.mesh
2411 meshPart = self.mesh
2412 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2414 def ExportGMF(self, f, meshPart=None):
2416 Export the mesh in a file in GMF format.
2417 GMF files must have .mesh extension for the ASCII format and .meshb for
2418 the bynary format. Other extensions are not allowed.
2422 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2425 unRegister = genObjUnRegister()
2426 if isinstance( meshPart, list ):
2427 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2428 unRegister.set( meshPart )
2429 if isinstance( meshPart, Mesh ):
2430 meshPart = meshPart.mesh
2432 meshPart = self.mesh
2433 self.mesh.ExportGMF(meshPart, f, True)
2435 def ExportToMED(self, *args, **kwargs):
2437 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2438 Export the mesh in a file in MED format
2439 allowing to overwrite the file if it exists or add the exported data to its contents
2442 fileName: the file name
2443 opt (boolean): parameter for creating/not creating
2444 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2445 overwrite: boolean parameter for overwriting/not overwriting the file
2446 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2448 - 1D if all mesh nodes lie on OX coordinate axis, or
2449 - 2D if all mesh nodes lie on XOY coordinate plane, or
2450 - 3D in the rest cases.
2452 If **autoDimension** is *False*, the space dimension is always 3.
2455 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2456 # process positional arguments
2457 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2459 auto_groups = args[1] if len(args) > 1 else False
2460 overwrite = args[2] if len(args) > 2 else True
2461 autoDimension = args[3] if len(args) > 3 else True
2462 # process keywords arguments
2463 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2464 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2465 overwrite = kwargs.get("overwrite", overwrite)
2466 autoDimension = kwargs.get("autoDimension", autoDimension)
2468 # invoke engine's function
2469 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2471 def ExportToMEDX(self, *args, **kwargs):
2473 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2474 Export the mesh in a file in MED format
2477 fileName: the file name
2478 opt (boolean): parameter for creating/not creating
2479 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2480 overwrite: boolean parameter for overwriting/not overwriting the file
2481 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2483 - 1D if all mesh nodes lie on OX coordinate axis, or
2484 - 2D if all mesh nodes lie on XOY coordinate plane, or
2485 - 3D in the rest cases.
2487 If **autoDimension** is *False*, the space dimension is always 3.
2490 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2491 # process positional arguments
2492 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2494 auto_groups = args[1] if len(args) > 1 else False
2495 overwrite = args[2] if len(args) > 2 else True
2496 autoDimension = args[3] if len(args) > 3 else True
2497 # process keywords arguments
2498 auto_groups = kwargs.get("auto_groups", auto_groups)
2499 overwrite = kwargs.get("overwrite", overwrite)
2500 autoDimension = kwargs.get("autoDimension", autoDimension)
2502 # invoke engine's function
2503 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2505 # Operations with groups:
2506 # ----------------------
2507 def CreateEmptyGroup(self, elementType, name):
2509 Create an empty standalone mesh group
2512 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2513 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2514 name: the name of the mesh group
2517 :class:`SMESH.SMESH_Group`
2520 return self.mesh.CreateGroup(elementType, name)
2522 def Group(self, grp, name=""):
2524 Create a mesh group based on the geometric object *grp*
2525 and give it a *name*.
2526 If *name* is not defined the name of the geometric group is used
2529 Works like :meth:`GroupOnGeom`.
2532 grp: a geometric group, a vertex, an edge, a face or a solid
2533 name: the name of the mesh group
2536 :class:`SMESH.SMESH_GroupOnGeom`
2539 return self.GroupOnGeom(grp, name)
2541 def GroupOnGeom(self, grp, name="", typ=None):
2543 Create a mesh group based on the geometrical object *grp*
2544 and give it a *name*.
2545 if *name* is not defined the name of the geometric group is used
2548 grp: a geometrical group, a vertex, an edge, a face or a solid
2549 name: the name of the mesh group
2550 typ: the type of elements in the group; either of
2551 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2552 automatically detected by the type of the geometry
2555 :class:`SMESH.SMESH_GroupOnGeom`
2558 AssureGeomPublished( self, grp, name )
2560 name = grp.GetName()
2562 typ = self._groupTypeFromShape( grp )
2563 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2565 def _groupTypeFromShape( self, shape ):
2567 Pivate method to get a type of group on geometry
2569 tgeo = str(shape.GetShapeType())
2570 if tgeo == "VERTEX":
2572 elif tgeo == "EDGE":
2574 elif tgeo == "FACE" or tgeo == "SHELL":
2576 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2578 elif tgeo == "COMPOUND":
2579 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2581 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2582 return self._groupTypeFromShape( sub[0] )
2584 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2587 def GroupOnFilter(self, typ, name, filter):
2589 Create a mesh group with given *name* based on the *filter*.
2590 It is a special type of group dynamically updating it's contents during
2594 typ: the type of elements in the group; either of
2595 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2596 name: the name of the mesh group
2597 filter (SMESH.Filter): the filter defining group contents
2600 :class:`SMESH.SMESH_GroupOnFilter`
2603 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2605 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2607 Create a mesh group by the given ids of elements
2610 groupName: the name of the mesh group
2611 elementType: the type of elements in the group; either of
2612 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2613 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2616 :class:`SMESH.SMESH_Group`
2619 group = self.mesh.CreateGroup(elementType, groupName)
2620 if isinstance( elemIDs, Mesh ):
2621 elemIDs = elemIDs.GetMesh()
2622 if hasattr( elemIDs, "GetIDs" ):
2623 if hasattr( elemIDs, "SetMesh" ):
2624 elemIDs.SetMesh( self.GetMesh() )
2625 group.AddFrom( elemIDs )
2633 CritType=FT_Undefined,
2636 UnaryOp=FT_Undefined,
2639 Create a mesh group by the given conditions
2642 groupName: the name of the mesh group
2643 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2644 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2645 Note that the items starting from FT_LessThan are not suitable for CritType.
2646 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2647 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2648 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2649 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2650 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2653 :class:`SMESH.SMESH_GroupOnFilter`
2656 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2657 group = self.MakeGroupByCriterion(groupName, aCriterion)
2660 def MakeGroupByCriterion(self, groupName, Criterion):
2662 Create a mesh group by the given criterion
2665 groupName: the name of the mesh group
2666 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2669 :class:`SMESH.SMESH_GroupOnFilter`
2672 :meth:`smeshBuilder.GetCriterion`
2675 return self.MakeGroupByCriteria( groupName, [Criterion] )
2677 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2679 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2682 groupName: the name of the mesh group
2683 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2684 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2687 :class:`SMESH.SMESH_GroupOnFilter`
2690 :meth:`smeshBuilder.GetCriterion`
2693 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2694 group = self.MakeGroupByFilter(groupName, aFilter)
2697 def MakeGroupByFilter(self, groupName, theFilter):
2699 Create a mesh group by the given filter
2702 groupName (string): the name of the mesh group
2703 theFilter (SMESH.Filter): the filter
2706 :class:`SMESH.SMESH_GroupOnFilter`
2709 :meth:`smeshBuilder.GetFilter`
2712 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2713 #theFilter.SetMesh( self.mesh )
2714 #group.AddFrom( theFilter )
2715 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2718 def RemoveGroup(self, group):
2723 group (SMESH.SMESH_GroupBase): group to remove
2726 self.mesh.RemoveGroup(group)
2728 def RemoveGroupWithContents(self, group):
2730 Remove a group with its contents
2733 group (SMESH.SMESH_GroupBase): group to remove
2736 self.mesh.RemoveGroupWithContents(group)
2738 def GetGroups(self, elemType = SMESH.ALL):
2740 Get the list of groups existing in the mesh in the order of creation
2741 (starting from the oldest one)
2744 elemType (SMESH.ElementType): type of elements the groups contain;
2745 by default groups of elements of all types are returned
2748 a list of :class:`SMESH.SMESH_GroupBase`
2751 groups = self.mesh.GetGroups()
2752 if elemType == SMESH.ALL:
2756 if g.GetType() == elemType:
2757 typedGroups.append( g )
2764 Get the number of groups existing in the mesh
2767 the quantity of groups as an integer value
2770 return self.mesh.NbGroups()
2772 def GetGroupNames(self):
2774 Get the list of names of groups existing in the mesh
2780 groups = self.GetGroups()
2782 for group in groups:
2783 names.append(group.GetName())
2786 def GetGroupByName(self, name, elemType = None):
2788 Find groups by name and type
2791 name (string): name of the group of interest
2792 elemType (SMESH.ElementType): type of elements the groups contain;
2793 by default one group of any type is returned;
2794 if elemType == SMESH.ALL then all groups of any type are returned
2797 a list of :class:`SMESH.SMESH_GroupBase`
2801 for group in self.GetGroups():
2802 if group.GetName() == name:
2803 if elemType is None:
2805 if ( elemType == SMESH.ALL or
2806 group.GetType() == elemType ):
2807 groups.append( group )
2810 def UnionGroups(self, group1, group2, name):
2812 Produce a union of two groups.
2813 A new group is created. All mesh elements that are
2814 present in the initial groups are added to the new one
2817 group1 (SMESH.SMESH_GroupBase): a group
2818 group2 (SMESH.SMESH_GroupBase): another group
2821 instance of :class:`SMESH.SMESH_Group`
2824 return self.mesh.UnionGroups(group1, group2, name)
2826 def UnionListOfGroups(self, groups, name):
2828 Produce a union list of groups.
2829 New group is created. All mesh elements that are present in
2830 initial groups are added to the new one
2833 groups: list of :class:`SMESH.SMESH_GroupBase`
2836 instance of :class:`SMESH.SMESH_Group`
2838 return self.mesh.UnionListOfGroups(groups, name)
2840 def IntersectGroups(self, group1, group2, name):
2842 Prodice an intersection of two groups.
2843 A new group is created. All mesh elements that are common
2844 for the two initial groups are added to the new one.
2847 group1 (SMESH.SMESH_GroupBase): a group
2848 group2 (SMESH.SMESH_GroupBase): another group
2851 instance of :class:`SMESH.SMESH_Group`
2854 return self.mesh.IntersectGroups(group1, group2, name)
2856 def IntersectListOfGroups(self, groups, name):
2858 Produce an intersection of groups.
2859 New group is created. All mesh elements that are present in all
2860 initial groups simultaneously are added to the new one
2863 groups: a list of :class:`SMESH.SMESH_GroupBase`
2866 instance of :class:`SMESH.SMESH_Group`
2868 return self.mesh.IntersectListOfGroups(groups, name)
2870 def CutGroups(self, main_group, tool_group, name):
2872 Produce a cut of two groups.
2873 A new group is created. All mesh elements that are present in
2874 the main group but are not present in the tool group are added to the new one
2877 main_group (SMESH.SMESH_GroupBase): a group to cut from
2878 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2881 an instance of :class:`SMESH.SMESH_Group`
2884 return self.mesh.CutGroups(main_group, tool_group, name)
2886 def CutListOfGroups(self, main_groups, tool_groups, name):
2888 Produce a cut of groups.
2889 A new group is created. All mesh elements that are present in main groups
2890 but do not present in tool groups are added to the new one
2893 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2894 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2897 an instance of :class:`SMESH.SMESH_Group`
2900 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2902 def CreateDimGroup(self, groups, elemType, name,
2903 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2905 Create a standalone group of entities basing on nodes of other groups.
2908 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2909 elemType: a type of elements to include to the new group; either of
2910 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2911 name: a name of the new group.
2912 nbCommonNodes: a criterion of inclusion of an element to the new group
2913 basing on number of element nodes common with reference *groups*.
2914 Meaning of possible values are:
2916 - SMESH.ALL_NODES - include if all nodes are common,
2917 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2918 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2919 - SMEHS.MAJORITY - include if half of nodes or more are common.
2920 underlyingOnly: if *True* (default), an element is included to the
2921 new group provided that it is based on nodes of an element of *groups*;
2922 in this case the reference *groups* are supposed to be of higher dimension
2923 than *elemType*, which can be useful for example to get all faces lying on
2924 volumes of the reference *groups*.
2927 an instance of :class:`SMESH.SMESH_Group`
2930 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2932 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2934 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2936 Distribute all faces of the mesh among groups using sharp edges and optionally
2937 existing 1D elements as group boundaries.
2940 sharpAngle: edge is considered sharp if an angle between normals of
2941 adjacent faces is more than \a sharpAngle in degrees.
2942 createEdges (boolean): to create 1D elements for detected sharp edges.
2943 useExistingEdges (boolean): to use existing edges as group boundaries
2945 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2947 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2948 self.mesh.SetParameters(Parameters)
2949 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2951 def ConvertToStandalone(self, group):
2953 Convert group on geom into standalone group
2956 return self.mesh.ConvertToStandalone(group)
2958 # Get some info about mesh:
2959 # ------------------------
2961 def GetLog(self, clearAfterGet):
2963 Return the log of nodes and elements added or removed
2964 since the previous clear of the log.
2967 clearAfterGet: log is emptied after Get (safe if concurrents access)
2970 list of SMESH.log_block structures { commandType, number, coords, indexes }
2973 return self.mesh.GetLog(clearAfterGet)
2977 Clear the log of nodes and elements added or removed since the previous
2978 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2981 self.mesh.ClearLog()
2983 def SetAutoColor(self, theAutoColor):
2985 Toggle auto color mode on the object.
2986 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2989 theAutoColor (boolean): the flag which toggles auto color mode.
2992 self.mesh.SetAutoColor(theAutoColor)
2994 def GetAutoColor(self):
2996 Get flag of object auto color mode.
3002 return self.mesh.GetAutoColor()
3009 integer value, which is the internal Id of the mesh
3012 return self.mesh.GetId()
3014 def HasDuplicatedGroupNamesMED(self):
3016 Check the group names for duplications.
3017 Consider the maximum group name length stored in MED file.
3023 return self.mesh.HasDuplicatedGroupNamesMED()
3025 def GetMeshEditor(self):
3027 Obtain the mesh editor tool
3030 an instance of :class:`SMESH.SMESH_MeshEditor`
3035 def GetIDSource(self, ids, elemType = SMESH.ALL):
3037 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3038 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3042 elemType: type of elements; this parameter is used to distinguish
3043 IDs of nodes from IDs of elements; by default ids are treated as
3044 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3047 an instance of :class:`SMESH.SMESH_IDSource`
3050 call UnRegister() for the returned object as soon as it is no more useful::
3052 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3053 mesh.DoSomething( idSrc )
3057 if isinstance( ids, int ):
3059 return self.editor.MakeIDSource(ids, elemType)
3062 # Get information about mesh contents:
3063 # ------------------------------------
3065 def GetMeshInfo(self, obj = None):
3067 Get the mesh statistic.
3068 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
3069 an item of :class:`SMESH.EntityType`.
3072 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3075 if not obj: obj = self.mesh
3076 return self.smeshpyD.GetMeshInfo(obj)
3080 Return the number of nodes in the mesh
3086 return self.mesh.NbNodes()
3088 def NbElements(self):
3090 Return the number of elements in the mesh
3096 return self.mesh.NbElements()
3098 def Nb0DElements(self):
3100 Return the number of 0d elements in the mesh
3106 return self.mesh.Nb0DElements()
3110 Return the number of ball discrete elements in the mesh
3116 return self.mesh.NbBalls()
3120 Return the number of edges in the mesh
3126 return self.mesh.NbEdges()
3128 def NbEdgesOfOrder(self, elementOrder):
3130 Return the number of edges with the given order in the mesh
3133 elementOrder: the order of elements
3134 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3140 return self.mesh.NbEdgesOfOrder(elementOrder)
3144 Return the number of faces in the mesh
3150 return self.mesh.NbFaces()
3152 def NbFacesOfOrder(self, elementOrder):
3154 Return the number of faces with the given order in the mesh
3157 elementOrder: the order of elements
3158 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3164 return self.mesh.NbFacesOfOrder(elementOrder)
3166 def NbTriangles(self):
3168 Return the number of triangles in the mesh
3174 return self.mesh.NbTriangles()
3176 def NbTrianglesOfOrder(self, elementOrder):
3178 Return the number of triangles with the given order in the mesh
3181 elementOrder: is the order of elements
3182 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3188 return self.mesh.NbTrianglesOfOrder(elementOrder)
3190 def NbBiQuadTriangles(self):
3192 Return the number of biquadratic triangles in the mesh
3198 return self.mesh.NbBiQuadTriangles()
3200 def NbQuadrangles(self):
3202 Return the number of quadrangles in the mesh
3208 return self.mesh.NbQuadrangles()
3210 def NbQuadranglesOfOrder(self, elementOrder):
3212 Return the number of quadrangles with the given order in the mesh
3215 elementOrder: the order of elements
3216 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3222 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3224 def NbBiQuadQuadrangles(self):
3226 Return the number of biquadratic quadrangles in the mesh
3232 return self.mesh.NbBiQuadQuadrangles()
3234 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3236 Return the number of polygons of given order in the mesh
3239 elementOrder: the order of elements
3240 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3246 return self.mesh.NbPolygonsOfOrder(elementOrder)
3248 def NbVolumes(self):
3250 Return the number of volumes in the mesh
3256 return self.mesh.NbVolumes()
3259 def NbVolumesOfOrder(self, elementOrder):
3261 Return the number of volumes with the given order in the mesh
3264 elementOrder: the order of elements
3265 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3271 return self.mesh.NbVolumesOfOrder(elementOrder)
3275 Return the number of tetrahedrons in the mesh
3281 return self.mesh.NbTetras()
3283 def NbTetrasOfOrder(self, elementOrder):
3285 Return the number of tetrahedrons with the given order in the mesh
3288 elementOrder: the order of elements
3289 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3295 return self.mesh.NbTetrasOfOrder(elementOrder)
3299 Return the number of hexahedrons in the mesh
3305 return self.mesh.NbHexas()
3307 def NbHexasOfOrder(self, elementOrder):
3309 Return the number of hexahedrons with the given order in the mesh
3312 elementOrder: the order of elements
3313 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3319 return self.mesh.NbHexasOfOrder(elementOrder)
3321 def NbTriQuadraticHexas(self):
3323 Return the number of triquadratic hexahedrons in the mesh
3329 return self.mesh.NbTriQuadraticHexas()
3331 def NbPyramids(self):
3333 Return the number of pyramids in the mesh
3339 return self.mesh.NbPyramids()
3341 def NbPyramidsOfOrder(self, elementOrder):
3343 Return the number of pyramids with the given order in the mesh
3346 elementOrder: the order of elements
3347 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3353 return self.mesh.NbPyramidsOfOrder(elementOrder)
3357 Return the number of prisms in the mesh
3363 return self.mesh.NbPrisms()
3365 def NbPrismsOfOrder(self, elementOrder):
3367 Return the number of prisms with the given order in the mesh
3370 elementOrder: the order of elements
3371 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3377 return self.mesh.NbPrismsOfOrder(elementOrder)
3379 def NbHexagonalPrisms(self):
3381 Return the number of hexagonal prisms in the mesh
3387 return self.mesh.NbHexagonalPrisms()
3389 def NbPolyhedrons(self):
3391 Return the number of polyhedrons in the mesh
3397 return self.mesh.NbPolyhedrons()
3399 def NbSubMesh(self):
3401 Return the number of submeshes in the mesh
3407 return self.mesh.NbSubMesh()
3409 def GetElementsId(self):
3411 Return the list of all mesh elements IDs
3414 the list of integer values
3417 :meth:`GetElementsByType`
3420 return self.mesh.GetElementsId()
3422 def GetElementsByType(self, elementType):
3424 Return the list of IDs of mesh elements with the given type
3427 elementType (SMESH.ElementType): the required type of elements
3430 list of integer values
3433 return self.mesh.GetElementsByType(elementType)
3435 def GetNodesId(self):
3437 Return the list of mesh nodes IDs
3440 the list of integer values
3443 return self.mesh.GetNodesId()
3445 # Get the information about mesh elements:
3446 # ------------------------------------
3448 def GetElementType(self, id, iselem=True):
3450 Return the type of mesh element or node
3453 the value from :class:`SMESH.ElementType` enumeration.
3454 Return SMESH.ALL if element or node with the given ID does not exist
3457 return self.mesh.GetElementType(id, iselem)
3459 def GetElementGeomType(self, id):
3461 Return the geometric type of mesh element
3464 the value from :class:`SMESH.EntityType` enumeration.
3467 return self.mesh.GetElementGeomType(id)
3469 def GetElementShape(self, id):
3471 Return the shape type of mesh element
3474 the value from :class:`SMESH.GeometryType` enumeration.
3477 return self.mesh.GetElementShape(id)
3479 def GetSubMeshElementsId(self, Shape):
3481 Return the list of sub-mesh elements IDs
3484 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3485 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3488 list of integer values
3491 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3492 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3495 return self.mesh.GetSubMeshElementsId(ShapeID)
3497 def GetSubMeshNodesId(self, Shape, all):
3499 Return the list of sub-mesh nodes IDs
3502 Shape: a geom object (sub-shape).
3503 *Shape* must be the sub-shape of a :meth:`GetShape`
3504 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3507 list of integer values
3510 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3511 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3514 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3516 def GetSubMeshElementType(self, Shape):
3518 Return type of elements on given shape
3521 Shape: a geom object (sub-shape).
3522 *Shape* must be a sub-shape of a ShapeToMesh()
3525 :class:`SMESH.ElementType`
3528 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3529 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3532 return self.mesh.GetSubMeshElementType(ShapeID)
3536 Get the mesh description
3542 return self.mesh.Dump()
3545 # Get the information about nodes and elements of a mesh by its IDs:
3546 # -----------------------------------------------------------
3548 def GetNodeXYZ(self, id):
3550 Get XYZ coordinates of a node.
3551 If there is no node for the given ID - return an empty list
3554 list of float values
3557 return self.mesh.GetNodeXYZ(id)
3559 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3561 Return list of IDs of inverse elements for the given node.
3562 If there is no node for the given ID - return an empty list
3566 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3569 list of integer values
3572 return self.mesh.GetNodeInverseElements(id,elemType)
3574 def GetNodePosition(self,NodeID):
3576 Return the position of a node on the shape
3579 :class:`SMESH.NodePosition`
3582 return self.mesh.GetNodePosition(NodeID)
3584 def GetElementPosition(self,ElemID):
3586 Return the position of an element on the shape
3589 :class:`SMESH.ElementPosition`
3592 return self.mesh.GetElementPosition(ElemID)
3594 def GetShapeID(self, id):
3596 Return the ID of the shape, on which the given node was generated.
3599 an integer value > 0 or -1 if there is no node for the given
3600 ID or the node is not assigned to any geometry
3603 return self.mesh.GetShapeID(id)
3605 def GetShapeIDForElem(self,id):
3607 Return the ID of the shape, on which the given element was generated.
3610 an integer value > 0 or -1 if there is no element for the given
3611 ID or the element is not assigned to any geometry
3614 return self.mesh.GetShapeIDForElem(id)
3616 def GetElemNbNodes(self, id):
3618 Return the number of nodes of the given element
3621 an integer value > 0 or -1 if there is no element for the given ID
3624 return self.mesh.GetElemNbNodes(id)
3626 def GetElemNode(self, id, index):
3628 Return the node ID the given (zero based) index for the given element.
3630 * If there is no element for the given ID - return -1.
3631 * If there is no node for the given index - return -2.
3634 id (int): element ID
3635 index (int): node index within the element
3638 an integer value (ID)
3641 :meth:`GetElemNodes`
3644 return self.mesh.GetElemNode(id, index)
3646 def GetElemNodes(self, id):
3648 Return the IDs of nodes of the given element
3651 a list of integer values
3654 return self.mesh.GetElemNodes(id)
3656 def IsMediumNode(self, elementID, nodeID):
3658 Return true if the given node is the medium node in the given quadratic element
3661 return self.mesh.IsMediumNode(elementID, nodeID)
3663 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3665 Return true if the given node is the medium node in one of quadratic elements
3668 nodeID: ID of the node
3669 elementType: the type of elements to check a state of the node, either of
3670 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3673 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3675 def ElemNbEdges(self, id):
3677 Return the number of edges for the given element
3680 return self.mesh.ElemNbEdges(id)
3682 def ElemNbFaces(self, id):
3684 Return the number of faces for the given element
3687 return self.mesh.ElemNbFaces(id)
3689 def GetElemFaceNodes(self,elemId, faceIndex):
3691 Return nodes of given face (counted from zero) for given volumic element.
3694 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3696 def GetFaceNormal(self, faceId, normalized=False):
3698 Return three components of normal of given mesh face
3699 (or an empty array in KO case)
3702 return self.mesh.GetFaceNormal(faceId,normalized)
3704 def FindElementByNodes(self, nodes):
3706 Return an element based on all given nodes.
3709 return self.mesh.FindElementByNodes(nodes)
3711 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3713 Return elements including all given nodes.
3716 return self.mesh.GetElementsByNodes( nodes, elemType )
3718 def IsPoly(self, id):
3720 Return true if the given element is a polygon
3723 return self.mesh.IsPoly(id)
3725 def IsQuadratic(self, id):
3727 Return true if the given element is quadratic
3730 return self.mesh.IsQuadratic(id)
3732 def GetBallDiameter(self, id):
3734 Return diameter of a ball discrete element or zero in case of an invalid *id*
3737 return self.mesh.GetBallDiameter(id)
3739 def BaryCenter(self, id):
3741 Return XYZ coordinates of the barycenter of the given element.
3742 If there is no element for the given ID - return an empty list
3745 a list of three double values
3748 :meth:`smeshBuilder.GetGravityCenter`
3751 return self.mesh.BaryCenter(id)
3753 def GetIdsFromFilter(self, filter, meshParts=[] ):
3755 Pass mesh elements through the given filter and return IDs of fitting elements
3758 filter: :class:`SMESH.Filter`
3759 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3765 :meth:`SMESH.Filter.GetIDs`
3766 :meth:`SMESH.Filter.GetElementsIdFromParts`
3769 filter.SetMesh( self.mesh )
3772 if isinstance( meshParts, Mesh ):
3773 filter.SetMesh( meshParts.GetMesh() )
3774 return theFilter.GetIDs()
3775 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3776 meshParts = [ meshParts ]
3777 return filter.GetElementsIdFromParts( meshParts )
3779 return filter.GetIDs()
3781 # Get mesh measurements information:
3782 # ------------------------------------
3784 def GetFreeBorders(self):
3786 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3787 Return a list of special structures (borders).
3790 a list of :class:`SMESH.FreeEdges.Border`
3793 aFilterMgr = self.smeshpyD.CreateFilterManager()
3794 aPredicate = aFilterMgr.CreateFreeEdges()
3795 aPredicate.SetMesh(self.mesh)
3796 aBorders = aPredicate.GetBorders()
3797 aFilterMgr.UnRegister()
3800 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3802 Get minimum distance between two nodes, elements or distance to the origin
3805 id1: first node/element id
3806 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3807 isElem1: *True* if *id1* is element id, *False* if it is node id
3808 isElem2: *True* if *id2* is element id, *False* if it is node id
3811 minimum distance value
3813 :meth:`GetMinDistance`
3816 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3817 return aMeasure.value
3819 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3821 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3824 id1: first node/element id
3825 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3826 isElem1: *True* if *id1* is element id, *False* if it is node id
3827 isElem2: *True* if *id2* is element id, *False* if it is node id
3830 :class:`SMESH.Measure` structure
3836 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3838 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3841 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3843 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3848 aMeasurements = self.smeshpyD.CreateMeasurements()
3849 aMeasure = aMeasurements.MinDistance(id1, id2)
3850 genObjUnRegister([aMeasurements,id1, id2])
3853 def BoundingBox(self, objects=None, isElem=False):
3855 Get bounding box of the specified object(s)
3858 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3859 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3860 *False* specifies that *objects* are nodes
3863 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3866 :meth:`GetBoundingBox()`
3869 result = self.GetBoundingBox(objects, isElem)
3873 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3876 def GetBoundingBox(self, objects=None, isElem=False):
3878 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3881 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3882 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3883 False means that *objects* are nodes
3886 :class:`SMESH.Measure` structure
3889 :meth:`BoundingBox()`
3893 objects = [self.mesh]
3894 elif isinstance(objects, tuple):
3895 objects = list(objects)
3896 if not isinstance(objects, list):
3898 if len(objects) > 0 and isinstance(objects[0], int):
3901 unRegister = genObjUnRegister()
3903 if isinstance(o, Mesh):
3904 srclist.append(o.mesh)
3905 elif hasattr(o, "_narrow"):
3906 src = o._narrow(SMESH.SMESH_IDSource)
3907 if src: srclist.append(src)
3909 elif isinstance(o, list):
3911 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3913 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3914 unRegister.set( srclist[-1] )
3917 aMeasurements = self.smeshpyD.CreateMeasurements()
3918 unRegister.set( aMeasurements )
3919 aMeasure = aMeasurements.BoundingBox(srclist)
3922 # Mesh edition (SMESH_MeshEditor functionality):
3923 # ---------------------------------------------
3925 def RemoveElements(self, IDsOfElements):
3927 Remove the elements from the mesh by ids
3930 IDsOfElements: is a list of ids of elements to remove
3936 return self.editor.RemoveElements(IDsOfElements)
3938 def RemoveNodes(self, IDsOfNodes):
3940 Remove nodes from mesh by ids
3943 IDsOfNodes: is a list of ids of nodes to remove
3949 return self.editor.RemoveNodes(IDsOfNodes)
3951 def RemoveOrphanNodes(self):
3953 Remove all orphan (free) nodes from mesh
3956 number of the removed nodes
3959 return self.editor.RemoveOrphanNodes()
3961 def AddNode(self, x, y, z):
3963 Add a node to the mesh by coordinates
3969 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3970 if hasVars: self.mesh.SetParameters(Parameters)
3971 return self.editor.AddNode( x, y, z)
3973 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3975 Create a 0D element on a node with given number.
3978 IDOfNode: the ID of node for creation of the element.
3979 DuplicateElements: to add one more 0D element to a node or not
3982 ID of the new 0D element
3985 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3987 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3989 Create 0D elements on all nodes of the given elements except those
3990 nodes on which a 0D element already exists.
3993 theObject: an object on whose nodes 0D elements will be created.
3994 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3995 theGroupName: optional name of a group to add 0D elements created
3996 and/or found on nodes of *theObject*.
3997 DuplicateElements: to add one more 0D element to a node or not
4000 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4001 IDs of new and/or found 0D elements. IDs of 0D elements
4002 can be retrieved from the returned object by
4003 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4006 unRegister = genObjUnRegister()
4007 if isinstance( theObject, Mesh ):
4008 theObject = theObject.GetMesh()
4009 elif isinstance( theObject, list ):
4010 theObject = self.GetIDSource( theObject, SMESH.ALL )
4011 unRegister.set( theObject )
4012 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4014 def AddBall(self, IDOfNode, diameter):
4016 Create a ball element on a node with given ID.
4019 IDOfNode: the ID of node for creation of the element.
4020 diameter: the bal diameter.
4023 ID of the new ball element
4026 return self.editor.AddBall( IDOfNode, diameter )
4028 def AddEdge(self, IDsOfNodes):
4030 Create a linear or quadratic edge (this is determined
4031 by the number of given nodes).
4034 IDsOfNodes: list of node IDs for creation of the element.
4035 The order of nodes in this list should correspond to
4036 the :ref:`connectivity convention <connectivity_page>`.
4042 return self.editor.AddEdge(IDsOfNodes)
4044 def AddFace(self, IDsOfNodes):
4046 Create a linear or quadratic face (this is determined
4047 by the number of given nodes).
4050 IDsOfNodes: list of node IDs for creation of the element.
4051 The order of nodes in this list should correspond to
4052 the :ref:`connectivity convention <connectivity_page>`.
4058 return self.editor.AddFace(IDsOfNodes)
4060 def AddPolygonalFace(self, IdsOfNodes):
4062 Add a polygonal face defined by a list of node IDs
4065 IdsOfNodes: the list of node IDs for creation of the element.
4071 return self.editor.AddPolygonalFace(IdsOfNodes)
4073 def AddQuadPolygonalFace(self, IdsOfNodes):
4075 Add a quadratic polygonal face defined by a list of node IDs
4078 IdsOfNodes: the list of node IDs for creation of the element;
4079 corner nodes follow first.
4085 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4087 def AddVolume(self, IDsOfNodes):
4089 Create both simple and quadratic volume (this is determined
4090 by the number of given nodes).
4093 IDsOfNodes: list of node IDs for creation of the element.
4094 The order of nodes in this list should correspond to
4095 the :ref:`connectivity convention <connectivity_page>`.
4098 ID of the new volumic element
4101 return self.editor.AddVolume(IDsOfNodes)
4103 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4105 Create a volume of many faces, giving nodes for each face.
4108 IdsOfNodes: list of node IDs for volume creation, face by face.
4109 Quantities: list of integer values, Quantities[i]
4110 gives the quantity of nodes in face number i.
4113 ID of the new volumic element
4116 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4118 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4120 Create a volume of many faces, giving the IDs of the existing faces.
4123 The created volume will refer only to the nodes
4124 of the given faces, not to the faces themselves.
4127 IdsOfFaces: the list of face IDs for volume creation.
4130 ID of the new volumic element
4133 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4136 def SetNodeOnVertex(self, NodeID, Vertex):
4138 Bind a node to a vertex
4142 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4145 True if succeed else raises an exception
4148 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4149 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4153 self.editor.SetNodeOnVertex(NodeID, VertexID)
4154 except SALOME.SALOME_Exception as inst:
4155 raise ValueError(inst.details.text)
4159 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4161 Store the node position on an edge
4165 Edge: an edge (GEOM.GEOM_Object) or edge ID
4166 paramOnEdge: a parameter on the edge where the node is located
4169 True if succeed else raises an exception
4172 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4173 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4177 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4178 except SALOME.SALOME_Exception as inst:
4179 raise ValueError(inst.details.text)
4182 def SetNodeOnFace(self, NodeID, Face, u, v):
4184 Store node position on a face
4188 Face: a face (GEOM.GEOM_Object) or face ID
4189 u: U parameter on the face where the node is located
4190 v: V parameter on the face where the node is located
4193 True if succeed else raises an exception
4196 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4197 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4201 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4202 except SALOME.SALOME_Exception as inst:
4203 raise ValueError(inst.details.text)
4206 def SetNodeInVolume(self, NodeID, Solid):
4208 Bind a node to a solid
4212 Solid: a solid (GEOM.GEOM_Object) or solid ID
4215 True if succeed else raises an exception
4218 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4219 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4223 self.editor.SetNodeInVolume(NodeID, SolidID)
4224 except SALOME.SALOME_Exception as inst:
4225 raise ValueError(inst.details.text)
4228 def SetMeshElementOnShape(self, ElementID, Shape):
4230 Bind an element to a shape
4233 ElementID: an element ID
4234 Shape: a shape (GEOM.GEOM_Object) or shape ID
4237 True if succeed else raises an exception
4240 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4241 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4245 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4246 except SALOME.SALOME_Exception as inst:
4247 raise ValueError(inst.details.text)
4251 def MoveNode(self, NodeID, x, y, z):
4253 Move the node with the given id
4256 NodeID: the id of the node
4257 x: a new X coordinate
4258 y: a new Y coordinate
4259 z: a new Z coordinate
4262 True if succeed else False
4265 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4266 if hasVars: self.mesh.SetParameters(Parameters)
4267 return self.editor.MoveNode(NodeID, x, y, z)
4269 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4271 Find the node closest to a point and moves it to a point location
4274 x: the X coordinate of a point
4275 y: the Y coordinate of a point
4276 z: the Z coordinate of a point
4277 NodeID: if specified (>0), the node with this ID is moved,
4278 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4281 the ID of a moved node
4284 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4285 if hasVars: self.mesh.SetParameters(Parameters)
4286 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4288 def FindNodeClosestTo(self, x, y, z):
4290 Find the node closest to a point
4293 x: the X coordinate of a point
4294 y: the Y coordinate of a point
4295 z: the Z coordinate of a point
4301 return self.editor.FindNodeClosestTo(x, y, z)
4303 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4305 Find the elements where a point lays IN or ON
4308 x,y,z (float): coordinates of the point
4309 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4310 means elements of any type excluding nodes, discrete and 0D elements.
4311 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4314 list of IDs of found elements
4317 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4319 return self.editor.FindElementsByPoint(x, y, z, elementType)
4321 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4323 Project a point to a mesh object.
4324 Return ID of an element of given type where the given point is projected
4325 and coordinates of the projection point.
4326 In the case if nothing found, return -1 and []
4328 if isinstance( meshObject, Mesh ):
4329 meshObject = meshObject.GetMesh()
4331 meshObject = self.GetMesh()
4332 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4334 def GetPointState(self, x, y, z):
4336 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4337 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4338 UNKNOWN state means that either mesh is wrong or the analysis fails.
4341 return self.editor.GetPointState(x, y, z)
4343 def IsManifold(self):
4345 Check if a 2D mesh is manifold
4348 return self.editor.IsManifold()
4350 def IsCoherentOrientation2D(self):
4352 Check if orientation of 2D elements is coherent
4355 return self.editor.IsCoherentOrientation2D()
4357 def Get1DBranches( self, edges, startNode = 0 ):
4359 Partition given 1D elements into groups of contiguous edges.
4360 A node where number of meeting edges != 2 is a group end.
4361 An optional startNode is used to orient groups it belongs to.
4364 A list of edge groups and a list of corresponding node groups,
4365 where the group is a list of IDs of edges or elements.
4366 If a group is closed, the first and last nodes of the group are same.
4368 if isinstance( edges, Mesh ):
4369 edges = edges.GetMesh()
4370 unRegister = genObjUnRegister()
4371 if isinstance( edges, list ):
4372 edges = self.GetIDSource( edges, SMESH.EDGE )
4373 unRegister.set( edges )
4374 return self.editor.Get1DBranches( edges, startNode )
4376 def FindSharpEdges( self, angle, addExisting=False ):
4378 Return sharp edges of faces and non-manifold ones.
4379 Optionally add existing edges.
4382 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4383 addExisting: to return existing edges (1D elements) as well
4386 list of FaceEdge structures
4388 angle = ParseParameters( angle )[0]
4389 return self.editor.FindSharpEdges( angle, addExisting )
4391 def MeshToPassThroughAPoint(self, x, y, z):
4393 Find the node closest to a point and moves it to a point location
4396 x: the X coordinate of a point
4397 y: the Y coordinate of a point
4398 z: the Z coordinate of a point
4401 the ID of a moved node
4404 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4406 def InverseDiag(self, NodeID1, NodeID2):
4408 Replace two neighbour triangles sharing Node1-Node2 link
4409 with the triangles built on the same 4 nodes but having other common link.
4412 NodeID1: the ID of the first node
4413 NodeID2: the ID of the second node
4416 False if proper faces were not found
4418 return self.editor.InverseDiag(NodeID1, NodeID2)
4420 def DeleteDiag(self, NodeID1, NodeID2):
4422 Replace two neighbour triangles sharing *Node1-Node2* link
4423 with a quadrangle built on the same 4 nodes.
4426 NodeID1: ID of the first node
4427 NodeID2: ID of the second node
4430 False if proper faces were not found
4433 return self.editor.DeleteDiag(NodeID1, NodeID2)
4435 def Reorient(self, IDsOfElements=None):
4437 Reorient elements by ids
4440 IDsOfElements: if undefined reorients all mesh elements
4443 True if succeed else False
4446 if IDsOfElements == None:
4447 IDsOfElements = self.GetElementsId()
4448 return self.editor.Reorient(IDsOfElements)
4450 def ReorientObject(self, theObject):
4452 Reorient all elements of the object
4455 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4458 True if succeed else False
4461 if ( isinstance( theObject, Mesh )):
4462 theObject = theObject.GetMesh()
4463 return self.editor.ReorientObject(theObject)
4465 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4467 Reorient faces contained in *the2DObject*.
4470 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4471 theDirection: is a desired direction of normal of *theFace*.
4472 It can be either a GEOM vector or a list of coordinates [x,y,z].
4473 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4474 compared with theDirection. It can be either ID of face or a point
4475 by which the face will be found. The point can be given as either
4476 a GEOM vertex or a list of point coordinates.
4479 number of reoriented faces
4482 unRegister = genObjUnRegister()
4484 if isinstance( the2DObject, Mesh ):
4485 the2DObject = the2DObject.GetMesh()
4486 if isinstance( the2DObject, list ):
4487 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4488 unRegister.set( the2DObject )
4489 # check theDirection
4490 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4491 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4492 if isinstance( theDirection, list ):
4493 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4494 # prepare theFace and thePoint
4495 theFace = theFaceOrPoint
4496 thePoint = PointStruct(0,0,0)
4497 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4498 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4500 if isinstance( theFaceOrPoint, list ):
4501 thePoint = PointStruct( *theFaceOrPoint )
4503 if isinstance( theFaceOrPoint, PointStruct ):
4504 thePoint = theFaceOrPoint
4506 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4508 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4510 Reorient faces according to adjacent volumes.
4513 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4514 either IDs of faces or face groups.
4515 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4516 theOutsideNormal: to orient faces to have their normals
4517 pointing either *outside* or *inside* the adjacent volumes.
4520 number of reoriented faces.
4523 unRegister = genObjUnRegister()
4525 if not isinstance( the2DObject, list ):
4526 the2DObject = [ the2DObject ]
4527 elif the2DObject and isinstance( the2DObject[0], int ):
4528 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4529 unRegister.set( the2DObject )
4530 the2DObject = [ the2DObject ]
4531 for i,obj2D in enumerate( the2DObject ):
4532 if isinstance( obj2D, Mesh ):
4533 the2DObject[i] = obj2D.GetMesh()
4534 if isinstance( obj2D, list ):
4535 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4536 unRegister.set( the2DObject[i] )
4538 if isinstance( the3DObject, Mesh ):
4539 the3DObject = the3DObject.GetMesh()
4540 if isinstance( the3DObject, list ):
4541 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4542 unRegister.set( the3DObject )
4543 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4545 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4547 Fuse the neighbouring triangles into quadrangles.
4550 IDsOfElements: The triangles to be fused.
4551 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4552 applied to possible quadrangles to choose a neighbour to fuse with.
4553 Note that not all items of :class:`SMESH.FunctorType` corresponds
4554 to numerical functors.
4555 MaxAngle: is the maximum angle between element normals at which the fusion
4556 is still performed; theMaxAngle is measured in radians.
4557 Also it could be a name of variable which defines angle in degrees.
4560 True in case of success, False otherwise.
4563 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4564 self.mesh.SetParameters(Parameters)
4565 if not IDsOfElements:
4566 IDsOfElements = self.GetElementsId()
4567 Functor = self.smeshpyD.GetFunctor(theCriterion)
4568 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4570 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4572 Fuse the neighbouring triangles of the object into quadrangles
4575 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4576 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4577 applied to possible quadrangles to choose a neighbour to fuse with.
4578 Note that not all items of :class:`SMESH.FunctorType` corresponds
4579 to numerical functors.
4580 MaxAngle: a max angle between element normals at which the fusion
4581 is still performed; theMaxAngle is measured in radians.
4584 True in case of success, False otherwise.
4587 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4588 self.mesh.SetParameters(Parameters)
4589 if isinstance( theObject, Mesh ):
4590 theObject = theObject.GetMesh()
4591 Functor = self.smeshpyD.GetFunctor(theCriterion)
4592 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4594 def QuadToTri (self, IDsOfElements, theCriterion = None):
4596 Split quadrangles into triangles.
4599 IDsOfElements: the faces to be splitted.
4600 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4601 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4602 value, then quadrangles will be split by the smallest diagonal.
4603 Note that not all items of :class:`SMESH.FunctorType` corresponds
4604 to numerical functors.
4607 True in case of success, False otherwise.
4609 if IDsOfElements == []:
4610 IDsOfElements = self.GetElementsId()
4611 if theCriterion is None:
4612 theCriterion = FT_MaxElementLength2D
4613 Functor = self.smeshpyD.GetFunctor(theCriterion)
4614 return self.editor.QuadToTri(IDsOfElements, Functor)
4616 def QuadToTriObject (self, theObject, theCriterion = None):
4618 Split quadrangles into triangles.
4621 theObject: the object from which the list of elements is taken,
4622 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4623 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4624 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4625 value, then quadrangles will be split by the smallest diagonal.
4626 Note that not all items of :class:`SMESH.FunctorType` corresponds
4627 to numerical functors.
4630 True in case of success, False otherwise.
4632 if ( isinstance( theObject, Mesh )):
4633 theObject = theObject.GetMesh()
4634 if theCriterion is None:
4635 theCriterion = FT_MaxElementLength2D
4636 Functor = self.smeshpyD.GetFunctor(theCriterion)
4637 return self.editor.QuadToTriObject(theObject, Functor)
4639 def QuadTo4Tri (self, theElements=[]):
4641 Split each of given quadrangles into 4 triangles. A node is added at the center of
4645 theElements: the faces to be splitted. This can be either
4646 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4647 or a list of face IDs. By default all quadrangles are split
4649 unRegister = genObjUnRegister()
4650 if isinstance( theElements, Mesh ):
4651 theElements = theElements.mesh
4652 elif not theElements:
4653 theElements = self.mesh
4654 elif isinstance( theElements, list ):
4655 theElements = self.GetIDSource( theElements, SMESH.FACE )
4656 unRegister.set( theElements )
4657 return self.editor.QuadTo4Tri( theElements )
4659 def SplitQuad (self, IDsOfElements, Diag13):
4661 Split quadrangles into triangles.
4664 IDsOfElements: the faces to be splitted
4665 Diag13 (boolean): is used to choose a diagonal for splitting.
4668 True in case of success, False otherwise.
4670 if IDsOfElements == []:
4671 IDsOfElements = self.GetElementsId()
4672 return self.editor.SplitQuad(IDsOfElements, Diag13)
4674 def SplitQuadObject (self, theObject, Diag13):
4676 Split quadrangles into triangles.
4679 theObject: the object from which the list of elements is taken,
4680 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4681 Diag13 (boolean): is used to choose a diagonal for splitting.
4684 True in case of success, False otherwise.
4686 if ( isinstance( theObject, Mesh )):
4687 theObject = theObject.GetMesh()
4688 return self.editor.SplitQuadObject(theObject, Diag13)
4690 def BestSplit (self, IDOfQuad, theCriterion):
4692 Find a better splitting of the given quadrangle.
4695 IDOfQuad: the ID of the quadrangle to be splitted.
4696 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4697 choose a diagonal for splitting.
4698 Note that not all items of :class:`SMESH.FunctorType` corresponds
4699 to numerical functors.
4702 * 1 if 1-3 diagonal is better,
4703 * 2 if 2-4 diagonal is better,
4704 * 0 if error occurs.
4706 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4708 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4710 Split volumic elements into tetrahedrons
4713 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4714 method: flags passing splitting method:
4715 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4716 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4718 unRegister = genObjUnRegister()
4719 if isinstance( elems, Mesh ):
4720 elems = elems.GetMesh()
4721 if ( isinstance( elems, list )):
4722 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4723 unRegister.set( elems )
4724 self.editor.SplitVolumesIntoTetra(elems, method)
4727 def SplitBiQuadraticIntoLinear(self, elems=None):
4729 Split bi-quadratic elements into linear ones without creation of additional nodes:
4731 - bi-quadratic triangle will be split into 3 linear quadrangles;
4732 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4733 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4735 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4736 will be split in order to keep the mesh conformal.
4739 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4740 if None (default), all bi-quadratic elements will be split
4742 unRegister = genObjUnRegister()
4743 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4744 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4745 unRegister.set( elems )
4747 elems = [ self.GetMesh() ]
4748 if isinstance( elems, Mesh ):
4749 elems = [ elems.GetMesh() ]
4750 if not isinstance( elems, list ):
4752 self.editor.SplitBiQuadraticIntoLinear( elems )
4754 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4755 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4757 Split hexahedra into prisms
4760 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4761 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4762 gives a normal vector defining facets to split into triangles.
4763 *startHexPoint* can be either a triple of coordinates or a vertex.
4764 facetNormal: a normal to a facet to split into triangles of a
4765 hexahedron found by *startHexPoint*.
4766 *facetNormal* can be either a triple of coordinates or an edge.
4767 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4768 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4769 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4770 to *startHexPoint* are split, else *startHexPoint*
4771 is used to find the facet to split in all domains present in *elems*.
4774 unRegister = genObjUnRegister()
4775 if isinstance( elems, Mesh ):
4776 elems = elems.GetMesh()
4777 if ( isinstance( elems, list )):
4778 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4779 unRegister.set( elems )
4782 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4783 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4784 elif isinstance( startHexPoint, list ):
4785 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4788 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4789 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4790 elif isinstance( facetNormal, list ):
4791 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4794 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4796 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4798 def SplitQuadsNearTriangularFacets(self):
4800 Split quadrangle faces near triangular facets of volumes
4802 faces_array = self.GetElementsByType(SMESH.FACE)
4803 for face_id in faces_array:
4804 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4805 quad_nodes = self.mesh.GetElemNodes(face_id)
4806 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4807 isVolumeFound = False
4808 for node1_elem in node1_elems:
4809 if not isVolumeFound:
4810 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4811 nb_nodes = self.GetElemNbNodes(node1_elem)
4812 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4813 volume_elem = node1_elem
4814 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4815 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4816 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4817 isVolumeFound = True
4818 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4819 self.SplitQuad([face_id], False) # diagonal 2-4
4820 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4821 isVolumeFound = True
4822 self.SplitQuad([face_id], True) # diagonal 1-3
4823 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4824 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4825 isVolumeFound = True
4826 self.SplitQuad([face_id], True) # diagonal 1-3
4828 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4830 Split hexahedrons into tetrahedrons.
4832 This operation uses :doc:`pattern_mapping` functionality for splitting.
4835 theObject: the object from which the list of hexahedrons is taken;
4836 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4837 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4838 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4839 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4840 key-point will be mapped into *theNode001*-th node of each volume.
4841 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4844 True in case of success, False otherwise.
4852 # (0,0,1) 4.---------.7 * |
4859 # (0,0,0) 0.---------.3
4860 pattern_tetra = "!!! Nb of points: \n 8 \n\
4870 !!! Indices of points of 6 tetras: \n\
4878 pattern = self.smeshpyD.GetPattern()
4879 isDone = pattern.LoadFromFile(pattern_tetra)
4881 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4884 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4885 isDone = pattern.MakeMesh(self.mesh, False, False)
4886 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4888 # split quafrangle faces near triangular facets of volumes
4889 self.SplitQuadsNearTriangularFacets()
4893 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4895 Split hexahedrons into prisms.
4897 Uses the :doc:`pattern_mapping` functionality for splitting.
4900 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4901 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4902 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4903 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4904 will be mapped into the *theNode001* -th node of each volume.
4905 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4908 True in case of success, False otherwise.
4910 # Pattern: 5.---------.6
4915 # (0,0,1) 4.---------.7 |
4922 # (0,0,0) 0.---------.3
4923 pattern_prism = "!!! Nb of points: \n 8 \n\
4933 !!! Indices of points of 2 prisms: \n\
4937 pattern = self.smeshpyD.GetPattern()
4938 isDone = pattern.LoadFromFile(pattern_prism)
4940 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4943 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4944 isDone = pattern.MakeMesh(self.mesh, False, False)
4945 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4947 # Split quafrangle faces near triangular facets of volumes
4948 self.SplitQuadsNearTriangularFacets()
4952 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4953 MaxNbOfIterations, MaxAspectRatio, Method):
4958 IDsOfElements: the list if ids of elements to smooth
4959 IDsOfFixedNodes: the list of ids of fixed nodes.
4960 Note that nodes built on edges and boundary nodes are always fixed.
4961 MaxNbOfIterations: the maximum number of iterations
4962 MaxAspectRatio: varies in range [1.0, inf]
4963 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4964 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4967 True in case of success, False otherwise.
4970 if IDsOfElements == []:
4971 IDsOfElements = self.GetElementsId()
4972 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4973 self.mesh.SetParameters(Parameters)
4974 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4975 MaxNbOfIterations, MaxAspectRatio, Method)
4977 def SmoothObject(self, theObject, IDsOfFixedNodes,
4978 MaxNbOfIterations, MaxAspectRatio, Method):
4980 Smooth elements which belong to the given object
4983 theObject: the object to smooth
4984 IDsOfFixedNodes: the list of ids of fixed nodes.
4985 Note that nodes built on edges and boundary nodes are always fixed.
4986 MaxNbOfIterations: the maximum number of iterations
4987 MaxAspectRatio: varies in range [1.0, inf]
4988 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4989 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4992 True in case of success, False otherwise.
4995 if ( isinstance( theObject, Mesh )):
4996 theObject = theObject.GetMesh()
4997 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4998 MaxNbOfIterations, MaxAspectRatio, Method)
5000 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5001 MaxNbOfIterations, MaxAspectRatio, Method):
5003 Parametrically smooth the given elements
5006 IDsOfElements: the list if ids of elements to smooth
5007 IDsOfFixedNodes: the list of ids of fixed nodes.
5008 Note that nodes built on edges and boundary nodes are always fixed.
5009 MaxNbOfIterations: the maximum number of iterations
5010 MaxAspectRatio: varies in range [1.0, inf]
5011 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5012 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5015 True in case of success, False otherwise.
5018 if IDsOfElements == []:
5019 IDsOfElements = self.GetElementsId()
5020 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5021 self.mesh.SetParameters(Parameters)
5022 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5023 MaxNbOfIterations, MaxAspectRatio, Method)
5025 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5026 MaxNbOfIterations, MaxAspectRatio, Method):
5028 Parametrically smooth the elements which belong to the given object
5031 theObject: the object to smooth
5032 IDsOfFixedNodes: the list of ids of fixed nodes.
5033 Note that nodes built on edges and boundary nodes are always fixed.
5034 MaxNbOfIterations: the maximum number of iterations
5035 MaxAspectRatio: varies in range [1.0, inf]
5036 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5037 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5040 True in case of success, False otherwise.
5043 if ( isinstance( theObject, Mesh )):
5044 theObject = theObject.GetMesh()
5045 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5046 MaxNbOfIterations, MaxAspectRatio, Method)
5048 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5050 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5051 them with quadratic with the same id.
5054 theForce3d: method of new node creation:
5056 * False - the medium node lies at the geometrical entity from which the mesh element is built
5057 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5058 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5059 theToBiQuad: If True, converts the mesh to bi-quadratic
5062 :class:`SMESH.ComputeError` which can hold a warning
5065 If *theSubMesh* is provided, the mesh can become non-conformal
5068 if isinstance( theSubMesh, Mesh ):
5069 theSubMesh = theSubMesh.mesh
5071 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5074 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5076 self.editor.ConvertToQuadratic(theForce3d)
5077 error = self.editor.GetLastError()
5078 if error and error.comment:
5079 print(error.comment)
5082 def ConvertFromQuadratic(self, theSubMesh=None):
5084 Convert the mesh from quadratic to ordinary,
5085 deletes old quadratic elements,
5086 replacing them with ordinary mesh elements with the same id.
5089 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5092 If *theSubMesh* is provided, the mesh can become non-conformal
5096 self.editor.ConvertFromQuadraticObject(theSubMesh)
5098 return self.editor.ConvertFromQuadratic()
5100 def Make2DMeshFrom3D(self):
5102 Create 2D mesh as skin on boundary faces of a 3D mesh
5105 True if operation has been completed successfully, False otherwise
5108 return self.editor.Make2DMeshFrom3D()
5110 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5111 toCopyElements=False, toCopyExistingBondary=False):
5113 Create missing boundary elements
5116 elements: elements whose boundary is to be checked:
5117 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5118 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5119 dimension: defines type of boundary elements to create, either of
5120 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5121 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5122 groupName: a name of group to store created boundary elements in,
5123 "" means not to create the group
5124 meshName: a name of new mesh to store created boundary elements in,
5125 "" means not to create the new mesh
5126 toCopyElements: if True, the checked elements will be copied into
5127 the new mesh else only boundary elements will be copied into the new mesh
5128 toCopyExistingBondary: if True, not only new but also pre-existing
5129 boundary elements will be copied into the new mesh
5132 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5135 unRegister = genObjUnRegister()
5136 if isinstance( elements, Mesh ):
5137 elements = elements.GetMesh()
5138 if ( isinstance( elements, list )):
5139 elemType = SMESH.ALL
5140 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5141 elements = self.editor.MakeIDSource(elements, elemType)
5142 unRegister.set( elements )
5143 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5144 toCopyElements,toCopyExistingBondary)
5145 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5148 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5149 toCopyAll=False, groups=[]):
5151 Create missing boundary elements around either the whole mesh or
5155 dimension: defines type of boundary elements to create, either of
5156 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5157 groupName: a name of group to store all boundary elements in,
5158 "" means not to create the group
5159 meshName: a name of a new mesh, which is a copy of the initial
5160 mesh + created boundary elements; "" means not to create the new mesh
5161 toCopyAll: if True, the whole initial mesh will be copied into
5162 the new mesh else only boundary elements will be copied into the new mesh
5163 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5166 tuple( long, mesh, group )
5167 - long - number of added boundary elements
5168 - mesh - the :class:`Mesh` where elements were added to
5169 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5172 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5174 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5175 return nb, mesh, group
5177 def RenumberNodes(self):
5179 Renumber mesh nodes to remove unused node IDs
5181 self.editor.RenumberNodes()
5183 def RenumberElements(self):
5185 Renumber mesh elements to remove unused element IDs
5187 self.editor.RenumberElements()
5189 def _getIdSourceList(self, arg, idType, unRegister):
5191 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5193 if arg and isinstance( arg, list ):
5194 if isinstance( arg[0], int ):
5195 arg = self.GetIDSource( arg, idType )
5196 unRegister.set( arg )
5197 elif isinstance( arg[0], Mesh ):
5198 arg[0] = arg[0].GetMesh()
5199 elif isinstance( arg, Mesh ):
5201 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5205 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5206 MakeGroups=False, TotalAngle=False):
5208 Generate new elements by rotation of the given elements and nodes around the axis
5211 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5212 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5213 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5214 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5215 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5216 which defines angle in degrees
5217 NbOfSteps: the number of steps
5218 Tolerance: tolerance
5219 MakeGroups: forces the generation of new groups from existing ones
5220 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5221 of all steps, else - size of each step
5224 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5227 unRegister = genObjUnRegister()
5228 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5229 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5230 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5232 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5233 Axis = self.smeshpyD.GetAxisStruct( Axis )
5234 if isinstance( Axis, list ):
5235 Axis = SMESH.AxisStruct( *Axis )
5237 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5238 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5239 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5240 self.mesh.SetParameters(Parameters)
5241 if TotalAngle and NbOfSteps:
5242 AngleInRadians /= NbOfSteps
5243 return self.editor.RotationSweepObjects( nodes, edges, faces,
5244 Axis, AngleInRadians,
5245 NbOfSteps, Tolerance, MakeGroups)
5247 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5248 MakeGroups=False, TotalAngle=False):
5250 Generate new elements by rotation of the elements around the axis
5253 IDsOfElements: the list of ids of elements to sweep
5254 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5255 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5256 NbOfSteps: the number of steps
5257 Tolerance: tolerance
5258 MakeGroups: forces the generation of new groups from existing ones
5259 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5260 of all steps, else - size of each step
5263 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5266 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5267 AngleInRadians, NbOfSteps, Tolerance,
5268 MakeGroups, TotalAngle)
5270 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5271 MakeGroups=False, TotalAngle=False):
5273 Generate new elements by rotation of the elements of object around the axis
5274 theObject object which elements should be sweeped.
5275 It can be a mesh, a sub mesh or a group.
5278 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5279 AngleInRadians: the angle of Rotation
5280 NbOfSteps: number of steps
5281 Tolerance: tolerance
5282 MakeGroups: forces the generation of new groups from existing ones
5283 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5284 of all steps, else - size of each step
5287 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5290 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5291 AngleInRadians, NbOfSteps, Tolerance,
5292 MakeGroups, TotalAngle )
5294 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5295 MakeGroups=False, TotalAngle=False):
5297 Generate new elements by rotation of the elements of object around the axis
5298 theObject object which elements should be sweeped.
5299 It can be a mesh, a sub mesh or a group.
5302 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5303 AngleInRadians: the angle of Rotation
5304 NbOfSteps: number of steps
5305 Tolerance: tolerance
5306 MakeGroups: forces the generation of new groups from existing ones
5307 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5308 of all steps, else - size of each step
5311 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5312 empty list otherwise
5315 return self.RotationSweepObjects([],theObject,[], Axis,
5316 AngleInRadians, NbOfSteps, Tolerance,
5317 MakeGroups, TotalAngle)
5319 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5320 MakeGroups=False, TotalAngle=False):
5322 Generate new elements by rotation of the elements of object around the axis
5323 theObject object which elements should be sweeped.
5324 It can be a mesh, a sub mesh or a group.
5327 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5328 AngleInRadians: the angle of Rotation
5329 NbOfSteps: number of steps
5330 Tolerance: tolerance
5331 MakeGroups: forces the generation of new groups from existing ones
5332 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5333 of all steps, else - size of each step
5336 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5339 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5340 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5342 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5343 scaleFactors=[], linearVariation=False, basePoint=[] ):
5345 Generate new elements by extrusion of the given elements and nodes
5348 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5349 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5350 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5351 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5352 the direction and value of extrusion for one step (the total extrusion
5353 length will be NbOfSteps * ||StepVector||)
5354 NbOfSteps: the number of steps
5355 MakeGroups: forces the generation of new groups from existing ones
5356 scaleFactors: optional scale factors to apply during extrusion
5357 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5358 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5359 basePoint: optional scaling center; if not provided, a gravity center of
5360 nodes and elements being extruded is used as the scaling center.
5363 - a list of tree components of the point or
5367 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5369 Example: :ref:`tui_extrusion`
5371 unRegister = genObjUnRegister()
5372 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5373 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5374 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5376 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5377 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5378 if isinstance( StepVector, list ):
5379 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5381 if isinstance( basePoint, int):
5382 xyz = self.GetNodeXYZ( basePoint )
5384 raise RuntimeError("Invalid node ID: %s" % basePoint)
5386 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5387 basePoint = self.geompyD.PointCoordinates( basePoint )
5389 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5390 Parameters = StepVector.PS.parameters + var_separator + Parameters
5391 self.mesh.SetParameters(Parameters)
5393 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5394 StepVector, NbOfSteps,
5395 scaleFactors, linearVariation, basePoint,
5399 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5401 Generate new elements by extrusion of the elements with given ids
5404 IDsOfElements: the list of ids of elements or nodes for extrusion
5405 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5406 the direction and value of extrusion for one step (the total extrusion
5407 length will be NbOfSteps * ||StepVector||)
5408 NbOfSteps: the number of steps
5409 MakeGroups: forces the generation of new groups from existing ones
5410 IsNodes: is True if elements with given ids are nodes
5413 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5415 Example: :ref:`tui_extrusion`
5418 if IsNodes: n = IDsOfElements
5419 else : e,f, = IDsOfElements,IDsOfElements
5420 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5422 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5423 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5425 Generate new elements by extrusion along the normal to a discretized surface or wire
5428 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5429 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5430 StepSize: length of one extrusion step (the total extrusion
5431 length will be *NbOfSteps* *StepSize*).
5432 NbOfSteps: number of extrusion steps.
5433 ByAverageNormal: if True each node is translated by *StepSize*
5434 along the average of the normal vectors to the faces sharing the node;
5435 else each node is translated along the same average normal till
5436 intersection with the plane got by translation of the face sharing
5437 the node along its own normal by *StepSize*.
5438 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5439 for every node of *Elements*.
5440 MakeGroups: forces generation of new groups from existing ones.
5441 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5442 is not yet implemented. This parameter is used if *Elements* contains
5443 both faces and edges, i.e. *Elements* is a Mesh.
5446 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5447 empty list otherwise.
5448 Example: :ref:`tui_extrusion`
5451 unRegister = genObjUnRegister()
5452 if isinstance( Elements, Mesh ):
5453 Elements = [ Elements.GetMesh() ]
5454 if isinstance( Elements, list ):
5456 raise RuntimeError("Elements empty!")
5457 if isinstance( Elements[0], int ):
5458 Elements = self.GetIDSource( Elements, SMESH.ALL )
5459 unRegister.set( Elements )
5460 if not isinstance( Elements, list ):
5461 Elements = [ Elements ]
5462 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5463 self.mesh.SetParameters(Parameters)
5464 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5465 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5467 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5469 Generate new elements by extrusion of the elements or nodes which belong to the object
5472 theObject: the object whose elements or nodes should be processed.
5473 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5474 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5475 the direction and value of extrusion for one step (the total extrusion
5476 length will be NbOfSteps * ||StepVector||)
5477 NbOfSteps: the number of steps
5478 MakeGroups: forces the generation of new groups from existing ones
5479 IsNodes: is True if elements to extrude are nodes
5482 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5483 Example: :ref:`tui_extrusion`
5487 if IsNodes: n = theObject
5488 else : e,f, = theObject,theObject
5489 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5491 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5493 Generate new elements by extrusion of edges which belong to the object
5496 theObject: object whose 1D elements should be processed.
5497 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5498 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5499 the direction and value of extrusion for one step (the total extrusion
5500 length will be NbOfSteps * ||StepVector||)
5501 NbOfSteps: the number of steps
5502 MakeGroups: to generate new groups from existing ones
5505 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5506 Example: :ref:`tui_extrusion`
5509 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5511 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5513 Generate new elements by extrusion of faces which belong to the object
5516 theObject: object whose 2D elements should be processed.
5517 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5518 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5519 the direction and value of extrusion for one step (the total extrusion
5520 length will be NbOfSteps * ||StepVector||)
5521 NbOfSteps: the number of steps
5522 MakeGroups: forces the generation of new groups from existing ones
5525 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5526 Example: :ref:`tui_extrusion`
5529 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5531 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5532 ExtrFlags, SewTolerance, MakeGroups=False):
5534 Generate new elements by extrusion of the elements with given ids
5537 IDsOfElements: is ids of elements
5538 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5539 the direction and value of extrusion for one step (the total extrusion
5540 length will be NbOfSteps * ||StepVector||)
5541 NbOfSteps: the number of steps
5542 ExtrFlags: sets flags for extrusion
5543 SewTolerance: uses for comparing locations of nodes if flag
5544 EXTRUSION_FLAG_SEW is set
5545 MakeGroups: forces the generation of new groups from existing ones
5548 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5551 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5552 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5553 if isinstance( StepVector, list ):
5554 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5555 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5556 ExtrFlags, SewTolerance, MakeGroups)
5558 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5559 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5560 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5562 Generate new elements by extrusion of the given elements and nodes along the path.
5563 The path of extrusion must be a meshed edge.
5566 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5567 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5568 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5569 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5570 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5571 contains not only path segments, else it can be None
5572 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5573 HasAngles: allows the shape to be rotated around the path
5574 to get the resulting mesh in a helical fashion
5575 Angles: list of angles
5576 LinearVariation: forces the computation of rotation angles as linear
5577 variation of the given Angles along path steps
5578 HasRefPoint: allows using the reference point
5579 RefPoint: the reference point around which the shape is rotated (the mass center of the
5580 shape by default). The User can specify any point as the Reference Point.
5581 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5582 MakeGroups: forces the generation of new groups from existing ones
5585 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5586 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5587 Example: :ref:`tui_extrusion_along_path`
5590 unRegister = genObjUnRegister()
5591 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5592 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5593 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5595 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5596 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5597 if isinstance( RefPoint, list ):
5598 if not RefPoint: RefPoint = [0,0,0]
5599 RefPoint = SMESH.PointStruct( *RefPoint )
5600 if isinstance( PathMesh, Mesh ):
5601 PathMesh = PathMesh.GetMesh()
5602 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5603 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5604 self.mesh.SetParameters(Parameters)
5605 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5606 PathMesh, PathShape, NodeStart,
5607 HasAngles, Angles, LinearVariation,
5608 HasRefPoint, RefPoint, MakeGroups)
5610 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5611 HasAngles=False, Angles=[], LinearVariation=False,
5612 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5613 ElemType=SMESH.FACE):
5615 Generate new elements by extrusion of the given elements.
5616 The path of extrusion must be a meshed edge.
5619 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5620 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5621 NodeStart: the start node from Path. Defines the direction of extrusion
5622 HasAngles: allows the shape to be rotated around the path
5623 to get the resulting mesh in a helical fashion
5624 Angles: list of angles in radians
5625 LinearVariation: forces the computation of rotation angles as linear
5626 variation of the given Angles along path steps
5627 HasRefPoint: allows using the reference point
5628 RefPoint: the reference point around which the elements are rotated (the mass
5629 center of the elements by default).
5630 The User can specify any point as the Reference Point.
5631 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5632 MakeGroups: forces the generation of new groups from existing ones
5633 ElemType: type of elements for extrusion (if param Base is a mesh)
5636 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5637 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5638 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5640 Example: :ref:`tui_extrusion_along_path`
5644 if ElemType == SMESH.NODE: n = Base
5645 if ElemType == SMESH.EDGE: e = Base
5646 if ElemType == SMESH.FACE: f = Base
5647 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5648 HasAngles, Angles, LinearVariation,
5649 HasRefPoint, RefPoint, MakeGroups)
5650 if MakeGroups: return gr,er
5653 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5654 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5655 MakeGroups=False, LinearVariation=False):
5657 Generate new elements by extrusion of the given elements.
5658 The path of extrusion must be a meshed edge.
5661 IDsOfElements: ids of elements
5662 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5663 PathShape: shape (edge) defines the sub-mesh for the path
5664 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5665 HasAngles: allows the shape to be rotated around the path
5666 to get the resulting mesh in a helical fashion
5667 Angles: list of angles in radians
5668 HasRefPoint: allows using the reference point
5669 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5670 The User can specify any point as the Reference Point.
5671 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5672 MakeGroups: forces the generation of new groups from existing ones
5673 LinearVariation: forces the computation of rotation angles as linear
5674 variation of the given Angles along path steps
5677 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5678 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5679 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5680 Example: :ref:`tui_extrusion_along_path`
5683 n,e,f = [],IDsOfElements,IDsOfElements
5684 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5685 NodeStart, HasAngles, Angles,
5687 HasRefPoint, RefPoint, MakeGroups)
5688 if MakeGroups: return gr,er
5691 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5692 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5693 MakeGroups=False, LinearVariation=False):
5695 Generate new elements by extrusion of the elements which belong to the object.
5696 The path of extrusion must be a meshed edge.
5699 theObject: the object whose elements should be processed.
5700 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5701 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5702 PathShape: shape (edge) defines the sub-mesh for the path
5703 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5704 HasAngles: allows the shape to be rotated around the path
5705 to get the resulting mesh in a helical fashion
5706 Angles: list of angles
5707 HasRefPoint: allows using the reference point
5708 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5709 The User can specify any point as the Reference Point.
5710 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5711 MakeGroups: forces the generation of new groups from existing ones
5712 LinearVariation: forces the computation of rotation angles as linear
5713 variation of the given Angles along path steps
5716 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5717 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5718 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5719 Example: :ref:`tui_extrusion_along_path`
5722 n,e,f = [],theObject,theObject
5723 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5724 HasAngles, Angles, LinearVariation,
5725 HasRefPoint, RefPoint, MakeGroups)
5726 if MakeGroups: return gr,er
5729 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5730 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5731 MakeGroups=False, LinearVariation=False):
5733 Generate new elements by extrusion of mesh segments which belong to the object.
5734 The path of extrusion must be a meshed edge.
5737 theObject: the object whose 1D elements should be processed.
5738 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5739 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5740 PathShape: shape (edge) defines the sub-mesh for the path
5741 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5742 HasAngles: allows the shape to be rotated around the path
5743 to get the resulting mesh in a helical fashion
5744 Angles: list of angles
5745 HasRefPoint: allows using the reference point
5746 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5747 The User can specify any point as the Reference Point.
5748 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5749 MakeGroups: forces the generation of new groups from existing ones
5750 LinearVariation: forces the computation of rotation angles as linear
5751 variation of the given Angles along path steps
5754 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5755 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5756 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5757 Example: :ref:`tui_extrusion_along_path`
5760 n,e,f = [],theObject,[]
5761 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5762 HasAngles, Angles, LinearVariation,
5763 HasRefPoint, RefPoint, MakeGroups)
5764 if MakeGroups: return gr,er
5767 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5768 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5769 MakeGroups=False, LinearVariation=False):
5771 Generate new elements by extrusion of faces which belong to the object.
5772 The path of extrusion must be a meshed edge.
5775 theObject: the object whose 2D elements should be processed.
5776 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5777 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5778 PathShape: shape (edge) defines the sub-mesh for the path
5779 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5780 HasAngles: allows the shape to be rotated around the path
5781 to get the resulting mesh in a helical fashion
5782 Angles: list of angles
5783 HasRefPoint: allows using the reference point
5784 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5785 The User can specify any point as the Reference Point.
5786 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5787 MakeGroups: forces the generation of new groups from existing ones
5788 LinearVariation: forces the computation of rotation angles as linear
5789 variation of the given Angles along path steps
5792 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5793 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5794 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5795 Example: :ref:`tui_extrusion_along_path`
5798 n,e,f = [],[],theObject
5799 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5800 HasAngles, Angles, LinearVariation,
5801 HasRefPoint, RefPoint, MakeGroups)
5802 if MakeGroups: return gr,er
5805 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5807 Create a symmetrical copy of mesh elements
5810 IDsOfElements: list of elements ids
5811 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5812 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5813 If the *Mirror* is a geom object this parameter is unnecessary
5814 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5815 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5818 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5821 if IDsOfElements == []:
5822 IDsOfElements = self.GetElementsId()
5823 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5824 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5825 theMirrorType = Mirror._mirrorType
5827 self.mesh.SetParameters(Mirror.parameters)
5828 if Copy and MakeGroups:
5829 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5830 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5833 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5835 Create a new mesh by a symmetrical copy of mesh elements
5838 IDsOfElements: the list of elements ids
5839 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5840 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5841 If the *Mirror* is a geom object this parameter is unnecessary
5842 MakeGroups: to generate new groups from existing ones
5843 NewMeshName: a name of the new mesh to create
5846 instance of class :class:`Mesh`
5849 if IDsOfElements == []:
5850 IDsOfElements = self.GetElementsId()
5851 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5852 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5853 theMirrorType = Mirror._mirrorType
5855 self.mesh.SetParameters(Mirror.parameters)
5856 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5857 MakeGroups, NewMeshName)
5858 return Mesh(self.smeshpyD,self.geompyD,mesh)
5860 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5862 Create a symmetrical copy of the object
5865 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5866 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5867 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5868 If the *Mirror* is a geom object this parameter is unnecessary
5869 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5870 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5873 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5876 if ( isinstance( theObject, Mesh )):
5877 theObject = theObject.GetMesh()
5878 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5879 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5880 theMirrorType = Mirror._mirrorType
5882 self.mesh.SetParameters(Mirror.parameters)
5883 if Copy and MakeGroups:
5884 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5885 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5888 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5890 Create a new mesh by a symmetrical copy of the object
5893 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5894 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5895 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5896 If the *Mirror* is a geom object this parameter is unnecessary
5897 MakeGroups: forces the generation of new groups from existing ones
5898 NewMeshName: the name of the new mesh to create
5901 instance of class :class:`Mesh`
5904 if ( isinstance( theObject, Mesh )):
5905 theObject = theObject.GetMesh()
5906 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5907 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5908 theMirrorType = Mirror._mirrorType
5910 self.mesh.SetParameters(Mirror.parameters)
5911 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5912 MakeGroups, NewMeshName)
5913 return Mesh( self.smeshpyD,self.geompyD,mesh )
5915 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5917 Translate the elements
5920 IDsOfElements: list of elements ids
5921 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5922 Copy: allows copying the translated elements
5923 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5926 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5929 if IDsOfElements == []:
5930 IDsOfElements = self.GetElementsId()
5931 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5932 Vector = self.smeshpyD.GetDirStruct(Vector)
5933 if isinstance( Vector, list ):
5934 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5935 self.mesh.SetParameters(Vector.PS.parameters)
5936 if Copy and MakeGroups:
5937 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5938 self.editor.Translate(IDsOfElements, Vector, Copy)
5941 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5943 Create a new mesh of translated elements
5946 IDsOfElements: list of elements ids
5947 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5948 MakeGroups: forces the generation of new groups from existing ones
5949 NewMeshName: the name of the newly created mesh
5952 instance of class :class:`Mesh`
5955 if IDsOfElements == []:
5956 IDsOfElements = self.GetElementsId()
5957 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5958 Vector = self.smeshpyD.GetDirStruct(Vector)
5959 if isinstance( Vector, list ):
5960 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5961 self.mesh.SetParameters(Vector.PS.parameters)
5962 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5963 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5965 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5967 Translate the object
5970 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5971 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5972 Copy: allows copying the translated elements
5973 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5976 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5979 if ( isinstance( theObject, Mesh )):
5980 theObject = theObject.GetMesh()
5981 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5982 Vector = self.smeshpyD.GetDirStruct(Vector)
5983 if isinstance( Vector, list ):
5984 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5985 self.mesh.SetParameters(Vector.PS.parameters)
5986 if Copy and MakeGroups:
5987 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5988 self.editor.TranslateObject(theObject, Vector, Copy)
5991 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5993 Create a new mesh from the translated object
5996 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5997 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5998 MakeGroups: forces the generation of new groups from existing ones
5999 NewMeshName: the name of the newly created mesh
6002 instance of class :class:`Mesh`
6005 if isinstance( theObject, Mesh ):
6006 theObject = theObject.GetMesh()
6007 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6008 Vector = self.smeshpyD.GetDirStruct(Vector)
6009 if isinstance( Vector, list ):
6010 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6011 self.mesh.SetParameters(Vector.PS.parameters)
6012 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6013 return Mesh( self.smeshpyD, self.geompyD, mesh )
6017 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6022 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6023 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6024 theScaleFact: list of 1-3 scale factors for axises
6025 Copy: allows copying the translated elements
6026 MakeGroups: forces the generation of new groups from existing
6030 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6031 empty list otherwise
6033 unRegister = genObjUnRegister()
6034 if ( isinstance( theObject, Mesh )):
6035 theObject = theObject.GetMesh()
6036 if ( isinstance( theObject, list )):
6037 theObject = self.GetIDSource(theObject, SMESH.ALL)
6038 unRegister.set( theObject )
6039 if ( isinstance( thePoint, list )):
6040 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6041 if ( isinstance( theScaleFact, float )):
6042 theScaleFact = [theScaleFact]
6043 if ( isinstance( theScaleFact, int )):
6044 theScaleFact = [ float(theScaleFact)]
6046 self.mesh.SetParameters(thePoint.parameters)
6048 if Copy and MakeGroups:
6049 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6050 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6053 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6055 Create a new mesh from the translated object
6058 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6059 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6060 theScaleFact: list of 1-3 scale factors for axises
6061 MakeGroups: forces the generation of new groups from existing ones
6062 NewMeshName: the name of the newly created mesh
6065 instance of class :class:`Mesh`
6067 unRegister = genObjUnRegister()
6068 if (isinstance(theObject, Mesh)):
6069 theObject = theObject.GetMesh()
6070 if ( isinstance( theObject, list )):
6071 theObject = self.GetIDSource(theObject,SMESH.ALL)
6072 unRegister.set( theObject )
6073 if ( isinstance( thePoint, list )):
6074 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6075 if ( isinstance( theScaleFact, float )):
6076 theScaleFact = [theScaleFact]
6077 if ( isinstance( theScaleFact, int )):
6078 theScaleFact = [ float(theScaleFact)]
6080 self.mesh.SetParameters(thePoint.parameters)
6081 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6082 MakeGroups, NewMeshName)
6083 return Mesh( self.smeshpyD, self.geompyD, mesh )
6087 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6092 IDsOfElements: list of elements ids
6093 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6094 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6095 Copy: allows copying the rotated elements
6096 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6099 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6103 if IDsOfElements == []:
6104 IDsOfElements = self.GetElementsId()
6105 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6106 Axis = self.smeshpyD.GetAxisStruct(Axis)
6107 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6108 Parameters = Axis.parameters + var_separator + Parameters
6109 self.mesh.SetParameters(Parameters)
6110 if Copy and MakeGroups:
6111 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6112 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6115 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6117 Create a new mesh of rotated elements
6120 IDsOfElements: list of element ids
6121 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6122 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6123 MakeGroups: forces the generation of new groups from existing ones
6124 NewMeshName: the name of the newly created mesh
6127 instance of class :class:`Mesh`
6130 if IDsOfElements == []:
6131 IDsOfElements = self.GetElementsId()
6132 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6133 Axis = self.smeshpyD.GetAxisStruct(Axis)
6134 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6135 Parameters = Axis.parameters + var_separator + Parameters
6136 self.mesh.SetParameters(Parameters)
6137 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6138 MakeGroups, NewMeshName)
6139 return Mesh( self.smeshpyD, self.geompyD, mesh )
6141 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6146 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6147 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6148 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6149 Copy: allows copying the rotated elements
6150 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6153 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6156 if (isinstance(theObject, Mesh)):
6157 theObject = theObject.GetMesh()
6158 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6159 Axis = self.smeshpyD.GetAxisStruct(Axis)
6160 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6161 Parameters = Axis.parameters + ":" + Parameters
6162 self.mesh.SetParameters(Parameters)
6163 if Copy and MakeGroups:
6164 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6165 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6168 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6170 Create a new mesh from the rotated object
6173 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6174 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6175 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6176 MakeGroups: forces the generation of new groups from existing ones
6177 NewMeshName: the name of the newly created mesh
6180 instance of class :class:`Mesh`
6183 if (isinstance( theObject, Mesh )):
6184 theObject = theObject.GetMesh()
6185 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6186 Axis = self.smeshpyD.GetAxisStruct(Axis)
6187 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6188 Parameters = Axis.parameters + ":" + Parameters
6189 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6190 MakeGroups, NewMeshName)
6191 self.mesh.SetParameters(Parameters)
6192 return Mesh( self.smeshpyD, self.geompyD, mesh )
6194 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6196 Create an offset mesh from the given 2D object
6199 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6200 theValue (float): signed offset size
6201 MakeGroups (boolean): forces the generation of new groups from existing ones
6202 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6203 False means to remove original elements.
6204 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6207 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6210 if isinstance( theObject, Mesh ):
6211 theObject = theObject.GetMesh()
6212 theValue,Parameters,hasVars = ParseParameters(Value)
6213 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6214 self.mesh.SetParameters(Parameters)
6215 # if mesh_groups[0]:
6216 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6219 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6221 Find groups of adjacent nodes within Tolerance.
6224 Tolerance (float): the value of tolerance
6225 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6226 corner and medium nodes in separate groups thus preventing
6227 their further merge.
6230 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6233 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6235 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6236 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6238 Find groups of adjacent nodes within Tolerance.
6241 Tolerance: the value of tolerance
6242 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` or node IDs
6243 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6244 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6245 corner and medium nodes in separate groups thus preventing
6246 their further merge.
6249 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6252 unRegister = genObjUnRegister()
6253 if (isinstance( SubMeshOrGroup, Mesh )):
6254 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6255 if isinstance( SubMeshOrGroup, list ):
6256 SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE )
6257 unRegister.set( SubMeshOrGroup )
6259 if not isinstance( exceptNodes, list ):
6260 exceptNodes = [ exceptNodes ]
6261 if exceptNodes and isinstance( exceptNodes[0], int ):
6262 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6263 unRegister.set( exceptNodes )
6265 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6266 exceptNodes, SeparateCornerAndMediumNodes)
6268 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6273 GroupsOfNodes: a list of groups of nodes IDs for merging.
6274 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6275 in all elements and groups by nodes 1 and 25 correspondingly
6276 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6277 If *NodesToKeep* does not include a node to keep for some group to merge,
6278 then the first node in the group is kept.
6279 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6282 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6283 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6285 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6287 Find the elements built on the same nodes.
6290 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6293 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6296 if not MeshOrSubMeshOrGroup:
6297 MeshOrSubMeshOrGroup=self.mesh
6298 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6299 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6300 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6302 def MergeElements(self, GroupsOfElementsID):
6304 Merge elements in each given group.
6307 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6308 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6309 replaced in all groups by elements 1 and 25)
6312 self.editor.MergeElements(GroupsOfElementsID)
6314 def MergeEqualElements(self):
6316 Leave one element and remove all other elements built on the same nodes.
6319 self.editor.MergeEqualElements()
6321 def FindFreeBorders(self, ClosedOnly=True):
6323 Returns all or only closed free borders
6326 list of SMESH.FreeBorder's
6329 return self.editor.FindFreeBorders( ClosedOnly )
6331 def FillHole(self, holeNodes, groupName=""):
6333 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6336 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6337 must describe all sequential nodes of the hole border. The first and the last
6338 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6339 groupName (string): name of a group to add new faces
6341 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6345 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6346 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6347 if not isinstance( holeNodes, SMESH.FreeBorder ):
6348 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6349 self.editor.FillHole( holeNodes, groupName )
6351 def FindCoincidentFreeBorders (self, tolerance=0.):
6353 Return groups of FreeBorder's coincident within the given tolerance.
6356 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6357 size of elements adjacent to free borders being compared is used.
6360 SMESH.CoincidentFreeBorders structure
6363 return self.editor.FindCoincidentFreeBorders( tolerance )
6365 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6367 Sew FreeBorder's of each group
6370 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6371 where each enclosed list contains node IDs of a group of coincident free
6372 borders such that each consequent triple of IDs within a group describes
6373 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6374 last node of a border.
6375 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6376 groups of coincident free borders, each group including two borders.
6377 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6378 polygons if a node of opposite border falls on a face edge, else such
6379 faces are split into several ones.
6380 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6381 polyhedra if a node of opposite border falls on a volume edge, else such
6382 volumes, if any, remain intact and the mesh becomes non-conformal.
6385 a number of successfully sewed groups
6388 if freeBorders and isinstance( freeBorders, list ):
6389 # construct SMESH.CoincidentFreeBorders
6390 if isinstance( freeBorders[0], int ):
6391 freeBorders = [freeBorders]
6393 coincidentGroups = []
6394 for nodeList in freeBorders:
6395 if not nodeList or len( nodeList ) % 3:
6396 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6399 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6400 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6401 nodeList = nodeList[3:]
6403 coincidentGroups.append( group )
6405 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6407 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6409 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6410 FirstNodeID2, SecondNodeID2, LastNodeID2,
6411 CreatePolygons, CreatePolyedrs):
6416 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6419 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6420 FirstNodeID2, SecondNodeID2, LastNodeID2,
6421 CreatePolygons, CreatePolyedrs)
6423 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6424 FirstNodeID2, SecondNodeID2):
6426 Sew conform free borders
6429 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6432 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6433 FirstNodeID2, SecondNodeID2)
6435 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6436 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6441 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6444 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6445 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6447 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6448 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6449 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6451 Sew two sides of a mesh. The nodes belonging to Side1 are
6452 merged with the nodes of elements of Side2.
6453 The number of elements in theSide1 and in theSide2 must be
6454 equal and they should have similar nodal connectivity.
6455 The nodes to merge should belong to side borders and
6456 the first node should be linked to the second.
6459 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6462 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6463 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6464 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6466 def ChangeElemNodes(self, ide, newIDs):
6468 Set new nodes for the given element.
6475 False if the number of nodes does not correspond to the type of element
6478 return self.editor.ChangeElemNodes(ide, newIDs)
6480 def GetLastCreatedNodes(self):
6482 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6483 created, this method return the list of their IDs.
6484 If new nodes were not created - return empty list
6487 the list of integer values (can be empty)
6490 return self.editor.GetLastCreatedNodes()
6492 def GetLastCreatedElems(self):
6494 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6495 created this method return the list of their IDs.
6496 If new elements were not created - return empty list
6499 the list of integer values (can be empty)
6502 return self.editor.GetLastCreatedElems()
6504 def ClearLastCreated(self):
6506 Forget what nodes and elements were created by the last mesh edition operation
6509 self.editor.ClearLastCreated()
6511 def DoubleElements(self, theElements, theGroupName=""):
6513 Create duplicates of given elements, i.e. create new elements based on the
6514 same nodes as the given ones.
6517 theElements: container of elements to duplicate. It can be a
6518 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6519 or a list of element IDs. If *theElements* is
6520 a :class:`Mesh`, elements of highest dimension are duplicated
6521 theGroupName: a name of group to contain the generated elements.
6522 If a group with such a name already exists, the new elements
6523 are added to the existing group, else a new group is created.
6524 If *theGroupName* is empty, new elements are not added
6528 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6529 None if *theGroupName* == "".
6532 unRegister = genObjUnRegister()
6533 if isinstance( theElements, Mesh ):
6534 theElements = theElements.mesh
6535 elif isinstance( theElements, list ):
6536 theElements = self.GetIDSource( theElements, SMESH.ALL )
6537 unRegister.set( theElements )
6538 return self.editor.DoubleElements(theElements, theGroupName)
6540 def DoubleNodes(self, theNodes, theModifiedElems):
6542 Create a hole in a mesh by doubling the nodes of some particular elements
6545 theNodes: IDs of nodes to be doubled
6546 theModifiedElems: IDs of elements to be updated by the new (doubled)
6547 nodes. If list of element identifiers is empty then nodes are doubled but
6548 they not assigned to elements
6551 True if operation has been completed successfully, False otherwise
6554 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6556 def DoubleNode(self, theNodeId, theModifiedElems):
6558 Create a hole in a mesh by doubling the nodes of some particular elements.
6559 This method provided for convenience works as :meth:`DoubleNodes`.
6562 theNodeId: IDs of node to double
6563 theModifiedElems: IDs of elements to update
6566 True if operation has been completed successfully, False otherwise
6569 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6571 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6573 Create a hole in a mesh by doubling the nodes of some particular elements.
6574 This method provided for convenience works as :meth:`DoubleNodes`.
6577 theNodes: group of nodes to double.
6578 theModifiedElems: group of elements to update.
6579 theMakeGroup: forces the generation of a group containing new nodes.
6582 True or a created group if operation has been completed successfully,
6583 False or None otherwise
6587 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6588 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6590 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6592 Create a hole in a mesh by doubling the nodes of some particular elements.
6593 This method provided for convenience works as :meth:`DoubleNodes`.
6596 theNodes: list of groups of nodes to double.
6597 theModifiedElems: list of groups of elements to update.
6598 theMakeGroup: forces the generation of a group containing new nodes.
6601 True if operation has been completed successfully, False otherwise
6605 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6606 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6608 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6610 Create a hole in a mesh by doubling the nodes of some particular elements
6613 theElems: the list of elements (edges or faces) to replicate.
6614 The nodes for duplication could be found from these elements
6615 theNodesNot: list of nodes NOT to replicate
6616 theAffectedElems: the list of elements (cells and edges) to which the
6617 replicated nodes should be associated to
6620 True if operation has been completed successfully, False otherwise
6623 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6625 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6627 Create a hole in a mesh by doubling the nodes of some particular elements
6630 theElems: the list of elements (edges or faces) to replicate.
6631 The nodes for duplication could be found from these elements
6632 theNodesNot: list of nodes NOT to replicate
6633 theShape: shape to detect affected elements (element which geometric center
6634 located on or inside shape).
6635 The replicated nodes should be associated to affected elements.
6638 True if operation has been completed successfully, False otherwise
6641 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6643 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6644 theMakeGroup=False, theMakeNodeGroup=False):
6646 Create a hole in a mesh by doubling the nodes of some particular elements.
6647 This method provided for convenience works as :meth:`DoubleNodes`.
6650 theElems: group of of elements (edges or faces) to replicate.
6651 theNodesNot: group of nodes NOT to replicate.
6652 theAffectedElems: group of elements to which the replicated nodes
6653 should be associated to.
6654 theMakeGroup: forces the generation of a group containing new elements.
6655 theMakeNodeGroup: forces the generation of a group containing new nodes.
6658 True or created groups (one or two) if operation has been completed successfully,
6659 False or None otherwise
6662 if theMakeGroup or theMakeNodeGroup:
6663 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6665 theMakeGroup, theMakeNodeGroup)
6666 if theMakeGroup and theMakeNodeGroup:
6669 return twoGroups[ int(theMakeNodeGroup) ]
6670 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6672 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6674 Create a hole in a mesh by doubling the nodes of some particular elements.
6675 This method provided for convenience works as :meth:`DoubleNodes`.
6678 theElems: group of of elements (edges or faces) to replicate
6679 theNodesNot: group of nodes not to replicate
6680 theShape: shape to detect affected elements (element which geometric center
6681 located on or inside shape).
6682 The replicated nodes should be associated to affected elements
6685 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6687 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6688 theMakeGroup=False, theMakeNodeGroup=False):
6690 Create a hole in a mesh by doubling the nodes of some particular elements.
6691 This method provided for convenience works as :meth:`DoubleNodes`.
6694 theElems: list of groups of elements (edges or faces) to replicate
6695 theNodesNot: list of groups of nodes NOT to replicate
6696 theAffectedElems: group of elements to which the replicated nodes
6697 should be associated to
6698 theMakeGroup: forces generation of a group containing new elements.
6699 theMakeNodeGroup: forces generation of a group containing new nodes
6702 True or created groups (one or two) if operation has been completed successfully,
6703 False or None otherwise
6706 if theMakeGroup or theMakeNodeGroup:
6707 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6709 theMakeGroup, theMakeNodeGroup)
6710 if theMakeGroup and theMakeNodeGroup:
6713 return twoGroups[ int(theMakeNodeGroup) ]
6714 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6716 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6718 Create a hole in a mesh by doubling the nodes of some particular elements.
6719 This method provided for convenience works as :meth:`DoubleNodes`.
6722 theElems: list of groups of elements (edges or faces) to replicate
6723 theNodesNot: list of groups of nodes NOT to replicate
6724 theShape: shape to detect affected elements (element which geometric center
6725 located on or inside shape).
6726 The replicated nodes should be associated to affected elements
6729 True if operation has been completed successfully, False otherwise
6732 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6734 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6736 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6737 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6740 theElems: list of groups of nodes or elements (edges or faces) to replicate
6741 theNodesNot: list of groups of nodes NOT to replicate
6742 theShape: shape to detect affected elements (element which geometric center
6743 located on or inside shape).
6744 The replicated nodes should be associated to affected elements
6747 groups of affected elements in order: volumes, faces, edges
6750 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6752 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6755 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6756 The list of groups must describe a partition of the mesh volumes.
6757 The nodes of the internal faces at the boundaries of the groups are doubled.
6758 In option, the internal faces are replaced by flat elements.
6759 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6762 theDomains: list of groups of volumes
6763 createJointElems: if True, create the elements
6764 onAllBoundaries: if True, the nodes and elements are also created on
6765 the boundary between *theDomains* and the rest mesh
6768 True if operation has been completed successfully, False otherwise
6771 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6773 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6775 Double nodes on some external faces and create flat elements.
6776 Flat elements are mainly used by some types of mechanic calculations.
6778 Each group of the list must be constituted of faces.
6779 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6782 theGroupsOfFaces: list of groups of faces
6785 True if operation has been completed successfully, False otherwise
6788 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6790 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6792 Identify all the elements around a geom shape, get the faces delimiting the hole
6794 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6796 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6798 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6799 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6800 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6801 If there are several paths connecting a pair of points, the shortest path is
6802 selected by the module. Position of the cutting plane is defined by the two
6803 points and an optional vector lying on the plane specified by a PolySegment.
6804 By default the vector is defined by Mesh module as following. A middle point
6805 of the two given points is computed. The middle point is projected to the mesh.
6806 The vector goes from the middle point to the projection point. In case of planar
6807 mesh, the vector is normal to the mesh.
6809 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6812 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6813 groupName: optional name of a group where created mesh segments will be added.
6816 editor = self.editor
6818 editor = self.mesh.GetMeshEditPreviewer()
6819 segmentsRes = editor.MakePolyLine( segments, groupName )
6820 for i, seg in enumerate( segmentsRes ):
6821 segments[i].vector = seg.vector
6823 return editor.GetPreviewData()
6826 def MakeSlot(self, segmentGroup, width ):
6828 Create a slot of given width around given 1D elements lying on a triangle mesh.
6829 The slot is consrtucted by cutting faces by cylindrical surfaces made
6830 around each segment. Segments are expected to be created by MakePolyLine().
6833 FaceEdge's located at the slot boundary
6835 return self.editor.MakeSlot( segmentGroup, width )
6837 def GetFunctor(self, funcType ):
6839 Return a cached numerical functor by its type.
6842 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6843 Note that not all items correspond to numerical functors.
6846 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6849 fn = self.functors[ funcType._v ]
6851 fn = self.smeshpyD.GetFunctor(funcType)
6852 fn.SetMesh(self.mesh)
6853 self.functors[ funcType._v ] = fn
6856 def FunctorValue(self, funcType, elemId, isElem=True):
6858 Return value of a functor for a given element
6861 funcType: an item of :class:`SMESH.FunctorType` enum.
6862 elemId: element or node ID
6863 isElem: *elemId* is ID of element or node
6866 the functor value or zero in case of invalid arguments
6869 fn = self.GetFunctor( funcType )
6870 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6871 val = fn.GetValue(elemId)
6876 def GetLength(self, elemId=None):
6878 Get length of 1D element or sum of lengths of all 1D mesh elements
6881 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6884 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6889 length = self.smeshpyD.GetLength(self)
6891 length = self.FunctorValue(SMESH.FT_Length, elemId)
6894 def GetArea(self, elemId=None):
6896 Get area of 2D element or sum of areas of all 2D mesh elements
6897 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6900 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6905 area = self.smeshpyD.GetArea(self)
6907 area = self.FunctorValue(SMESH.FT_Area, elemId)
6910 def GetVolume(self, elemId=None):
6912 Get volume of 3D element or sum of volumes of all 3D mesh elements
6915 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6918 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6923 volume = self.smeshpyD.GetVolume(self)
6925 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6928 def GetAngle(self, node1, node2, node3 ):
6930 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
6933 node1,node2,node3: IDs of the three nodes
6936 Angle in radians [0,PI]. -1 if failure case.
6938 p1 = self.GetNodeXYZ( node1 )
6939 p2 = self.GetNodeXYZ( node2 )
6940 p3 = self.GetNodeXYZ( node3 )
6941 if p1 and p2 and p3:
6942 return self.smeshpyD.GetAngle( p1,p2,p3 )
6946 def GetMaxElementLength(self, elemId):
6948 Get maximum element length.
6951 elemId: mesh element ID
6954 element's maximum length value
6957 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6958 ftype = SMESH.FT_MaxElementLength3D
6960 ftype = SMESH.FT_MaxElementLength2D
6961 return self.FunctorValue(ftype, elemId)
6963 def GetAspectRatio(self, elemId):
6965 Get aspect ratio of 2D or 3D element.
6968 elemId: mesh element ID
6971 element's aspect ratio value
6974 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6975 ftype = SMESH.FT_AspectRatio3D
6977 ftype = SMESH.FT_AspectRatio
6978 return self.FunctorValue(ftype, elemId)
6980 def GetWarping(self, elemId):
6982 Get warping angle of 2D element.
6985 elemId: mesh element ID
6988 element's warping angle value
6991 return self.FunctorValue(SMESH.FT_Warping, elemId)
6993 def GetMinimumAngle(self, elemId):
6995 Get minimum angle of 2D element.
6998 elemId: mesh element ID
7001 element's minimum angle value
7004 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7006 def GetTaper(self, elemId):
7008 Get taper of 2D element.
7011 elemId: mesh element ID
7014 element's taper value
7017 return self.FunctorValue(SMESH.FT_Taper, elemId)
7019 def GetSkew(self, elemId):
7021 Get skew of 2D element.
7024 elemId: mesh element ID
7027 element's skew value
7030 return self.FunctorValue(SMESH.FT_Skew, elemId)
7032 def GetMinMax(self, funType, meshPart=None):
7034 Return minimal and maximal value of a given functor.
7037 funType (SMESH.FunctorType): a functor type.
7038 Note that not all items of :class:`SMESH.FunctorType` corresponds
7039 to numerical functors.
7040 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7046 unRegister = genObjUnRegister()
7047 if isinstance( meshPart, list ):
7048 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7049 unRegister.set( meshPart )
7050 if isinstance( meshPart, Mesh ):
7051 meshPart = meshPart.mesh
7052 fun = self.GetFunctor( funType )
7055 if hasattr( meshPart, "SetMesh" ):
7056 meshPart.SetMesh( self.mesh ) # set mesh to filter
7057 hist = fun.GetLocalHistogram( 1, False, meshPart )
7059 hist = fun.GetHistogram( 1, False )
7061 return hist[0].min, hist[0].max
7064 pass # end of Mesh class
7067 class meshProxy(SMESH._objref_SMESH_Mesh):
7069 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7070 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7072 def __init__(self,*args):
7073 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7074 def __deepcopy__(self, memo=None):
7075 new = self.__class__(self)
7077 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7078 if len( args ) == 3:
7079 args += SMESH.ALL_NODES, True
7080 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7081 def ExportToMEDX(self, *args): # function removed
7082 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7083 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7084 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7085 def ExportToMED(self, *args): # function removed
7086 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7087 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7089 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7091 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7092 def ExportPartToMED(self, *args): # 'version' parameter removed
7093 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7094 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7095 def ExportMED(self, *args): # signature of method changed
7096 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7098 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7100 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7102 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7105 class submeshProxy(SMESH._objref_SMESH_subMesh):
7108 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7110 def __init__(self,*args):
7111 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7113 def __deepcopy__(self, memo=None):
7114 new = self.__class__(self)
7117 def Compute(self,refresh=False):
7119 Compute the sub-mesh and return the status of the computation
7122 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7127 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7128 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7132 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7134 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7136 if salome.sg.hasDesktop():
7137 if refresh: salome.sg.updateObjBrowser()
7142 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7145 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7147 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7148 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7151 def __init__(self,*args):
7152 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7154 def __getattr__(self, name ): # method called if an attribute not found
7155 if not self.mesh: # look for name() method in Mesh class
7156 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7157 if hasattr( self.mesh, name ):
7158 return getattr( self.mesh, name )
7159 if name == "ExtrusionAlongPathObjX":
7160 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7161 print("meshEditor: attribute '%s' NOT FOUND" % name)
7163 def __deepcopy__(self, memo=None):
7164 new = self.__class__(self)
7166 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7167 if len( args ) == 1: args += False,
7168 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7169 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7170 if len( args ) == 2: args += False,
7171 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7172 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7173 if len( args ) == 1:
7174 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7175 NodesToKeep = args[1]
7176 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7177 unRegister = genObjUnRegister()
7179 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7180 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7181 if not isinstance( NodesToKeep, list ):
7182 NodesToKeep = [ NodesToKeep ]
7183 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7185 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7187 class Pattern(SMESH._objref_SMESH_Pattern):
7189 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7190 variables in some methods
7193 def LoadFromFile(self, patternTextOrFile ):
7194 text = patternTextOrFile
7195 if os.path.exists( text ):
7196 text = open( patternTextOrFile ).read()
7198 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7200 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7201 decrFun = lambda i: i-1
7202 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7203 theMesh.SetParameters(Parameters)
7204 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7206 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7207 decrFun = lambda i: i-1
7208 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7209 theMesh.SetParameters(Parameters)
7210 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7212 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7213 if isinstance( mesh, Mesh ):
7214 mesh = mesh.GetMesh()
7215 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7217 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7219 Registering the new proxy for Pattern
7224 Private class used to bind methods creating algorithms to the class Mesh
7227 def __init__(self, method):
7229 self.defaultAlgoType = ""
7230 self.algoTypeToClass = {}
7231 self.method = method
7233 def add(self, algoClass):
7235 Store a python class of algorithm
7237 if inspect.isclass(algoClass) and \
7238 hasattr( algoClass, "algoType"):
7239 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7240 if not self.defaultAlgoType and \
7241 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7242 self.defaultAlgoType = algoClass.algoType
7243 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7245 def copy(self, mesh):
7247 Create a copy of self and assign mesh to the copy
7250 other = algoCreator( self.method )
7251 other.defaultAlgoType = self.defaultAlgoType
7252 other.algoTypeToClass = self.algoTypeToClass
7256 def __call__(self,algo="",geom=0,*args):
7258 Create an instance of algorithm
7262 if isinstance( algo, str ):
7264 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7265 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7270 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7272 elif not algoType and isinstance( geom, str ):
7277 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7279 elif isinstance( arg, str ) and not algoType:
7282 import traceback, sys
7283 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7284 sys.stderr.write( msg + '\n' )
7285 tb = traceback.extract_stack(None,2)
7286 traceback.print_list( [tb[0]] )
7288 algoType = self.defaultAlgoType
7289 if not algoType and self.algoTypeToClass:
7290 algoType = sorted( self.algoTypeToClass.keys() )[0]
7291 if algoType in self.algoTypeToClass:
7292 #print("Create algo",algoType)
7293 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7294 raise RuntimeError( "No class found for algo type %s" % algoType)
7297 class hypMethodWrapper:
7299 Private class used to substitute and store variable parameters of hypotheses.
7302 def __init__(self, hyp, method):
7304 self.method = method
7305 #print("REBIND:", method.__name__)
7308 def __call__(self,*args):
7310 call a method of hypothesis with calling SetVarParameter() before
7314 return self.method( self.hyp, *args ) # hypothesis method with no args
7316 #print("MethWrapper.__call__", self.method.__name__, args)
7318 parsed = ParseParameters(*args) # replace variables with their values
7319 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7320 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7321 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7322 # maybe there is a replaced string arg which is not variable
7323 result = self.method( self.hyp, *args )
7324 except ValueError as detail: # raised by ParseParameters()
7326 result = self.method( self.hyp, *args )
7327 except omniORB.CORBA.BAD_PARAM:
7328 raise ValueError(detail) # wrong variable name
7333 class genObjUnRegister:
7335 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7338 def __init__(self, genObj=None):
7339 self.genObjList = []
7343 def set(self, genObj):
7344 "Store one or a list of of SALOME.GenericObj'es"
7345 if isinstance( genObj, list ):
7346 self.genObjList.extend( genObj )
7348 self.genObjList.append( genObj )
7352 for genObj in self.genObjList:
7353 if genObj and hasattr( genObj, "UnRegister" ):
7356 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7358 Bind methods creating mesher plug-ins to the Mesh class
7361 # print("pluginName: ", pluginName)
7362 pluginBuilderName = pluginName + "Builder"
7364 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7365 except Exception as e:
7366 from salome_utils import verbose
7367 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7369 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7370 plugin = eval( pluginBuilderName )
7371 # print(" plugin:" , str(plugin))
7373 # add methods creating algorithms to Mesh
7374 for k in dir( plugin ):
7375 if k[0] == '_': continue
7376 algo = getattr( plugin, k )
7377 #print(" algo:", str(algo))
7378 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7379 #print(" meshMethod:" , str(algo.meshMethod))
7380 if not hasattr( Mesh, algo.meshMethod ):
7381 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7383 _mmethod = getattr( Mesh, algo.meshMethod )
7384 if hasattr( _mmethod, "add" ):