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,
738 Concatenate the given meshes into one mesh. All groups of input meshes will be
739 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
750 an instance of class :class:`Mesh`
753 if not meshes: return None
754 for i,m in enumerate(meshes):
755 if isinstance(m, Mesh):
756 meshes[i] = m.GetMesh()
757 mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
758 meshes[0].SetParameters(Parameters)
760 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
761 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
763 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
764 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
765 aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
768 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
770 Create a mesh by copying a part of another mesh.
773 meshPart: a part of mesh to copy, either
774 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
775 To copy nodes or elements not forming any mesh object,
776 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
777 meshName: a name of the new mesh
778 toCopyGroups: to create in the new mesh groups the copied elements belongs to
779 toKeepIDs: to preserve order of the copied elements or not
782 an instance of class :class:`Mesh`
785 if isinstance( meshPart, Mesh ):
786 meshPart = meshPart.GetMesh()
787 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
788 return Mesh(self, self.geompyD, mesh)
790 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
791 toReuseHypotheses=True, toCopyElements=True):
793 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
794 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
795 To facilitate and speed up the operation, consider using
796 "Set presentation parameters and sub-shapes from arguments" option in
797 a dialog of geometrical operation used to create the new geometry.
800 sourceMesh: the mesh to copy definition of.
801 newGeom: the new geomtry.
802 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
803 toCopyGroups: to create groups in the new mesh.
804 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
805 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
808 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
809 *invalidEntries* are study entries of objects whose
810 counterparts are not found in the *newGeom*, followed by entries
811 of mesh sub-objects that are invalid because they depend on a not found
814 if isinstance( sourceMesh, Mesh ):
815 sourceMesh = sourceMesh.GetMesh()
817 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
818 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
822 return ( ok, Mesh(self, self.geompyD, newMesh),
823 newGroups, newSubMeshes, newHypotheses, invalidEntries )
825 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
827 Return IDs of sub-shapes
830 theMainObject (GEOM.GEOM_Object): a shape
831 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
833 the list of integer values
836 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
838 def GetPattern(self):
840 Create a pattern mapper.
843 an instance of :class:`SMESH.SMESH_Pattern`
845 :ref:`Example of Patterns usage <tui_pattern_mapping>`
848 return SMESH._objref_SMESH_Gen.GetPattern(self)
850 def SetBoundaryBoxSegmentation(self, nbSegments):
852 Set number of segments per diagonal of boundary box of geometry, by which
853 default segment length of appropriate 1D hypotheses is defined in GUI.
857 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
859 # Filtering. Auxiliary functions:
860 # ------------------------------
862 def GetEmptyCriterion(self):
864 Create an empty criterion
867 :class:`SMESH.Filter.Criterion`
870 Type = self.EnumToLong(FT_Undefined)
871 Compare = self.EnumToLong(FT_Undefined)
875 UnaryOp = self.EnumToLong(FT_Undefined)
876 BinaryOp = self.EnumToLong(FT_Undefined)
879 Precision = -1 ##@1e-07
880 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
881 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
883 def GetCriterion(self,elementType,
885 Compare = FT_EqualTo,
887 UnaryOp=FT_Undefined,
888 BinaryOp=FT_Undefined,
891 Create a criterion by the given parameters
892 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
895 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
896 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
897 Note that the items starting from FT_LessThan are not suitable for *CritType*.
898 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
899 Threshold: the threshold value (range of ids as string, shape, numeric)
900 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
901 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
903 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
904 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
907 :class:`SMESH.Filter.Criterion`
909 Example: :ref:`combining_filters`
912 if not CritType in SMESH.FunctorType._items:
913 raise TypeError("CritType should be of SMESH.FunctorType")
914 aCriterion = self.GetEmptyCriterion()
915 aCriterion.TypeOfElement = elementType
916 aCriterion.Type = self.EnumToLong(CritType)
917 aCriterion.Tolerance = Tolerance
919 aThreshold = Threshold
921 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
922 aCriterion.Compare = self.EnumToLong(Compare)
923 elif Compare == "=" or Compare == "==":
924 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
926 aCriterion.Compare = self.EnumToLong(FT_LessThan)
928 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
929 elif Compare != FT_Undefined:
930 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
933 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
934 FT_BelongToCylinder, FT_LyingOnGeom]:
935 # Check that Threshold is GEOM object
936 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
937 aCriterion.ThresholdStr = GetName(aThreshold)
938 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
939 if not aCriterion.ThresholdID:
940 name = aCriterion.ThresholdStr
942 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
943 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
944 # or a name of GEOM object
945 elif isinstance( aThreshold, str ):
946 aCriterion.ThresholdStr = aThreshold
948 raise TypeError("The Threshold should be a shape.")
949 if isinstance(UnaryOp,float):
950 aCriterion.Tolerance = UnaryOp
951 UnaryOp = FT_Undefined
953 elif CritType == FT_BelongToMeshGroup:
954 # Check that Threshold is a group
955 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
956 if aThreshold.GetType() != elementType:
957 raise ValueError("Group type mismatches Element type")
958 aCriterion.ThresholdStr = aThreshold.GetName()
959 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
960 study = salome.myStudy
962 so = study.FindObjectIOR( aCriterion.ThresholdID )
966 aCriterion.ThresholdID = entry
968 raise TypeError("The Threshold should be a Mesh Group")
969 elif CritType == FT_RangeOfIds:
970 # Check that Threshold is string
971 if isinstance(aThreshold, str):
972 aCriterion.ThresholdStr = aThreshold
974 raise TypeError("The Threshold should be a string.")
975 elif CritType == FT_CoplanarFaces:
976 # Check the Threshold
977 if isinstance(aThreshold, int):
978 aCriterion.ThresholdID = str(aThreshold)
979 elif isinstance(aThreshold, str):
982 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
983 aCriterion.ThresholdID = aThreshold
985 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
986 elif CritType == FT_ConnectedElements:
987 # Check the Threshold
988 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
989 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
990 if not aCriterion.ThresholdID:
991 name = aThreshold.GetName()
993 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
994 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
995 elif isinstance(aThreshold, int): # node id
996 aCriterion.Threshold = aThreshold
997 elif isinstance(aThreshold, list): # 3 point coordinates
998 if len( aThreshold ) < 3:
999 raise ValueError("too few point coordinates, must be 3")
1000 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1001 elif isinstance(aThreshold, str):
1002 if aThreshold.isdigit():
1003 aCriterion.Threshold = aThreshold # node id
1005 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1007 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1008 "or a list of point coordinates and not '%s'"%aThreshold)
1009 elif CritType == FT_ElemGeomType:
1010 # Check the Threshold
1012 aCriterion.Threshold = self.EnumToLong(aThreshold)
1013 assert( aThreshold in SMESH.GeometryType._items )
1015 if isinstance(aThreshold, int):
1016 aCriterion.Threshold = aThreshold
1018 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1021 elif CritType == FT_EntityType:
1022 # Check the Threshold
1024 aCriterion.Threshold = self.EnumToLong(aThreshold)
1025 assert( aThreshold in SMESH.EntityType._items )
1027 if isinstance(aThreshold, int):
1028 aCriterion.Threshold = aThreshold
1030 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1034 elif CritType == FT_GroupColor:
1035 # Check the Threshold
1037 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1039 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1041 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1042 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1043 FT_BareBorderFace, FT_BareBorderVolume,
1044 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1045 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1046 # At this point the Threshold is unnecessary
1047 if aThreshold == FT_LogicalNOT:
1048 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1049 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1050 aCriterion.BinaryOp = aThreshold
1054 aThreshold = float(aThreshold)
1055 aCriterion.Threshold = aThreshold
1057 raise TypeError("The Threshold should be a number.")
1060 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1061 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1063 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1064 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1066 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1067 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1069 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1070 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1074 def GetFilter(self,elementType,
1075 CritType=FT_Undefined,
1078 UnaryOp=FT_Undefined,
1082 Create a filter with the given parameters
1085 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1086 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1087 Note that the items starting from FT_LessThan are not suitable for CritType.
1088 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1089 Threshold: the threshold value (range of ids as string, shape, numeric)
1090 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1091 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1092 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1093 mesh: the mesh to initialize the filter with
1096 :class:`SMESH.Filter`
1099 See :doc:`Filters usage examples <tui_filters>`
1102 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1103 aFilterMgr = self.CreateFilterManager()
1104 aFilter = aFilterMgr.CreateFilter()
1106 aCriteria.append(aCriterion)
1107 aFilter.SetCriteria(aCriteria)
1109 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1110 else : aFilter.SetMesh( mesh )
1111 aFilterMgr.UnRegister()
1114 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1116 Create a filter from criteria
1119 criteria: a list of :class:`SMESH.Filter.Criterion`
1120 binOp: binary operator used when binary operator of criteria is undefined
1123 :class:`SMESH.Filter`
1126 See :doc:`Filters usage examples <tui_filters>`
1129 for i in range( len( criteria ) - 1 ):
1130 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1131 criteria[i].BinaryOp = self.EnumToLong( binOp )
1132 aFilterMgr = self.CreateFilterManager()
1133 aFilter = aFilterMgr.CreateFilter()
1134 aFilter.SetCriteria(criteria)
1135 aFilterMgr.UnRegister()
1138 def GetFunctor(self,theCriterion):
1140 Create a numerical functor by its type
1143 theCriterion (SMESH.FunctorType): functor type.
1144 Note that not all items correspond to numerical functors.
1147 :class:`SMESH.NumericalFunctor`
1150 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1152 aFilterMgr = self.CreateFilterManager()
1154 if theCriterion == FT_AspectRatio:
1155 functor = aFilterMgr.CreateAspectRatio()
1156 elif theCriterion == FT_AspectRatio3D:
1157 functor = aFilterMgr.CreateAspectRatio3D()
1158 elif theCriterion == FT_Warping:
1159 functor = aFilterMgr.CreateWarping()
1160 elif theCriterion == FT_MinimumAngle:
1161 functor = aFilterMgr.CreateMinimumAngle()
1162 elif theCriterion == FT_Taper:
1163 functor = aFilterMgr.CreateTaper()
1164 elif theCriterion == FT_Skew:
1165 functor = aFilterMgr.CreateSkew()
1166 elif theCriterion == FT_Area:
1167 functor = aFilterMgr.CreateArea()
1168 elif theCriterion == FT_Volume3D:
1169 functor = aFilterMgr.CreateVolume3D()
1170 elif theCriterion == FT_MaxElementLength2D:
1171 functor = aFilterMgr.CreateMaxElementLength2D()
1172 elif theCriterion == FT_MaxElementLength3D:
1173 functor = aFilterMgr.CreateMaxElementLength3D()
1174 elif theCriterion == FT_MultiConnection:
1175 functor = aFilterMgr.CreateMultiConnection()
1176 elif theCriterion == FT_MultiConnection2D:
1177 functor = aFilterMgr.CreateMultiConnection2D()
1178 elif theCriterion == FT_Length:
1179 functor = aFilterMgr.CreateLength()
1180 elif theCriterion == FT_Length2D:
1181 functor = aFilterMgr.CreateLength2D()
1182 elif theCriterion == FT_Deflection2D:
1183 functor = aFilterMgr.CreateDeflection2D()
1184 elif theCriterion == FT_NodeConnectivityNumber:
1185 functor = aFilterMgr.CreateNodeConnectivityNumber()
1186 elif theCriterion == FT_BallDiameter:
1187 functor = aFilterMgr.CreateBallDiameter()
1189 print("Error: given parameter is not numerical functor type.")
1190 aFilterMgr.UnRegister()
1193 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1198 theHType (string): mesh hypothesis type
1199 theLibName (string): mesh plug-in library name
1202 created hypothesis instance
1204 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1206 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1209 # wrap hypothesis methods
1210 for meth_name in dir( hyp.__class__ ):
1211 if not meth_name.startswith("Get") and \
1212 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1213 method = getattr ( hyp.__class__, meth_name )
1214 if callable(method):
1215 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1219 def GetMeshInfo(self, obj):
1221 Get the mesh statistic.
1222 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1223 an item of :class:`SMESH.EntityType`.
1226 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1229 if isinstance( obj, Mesh ):
1232 if hasattr(obj, "GetMeshInfo"):
1233 values = obj.GetMeshInfo()
1234 for i in range(SMESH.Entity_Last._v):
1235 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1239 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1241 Get minimum distance between two objects
1243 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1244 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1247 src1 (SMESH.SMESH_IDSource): first source object
1248 src2 (SMESH.SMESH_IDSource): second source object
1249 id1 (int): node/element id from the first source
1250 id2 (int): node/element id from the second (or first) source
1251 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1252 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1255 minimum distance value
1258 :meth:`GetMinDistance`
1261 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1265 result = result.value
1268 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1270 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1272 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1273 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1276 src1 (SMESH.SMESH_IDSource): first source object
1277 src2 (SMESH.SMESH_IDSource): second source object
1278 id1 (int): node/element id from the first source
1279 id2 (int): node/element id from the second (or first) source
1280 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1281 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1284 :class:`SMESH.Measure` structure or None if input data is invalid
1289 if isinstance(src1, Mesh): src1 = src1.mesh
1290 if isinstance(src2, Mesh): src2 = src2.mesh
1291 if src2 is None and id2 != 0: src2 = src1
1292 if not hasattr(src1, "_narrow"): return None
1293 src1 = src1._narrow(SMESH.SMESH_IDSource)
1294 if not src1: return None
1295 unRegister = genObjUnRegister()
1298 e = m.GetMeshEditor()
1300 src1 = e.MakeIDSource([id1], SMESH.FACE)
1302 src1 = e.MakeIDSource([id1], SMESH.NODE)
1303 unRegister.set( src1 )
1305 if hasattr(src2, "_narrow"):
1306 src2 = src2._narrow(SMESH.SMESH_IDSource)
1307 if src2 and id2 != 0:
1309 e = m.GetMeshEditor()
1311 src2 = e.MakeIDSource([id2], SMESH.FACE)
1313 src2 = e.MakeIDSource([id2], SMESH.NODE)
1314 unRegister.set( src2 )
1317 aMeasurements = self.CreateMeasurements()
1318 unRegister.set( aMeasurements )
1319 result = aMeasurements.MinDistance(src1, src2)
1322 def BoundingBox(self, objects):
1324 Get bounding box of the specified object(s)
1327 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1330 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1333 :meth:`GetBoundingBox`
1336 result = self.GetBoundingBox(objects)
1340 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1343 def GetBoundingBox(self, objects):
1345 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1348 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1351 :class:`SMESH.Measure` structure
1357 if isinstance(objects, tuple):
1358 objects = list(objects)
1359 if not isinstance(objects, list):
1363 if isinstance(o, Mesh):
1364 srclist.append(o.mesh)
1365 elif hasattr(o, "_narrow"):
1366 src = o._narrow(SMESH.SMESH_IDSource)
1367 if src: srclist.append(src)
1370 aMeasurements = self.CreateMeasurements()
1371 result = aMeasurements.BoundingBox(srclist)
1372 aMeasurements.UnRegister()
1375 def GetLength(self, obj):
1377 Get sum of lengths of all 1D elements in the mesh object.
1380 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1383 sum of lengths of all 1D elements
1386 if isinstance(obj, Mesh): obj = obj.mesh
1387 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1388 aMeasurements = self.CreateMeasurements()
1389 value = aMeasurements.Length(obj)
1390 aMeasurements.UnRegister()
1393 def GetArea(self, obj):
1395 Get sum of areas of all 2D elements in the mesh object.
1398 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1401 sum of areas of all 2D elements
1404 if isinstance(obj, Mesh): obj = obj.mesh
1405 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1406 aMeasurements = self.CreateMeasurements()
1407 value = aMeasurements.Area(obj)
1408 aMeasurements.UnRegister()
1411 def GetVolume(self, obj):
1413 Get sum of volumes of all 3D elements in the mesh object.
1416 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1419 sum of volumes of all 3D elements
1422 if isinstance(obj, Mesh): obj = obj.mesh
1423 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1424 aMeasurements = self.CreateMeasurements()
1425 value = aMeasurements.Volume(obj)
1426 aMeasurements.UnRegister()
1429 def GetGravityCenter(self, obj):
1431 Get gravity center of all nodes of the mesh object.
1434 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1437 Three components of the gravity center (x,y,z)
1439 if isinstance(obj, Mesh): obj = obj.mesh
1440 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1441 aMeasurements = self.CreateMeasurements()
1442 pointStruct = aMeasurements.GravityCenter(obj)
1443 aMeasurements.UnRegister()
1444 return pointStruct.x, pointStruct.y, pointStruct.z
1446 pass # end of class smeshBuilder
1449 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1450 """Registering the new proxy for SMESH.SMESH_Gen"""
1453 def New( instance=None, instanceGeom=None):
1455 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1456 interface to create or load meshes.
1461 salome.salome_init()
1462 from salome.smesh import smeshBuilder
1463 smesh = smeshBuilder.New()
1466 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1467 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1469 :class:`smeshBuilder` instance
1474 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1476 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1481 smeshInst = smeshBuilder()
1482 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1483 smeshInst.init_smesh(instanceGeom)
1487 # Public class: Mesh
1488 # ==================
1491 class Mesh(metaclass = MeshMeta):
1493 This class allows defining and managing a mesh.
1494 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1495 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1496 new nodes and elements and by changing the existing entities), to get information
1497 about a mesh and to export a mesh in different formats.
1504 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1509 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1510 sets the GUI name of this mesh to *name*.
1513 smeshpyD: an instance of smeshBuilder class
1514 geompyD: an instance of geomBuilder class
1515 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1516 name: Study name of the mesh
1519 self.smeshpyD = smeshpyD
1520 self.geompyD = geompyD
1525 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1528 # publish geom of mesh (issue 0021122)
1529 if not self.geom.GetStudyEntry():
1533 geo_name = name + " shape"
1535 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1536 geompyD.addToStudy( self.geom, geo_name )
1537 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1539 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1542 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1544 self.smeshpyD.SetName(self.mesh, name)
1546 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1549 self.geom = self.mesh.GetShapeToMesh()
1551 self.editor = self.mesh.GetMeshEditor()
1552 self.functors = [None] * SMESH.FT_Undefined._v
1554 # set self to algoCreator's
1555 for attrName in dir(self):
1556 attr = getattr( self, attrName )
1557 if isinstance( attr, algoCreator ):
1558 setattr( self, attrName, attr.copy( self ))
1565 Destructor. Clean-up resources
1568 #self.mesh.UnRegister()
1572 def SetMesh(self, theMesh):
1574 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1577 theMesh: a :class:`SMESH.SMESH_Mesh` object
1581 # do not call Register() as this prevents mesh servant deletion at closing study
1582 #if self.mesh: self.mesh.UnRegister()
1585 #self.mesh.Register()
1586 self.geom = self.mesh.GetShapeToMesh()
1591 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1594 a :class:`SMESH.SMESH_Mesh` object
1601 Get the name of the mesh
1604 the name of the mesh as a string
1607 name = GetName(self.GetMesh())
1610 def SetName(self, name):
1612 Set a name to the mesh
1615 name: a new name of the mesh
1618 self.smeshpyD.SetName(self.GetMesh(), name)
1620 def GetSubMesh(self, geom, name):
1622 Get a sub-mesh object associated to a *geom* geometrical object.
1625 geom: a geometrical object (shape)
1626 name: a name for the sub-mesh in the Object Browser
1629 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1630 which lies on the given shape
1633 A sub-mesh is implicitly created when a sub-shape is specified at
1634 creating an algorithm, for example::
1636 algo1D = mesh.Segment(geom=Edge_1)
1638 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1639 The created sub-mesh can be retrieved from the algorithm::
1641 submesh = algo1D.GetSubMesh()
1644 AssureGeomPublished( self, geom, name )
1645 submesh = self.mesh.GetSubMesh( geom, name )
1650 Return the shape associated to the mesh
1658 def SetShape(self, geom):
1660 Associate the given shape to the mesh (entails the recreation of the mesh)
1663 geom: the shape to be meshed (GEOM_Object)
1666 self.mesh = self.smeshpyD.CreateMesh(geom)
1668 def HasShapeToMesh(self):
1670 Return ``True`` if this mesh is based on geometry
1672 return self.mesh.HasShapeToMesh()
1676 Load mesh from the study after opening the study
1680 def IsReadyToCompute(self, theSubObject):
1682 Return true if the hypotheses are defined well
1685 theSubObject: a sub-shape of a mesh shape
1691 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1693 def GetAlgoState(self, theSubObject):
1695 Return errors of hypotheses definition.
1696 The list of errors is empty if everything is OK.
1699 theSubObject: a sub-shape of a mesh shape
1705 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1707 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1709 Return a geometrical object on which the given element was built.
1710 The returned geometrical object, if not nil, is either found in the
1711 study or published by this method with the given name
1714 theElementID: the id of the mesh element
1715 theGeomName: the user-defined name of the geometrical object
1718 GEOM.GEOM_Object instance
1721 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1723 def MeshDimension(self):
1725 Return the mesh dimension depending on the dimension of the underlying shape
1726 or, if the mesh is not based on any shape, basing on deimension of elements
1729 mesh dimension as an integer value [0,3]
1732 if self.mesh.HasShapeToMesh():
1733 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1734 if len( shells ) > 0 :
1736 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1738 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1743 if self.NbVolumes() > 0: return 3
1744 if self.NbFaces() > 0: return 2
1745 if self.NbEdges() > 0: return 1
1748 def Evaluate(self, geom=0):
1750 Evaluate size of prospective mesh on a shape
1753 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1754 To know predicted number of e.g. edges, inquire it this way::
1756 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1759 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1761 geom = self.mesh.GetShapeToMesh()
1764 return self.smeshpyD.Evaluate(self.mesh, geom)
1767 def Compute(self, geom=0, discardModifs=False, refresh=False):
1769 Compute the mesh and return the status of the computation
1772 geom: geomtrical shape on which mesh data should be computed
1773 discardModifs: if True and the mesh has been edited since
1774 a last total re-compute and that may prevent successful partial re-compute,
1775 then the mesh is cleaned before Compute()
1776 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1782 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1784 geom = self.mesh.GetShapeToMesh()
1789 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1791 ok = self.smeshpyD.Compute(self.mesh, geom)
1792 except SALOME.SALOME_Exception as ex:
1793 print("Mesh computation failed, exception caught:")
1794 print(" ", ex.details.text)
1797 print("Mesh computation failed, exception caught:")
1798 traceback.print_exc()
1802 # Treat compute errors
1803 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1805 for err in computeErrors:
1806 if self.mesh.HasShapeToMesh():
1807 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1809 stdErrors = ["OK", #COMPERR_OK
1810 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1811 "std::exception", #COMPERR_STD_EXCEPTION
1812 "OCC exception", #COMPERR_OCC_EXCEPTION
1813 "..", #COMPERR_SLM_EXCEPTION
1814 "Unknown exception", #COMPERR_EXCEPTION
1815 "Memory allocation problem", #COMPERR_MEMORY_PB
1816 "Algorithm failed", #COMPERR_ALGO_FAILED
1817 "Unexpected geometry", #COMPERR_BAD_SHAPE
1818 "Warning", #COMPERR_WARNING
1819 "Computation cancelled",#COMPERR_CANCELED
1820 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1822 if err.code < len(stdErrors): errText = stdErrors[err.code]
1824 errText = "code %s" % -err.code
1825 if errText: errText += ". "
1826 errText += err.comment
1827 if allReasons: allReasons += "\n"
1829 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1831 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1835 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1837 if err.isGlobalAlgo:
1845 reason = '%s %sD algorithm is missing' % (glob, dim)
1846 elif err.state == HYP_MISSING:
1847 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1848 % (glob, dim, name, dim))
1849 elif err.state == HYP_NOTCONFORM:
1850 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1851 elif err.state == HYP_BAD_PARAMETER:
1852 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1853 % ( glob, dim, name ))
1854 elif err.state == HYP_BAD_GEOMETRY:
1855 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1856 'geometry' % ( glob, dim, name ))
1857 elif err.state == HYP_HIDDEN_ALGO:
1858 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1859 'algorithm of upper dimension generating %sD mesh'
1860 % ( glob, dim, name, glob, dim ))
1862 reason = ("For unknown reason. "
1863 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1865 if allReasons: allReasons += "\n"
1866 allReasons += "- " + reason
1868 if not ok or allReasons != "":
1869 msg = '"' + GetName(self.mesh) + '"'
1870 if ok: msg += " has been computed with warnings"
1871 else: msg += " has not been computed"
1872 if allReasons != "": msg += ":"
1877 if salome.sg.hasDesktop():
1878 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1879 if refresh: salome.sg.updateObjBrowser()
1883 def GetComputeErrors(self, shape=0 ):
1885 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1889 shape = self.mesh.GetShapeToMesh()
1890 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1892 def GetSubShapeName(self, subShapeID ):
1894 Return a name of a sub-shape by its ID.
1895 Possible variants (for *subShapeID* == 3):
1897 - **"Face_12"** - published sub-shape
1898 - **FACE #3** - not published sub-shape
1899 - **sub-shape #3** - invalid sub-shape ID
1900 - **#3** - error in this function
1903 subShapeID: a unique ID of a sub-shape
1906 a string describing the sub-shape
1910 if not self.mesh.HasShapeToMesh():
1914 mainIOR = salome.orb.object_to_string( self.GetShape() )
1916 mainSO = s.FindObjectIOR(mainIOR)
1919 shapeText = '"%s"' % mainSO.GetName()
1920 subIt = s.NewChildIterator(mainSO)
1922 subSO = subIt.Value()
1924 obj = subSO.GetObject()
1925 if not obj: continue
1926 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1929 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1932 if ids == subShapeID:
1933 shapeText = '"%s"' % subSO.GetName()
1936 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1938 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1940 shapeText = 'sub-shape #%s' % (subShapeID)
1942 shapeText = "#%s" % (subShapeID)
1945 def GetFailedShapes(self, publish=False):
1947 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1948 error of an algorithm
1951 publish: if *True*, the returned groups will be published in the study
1954 a list of GEOM groups each named after a failed algorithm
1959 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1960 for err in computeErrors:
1961 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1962 if not shape: continue
1963 if err.algoName in algo2shapes:
1964 algo2shapes[ err.algoName ].append( shape )
1966 algo2shapes[ err.algoName ] = [ shape ]
1970 for algoName, shapes in list(algo2shapes.items()):
1972 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1973 otherTypeShapes = []
1975 group = self.geompyD.CreateGroup( self.geom, groupType )
1976 for shape in shapes:
1977 if shape.GetShapeType() == shapes[0].GetShapeType():
1978 sameTypeShapes.append( shape )
1980 otherTypeShapes.append( shape )
1981 self.geompyD.UnionList( group, sameTypeShapes )
1983 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1985 group.SetName( algoName )
1986 groups.append( group )
1987 shapes = otherTypeShapes
1990 for group in groups:
1991 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1994 def GetMeshOrder(self):
1996 Return sub-mesh objects list in meshing order
1999 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2002 return self.mesh.GetMeshOrder()
2004 def SetMeshOrder(self, submeshes):
2006 Set order in which concurrent sub-meshes should be meshed
2009 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2012 return self.mesh.SetMeshOrder(submeshes)
2014 def Clear(self, refresh=False):
2016 Remove all nodes and elements generated on geometry. Imported elements remain.
2019 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2023 if ( salome.sg.hasDesktop() ):
2024 if refresh: salome.sg.updateObjBrowser()
2026 def ClearSubMesh(self, geomId, refresh=False):
2028 Remove all nodes and elements of indicated shape
2031 geomId: the ID of a sub-shape to remove elements on
2032 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2035 self.mesh.ClearSubMesh(geomId)
2036 if salome.sg.hasDesktop():
2037 if refresh: salome.sg.updateObjBrowser()
2039 def AutomaticTetrahedralization(self, fineness=0):
2041 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2044 fineness: [0.0,1.0] defines mesh fineness
2050 dim = self.MeshDimension()
2052 self.RemoveGlobalHypotheses()
2053 self.Segment().AutomaticLength(fineness)
2055 self.Triangle().LengthFromEdges()
2060 return self.Compute()
2062 def AutomaticHexahedralization(self, fineness=0):
2064 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2067 fineness: [0.0, 1.0] defines mesh fineness
2073 dim = self.MeshDimension()
2074 # assign the hypotheses
2075 self.RemoveGlobalHypotheses()
2076 self.Segment().AutomaticLength(fineness)
2083 return self.Compute()
2085 def AddHypothesis(self, hyp, geom=0):
2090 hyp: a hypothesis to assign
2091 geom: a subhape of mesh geometry
2094 :class:`SMESH.Hypothesis_Status`
2097 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2098 hyp, geom = geom, hyp
2099 if isinstance( hyp, Mesh_Algorithm ):
2100 hyp = hyp.GetAlgorithm()
2105 geom = self.mesh.GetShapeToMesh()
2108 if self.mesh.HasShapeToMesh():
2109 hyp_type = hyp.GetName()
2110 lib_name = hyp.GetLibName()
2111 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2112 # if checkAll and geom:
2113 # checkAll = geom.GetType() == 37
2115 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2117 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2118 status = self.mesh.AddHypothesis(geom, hyp)
2120 status = HYP_BAD_GEOMETRY, ""
2121 hyp_name = GetName( hyp )
2124 geom_name = geom.GetName()
2125 isAlgo = hyp._narrow( SMESH_Algo )
2126 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2129 def IsUsedHypothesis(self, hyp, geom):
2131 Return True if an algorithm or hypothesis is assigned to a given shape
2134 hyp: an algorithm or hypothesis to check
2135 geom: a subhape of mesh geometry
2141 if not hyp: # or not geom
2143 if isinstance( hyp, Mesh_Algorithm ):
2144 hyp = hyp.GetAlgorithm()
2146 hyps = self.GetHypothesisList(geom)
2148 if h.GetId() == hyp.GetId():
2152 def RemoveHypothesis(self, hyp, geom=0):
2154 Unassign a hypothesis
2157 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2158 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2161 :class:`SMESH.Hypothesis_Status`
2166 if isinstance( hyp, Mesh_Algorithm ):
2167 hyp = hyp.GetAlgorithm()
2173 if self.IsUsedHypothesis( hyp, shape ):
2174 return self.mesh.RemoveHypothesis( shape, hyp )
2175 hypName = GetName( hyp )
2176 geoName = GetName( shape )
2177 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2180 def GetHypothesisList(self, geom):
2182 Get the list of hypotheses added on a geometry
2185 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2188 the sequence of :class:`SMESH.SMESH_Hypothesis`
2191 return self.mesh.GetHypothesisList( geom )
2193 def RemoveGlobalHypotheses(self):
2195 Remove all global hypotheses
2198 current_hyps = self.mesh.GetHypothesisList( self.geom )
2199 for hyp in current_hyps:
2200 self.mesh.RemoveHypothesis( self.geom, hyp )
2203 def ExportMED(self, *args, **kwargs):
2205 Export the mesh in a file in MED format
2206 allowing to overwrite the file if it exists or add the exported data to its contents
2209 fileName: is the file name
2210 auto_groups (boolean): parameter for creating/not creating
2211 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2212 the typical use is auto_groups=False.
2213 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2214 The minor must be between 0 and the current minor version of MED file library.
2215 If minor is equal to -1, the minor version is not changed (default).
2216 The major version (x, where version is x.y.z) cannot be changed.
2217 overwrite (boolean): parameter for overwriting/not overwriting the file
2218 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2219 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2221 - 1D if all mesh nodes lie on OX coordinate axis, or
2222 - 2D if all mesh nodes lie on XOY coordinate plane, or
2223 - 3D in the rest cases.
2225 If *autoDimension* is *False*, the space dimension is always 3.
2226 fields: list of GEOM fields defined on the shape to mesh.
2227 geomAssocFields: each character of this string means a need to export a
2228 corresponding field; correspondence between fields and characters is following:
2230 - 'v' stands for "_vertices_" field;
2231 - 'e' stands for "_edges_" field;
2232 - 'f' stands for "_faces_" field;
2233 - 's' stands for "_solids_" field.
2235 # process positional arguments
2236 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2238 auto_groups = args[1] if len(args) > 1 else False
2239 minor = args[2] if len(args) > 2 else -1
2240 overwrite = args[3] if len(args) > 3 else True
2241 meshPart = args[4] if len(args) > 4 else None
2242 autoDimension = args[5] if len(args) > 5 else True
2243 fields = args[6] if len(args) > 6 else []
2244 geomAssocFields = args[7] if len(args) > 7 else ''
2245 # process keywords arguments
2246 auto_groups = kwargs.get("auto_groups", auto_groups)
2247 minor = kwargs.get("minor", minor)
2248 overwrite = kwargs.get("overwrite", overwrite)
2249 meshPart = kwargs.get("meshPart", meshPart)
2250 autoDimension = kwargs.get("autoDimension", autoDimension)
2251 fields = kwargs.get("fields", fields)
2252 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2253 # invoke engine's function
2254 if meshPart or fields or geomAssocFields:
2255 unRegister = genObjUnRegister()
2256 if isinstance( meshPart, list ):
2257 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2258 unRegister.set( meshPart )
2259 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2260 fields, geomAssocFields)
2262 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2264 def ExportSAUV(self, f, auto_groups=0):
2266 Export the mesh in a file in SAUV format
2271 auto_groups: boolean parameter for creating/not creating
2272 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2273 the typical use is auto_groups=False.
2276 self.mesh.ExportSAUV(f, auto_groups)
2278 def ExportDAT(self, f, meshPart=None):
2280 Export the mesh in a file in DAT format
2284 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2288 unRegister = genObjUnRegister()
2289 if isinstance( meshPart, list ):
2290 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2291 unRegister.set( meshPart )
2292 self.mesh.ExportPartToDAT( meshPart, f )
2294 self.mesh.ExportDAT(f)
2296 def ExportUNV(self, f, meshPart=None):
2298 Export the mesh in a file in UNV format
2302 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2306 unRegister = genObjUnRegister()
2307 if isinstance( meshPart, list ):
2308 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2309 unRegister.set( meshPart )
2310 self.mesh.ExportPartToUNV( meshPart, f )
2312 self.mesh.ExportUNV(f)
2314 def ExportSTL(self, f, ascii=1, meshPart=None):
2316 Export the mesh in a file in STL format
2320 ascii: defines the file encoding
2321 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2325 unRegister = genObjUnRegister()
2326 if isinstance( meshPart, list ):
2327 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2328 unRegister.set( meshPart )
2329 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2331 self.mesh.ExportSTL(f, ascii)
2333 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2335 Export the mesh in a file in CGNS format
2339 overwrite: boolean parameter for overwriting/not overwriting the file
2340 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2341 groupElemsByType: if True all elements of same entity type are exported at ones,
2342 else elements are exported in order of their IDs which can cause creation
2343 of multiple cgns sections
2346 unRegister = genObjUnRegister()
2347 if isinstance( meshPart, list ):
2348 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2349 unRegister.set( meshPart )
2350 if isinstance( meshPart, Mesh ):
2351 meshPart = meshPart.mesh
2353 meshPart = self.mesh
2354 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2356 def ExportGMF(self, f, meshPart=None):
2358 Export the mesh in a file in GMF format.
2359 GMF files must have .mesh extension for the ASCII format and .meshb for
2360 the bynary format. Other extensions are not allowed.
2364 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2367 unRegister = genObjUnRegister()
2368 if isinstance( meshPart, list ):
2369 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2370 unRegister.set( meshPart )
2371 if isinstance( meshPart, Mesh ):
2372 meshPart = meshPart.mesh
2374 meshPart = self.mesh
2375 self.mesh.ExportGMF(meshPart, f, True)
2377 def ExportToMED(self, *args, **kwargs):
2379 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2380 Export the mesh in a file in MED format
2381 allowing to overwrite the file if it exists or add the exported data to its contents
2384 fileName: the file name
2385 opt (boolean): parameter for creating/not creating
2386 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2387 overwrite: boolean parameter for overwriting/not overwriting the file
2388 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2390 - 1D if all mesh nodes lie on OX coordinate axis, or
2391 - 2D if all mesh nodes lie on XOY coordinate plane, or
2392 - 3D in the rest cases.
2394 If **autoDimension** is *False*, the space dimension is always 3.
2397 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2398 # process positional arguments
2399 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2401 auto_groups = args[1] if len(args) > 1 else False
2402 overwrite = args[2] if len(args) > 2 else True
2403 autoDimension = args[3] if len(args) > 3 else True
2404 # process keywords arguments
2405 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2406 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2407 overwrite = kwargs.get("overwrite", overwrite)
2408 autoDimension = kwargs.get("autoDimension", autoDimension)
2410 # invoke engine's function
2411 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2413 def ExportToMEDX(self, *args, **kwargs):
2415 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2416 Export the mesh in a file in MED format
2419 fileName: the file name
2420 opt (boolean): parameter for creating/not creating
2421 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2422 overwrite: boolean parameter for overwriting/not overwriting the file
2423 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2425 - 1D if all mesh nodes lie on OX coordinate axis, or
2426 - 2D if all mesh nodes lie on XOY coordinate plane, or
2427 - 3D in the rest cases.
2429 If **autoDimension** is *False*, the space dimension is always 3.
2432 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2433 # process positional arguments
2434 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2436 auto_groups = args[1] if len(args) > 1 else False
2437 overwrite = args[2] if len(args) > 2 else True
2438 autoDimension = args[3] if len(args) > 3 else True
2439 # process keywords arguments
2440 auto_groups = kwargs.get("auto_groups", auto_groups)
2441 overwrite = kwargs.get("overwrite", overwrite)
2442 autoDimension = kwargs.get("autoDimension", autoDimension)
2444 # invoke engine's function
2445 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2447 # Operations with groups:
2448 # ----------------------
2449 def CreateEmptyGroup(self, elementType, name):
2451 Create an empty standalone mesh group
2454 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2455 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2456 name: the name of the mesh group
2459 :class:`SMESH.SMESH_Group`
2462 return self.mesh.CreateGroup(elementType, name)
2464 def Group(self, grp, name=""):
2466 Create a mesh group based on the geometric object *grp*
2467 and give it a *name*.
2468 If *name* is not defined the name of the geometric group is used
2471 Works like :meth:`GroupOnGeom`.
2474 grp: a geometric group, a vertex, an edge, a face or a solid
2475 name: the name of the mesh group
2478 :class:`SMESH.SMESH_GroupOnGeom`
2481 return self.GroupOnGeom(grp, name)
2483 def GroupOnGeom(self, grp, name="", typ=None):
2485 Create a mesh group based on the geometrical object *grp*
2486 and give it a *name*.
2487 if *name* is not defined the name of the geometric group is used
2490 grp: a geometrical group, a vertex, an edge, a face or a solid
2491 name: the name of the mesh group
2492 typ: the type of elements in the group; either of
2493 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2494 automatically detected by the type of the geometry
2497 :class:`SMESH.SMESH_GroupOnGeom`
2500 AssureGeomPublished( self, grp, name )
2502 name = grp.GetName()
2504 typ = self._groupTypeFromShape( grp )
2505 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2507 def _groupTypeFromShape( self, shape ):
2509 Pivate method to get a type of group on geometry
2511 tgeo = str(shape.GetShapeType())
2512 if tgeo == "VERTEX":
2514 elif tgeo == "EDGE":
2516 elif tgeo == "FACE" or tgeo == "SHELL":
2518 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2520 elif tgeo == "COMPOUND":
2521 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2523 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2524 return self._groupTypeFromShape( sub[0] )
2526 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2529 def GroupOnFilter(self, typ, name, filter):
2531 Create a mesh group with given *name* based on the *filter*.
2532 It is a special type of group dynamically updating it's contents during
2536 typ: the type of elements in the group; either of
2537 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2538 name: the name of the mesh group
2539 filter (SMESH.Filter): the filter defining group contents
2542 :class:`SMESH.SMESH_GroupOnFilter`
2545 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2547 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2549 Create a mesh group by the given ids of elements
2552 groupName: the name of the mesh group
2553 elementType: the type of elements in the group; either of
2554 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2555 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2558 :class:`SMESH.SMESH_Group`
2561 group = self.mesh.CreateGroup(elementType, groupName)
2562 if isinstance( elemIDs, Mesh ):
2563 elemIDs = elemIDs.GetMesh()
2564 if hasattr( elemIDs, "GetIDs" ):
2565 if hasattr( elemIDs, "SetMesh" ):
2566 elemIDs.SetMesh( self.GetMesh() )
2567 group.AddFrom( elemIDs )
2575 CritType=FT_Undefined,
2578 UnaryOp=FT_Undefined,
2581 Create a mesh group by the given conditions
2584 groupName: the name of the mesh group
2585 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2586 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2587 Note that the items starting from FT_LessThan are not suitable for CritType.
2588 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2589 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2590 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2591 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2592 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2595 :class:`SMESH.SMESH_GroupOnFilter`
2598 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2599 group = self.MakeGroupByCriterion(groupName, aCriterion)
2602 def MakeGroupByCriterion(self, groupName, Criterion):
2604 Create a mesh group by the given criterion
2607 groupName: the name of the mesh group
2608 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2611 :class:`SMESH.SMESH_GroupOnFilter`
2614 :meth:`smeshBuilder.GetCriterion`
2617 return self.MakeGroupByCriteria( groupName, [Criterion] )
2619 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2621 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2624 groupName: the name of the mesh group
2625 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2626 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2629 :class:`SMESH.SMESH_GroupOnFilter`
2632 :meth:`smeshBuilder.GetCriterion`
2635 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2636 group = self.MakeGroupByFilter(groupName, aFilter)
2639 def MakeGroupByFilter(self, groupName, theFilter):
2641 Create a mesh group by the given filter
2644 groupName (string): the name of the mesh group
2645 theFilter (SMESH.Filter): the filter
2648 :class:`SMESH.SMESH_GroupOnFilter`
2651 :meth:`smeshBuilder.GetFilter`
2654 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2655 #theFilter.SetMesh( self.mesh )
2656 #group.AddFrom( theFilter )
2657 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2660 def RemoveGroup(self, group):
2665 group (SMESH.SMESH_GroupBase): group to remove
2668 self.mesh.RemoveGroup(group)
2670 def RemoveGroupWithContents(self, group):
2672 Remove a group with its contents
2675 group (SMESH.SMESH_GroupBase): group to remove
2678 self.mesh.RemoveGroupWithContents(group)
2680 def GetGroups(self, elemType = SMESH.ALL):
2682 Get the list of groups existing in the mesh in the order of creation
2683 (starting from the oldest one)
2686 elemType (SMESH.ElementType): type of elements the groups contain;
2687 by default groups of elements of all types are returned
2690 a list of :class:`SMESH.SMESH_GroupBase`
2693 groups = self.mesh.GetGroups()
2694 if elemType == SMESH.ALL:
2698 if g.GetType() == elemType:
2699 typedGroups.append( g )
2706 Get the number of groups existing in the mesh
2709 the quantity of groups as an integer value
2712 return self.mesh.NbGroups()
2714 def GetGroupNames(self):
2716 Get the list of names of groups existing in the mesh
2722 groups = self.GetGroups()
2724 for group in groups:
2725 names.append(group.GetName())
2728 def GetGroupByName(self, name, elemType = None):
2730 Find groups by name and type
2733 name (string): name of the group of interest
2734 elemType (SMESH.ElementType): type of elements the groups contain;
2735 by default one group of any type is returned;
2736 if elemType == SMESH.ALL then all groups of any type are returned
2739 a list of :class:`SMESH.SMESH_GroupBase`
2743 for group in self.GetGroups():
2744 if group.GetName() == name:
2745 if elemType is None:
2747 if ( elemType == SMESH.ALL or
2748 group.GetType() == elemType ):
2749 groups.append( group )
2752 def UnionGroups(self, group1, group2, name):
2754 Produce a union of two groups.
2755 A new group is created. All mesh elements that are
2756 present in the initial groups are added to the new one
2759 group1 (SMESH.SMESH_GroupBase): a group
2760 group2 (SMESH.SMESH_GroupBase): another group
2763 instance of :class:`SMESH.SMESH_Group`
2766 return self.mesh.UnionGroups(group1, group2, name)
2768 def UnionListOfGroups(self, groups, name):
2770 Produce a union list of groups.
2771 New group is created. All mesh elements that are present in
2772 initial groups are added to the new one
2775 groups: list of :class:`SMESH.SMESH_GroupBase`
2778 instance of :class:`SMESH.SMESH_Group`
2780 return self.mesh.UnionListOfGroups(groups, name)
2782 def IntersectGroups(self, group1, group2, name):
2784 Prodice an intersection of two groups.
2785 A new group is created. All mesh elements that are common
2786 for the two initial groups are added to the new one.
2789 group1 (SMESH.SMESH_GroupBase): a group
2790 group2 (SMESH.SMESH_GroupBase): another group
2793 instance of :class:`SMESH.SMESH_Group`
2796 return self.mesh.IntersectGroups(group1, group2, name)
2798 def IntersectListOfGroups(self, groups, name):
2800 Produce an intersection of groups.
2801 New group is created. All mesh elements that are present in all
2802 initial groups simultaneously are added to the new one
2805 groups: a list of :class:`SMESH.SMESH_GroupBase`
2808 instance of :class:`SMESH.SMESH_Group`
2810 return self.mesh.IntersectListOfGroups(groups, name)
2812 def CutGroups(self, main_group, tool_group, name):
2814 Produce a cut of two groups.
2815 A new group is created. All mesh elements that are present in
2816 the main group but are not present in the tool group are added to the new one
2819 main_group (SMESH.SMESH_GroupBase): a group to cut from
2820 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2823 an instance of :class:`SMESH.SMESH_Group`
2826 return self.mesh.CutGroups(main_group, tool_group, name)
2828 def CutListOfGroups(self, main_groups, tool_groups, name):
2830 Produce a cut of groups.
2831 A new group is created. All mesh elements that are present in main groups
2832 but do not present in tool groups are added to the new one
2835 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2836 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2839 an instance of :class:`SMESH.SMESH_Group`
2842 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2844 def CreateDimGroup(self, groups, elemType, name,
2845 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2847 Create a standalone group of entities basing on nodes of other groups.
2850 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2851 elemType: a type of elements to include to the new group; either of
2852 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2853 name: a name of the new group.
2854 nbCommonNodes: a criterion of inclusion of an element to the new group
2855 basing on number of element nodes common with reference *groups*.
2856 Meaning of possible values are:
2858 - SMESH.ALL_NODES - include if all nodes are common,
2859 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2860 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2861 - SMEHS.MAJORITY - include if half of nodes or more are common.
2862 underlyingOnly: if *True* (default), an element is included to the
2863 new group provided that it is based on nodes of an element of *groups*;
2864 in this case the reference *groups* are supposed to be of higher dimension
2865 than *elemType*, which can be useful for example to get all faces lying on
2866 volumes of the reference *groups*.
2869 an instance of :class:`SMESH.SMESH_Group`
2872 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2874 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2877 def ConvertToStandalone(self, group):
2879 Convert group on geom into standalone group
2882 return self.mesh.ConvertToStandalone(group)
2884 # Get some info about mesh:
2885 # ------------------------
2887 def GetLog(self, clearAfterGet):
2889 Return the log of nodes and elements added or removed
2890 since the previous clear of the log.
2893 clearAfterGet: log is emptied after Get (safe if concurrents access)
2896 list of SMESH.log_block structures { commandType, number, coords, indexes }
2899 return self.mesh.GetLog(clearAfterGet)
2903 Clear the log of nodes and elements added or removed since the previous
2904 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2907 self.mesh.ClearLog()
2909 def SetAutoColor(self, theAutoColor):
2911 Toggle auto color mode on the object.
2912 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2915 theAutoColor (boolean): the flag which toggles auto color mode.
2918 self.mesh.SetAutoColor(theAutoColor)
2920 def GetAutoColor(self):
2922 Get flag of object auto color mode.
2928 return self.mesh.GetAutoColor()
2935 integer value, which is the internal Id of the mesh
2938 return self.mesh.GetId()
2940 def HasDuplicatedGroupNamesMED(self):
2942 Check the group names for duplications.
2943 Consider the maximum group name length stored in MED file.
2949 return self.mesh.HasDuplicatedGroupNamesMED()
2951 def GetMeshEditor(self):
2953 Obtain the mesh editor tool
2956 an instance of :class:`SMESH.SMESH_MeshEditor`
2961 def GetIDSource(self, ids, elemType = SMESH.ALL):
2963 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
2964 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2968 elemType: type of elements; this parameter is used to distinguish
2969 IDs of nodes from IDs of elements; by default ids are treated as
2970 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2973 an instance of :class:`SMESH.SMESH_IDSource`
2976 call UnRegister() for the returned object as soon as it is no more useful::
2978 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2979 mesh.DoSomething( idSrc )
2983 if isinstance( ids, int ):
2985 return self.editor.MakeIDSource(ids, elemType)
2988 # Get information about mesh contents:
2989 # ------------------------------------
2991 def GetMeshInfo(self, obj = None):
2993 Get the mesh statistic.
2994 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
2995 an item of :class:`SMESH.EntityType`.
2998 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3001 if not obj: obj = self.mesh
3002 return self.smeshpyD.GetMeshInfo(obj)
3006 Return the number of nodes in the mesh
3012 return self.mesh.NbNodes()
3014 def NbElements(self):
3016 Return the number of elements in the mesh
3022 return self.mesh.NbElements()
3024 def Nb0DElements(self):
3026 Return the number of 0d elements in the mesh
3032 return self.mesh.Nb0DElements()
3036 Return the number of ball discrete elements in the mesh
3042 return self.mesh.NbBalls()
3046 Return the number of edges in the mesh
3052 return self.mesh.NbEdges()
3054 def NbEdgesOfOrder(self, elementOrder):
3056 Return the number of edges with the given order in the mesh
3059 elementOrder: the order of elements
3060 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3066 return self.mesh.NbEdgesOfOrder(elementOrder)
3070 Return the number of faces in the mesh
3076 return self.mesh.NbFaces()
3078 def NbFacesOfOrder(self, elementOrder):
3080 Return the number of faces with the given order in the mesh
3083 elementOrder: the order of elements
3084 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3090 return self.mesh.NbFacesOfOrder(elementOrder)
3092 def NbTriangles(self):
3094 Return the number of triangles in the mesh
3100 return self.mesh.NbTriangles()
3102 def NbTrianglesOfOrder(self, elementOrder):
3104 Return the number of triangles with the given order in the mesh
3107 elementOrder: is the order of elements
3108 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3114 return self.mesh.NbTrianglesOfOrder(elementOrder)
3116 def NbBiQuadTriangles(self):
3118 Return the number of biquadratic triangles in the mesh
3124 return self.mesh.NbBiQuadTriangles()
3126 def NbQuadrangles(self):
3128 Return the number of quadrangles in the mesh
3134 return self.mesh.NbQuadrangles()
3136 def NbQuadranglesOfOrder(self, elementOrder):
3138 Return the number of quadrangles with the given order in the mesh
3141 elementOrder: the order of elements
3142 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3148 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3150 def NbBiQuadQuadrangles(self):
3152 Return the number of biquadratic quadrangles in the mesh
3158 return self.mesh.NbBiQuadQuadrangles()
3160 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3162 Return the number of polygons of given order in the mesh
3165 elementOrder: the order of elements
3166 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3172 return self.mesh.NbPolygonsOfOrder(elementOrder)
3174 def NbVolumes(self):
3176 Return the number of volumes in the mesh
3182 return self.mesh.NbVolumes()
3185 def NbVolumesOfOrder(self, elementOrder):
3187 Return the number of volumes with the given order in the mesh
3190 elementOrder: the order of elements
3191 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3197 return self.mesh.NbVolumesOfOrder(elementOrder)
3201 Return the number of tetrahedrons in the mesh
3207 return self.mesh.NbTetras()
3209 def NbTetrasOfOrder(self, elementOrder):
3211 Return the number of tetrahedrons with the given order in the mesh
3214 elementOrder: the order of elements
3215 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3221 return self.mesh.NbTetrasOfOrder(elementOrder)
3225 Return the number of hexahedrons in the mesh
3231 return self.mesh.NbHexas()
3233 def NbHexasOfOrder(self, elementOrder):
3235 Return the number of hexahedrons with the given order in the mesh
3238 elementOrder: the order of elements
3239 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3245 return self.mesh.NbHexasOfOrder(elementOrder)
3247 def NbTriQuadraticHexas(self):
3249 Return the number of triquadratic hexahedrons in the mesh
3255 return self.mesh.NbTriQuadraticHexas()
3257 def NbPyramids(self):
3259 Return the number of pyramids in the mesh
3265 return self.mesh.NbPyramids()
3267 def NbPyramidsOfOrder(self, elementOrder):
3269 Return the number of pyramids with the given order in the mesh
3272 elementOrder: the order of elements
3273 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3279 return self.mesh.NbPyramidsOfOrder(elementOrder)
3283 Return the number of prisms in the mesh
3289 return self.mesh.NbPrisms()
3291 def NbPrismsOfOrder(self, elementOrder):
3293 Return the number of prisms with the given order in the mesh
3296 elementOrder: the order of elements
3297 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3303 return self.mesh.NbPrismsOfOrder(elementOrder)
3305 def NbHexagonalPrisms(self):
3307 Return the number of hexagonal prisms in the mesh
3313 return self.mesh.NbHexagonalPrisms()
3315 def NbPolyhedrons(self):
3317 Return the number of polyhedrons in the mesh
3323 return self.mesh.NbPolyhedrons()
3325 def NbSubMesh(self):
3327 Return the number of submeshes in the mesh
3333 return self.mesh.NbSubMesh()
3335 def GetElementsId(self):
3337 Return the list of all mesh elements IDs
3340 the list of integer values
3343 :meth:`GetElementsByType`
3346 return self.mesh.GetElementsId()
3348 def GetElementsByType(self, elementType):
3350 Return the list of IDs of mesh elements with the given type
3353 elementType (SMESH.ElementType): the required type of elements
3356 list of integer values
3359 return self.mesh.GetElementsByType(elementType)
3361 def GetNodesId(self):
3363 Return the list of mesh nodes IDs
3366 the list of integer values
3369 return self.mesh.GetNodesId()
3371 # Get the information about mesh elements:
3372 # ------------------------------------
3374 def GetElementType(self, id, iselem=True):
3376 Return the type of mesh element or node
3379 the value from :class:`SMESH.ElementType` enumeration.
3380 Return SMESH.ALL if element or node with the given ID does not exist
3383 return self.mesh.GetElementType(id, iselem)
3385 def GetElementGeomType(self, id):
3387 Return the geometric type of mesh element
3390 the value from :class:`SMESH.EntityType` enumeration.
3393 return self.mesh.GetElementGeomType(id)
3395 def GetElementShape(self, id):
3397 Return the shape type of mesh element
3400 the value from :class:`SMESH.GeometryType` enumeration.
3403 return self.mesh.GetElementShape(id)
3405 def GetSubMeshElementsId(self, Shape):
3407 Return the list of sub-mesh elements IDs
3410 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3411 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3414 list of integer values
3417 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3418 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3421 return self.mesh.GetSubMeshElementsId(ShapeID)
3423 def GetSubMeshNodesId(self, Shape, all):
3425 Return the list of sub-mesh nodes IDs
3428 Shape: a geom object (sub-shape).
3429 *Shape* must be the sub-shape of a :meth:`GetShape`
3430 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3433 list of integer values
3436 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3437 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3440 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3442 def GetSubMeshElementType(self, Shape):
3444 Return type of elements on given shape
3447 Shape: a geom object (sub-shape).
3448 *Shape* must be a sub-shape of a ShapeToMesh()
3451 :class:`SMESH.ElementType`
3454 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3455 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3458 return self.mesh.GetSubMeshElementType(ShapeID)
3462 Get the mesh description
3468 return self.mesh.Dump()
3471 # Get the information about nodes and elements of a mesh by its IDs:
3472 # -----------------------------------------------------------
3474 def GetNodeXYZ(self, id):
3476 Get XYZ coordinates of a node.
3477 If there is no node for the given ID - return an empty list
3480 list of float values
3483 return self.mesh.GetNodeXYZ(id)
3485 def GetNodeInverseElements(self, id):
3487 Return list of IDs of inverse elements for the given node.
3488 If there is no node for the given ID - return an empty list
3491 list of integer values
3494 return self.mesh.GetNodeInverseElements(id)
3496 def GetNodePosition(self,NodeID):
3498 Return the position of a node on the shape
3501 :class:`SMESH.NodePosition`
3504 return self.mesh.GetNodePosition(NodeID)
3506 def GetElementPosition(self,ElemID):
3508 Return the position of an element on the shape
3511 :class:`SMESH.ElementPosition`
3514 return self.mesh.GetElementPosition(ElemID)
3516 def GetShapeID(self, id):
3518 Return the ID of the shape, on which the given node was generated.
3521 an integer value > 0 or -1 if there is no node for the given
3522 ID or the node is not assigned to any geometry
3525 return self.mesh.GetShapeID(id)
3527 def GetShapeIDForElem(self,id):
3529 Return the ID of the shape, on which the given element was generated.
3532 an integer value > 0 or -1 if there is no element for the given
3533 ID or the element is not assigned to any geometry
3536 return self.mesh.GetShapeIDForElem(id)
3538 def GetElemNbNodes(self, id):
3540 Return the number of nodes of the given element
3543 an integer value > 0 or -1 if there is no element for the given ID
3546 return self.mesh.GetElemNbNodes(id)
3548 def GetElemNode(self, id, index):
3550 Return the node ID the given (zero based) index for the given element.
3552 * If there is no element for the given ID - return -1.
3553 * If there is no node for the given index - return -2.
3556 id (int): element ID
3557 index (int): node index within the element
3560 an integer value (ID)
3563 :meth:`GetElemNodes`
3566 return self.mesh.GetElemNode(id, index)
3568 def GetElemNodes(self, id):
3570 Return the IDs of nodes of the given element
3573 a list of integer values
3576 return self.mesh.GetElemNodes(id)
3578 def IsMediumNode(self, elementID, nodeID):
3580 Return true if the given node is the medium node in the given quadratic element
3583 return self.mesh.IsMediumNode(elementID, nodeID)
3585 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3587 Return true if the given node is the medium node in one of quadratic elements
3590 nodeID: ID of the node
3591 elementType: the type of elements to check a state of the node, either of
3592 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3595 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3597 def ElemNbEdges(self, id):
3599 Return the number of edges for the given element
3602 return self.mesh.ElemNbEdges(id)
3604 def ElemNbFaces(self, id):
3606 Return the number of faces for the given element
3609 return self.mesh.ElemNbFaces(id)
3611 def GetElemFaceNodes(self,elemId, faceIndex):
3613 Return nodes of given face (counted from zero) for given volumic element.
3616 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3618 def GetFaceNormal(self, faceId, normalized=False):
3620 Return three components of normal of given mesh face
3621 (or an empty array in KO case)
3624 return self.mesh.GetFaceNormal(faceId,normalized)
3626 def FindElementByNodes(self, nodes):
3628 Return an element based on all given nodes.
3631 return self.mesh.FindElementByNodes(nodes)
3633 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3635 Return elements including all given nodes.
3638 return self.mesh.GetElementsByNodes( nodes, elemType )
3640 def IsPoly(self, id):
3642 Return true if the given element is a polygon
3645 return self.mesh.IsPoly(id)
3647 def IsQuadratic(self, id):
3649 Return true if the given element is quadratic
3652 return self.mesh.IsQuadratic(id)
3654 def GetBallDiameter(self, id):
3656 Return diameter of a ball discrete element or zero in case of an invalid *id*
3659 return self.mesh.GetBallDiameter(id)
3661 def BaryCenter(self, id):
3663 Return XYZ coordinates of the barycenter of the given element.
3664 If there is no element for the given ID - return an empty list
3667 a list of three double values
3670 return self.mesh.BaryCenter(id)
3672 def GetIdsFromFilter(self, theFilter):
3674 Pass mesh elements through the given filter and return IDs of fitting elements
3677 theFilter: :class:`SMESH.Filter`
3683 :meth:`SMESH.Filter.GetIDs`
3686 theFilter.SetMesh( self.mesh )
3687 return theFilter.GetIDs()
3689 # Get mesh measurements information:
3690 # ------------------------------------
3692 def GetFreeBorders(self):
3694 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3695 Return a list of special structures (borders).
3698 a list of :class:`SMESH.FreeEdges.Border`
3701 aFilterMgr = self.smeshpyD.CreateFilterManager()
3702 aPredicate = aFilterMgr.CreateFreeEdges()
3703 aPredicate.SetMesh(self.mesh)
3704 aBorders = aPredicate.GetBorders()
3705 aFilterMgr.UnRegister()
3708 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3710 Get minimum distance between two nodes, elements or distance to the origin
3713 id1: first node/element id
3714 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3715 isElem1: *True* if *id1* is element id, *False* if it is node id
3716 isElem2: *True* if *id2* is element id, *False* if it is node id
3719 minimum distance value
3721 :meth:`GetMinDistance`
3724 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3725 return aMeasure.value
3727 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3729 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3732 id1: first node/element id
3733 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3734 isElem1: *True* if *id1* is element id, *False* if it is node id
3735 isElem2: *True* if *id2* is element id, *False* if it is node id
3738 :class:`SMESH.Measure` structure
3744 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3746 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3749 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3751 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3756 aMeasurements = self.smeshpyD.CreateMeasurements()
3757 aMeasure = aMeasurements.MinDistance(id1, id2)
3758 genObjUnRegister([aMeasurements,id1, id2])
3761 def BoundingBox(self, objects=None, isElem=False):
3763 Get bounding box of the specified object(s)
3766 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3767 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3768 *False* specifies that *objects* are nodes
3771 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3774 :meth:`GetBoundingBox()`
3777 result = self.GetBoundingBox(objects, isElem)
3781 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3784 def GetBoundingBox(self, objects=None, isElem=False):
3786 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3789 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3790 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3791 False means that *objects* are nodes
3794 :class:`SMESH.Measure` structure
3797 :meth:`BoundingBox()`
3801 objects = [self.mesh]
3802 elif isinstance(objects, tuple):
3803 objects = list(objects)
3804 if not isinstance(objects, list):
3806 if len(objects) > 0 and isinstance(objects[0], int):
3809 unRegister = genObjUnRegister()
3811 if isinstance(o, Mesh):
3812 srclist.append(o.mesh)
3813 elif hasattr(o, "_narrow"):
3814 src = o._narrow(SMESH.SMESH_IDSource)
3815 if src: srclist.append(src)
3817 elif isinstance(o, list):
3819 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3821 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3822 unRegister.set( srclist[-1] )
3825 aMeasurements = self.smeshpyD.CreateMeasurements()
3826 unRegister.set( aMeasurements )
3827 aMeasure = aMeasurements.BoundingBox(srclist)
3830 # Mesh edition (SMESH_MeshEditor functionality):
3831 # ---------------------------------------------
3833 def RemoveElements(self, IDsOfElements):
3835 Remove the elements from the mesh by ids
3838 IDsOfElements: is a list of ids of elements to remove
3844 return self.editor.RemoveElements(IDsOfElements)
3846 def RemoveNodes(self, IDsOfNodes):
3848 Remove nodes from mesh by ids
3851 IDsOfNodes: is a list of ids of nodes to remove
3857 return self.editor.RemoveNodes(IDsOfNodes)
3859 def RemoveOrphanNodes(self):
3861 Remove all orphan (free) nodes from mesh
3864 number of the removed nodes
3867 return self.editor.RemoveOrphanNodes()
3869 def AddNode(self, x, y, z):
3871 Add a node to the mesh by coordinates
3877 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3878 if hasVars: self.mesh.SetParameters(Parameters)
3879 return self.editor.AddNode( x, y, z)
3881 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3883 Create a 0D element on a node with given number.
3886 IDOfNode: the ID of node for creation of the element.
3887 DuplicateElements: to add one more 0D element to a node or not
3890 ID of the new 0D element
3893 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3895 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3897 Create 0D elements on all nodes of the given elements except those
3898 nodes on which a 0D element already exists.
3901 theObject: an object on whose nodes 0D elements will be created.
3902 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3903 theGroupName: optional name of a group to add 0D elements created
3904 and/or found on nodes of *theObject*.
3905 DuplicateElements: to add one more 0D element to a node or not
3908 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3909 IDs of new and/or found 0D elements. IDs of 0D elements
3910 can be retrieved from the returned object by
3911 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3914 unRegister = genObjUnRegister()
3915 if isinstance( theObject, Mesh ):
3916 theObject = theObject.GetMesh()
3917 elif isinstance( theObject, list ):
3918 theObject = self.GetIDSource( theObject, SMESH.ALL )
3919 unRegister.set( theObject )
3920 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3922 def AddBall(self, IDOfNode, diameter):
3924 Create a ball element on a node with given ID.
3927 IDOfNode: the ID of node for creation of the element.
3928 diameter: the bal diameter.
3931 ID of the new ball element
3934 return self.editor.AddBall( IDOfNode, diameter )
3936 def AddEdge(self, IDsOfNodes):
3938 Create a linear or quadratic edge (this is determined
3939 by the number of given nodes).
3942 IDsOfNodes: list of node IDs for creation of the element.
3943 The order of nodes in this list should correspond to
3944 the :ref:`connectivity convention <connectivity_page>`.
3950 return self.editor.AddEdge(IDsOfNodes)
3952 def AddFace(self, IDsOfNodes):
3954 Create a linear or quadratic face (this is determined
3955 by the number of given nodes).
3958 IDsOfNodes: list of node IDs for creation of the element.
3959 The order of nodes in this list should correspond to
3960 the :ref:`connectivity convention <connectivity_page>`.
3966 return self.editor.AddFace(IDsOfNodes)
3968 def AddPolygonalFace(self, IdsOfNodes):
3970 Add a polygonal face defined by a list of node IDs
3973 IdsOfNodes: the list of node IDs for creation of the element.
3979 return self.editor.AddPolygonalFace(IdsOfNodes)
3981 def AddQuadPolygonalFace(self, IdsOfNodes):
3983 Add a quadratic polygonal face defined by a list of node IDs
3986 IdsOfNodes: the list of node IDs for creation of the element;
3987 corner nodes follow first.
3993 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
3995 def AddVolume(self, IDsOfNodes):
3997 Create both simple and quadratic volume (this is determined
3998 by the number of given nodes).
4001 IDsOfNodes: list of node IDs for creation of the element.
4002 The order of nodes in this list should correspond to
4003 the :ref:`connectivity convention <connectivity_page>`.
4006 ID of the new volumic element
4009 return self.editor.AddVolume(IDsOfNodes)
4011 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4013 Create a volume of many faces, giving nodes for each face.
4016 IdsOfNodes: list of node IDs for volume creation, face by face.
4017 Quantities: list of integer values, Quantities[i]
4018 gives the quantity of nodes in face number i.
4021 ID of the new volumic element
4024 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4026 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4028 Create a volume of many faces, giving the IDs of the existing faces.
4031 The created volume will refer only to the nodes
4032 of the given faces, not to the faces themselves.
4035 IdsOfFaces: the list of face IDs for volume creation.
4038 ID of the new volumic element
4041 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4044 def SetNodeOnVertex(self, NodeID, Vertex):
4046 Bind a node to a vertex
4050 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4053 True if succeed else raises an exception
4056 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4057 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4061 self.editor.SetNodeOnVertex(NodeID, VertexID)
4062 except SALOME.SALOME_Exception as inst:
4063 raise ValueError(inst.details.text)
4067 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4069 Store the node position on an edge
4073 Edge: an edge (GEOM.GEOM_Object) or edge ID
4074 paramOnEdge: a parameter on the edge where the node is located
4077 True if succeed else raises an exception
4080 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4081 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4085 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4086 except SALOME.SALOME_Exception as inst:
4087 raise ValueError(inst.details.text)
4090 def SetNodeOnFace(self, NodeID, Face, u, v):
4092 Store node position on a face
4096 Face: a face (GEOM.GEOM_Object) or face ID
4097 u: U parameter on the face where the node is located
4098 v: V parameter on the face where the node is located
4101 True if succeed else raises an exception
4104 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4105 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4109 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4110 except SALOME.SALOME_Exception as inst:
4111 raise ValueError(inst.details.text)
4114 def SetNodeInVolume(self, NodeID, Solid):
4116 Bind a node to a solid
4120 Solid: a solid (GEOM.GEOM_Object) or solid ID
4123 True if succeed else raises an exception
4126 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4127 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4131 self.editor.SetNodeInVolume(NodeID, SolidID)
4132 except SALOME.SALOME_Exception as inst:
4133 raise ValueError(inst.details.text)
4136 def SetMeshElementOnShape(self, ElementID, Shape):
4138 Bind an element to a shape
4141 ElementID: an element ID
4142 Shape: a shape (GEOM.GEOM_Object) or shape ID
4145 True if succeed else raises an exception
4148 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4149 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4153 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4154 except SALOME.SALOME_Exception as inst:
4155 raise ValueError(inst.details.text)
4159 def MoveNode(self, NodeID, x, y, z):
4161 Move the node with the given id
4164 NodeID: the id of the node
4165 x: a new X coordinate
4166 y: a new Y coordinate
4167 z: a new Z coordinate
4170 True if succeed else False
4173 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4174 if hasVars: self.mesh.SetParameters(Parameters)
4175 return self.editor.MoveNode(NodeID, x, y, z)
4177 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4179 Find the node closest to a point and moves it to a point location
4182 x: the X coordinate of a point
4183 y: the Y coordinate of a point
4184 z: the Z coordinate of a point
4185 NodeID: if specified (>0), the node with this ID is moved,
4186 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4189 the ID of a moved node
4192 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4193 if hasVars: self.mesh.SetParameters(Parameters)
4194 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4196 def FindNodeClosestTo(self, x, y, z):
4198 Find the node closest to a point
4201 x: the X coordinate of a point
4202 y: the Y coordinate of a point
4203 z: the Z coordinate of a point
4209 #preview = self.mesh.GetMeshEditPreviewer()
4210 #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4211 return self.editor.FindNodeClosestTo(x, y, z)
4213 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4215 Find the elements where a point lays IN or ON
4218 x,y,z (float): coordinates of the point
4219 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4220 means elements of any type excluding nodes, discrete and 0D elements.
4221 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4224 list of IDs of found elements
4227 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4229 return self.editor.FindElementsByPoint(x, y, z, elementType)
4231 def ProjectPoint(self, x,y,z, meshObject, elementType):
4233 Project a point to a mesh object.
4234 Return ID of an element of given type where the given point is projected
4235 and coordinates of the projection point.
4236 In the case if nothing found, return -1 and []
4238 if ( isinstance( meshObject, Mesh )):
4239 meshObject = meshObject.GetMesh()
4240 return self.editor.ProjectPoint( x,y,z, meshObject, elementType )
4242 def GetPointState(self, x, y, z):
4244 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4245 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4246 UNKNOWN state means that either mesh is wrong or the analysis fails.
4249 return self.editor.GetPointState(x, y, z)
4251 def IsManifold(self):
4253 Check if a 2D mesh is manifold
4256 return self.editor.IsManifold()
4258 def IsCoherentOrientation2D(self):
4260 Check if orientation of 2D elements is coherent
4263 return self.editor.IsCoherentOrientation2D()
4265 def MeshToPassThroughAPoint(self, x, y, z):
4267 Find the node closest to a point and moves it to a point location
4270 x: the X coordinate of a point
4271 y: the Y coordinate of a point
4272 z: the Z coordinate of a point
4275 the ID of a moved node
4278 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4280 def InverseDiag(self, NodeID1, NodeID2):
4282 Replace two neighbour triangles sharing Node1-Node2 link
4283 with the triangles built on the same 4 nodes but having other common link.
4286 NodeID1: the ID of the first node
4287 NodeID2: the ID of the second node
4290 False if proper faces were not found
4292 return self.editor.InverseDiag(NodeID1, NodeID2)
4294 def DeleteDiag(self, NodeID1, NodeID2):
4296 Replace two neighbour triangles sharing *Node1-Node2* link
4297 with a quadrangle built on the same 4 nodes.
4300 NodeID1: ID of the first node
4301 NodeID2: ID of the second node
4304 False if proper faces were not found
4307 return self.editor.DeleteDiag(NodeID1, NodeID2)
4309 def Reorient(self, IDsOfElements=None):
4311 Reorient elements by ids
4314 IDsOfElements: if undefined reorients all mesh elements
4317 True if succeed else False
4320 if IDsOfElements == None:
4321 IDsOfElements = self.GetElementsId()
4322 return self.editor.Reorient(IDsOfElements)
4324 def ReorientObject(self, theObject):
4326 Reorient all elements of the object
4329 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4332 True if succeed else False
4335 if ( isinstance( theObject, Mesh )):
4336 theObject = theObject.GetMesh()
4337 return self.editor.ReorientObject(theObject)
4339 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4341 Reorient faces contained in *the2DObject*.
4344 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4345 theDirection: is a desired direction of normal of *theFace*.
4346 It can be either a GEOM vector or a list of coordinates [x,y,z].
4347 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4348 compared with theDirection. It can be either ID of face or a point
4349 by which the face will be found. The point can be given as either
4350 a GEOM vertex or a list of point coordinates.
4353 number of reoriented faces
4356 unRegister = genObjUnRegister()
4358 if isinstance( the2DObject, Mesh ):
4359 the2DObject = the2DObject.GetMesh()
4360 if isinstance( the2DObject, list ):
4361 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4362 unRegister.set( the2DObject )
4363 # check theDirection
4364 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4365 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4366 if isinstance( theDirection, list ):
4367 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4368 # prepare theFace and thePoint
4369 theFace = theFaceOrPoint
4370 thePoint = PointStruct(0,0,0)
4371 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4372 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4374 if isinstance( theFaceOrPoint, list ):
4375 thePoint = PointStruct( *theFaceOrPoint )
4377 if isinstance( theFaceOrPoint, PointStruct ):
4378 thePoint = theFaceOrPoint
4380 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4382 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4384 Reorient faces according to adjacent volumes.
4387 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4388 either IDs of faces or face groups.
4389 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4390 theOutsideNormal: to orient faces to have their normals
4391 pointing either *outside* or *inside* the adjacent volumes.
4394 number of reoriented faces.
4397 unRegister = genObjUnRegister()
4399 if not isinstance( the2DObject, list ):
4400 the2DObject = [ the2DObject ]
4401 elif the2DObject and isinstance( the2DObject[0], int ):
4402 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4403 unRegister.set( the2DObject )
4404 the2DObject = [ the2DObject ]
4405 for i,obj2D in enumerate( the2DObject ):
4406 if isinstance( obj2D, Mesh ):
4407 the2DObject[i] = obj2D.GetMesh()
4408 if isinstance( obj2D, list ):
4409 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4410 unRegister.set( the2DObject[i] )
4412 if isinstance( the3DObject, Mesh ):
4413 the3DObject = the3DObject.GetMesh()
4414 if isinstance( the3DObject, list ):
4415 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4416 unRegister.set( the3DObject )
4417 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4419 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4421 Fuse the neighbouring triangles into quadrangles.
4424 IDsOfElements: The triangles to be fused.
4425 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4426 applied to possible quadrangles to choose a neighbour to fuse with.
4427 Note that not all items of :class:`SMESH.FunctorType` corresponds
4428 to numerical functors.
4429 MaxAngle: is the maximum angle between element normals at which the fusion
4430 is still performed; theMaxAngle is measured in radians.
4431 Also it could be a name of variable which defines angle in degrees.
4434 True in case of success, False otherwise.
4437 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4438 self.mesh.SetParameters(Parameters)
4439 if not IDsOfElements:
4440 IDsOfElements = self.GetElementsId()
4441 Functor = self.smeshpyD.GetFunctor(theCriterion)
4442 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4444 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4446 Fuse the neighbouring triangles of the object into quadrangles
4449 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4450 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4451 applied to possible quadrangles to choose a neighbour to fuse with.
4452 Note that not all items of :class:`SMESH.FunctorType` corresponds
4453 to numerical functors.
4454 MaxAngle: a max angle between element normals at which the fusion
4455 is still performed; theMaxAngle is measured in radians.
4458 True in case of success, False otherwise.
4461 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4462 self.mesh.SetParameters(Parameters)
4463 if isinstance( theObject, Mesh ):
4464 theObject = theObject.GetMesh()
4465 Functor = self.smeshpyD.GetFunctor(theCriterion)
4466 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4468 def QuadToTri (self, IDsOfElements, theCriterion = None):
4470 Split quadrangles into triangles.
4473 IDsOfElements: the faces to be splitted.
4474 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4475 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4476 value, then quadrangles will be split by the smallest diagonal.
4477 Note that not all items of :class:`SMESH.FunctorType` corresponds
4478 to numerical functors.
4481 True in case of success, False otherwise.
4483 if IDsOfElements == []:
4484 IDsOfElements = self.GetElementsId()
4485 if theCriterion is None:
4486 theCriterion = FT_MaxElementLength2D
4487 Functor = self.smeshpyD.GetFunctor(theCriterion)
4488 return self.editor.QuadToTri(IDsOfElements, Functor)
4490 def QuadToTriObject (self, theObject, theCriterion = None):
4492 Split quadrangles into triangles.
4495 theObject: the object from which the list of elements is taken,
4496 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4497 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4498 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4499 value, then quadrangles will be split by the smallest diagonal.
4500 Note that not all items of :class:`SMESH.FunctorType` corresponds
4501 to numerical functors.
4504 True in case of success, False otherwise.
4506 if ( isinstance( theObject, Mesh )):
4507 theObject = theObject.GetMesh()
4508 if theCriterion is None:
4509 theCriterion = FT_MaxElementLength2D
4510 Functor = self.smeshpyD.GetFunctor(theCriterion)
4511 return self.editor.QuadToTriObject(theObject, Functor)
4513 def QuadTo4Tri (self, theElements=[]):
4515 Split each of given quadrangles into 4 triangles. A node is added at the center of
4519 theElements: the faces to be splitted. This can be either
4520 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4521 or a list of face IDs. By default all quadrangles are split
4523 unRegister = genObjUnRegister()
4524 if isinstance( theElements, Mesh ):
4525 theElements = theElements.mesh
4526 elif not theElements:
4527 theElements = self.mesh
4528 elif isinstance( theElements, list ):
4529 theElements = self.GetIDSource( theElements, SMESH.FACE )
4530 unRegister.set( theElements )
4531 return self.editor.QuadTo4Tri( theElements )
4533 def SplitQuad (self, IDsOfElements, Diag13):
4535 Split quadrangles into triangles.
4538 IDsOfElements: the faces to be splitted
4539 Diag13 (boolean): is used to choose a diagonal for splitting.
4542 True in case of success, False otherwise.
4544 if IDsOfElements == []:
4545 IDsOfElements = self.GetElementsId()
4546 return self.editor.SplitQuad(IDsOfElements, Diag13)
4548 def SplitQuadObject (self, theObject, Diag13):
4550 Split quadrangles into triangles.
4553 theObject: the object from which the list of elements is taken,
4554 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4555 Diag13 (boolean): is used to choose a diagonal for splitting.
4558 True in case of success, False otherwise.
4560 if ( isinstance( theObject, Mesh )):
4561 theObject = theObject.GetMesh()
4562 return self.editor.SplitQuadObject(theObject, Diag13)
4564 def BestSplit (self, IDOfQuad, theCriterion):
4566 Find a better splitting of the given quadrangle.
4569 IDOfQuad: the ID of the quadrangle to be splitted.
4570 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4571 choose a diagonal for splitting.
4572 Note that not all items of :class:`SMESH.FunctorType` corresponds
4573 to numerical functors.
4576 * 1 if 1-3 diagonal is better,
4577 * 2 if 2-4 diagonal is better,
4578 * 0 if error occurs.
4580 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4582 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4584 Split volumic elements into tetrahedrons
4587 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4588 method: flags passing splitting method:
4589 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4590 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4592 unRegister = genObjUnRegister()
4593 if isinstance( elems, Mesh ):
4594 elems = elems.GetMesh()
4595 if ( isinstance( elems, list )):
4596 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4597 unRegister.set( elems )
4598 self.editor.SplitVolumesIntoTetra(elems, method)
4601 def SplitBiQuadraticIntoLinear(self, elems=None):
4603 Split bi-quadratic elements into linear ones without creation of additional nodes:
4605 - bi-quadratic triangle will be split into 3 linear quadrangles;
4606 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4607 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4609 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4610 will be split in order to keep the mesh conformal.
4613 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4614 if None (default), all bi-quadratic elements will be split
4616 unRegister = genObjUnRegister()
4617 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4618 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4619 unRegister.set( elems )
4621 elems = [ self.GetMesh() ]
4622 if isinstance( elems, Mesh ):
4623 elems = [ elems.GetMesh() ]
4624 if not isinstance( elems, list ):
4626 self.editor.SplitBiQuadraticIntoLinear( elems )
4628 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4629 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4631 Split hexahedra into prisms
4634 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4635 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4636 gives a normal vector defining facets to split into triangles.
4637 *startHexPoint* can be either a triple of coordinates or a vertex.
4638 facetNormal: a normal to a facet to split into triangles of a
4639 hexahedron found by *startHexPoint*.
4640 *facetNormal* can be either a triple of coordinates or an edge.
4641 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4642 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4643 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4644 to *startHexPoint* are split, else *startHexPoint*
4645 is used to find the facet to split in all domains present in *elems*.
4648 unRegister = genObjUnRegister()
4649 if isinstance( elems, Mesh ):
4650 elems = elems.GetMesh()
4651 if ( isinstance( elems, list )):
4652 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4653 unRegister.set( elems )
4656 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4657 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4658 elif isinstance( startHexPoint, list ):
4659 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4662 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4663 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4664 elif isinstance( facetNormal, list ):
4665 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4668 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4670 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4672 def SplitQuadsNearTriangularFacets(self):
4674 Split quadrangle faces near triangular facets of volumes
4676 faces_array = self.GetElementsByType(SMESH.FACE)
4677 for face_id in faces_array:
4678 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4679 quad_nodes = self.mesh.GetElemNodes(face_id)
4680 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4681 isVolumeFound = False
4682 for node1_elem in node1_elems:
4683 if not isVolumeFound:
4684 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4685 nb_nodes = self.GetElemNbNodes(node1_elem)
4686 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4687 volume_elem = node1_elem
4688 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4689 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4690 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4691 isVolumeFound = True
4692 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4693 self.SplitQuad([face_id], False) # diagonal 2-4
4694 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4695 isVolumeFound = True
4696 self.SplitQuad([face_id], True) # diagonal 1-3
4697 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4698 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4699 isVolumeFound = True
4700 self.SplitQuad([face_id], True) # diagonal 1-3
4702 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4704 Split hexahedrons into tetrahedrons.
4706 This operation uses :doc:`pattern_mapping` functionality for splitting.
4709 theObject: the object from which the list of hexahedrons is taken;
4710 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4711 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4712 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4713 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4714 key-point will be mapped into *theNode001*-th node of each volume.
4715 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4718 True in case of success, False otherwise.
4726 # (0,0,1) 4.---------.7 * |
4733 # (0,0,0) 0.---------.3
4734 pattern_tetra = "!!! Nb of points: \n 8 \n\
4744 !!! Indices of points of 6 tetras: \n\
4752 pattern = self.smeshpyD.GetPattern()
4753 isDone = pattern.LoadFromFile(pattern_tetra)
4755 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4758 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4759 isDone = pattern.MakeMesh(self.mesh, False, False)
4760 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4762 # split quafrangle faces near triangular facets of volumes
4763 self.SplitQuadsNearTriangularFacets()
4767 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4769 Split hexahedrons into prisms.
4771 Uses the :doc:`pattern_mapping` functionality for splitting.
4774 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4775 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4776 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4777 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4778 will be mapped into the *theNode001* -th node of each volume.
4779 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4782 True in case of success, False otherwise.
4784 # Pattern: 5.---------.6
4789 # (0,0,1) 4.---------.7 |
4796 # (0,0,0) 0.---------.3
4797 pattern_prism = "!!! Nb of points: \n 8 \n\
4807 !!! Indices of points of 2 prisms: \n\
4811 pattern = self.smeshpyD.GetPattern()
4812 isDone = pattern.LoadFromFile(pattern_prism)
4814 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4817 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4818 isDone = pattern.MakeMesh(self.mesh, False, False)
4819 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4821 # Split quafrangle faces near triangular facets of volumes
4822 self.SplitQuadsNearTriangularFacets()
4826 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4827 MaxNbOfIterations, MaxAspectRatio, Method):
4832 IDsOfElements: the list if ids of elements to smooth
4833 IDsOfFixedNodes: the list of ids of fixed nodes.
4834 Note that nodes built on edges and boundary nodes are always fixed.
4835 MaxNbOfIterations: the maximum number of iterations
4836 MaxAspectRatio: varies in range [1.0, inf]
4837 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4838 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4841 True in case of success, False otherwise.
4844 if IDsOfElements == []:
4845 IDsOfElements = self.GetElementsId()
4846 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4847 self.mesh.SetParameters(Parameters)
4848 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4849 MaxNbOfIterations, MaxAspectRatio, Method)
4851 def SmoothObject(self, theObject, IDsOfFixedNodes,
4852 MaxNbOfIterations, MaxAspectRatio, Method):
4854 Smooth elements which belong to the given object
4857 theObject: the object to smooth
4858 IDsOfFixedNodes: the list of ids of fixed nodes.
4859 Note that nodes built on edges and boundary nodes are always fixed.
4860 MaxNbOfIterations: the maximum number of iterations
4861 MaxAspectRatio: varies in range [1.0, inf]
4862 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4863 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4866 True in case of success, False otherwise.
4869 if ( isinstance( theObject, Mesh )):
4870 theObject = theObject.GetMesh()
4871 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4872 MaxNbOfIterations, MaxAspectRatio, Method)
4874 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4875 MaxNbOfIterations, MaxAspectRatio, Method):
4877 Parametrically smooth the given elements
4880 IDsOfElements: the list if ids of elements to smooth
4881 IDsOfFixedNodes: the list of ids of fixed nodes.
4882 Note that nodes built on edges and boundary nodes are always fixed.
4883 MaxNbOfIterations: the maximum number of iterations
4884 MaxAspectRatio: varies in range [1.0, inf]
4885 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4886 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4889 True in case of success, False otherwise.
4892 if IDsOfElements == []:
4893 IDsOfElements = self.GetElementsId()
4894 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4895 self.mesh.SetParameters(Parameters)
4896 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4897 MaxNbOfIterations, MaxAspectRatio, Method)
4899 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4900 MaxNbOfIterations, MaxAspectRatio, Method):
4902 Parametrically smooth the elements which belong to the given object
4905 theObject: the object to smooth
4906 IDsOfFixedNodes: the list of ids of fixed nodes.
4907 Note that nodes built on edges and boundary nodes are always fixed.
4908 MaxNbOfIterations: the maximum number of iterations
4909 MaxAspectRatio: varies in range [1.0, inf]
4910 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4911 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4914 True in case of success, False otherwise.
4917 if ( isinstance( theObject, Mesh )):
4918 theObject = theObject.GetMesh()
4919 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4920 MaxNbOfIterations, MaxAspectRatio, Method)
4922 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4924 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4925 them with quadratic with the same id.
4928 theForce3d: method of new node creation:
4930 * False - the medium node lies at the geometrical entity from which the mesh element is built
4931 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4932 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4933 theToBiQuad: If True, converts the mesh to bi-quadratic
4936 :class:`SMESH.ComputeError` which can hold a warning
4939 If *theSubMesh* is provided, the mesh can become non-conformal
4942 if isinstance( theSubMesh, Mesh ):
4943 theSubMesh = theSubMesh.mesh
4945 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
4948 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
4950 self.editor.ConvertToQuadratic(theForce3d)
4951 error = self.editor.GetLastError()
4952 if error and error.comment:
4953 print(error.comment)
4956 def ConvertFromQuadratic(self, theSubMesh=None):
4958 Convert the mesh from quadratic to ordinary,
4959 deletes old quadratic elements,
4960 replacing them with ordinary mesh elements with the same id.
4963 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4966 If *theSubMesh* is provided, the mesh can become non-conformal
4970 self.editor.ConvertFromQuadraticObject(theSubMesh)
4972 return self.editor.ConvertFromQuadratic()
4974 def Make2DMeshFrom3D(self):
4976 Create 2D mesh as skin on boundary faces of a 3D mesh
4979 True if operation has been completed successfully, False otherwise
4982 return self.editor.Make2DMeshFrom3D()
4984 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
4985 toCopyElements=False, toCopyExistingBondary=False):
4987 Create missing boundary elements
4990 elements: elements whose boundary is to be checked:
4991 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
4992 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
4993 dimension: defines type of boundary elements to create, either of
4994 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
4995 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
4996 groupName: a name of group to store created boundary elements in,
4997 "" means not to create the group
4998 meshName: a name of new mesh to store created boundary elements in,
4999 "" means not to create the new mesh
5000 toCopyElements: if True, the checked elements will be copied into
5001 the new mesh else only boundary elements will be copied into the new mesh
5002 toCopyExistingBondary: if True, not only new but also pre-existing
5003 boundary elements will be copied into the new mesh
5006 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5009 unRegister = genObjUnRegister()
5010 if isinstance( elements, Mesh ):
5011 elements = elements.GetMesh()
5012 if ( isinstance( elements, list )):
5013 elemType = SMESH.ALL
5014 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5015 elements = self.editor.MakeIDSource(elements, elemType)
5016 unRegister.set( elements )
5017 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5018 toCopyElements,toCopyExistingBondary)
5019 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5022 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5023 toCopyAll=False, groups=[]):
5025 Create missing boundary elements around either the whole mesh or
5029 dimension: defines type of boundary elements to create, either of
5030 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5031 groupName: a name of group to store all boundary elements in,
5032 "" means not to create the group
5033 meshName: a name of a new mesh, which is a copy of the initial
5034 mesh + created boundary elements; "" means not to create the new mesh
5035 toCopyAll: if True, the whole initial mesh will be copied into
5036 the new mesh else only boundary elements will be copied into the new mesh
5037 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5040 tuple( long, mesh, groups )
5041 - long - number of added boundary elements
5042 - mesh - the :class:`Mesh` where elements were added to
5043 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5046 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5048 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5049 return nb, mesh, group
5051 def RenumberNodes(self):
5053 Renumber mesh nodes to remove unused node IDs
5055 self.editor.RenumberNodes()
5057 def RenumberElements(self):
5059 Renumber mesh elements to remove unused element IDs
5061 self.editor.RenumberElements()
5063 def _getIdSourceList(self, arg, idType, unRegister):
5065 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5067 if arg and isinstance( arg, list ):
5068 if isinstance( arg[0], int ):
5069 arg = self.GetIDSource( arg, idType )
5070 unRegister.set( arg )
5071 elif isinstance( arg[0], Mesh ):
5072 arg[0] = arg[0].GetMesh()
5073 elif isinstance( arg, Mesh ):
5075 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5079 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5080 MakeGroups=False, TotalAngle=False):
5082 Generate new elements by rotation of the given elements and nodes around the axis
5085 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5086 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5087 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5088 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5089 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5090 which defines angle in degrees
5091 NbOfSteps: the number of steps
5092 Tolerance: tolerance
5093 MakeGroups: forces the generation of new groups from existing ones
5094 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5095 of all steps, else - size of each step
5098 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5101 unRegister = genObjUnRegister()
5102 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5103 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5104 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5106 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5107 Axis = self.smeshpyD.GetAxisStruct( Axis )
5108 if isinstance( Axis, list ):
5109 Axis = SMESH.AxisStruct( *Axis )
5111 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5112 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5113 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5114 self.mesh.SetParameters(Parameters)
5115 if TotalAngle and NbOfSteps:
5116 AngleInRadians /= NbOfSteps
5117 return self.editor.RotationSweepObjects( nodes, edges, faces,
5118 Axis, AngleInRadians,
5119 NbOfSteps, Tolerance, MakeGroups)
5121 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5122 MakeGroups=False, TotalAngle=False):
5124 Generate new elements by rotation of the elements around the axis
5127 IDsOfElements: the list of ids of elements to sweep
5128 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5129 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5130 NbOfSteps: the number of steps
5131 Tolerance: tolerance
5132 MakeGroups: forces the generation of new groups from existing ones
5133 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5134 of all steps, else - size of each step
5137 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5140 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5141 AngleInRadians, NbOfSteps, Tolerance,
5142 MakeGroups, TotalAngle)
5144 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5145 MakeGroups=False, TotalAngle=False):
5147 Generate new elements by rotation of the elements of object around the axis
5148 theObject object which elements should be sweeped.
5149 It can be a mesh, a sub mesh or a group.
5152 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5153 AngleInRadians: the angle of Rotation
5154 NbOfSteps: number of steps
5155 Tolerance: tolerance
5156 MakeGroups: forces the generation of new groups from existing ones
5157 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5158 of all steps, else - size of each step
5161 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5164 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5165 AngleInRadians, NbOfSteps, Tolerance,
5166 MakeGroups, TotalAngle )
5168 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5169 MakeGroups=False, TotalAngle=False):
5171 Generate new elements by rotation of the elements of object around the axis
5172 theObject object which elements should be sweeped.
5173 It can be a mesh, a sub mesh or a group.
5176 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5177 AngleInRadians: the angle of Rotation
5178 NbOfSteps: number of steps
5179 Tolerance: tolerance
5180 MakeGroups: forces the generation of new groups from existing ones
5181 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5182 of all steps, else - size of each step
5185 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5186 empty list otherwise
5189 return self.RotationSweepObjects([],theObject,[], Axis,
5190 AngleInRadians, NbOfSteps, Tolerance,
5191 MakeGroups, TotalAngle)
5193 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5194 MakeGroups=False, TotalAngle=False):
5196 Generate new elements by rotation of the elements of object around the axis
5197 theObject object which elements should be sweeped.
5198 It can be a mesh, a sub mesh or a group.
5201 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5202 AngleInRadians: the angle of Rotation
5203 NbOfSteps: number of steps
5204 Tolerance: tolerance
5205 MakeGroups: forces the generation of new groups from existing ones
5206 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5207 of all steps, else - size of each step
5210 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5213 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5214 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5216 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5217 scaleFactors=[], linearVariation=False, basePoint=[] ):
5219 Generate new elements by extrusion of the given elements and nodes
5222 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5223 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5224 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5225 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5226 the direction and value of extrusion for one step (the total extrusion
5227 length will be NbOfSteps * ||StepVector||)
5228 NbOfSteps: the number of steps
5229 MakeGroups: forces the generation of new groups from existing ones
5230 scaleFactors: optional scale factors to apply during extrusion
5231 linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5232 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5233 basePoint: optional scaling center; if not provided, a gravity center of
5234 nodes and elements being extruded is used as the scaling center.
5237 - a list of tree components of the point or
5241 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5243 Example: :ref:`tui_extrusion`
5245 unRegister = genObjUnRegister()
5246 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5247 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5248 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5250 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5251 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5252 if isinstance( StepVector, list ):
5253 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5255 if isinstance( basePoint, int):
5256 xyz = self.GetNodeXYZ( basePoint )
5258 raise RuntimeError("Invalid node ID: %s" % basePoint)
5260 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5261 basePoint = self.geompyD.PointCoordinates( basePoint )
5263 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5264 Parameters = StepVector.PS.parameters + var_separator + Parameters
5265 self.mesh.SetParameters(Parameters)
5267 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5268 StepVector, NbOfSteps,
5269 scaleFactors, linearVariation, basePoint,
5273 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5275 Generate new elements by extrusion of the elements with given ids
5278 IDsOfElements: the list of ids of elements or nodes for extrusion
5279 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5280 the direction and value of extrusion for one step (the total extrusion
5281 length will be NbOfSteps * ||StepVector||)
5282 NbOfSteps: the number of steps
5283 MakeGroups: forces the generation of new groups from existing ones
5284 IsNodes: is True if elements with given ids are nodes
5287 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5289 Example: :ref:`tui_extrusion`
5292 if IsNodes: n = IDsOfElements
5293 else : e,f, = IDsOfElements,IDsOfElements
5294 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5296 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5297 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5299 Generate new elements by extrusion along the normal to a discretized surface or wire
5302 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5303 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5304 StepSize: length of one extrusion step (the total extrusion
5305 length will be *NbOfSteps* *StepSize*).
5306 NbOfSteps: number of extrusion steps.
5307 ByAverageNormal: if True each node is translated by *StepSize*
5308 along the average of the normal vectors to the faces sharing the node;
5309 else each node is translated along the same average normal till
5310 intersection with the plane got by translation of the face sharing
5311 the node along its own normal by *StepSize*.
5312 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5313 for every node of *Elements*.
5314 MakeGroups: forces generation of new groups from existing ones.
5315 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5316 is not yet implemented. This parameter is used if *Elements* contains
5317 both faces and edges, i.e. *Elements* is a Mesh.
5320 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5321 empty list otherwise.
5322 Example: :ref:`tui_extrusion`
5325 unRegister = genObjUnRegister()
5326 if isinstance( Elements, Mesh ):
5327 Elements = [ Elements.GetMesh() ]
5328 if isinstance( Elements, list ):
5330 raise RuntimeError("Elements empty!")
5331 if isinstance( Elements[0], int ):
5332 Elements = self.GetIDSource( Elements, SMESH.ALL )
5333 unRegister.set( Elements )
5334 if not isinstance( Elements, list ):
5335 Elements = [ Elements ]
5336 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5337 self.mesh.SetParameters(Parameters)
5338 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5339 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5341 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5343 Generate new elements by extrusion of the elements or nodes which belong to the object
5346 theObject: the object whose elements or nodes should be processed.
5347 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5348 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5349 the direction and value of extrusion for one step (the total extrusion
5350 length will be NbOfSteps * ||StepVector||)
5351 NbOfSteps: the number of steps
5352 MakeGroups: forces the generation of new groups from existing ones
5353 IsNodes: is True if elements to extrude are nodes
5356 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5357 Example: :ref:`tui_extrusion`
5361 if IsNodes: n = theObject
5362 else : e,f, = theObject,theObject
5363 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5365 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5367 Generate new elements by extrusion of edges which belong to the object
5370 theObject: object whose 1D elements should be processed.
5371 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5372 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5373 the direction and value of extrusion for one step (the total extrusion
5374 length will be NbOfSteps * ||StepVector||)
5375 NbOfSteps: the number of steps
5376 MakeGroups: to generate new groups from existing ones
5379 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5380 Example: :ref:`tui_extrusion`
5383 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5385 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5387 Generate new elements by extrusion of faces which belong to the object
5390 theObject: object whose 2D elements should be processed.
5391 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5392 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5393 the direction and value of extrusion for one step (the total extrusion
5394 length will be NbOfSteps * ||StepVector||)
5395 NbOfSteps: the number of steps
5396 MakeGroups: forces the generation of new groups from existing ones
5399 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5400 Example: :ref:`tui_extrusion`
5403 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5405 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5406 ExtrFlags, SewTolerance, MakeGroups=False):
5408 Generate new elements by extrusion of the elements with given ids
5411 IDsOfElements: is ids of elements
5412 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5413 the direction and value of extrusion for one step (the total extrusion
5414 length will be NbOfSteps * ||StepVector||)
5415 NbOfSteps: the number of steps
5416 ExtrFlags: sets flags for extrusion
5417 SewTolerance: uses for comparing locations of nodes if flag
5418 EXTRUSION_FLAG_SEW is set
5419 MakeGroups: forces the generation of new groups from existing ones
5422 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5425 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5426 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5427 if isinstance( StepVector, list ):
5428 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5429 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5430 ExtrFlags, SewTolerance, MakeGroups)
5432 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5433 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5434 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5436 Generate new elements by extrusion of the given elements and nodes along the path.
5437 The path of extrusion must be a meshed edge.
5440 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5441 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5442 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5443 PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5444 PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5445 contains not only path segments, else it can be None
5446 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5447 HasAngles: allows the shape to be rotated around the path
5448 to get the resulting mesh in a helical fashion
5449 Angles: list of angles
5450 LinearVariation: forces the computation of rotation angles as linear
5451 variation of the given Angles along path steps
5452 HasRefPoint: allows using the reference point
5453 RefPoint: the reference point around which the shape is rotated (the mass center of the
5454 shape by default). The User can specify any point as the Reference Point.
5455 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5456 MakeGroups: forces the generation of new groups from existing ones
5459 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5460 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5461 Example: :ref:`tui_extrusion_along_path`
5464 unRegister = genObjUnRegister()
5465 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5466 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5467 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5469 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5470 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5471 if isinstance( RefPoint, list ):
5472 if not RefPoint: RefPoint = [0,0,0]
5473 RefPoint = SMESH.PointStruct( *RefPoint )
5474 if isinstance( PathMesh, Mesh ):
5475 PathMesh = PathMesh.GetMesh()
5476 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5477 Parameters = AnglesParameters + var_separator + RefPoint.parameters
5478 self.mesh.SetParameters(Parameters)
5479 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5480 PathMesh, PathShape, NodeStart,
5481 HasAngles, Angles, LinearVariation,
5482 HasRefPoint, RefPoint, MakeGroups)
5484 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5485 HasAngles=False, Angles=[], LinearVariation=False,
5486 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5487 ElemType=SMESH.FACE):
5489 Generate new elements by extrusion of the given elements.
5490 The path of extrusion must be a meshed edge.
5493 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5494 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5495 NodeStart: the start node from Path. Defines the direction of extrusion
5496 HasAngles: allows the shape to be rotated around the path
5497 to get the resulting mesh in a helical fashion
5498 Angles: list of angles in radians
5499 LinearVariation: forces the computation of rotation angles as linear
5500 variation of the given Angles along path steps
5501 HasRefPoint: allows using the reference point
5502 RefPoint: the reference point around which the elements are rotated (the mass
5503 center of the elements by default).
5504 The User can specify any point as the Reference Point.
5505 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5506 MakeGroups: forces the generation of new groups from existing ones
5507 ElemType: type of elements for extrusion (if param Base is a mesh)
5510 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5511 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5512 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5514 Example: :ref:`tui_extrusion_along_path`
5518 if ElemType == SMESH.NODE: n = Base
5519 if ElemType == SMESH.EDGE: e = Base
5520 if ElemType == SMESH.FACE: f = Base
5521 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5522 HasAngles, Angles, LinearVariation,
5523 HasRefPoint, RefPoint, MakeGroups)
5524 if MakeGroups: return gr,er
5527 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5528 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5529 MakeGroups=False, LinearVariation=False):
5531 Generate new elements by extrusion of the given elements.
5532 The path of extrusion must be a meshed edge.
5535 IDsOfElements: ids of elements
5536 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5537 PathShape: shape (edge) defines the sub-mesh for the path
5538 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5539 HasAngles: allows the shape to be rotated around the path
5540 to get the resulting mesh in a helical fashion
5541 Angles: list of angles in radians
5542 HasRefPoint: allows using the reference point
5543 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5544 The User can specify any point as the Reference Point.
5545 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5546 MakeGroups: forces the generation of new groups from existing ones
5547 LinearVariation: forces the computation of rotation angles as linear
5548 variation of the given Angles along path steps
5551 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5552 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5553 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5554 Example: :ref:`tui_extrusion_along_path`
5557 n,e,f = [],IDsOfElements,IDsOfElements
5558 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5559 NodeStart, HasAngles, Angles,
5561 HasRefPoint, RefPoint, MakeGroups)
5562 if MakeGroups: return gr,er
5565 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5566 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5567 MakeGroups=False, LinearVariation=False):
5569 Generate new elements by extrusion of the elements which belong to the object.
5570 The path of extrusion must be a meshed edge.
5573 theObject: the object whose elements should be processed.
5574 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5575 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5576 PathShape: shape (edge) defines the sub-mesh for the path
5577 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5578 HasAngles: allows the shape to be rotated around the path
5579 to get the resulting mesh in a helical fashion
5580 Angles: list of angles
5581 HasRefPoint: allows using the reference point
5582 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5583 The User can specify any point as the Reference Point.
5584 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5585 MakeGroups: forces the generation of new groups from existing ones
5586 LinearVariation: forces the computation of rotation angles as linear
5587 variation of the given Angles along path steps
5590 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5591 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5592 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5593 Example: :ref:`tui_extrusion_along_path`
5596 n,e,f = [],theObject,theObject
5597 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5598 HasAngles, Angles, LinearVariation,
5599 HasRefPoint, RefPoint, MakeGroups)
5600 if MakeGroups: return gr,er
5603 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5604 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5605 MakeGroups=False, LinearVariation=False):
5607 Generate new elements by extrusion of mesh segments which belong to the object.
5608 The path of extrusion must be a meshed edge.
5611 theObject: the object whose 1D elements should be processed.
5612 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5613 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5614 PathShape: shape (edge) defines the sub-mesh for the path
5615 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5616 HasAngles: allows the shape to be rotated around the path
5617 to get the resulting mesh in a helical fashion
5618 Angles: list of angles
5619 HasRefPoint: allows using the reference point
5620 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5621 The User can specify any point as the Reference Point.
5622 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5623 MakeGroups: forces the generation of new groups from existing ones
5624 LinearVariation: forces the computation of rotation angles as linear
5625 variation of the given Angles along path steps
5628 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5629 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5630 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5631 Example: :ref:`tui_extrusion_along_path`
5634 n,e,f = [],theObject,[]
5635 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5636 HasAngles, Angles, LinearVariation,
5637 HasRefPoint, RefPoint, MakeGroups)
5638 if MakeGroups: return gr,er
5641 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5642 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5643 MakeGroups=False, LinearVariation=False):
5645 Generate new elements by extrusion of faces which belong to the object.
5646 The path of extrusion must be a meshed edge.
5649 theObject: the object whose 2D elements should be processed.
5650 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5651 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5652 PathShape: shape (edge) defines the sub-mesh for the path
5653 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5654 HasAngles: allows the shape to be rotated around the path
5655 to get the resulting mesh in a helical fashion
5656 Angles: list of angles
5657 HasRefPoint: allows using the reference point
5658 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5659 The User can specify any point as the Reference Point.
5660 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5661 MakeGroups: forces the generation of new groups from existing ones
5662 LinearVariation: forces the computation of rotation angles as linear
5663 variation of the given Angles along path steps
5666 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5667 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5668 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5669 Example: :ref:`tui_extrusion_along_path`
5672 n,e,f = [],[],theObject
5673 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5674 HasAngles, Angles, LinearVariation,
5675 HasRefPoint, RefPoint, MakeGroups)
5676 if MakeGroups: return gr,er
5679 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5681 Create a symmetrical copy of mesh elements
5684 IDsOfElements: list of elements ids
5685 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5686 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5687 If the *Mirror* is a geom object this parameter is unnecessary
5688 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5689 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5692 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5695 if IDsOfElements == []:
5696 IDsOfElements = self.GetElementsId()
5697 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5698 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5699 theMirrorType = Mirror._mirrorType
5701 self.mesh.SetParameters(Mirror.parameters)
5702 if Copy and MakeGroups:
5703 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5704 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5707 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5709 Create a new mesh by a symmetrical copy of mesh elements
5712 IDsOfElements: the list of elements ids
5713 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5714 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5715 If the *Mirror* is a geom object this parameter is unnecessary
5716 MakeGroups: to generate new groups from existing ones
5717 NewMeshName: a name of the new mesh to create
5720 instance of class :class:`Mesh`
5723 if IDsOfElements == []:
5724 IDsOfElements = self.GetElementsId()
5725 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5726 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5727 theMirrorType = Mirror._mirrorType
5729 self.mesh.SetParameters(Mirror.parameters)
5730 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5731 MakeGroups, NewMeshName)
5732 return Mesh(self.smeshpyD,self.geompyD,mesh)
5734 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5736 Create a symmetrical copy of the object
5739 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5740 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5741 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5742 If the *Mirror* is a geom object this parameter is unnecessary
5743 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5744 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5747 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5750 if ( isinstance( theObject, Mesh )):
5751 theObject = theObject.GetMesh()
5752 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5753 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5754 theMirrorType = Mirror._mirrorType
5756 self.mesh.SetParameters(Mirror.parameters)
5757 if Copy and MakeGroups:
5758 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5759 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5762 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5764 Create a new mesh by a symmetrical copy of the object
5767 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5768 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5769 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5770 If the *Mirror* is a geom object this parameter is unnecessary
5771 MakeGroups: forces the generation of new groups from existing ones
5772 NewMeshName: the name of the new mesh to create
5775 instance of class :class:`Mesh`
5778 if ( isinstance( theObject, Mesh )):
5779 theObject = theObject.GetMesh()
5780 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5781 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5782 theMirrorType = Mirror._mirrorType
5784 self.mesh.SetParameters(Mirror.parameters)
5785 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5786 MakeGroups, NewMeshName)
5787 return Mesh( self.smeshpyD,self.geompyD,mesh )
5789 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5791 Translate the elements
5794 IDsOfElements: list of elements ids
5795 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5796 Copy: allows copying the translated elements
5797 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5800 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5803 if IDsOfElements == []:
5804 IDsOfElements = self.GetElementsId()
5805 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5806 Vector = self.smeshpyD.GetDirStruct(Vector)
5807 if isinstance( Vector, list ):
5808 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5809 self.mesh.SetParameters(Vector.PS.parameters)
5810 if Copy and MakeGroups:
5811 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5812 self.editor.Translate(IDsOfElements, Vector, Copy)
5815 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5817 Create a new mesh of translated elements
5820 IDsOfElements: list of elements ids
5821 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5822 MakeGroups: forces the generation of new groups from existing ones
5823 NewMeshName: the name of the newly created mesh
5826 instance of class :class:`Mesh`
5829 if IDsOfElements == []:
5830 IDsOfElements = self.GetElementsId()
5831 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5832 Vector = self.smeshpyD.GetDirStruct(Vector)
5833 if isinstance( Vector, list ):
5834 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5835 self.mesh.SetParameters(Vector.PS.parameters)
5836 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5837 return Mesh ( self.smeshpyD, self.geompyD, mesh )
5839 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5841 Translate the object
5844 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5845 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5846 Copy: allows copying the translated elements
5847 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5850 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5853 if ( isinstance( theObject, Mesh )):
5854 theObject = theObject.GetMesh()
5855 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5856 Vector = self.smeshpyD.GetDirStruct(Vector)
5857 if isinstance( Vector, list ):
5858 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5859 self.mesh.SetParameters(Vector.PS.parameters)
5860 if Copy and MakeGroups:
5861 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5862 self.editor.TranslateObject(theObject, Vector, Copy)
5865 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5867 Create a new mesh from the translated object
5870 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5871 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5872 MakeGroups: forces the generation of new groups from existing ones
5873 NewMeshName: the name of the newly created mesh
5876 instance of class :class:`Mesh`
5879 if isinstance( theObject, Mesh ):
5880 theObject = theObject.GetMesh()
5881 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5882 Vector = self.smeshpyD.GetDirStruct(Vector)
5883 if isinstance( Vector, list ):
5884 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5885 self.mesh.SetParameters(Vector.PS.parameters)
5886 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5887 return Mesh( self.smeshpyD, self.geompyD, mesh )
5891 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5896 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5897 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5898 theScaleFact: list of 1-3 scale factors for axises
5899 Copy: allows copying the translated elements
5900 MakeGroups: forces the generation of new groups from existing
5904 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5905 empty list otherwise
5907 unRegister = genObjUnRegister()
5908 if ( isinstance( theObject, Mesh )):
5909 theObject = theObject.GetMesh()
5910 if ( isinstance( theObject, list )):
5911 theObject = self.GetIDSource(theObject, SMESH.ALL)
5912 unRegister.set( theObject )
5913 if ( isinstance( thePoint, list )):
5914 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5915 if ( isinstance( theScaleFact, float )):
5916 theScaleFact = [theScaleFact]
5917 if ( isinstance( theScaleFact, int )):
5918 theScaleFact = [ float(theScaleFact)]
5920 self.mesh.SetParameters(thePoint.parameters)
5922 if Copy and MakeGroups:
5923 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5924 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5927 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5929 Create a new mesh from the translated object
5932 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5933 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5934 theScaleFact: list of 1-3 scale factors for axises
5935 MakeGroups: forces the generation of new groups from existing ones
5936 NewMeshName: the name of the newly created mesh
5939 instance of class :class:`Mesh`
5941 unRegister = genObjUnRegister()
5942 if (isinstance(theObject, Mesh)):
5943 theObject = theObject.GetMesh()
5944 if ( isinstance( theObject, list )):
5945 theObject = self.GetIDSource(theObject,SMESH.ALL)
5946 unRegister.set( theObject )
5947 if ( isinstance( thePoint, list )):
5948 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5949 if ( isinstance( theScaleFact, float )):
5950 theScaleFact = [theScaleFact]
5951 if ( isinstance( theScaleFact, int )):
5952 theScaleFact = [ float(theScaleFact)]
5954 self.mesh.SetParameters(thePoint.parameters)
5955 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
5956 MakeGroups, NewMeshName)
5957 return Mesh( self.smeshpyD, self.geompyD, mesh )
5961 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
5966 IDsOfElements: list of elements ids
5967 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5968 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5969 Copy: allows copying the rotated elements
5970 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5973 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5977 if IDsOfElements == []:
5978 IDsOfElements = self.GetElementsId()
5979 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
5980 Axis = self.smeshpyD.GetAxisStruct(Axis)
5981 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
5982 Parameters = Axis.parameters + var_separator + Parameters
5983 self.mesh.SetParameters(Parameters)
5984 if Copy and MakeGroups:
5985 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
5986 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
5989 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
5991 Create a new mesh of rotated elements
5994 IDsOfElements: list of element ids
5995 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
5996 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
5997 MakeGroups: forces the generation of new groups from existing ones
5998 NewMeshName: the name of the newly created mesh
6001 instance of class :class:`Mesh`
6004 if IDsOfElements == []:
6005 IDsOfElements = self.GetElementsId()
6006 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6007 Axis = self.smeshpyD.GetAxisStruct(Axis)
6008 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6009 Parameters = Axis.parameters + var_separator + Parameters
6010 self.mesh.SetParameters(Parameters)
6011 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6012 MakeGroups, NewMeshName)
6013 return Mesh( self.smeshpyD, self.geompyD, mesh )
6015 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6020 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6021 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6022 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6023 Copy: allows copying the rotated elements
6024 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6027 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6030 if (isinstance(theObject, Mesh)):
6031 theObject = theObject.GetMesh()
6032 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6033 Axis = self.smeshpyD.GetAxisStruct(Axis)
6034 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6035 Parameters = Axis.parameters + ":" + Parameters
6036 self.mesh.SetParameters(Parameters)
6037 if Copy and MakeGroups:
6038 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6039 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6042 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6044 Create a new mesh from the rotated object
6047 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6048 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6049 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6050 MakeGroups: forces the generation of new groups from existing ones
6051 NewMeshName: the name of the newly created mesh
6054 instance of class :class:`Mesh`
6057 if (isinstance( theObject, Mesh )):
6058 theObject = theObject.GetMesh()
6059 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6060 Axis = self.smeshpyD.GetAxisStruct(Axis)
6061 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6062 Parameters = Axis.parameters + ":" + Parameters
6063 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6064 MakeGroups, NewMeshName)
6065 self.mesh.SetParameters(Parameters)
6066 return Mesh( self.smeshpyD, self.geompyD, mesh )
6068 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6070 Create an offset mesh from the given 2D object
6073 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6074 theValue (float): signed offset size
6075 MakeGroups (boolean): forces the generation of new groups from existing ones
6076 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6077 False means to remove original elements.
6078 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6081 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6084 if isinstance( theObject, Mesh ):
6085 theObject = theObject.GetMesh()
6086 theValue,Parameters,hasVars = ParseParameters(Value)
6087 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6088 self.mesh.SetParameters(Parameters)
6089 # if mesh_groups[0]:
6090 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6093 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6095 Find groups of adjacent nodes within Tolerance.
6098 Tolerance (float): the value of tolerance
6099 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6100 corner and medium nodes in separate groups thus preventing
6101 their further merge.
6104 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6107 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6109 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6110 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6112 Find groups of adjacent nodes within Tolerance.
6115 Tolerance: the value of tolerance
6116 SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6117 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6118 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6119 corner and medium nodes in separate groups thus preventing
6120 their further merge.
6123 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6126 unRegister = genObjUnRegister()
6127 if (isinstance( SubMeshOrGroup, Mesh )):
6128 SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6129 if not isinstance( exceptNodes, list ):
6130 exceptNodes = [ exceptNodes ]
6131 if exceptNodes and isinstance( exceptNodes[0], int ):
6132 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6133 unRegister.set( exceptNodes )
6134 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6135 exceptNodes, SeparateCornerAndMediumNodes)
6137 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6142 GroupsOfNodes: a list of groups of nodes IDs for merging.
6143 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6144 in all elements and groups by nodes 1 and 25 correspondingly
6145 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6146 If *NodesToKeep* does not include a node to keep for some group to merge,
6147 then the first node in the group is kept.
6148 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6151 # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6152 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6154 def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6156 Find the elements built on the same nodes.
6159 MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6162 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6165 if not MeshOrSubMeshOrGroup:
6166 MeshOrSubMeshOrGroup=self.mesh
6167 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6168 MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6169 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6171 def MergeElements(self, GroupsOfElementsID):
6173 Merge elements in each given group.
6176 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6177 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6178 replaced in all groups by elements 1 and 25)
6181 self.editor.MergeElements(GroupsOfElementsID)
6183 def MergeEqualElements(self):
6185 Leave one element and remove all other elements built on the same nodes.
6188 self.editor.MergeEqualElements()
6190 def FindFreeBorders(self, ClosedOnly=True):
6192 Returns all or only closed free borders
6195 list of SMESH.FreeBorder's
6198 return self.editor.FindFreeBorders( ClosedOnly )
6200 def FillHole(self, holeNodes, groupName=""):
6202 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6205 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6206 must describe all sequential nodes of the hole border. The first and the last
6207 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6208 groupName (string): name of a group to add new faces
6210 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6214 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6215 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6216 if not isinstance( holeNodes, SMESH.FreeBorder ):
6217 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6218 self.editor.FillHole( holeNodes, groupName )
6220 def FindCoincidentFreeBorders (self, tolerance=0.):
6222 Return groups of FreeBorder's coincident within the given tolerance.
6225 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6226 size of elements adjacent to free borders being compared is used.
6229 SMESH.CoincidentFreeBorders structure
6232 return self.editor.FindCoincidentFreeBorders( tolerance )
6234 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6236 Sew FreeBorder's of each group
6239 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6240 where each enclosed list contains node IDs of a group of coincident free
6241 borders such that each consequent triple of IDs within a group describes
6242 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6243 last node of a border.
6244 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6245 groups of coincident free borders, each group including two borders.
6246 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6247 polygons if a node of opposite border falls on a face edge, else such
6248 faces are split into several ones.
6249 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6250 polyhedra if a node of opposite border falls on a volume edge, else such
6251 volumes, if any, remain intact and the mesh becomes non-conformal.
6254 a number of successfully sewed groups
6257 if freeBorders and isinstance( freeBorders, list ):
6258 # construct SMESH.CoincidentFreeBorders
6259 if isinstance( freeBorders[0], int ):
6260 freeBorders = [freeBorders]
6262 coincidentGroups = []
6263 for nodeList in freeBorders:
6264 if not nodeList or len( nodeList ) % 3:
6265 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6268 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6269 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6270 nodeList = nodeList[3:]
6272 coincidentGroups.append( group )
6274 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6276 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6278 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6279 FirstNodeID2, SecondNodeID2, LastNodeID2,
6280 CreatePolygons, CreatePolyedrs):
6285 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6288 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6289 FirstNodeID2, SecondNodeID2, LastNodeID2,
6290 CreatePolygons, CreatePolyedrs)
6292 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6293 FirstNodeID2, SecondNodeID2):
6295 Sew conform free borders
6298 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6301 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6302 FirstNodeID2, SecondNodeID2)
6304 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6305 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6310 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6313 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6314 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6316 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6317 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6318 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6320 Sew two sides of a mesh. The nodes belonging to Side1 are
6321 merged with the nodes of elements of Side2.
6322 The number of elements in theSide1 and in theSide2 must be
6323 equal and they should have similar nodal connectivity.
6324 The nodes to merge should belong to side borders and
6325 the first node should be linked to the second.
6328 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6331 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6332 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6333 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6335 def ChangeElemNodes(self, ide, newIDs):
6337 Set new nodes for the given element.
6344 False if the number of nodes does not correspond to the type of element
6347 return self.editor.ChangeElemNodes(ide, newIDs)
6349 def GetLastCreatedNodes(self):
6351 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6352 created, this method return the list of their IDs.
6353 If new nodes were not created - return empty list
6356 the list of integer values (can be empty)
6359 return self.editor.GetLastCreatedNodes()
6361 def GetLastCreatedElems(self):
6363 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6364 created this method return the list of their IDs.
6365 If new elements were not created - return empty list
6368 the list of integer values (can be empty)
6371 return self.editor.GetLastCreatedElems()
6373 def ClearLastCreated(self):
6375 Forget what nodes and elements were created by the last mesh edition operation
6378 self.editor.ClearLastCreated()
6380 def DoubleElements(self, theElements, theGroupName=""):
6382 Create duplicates of given elements, i.e. create new elements based on the
6383 same nodes as the given ones.
6386 theElements: container of elements to duplicate. It can be a
6387 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6388 or a list of element IDs. If *theElements* is
6389 a :class:`Mesh`, elements of highest dimension are duplicated
6390 theGroupName: a name of group to contain the generated elements.
6391 If a group with such a name already exists, the new elements
6392 are added to the existing group, else a new group is created.
6393 If *theGroupName* is empty, new elements are not added
6397 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6398 None if *theGroupName* == "".
6401 unRegister = genObjUnRegister()
6402 if isinstance( theElements, Mesh ):
6403 theElements = theElements.mesh
6404 elif isinstance( theElements, list ):
6405 theElements = self.GetIDSource( theElements, SMESH.ALL )
6406 unRegister.set( theElements )
6407 return self.editor.DoubleElements(theElements, theGroupName)
6409 def DoubleNodes(self, theNodes, theModifiedElems):
6411 Create a hole in a mesh by doubling the nodes of some particular elements
6414 theNodes: IDs of nodes to be doubled
6415 theModifiedElems: IDs of elements to be updated by the new (doubled)
6416 nodes. If list of element identifiers is empty then nodes are doubled but
6417 they not assigned to elements
6420 True if operation has been completed successfully, False otherwise
6423 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6425 def DoubleNode(self, theNodeId, theModifiedElems):
6427 Create a hole in a mesh by doubling the nodes of some particular elements.
6428 This method provided for convenience works as :meth:`DoubleNodes`.
6431 theNodeId: IDs of node to double
6432 theModifiedElems: IDs of elements to update
6435 True if operation has been completed successfully, False otherwise
6438 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6440 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6442 Create a hole in a mesh by doubling the nodes of some particular elements.
6443 This method provided for convenience works as :meth:`DoubleNodes`.
6446 theNodes: group of nodes to double.
6447 theModifiedElems: group of elements to update.
6448 theMakeGroup: forces the generation of a group containing new nodes.
6451 True or a created group if operation has been completed successfully,
6452 False or None otherwise
6456 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6457 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6459 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6461 Create a hole in a mesh by doubling the nodes of some particular elements.
6462 This method provided for convenience works as :meth:`DoubleNodes`.
6465 theNodes: list of groups of nodes to double.
6466 theModifiedElems: list of groups of elements to update.
6467 theMakeGroup: forces the generation of a group containing new nodes.
6470 True if operation has been completed successfully, False otherwise
6474 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6475 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6477 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6479 Create a hole in a mesh by doubling the nodes of some particular elements
6482 theElems: the list of elements (edges or faces) to replicate.
6483 The nodes for duplication could be found from these elements
6484 theNodesNot: list of nodes NOT to replicate
6485 theAffectedElems: the list of elements (cells and edges) to which the
6486 replicated nodes should be associated to
6489 True if operation has been completed successfully, False otherwise
6492 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6494 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6496 Create a hole in a mesh by doubling the nodes of some particular elements
6499 theElems: the list of elements (edges or faces) to replicate.
6500 The nodes for duplication could be found from these elements
6501 theNodesNot: list of nodes NOT to replicate
6502 theShape: shape to detect affected elements (element which geometric center
6503 located on or inside shape).
6504 The replicated nodes should be associated to affected elements.
6507 True if operation has been completed successfully, False otherwise
6510 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6512 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6513 theMakeGroup=False, theMakeNodeGroup=False):
6515 Create a hole in a mesh by doubling the nodes of some particular elements.
6516 This method provided for convenience works as :meth:`DoubleNodes`.
6519 theElems: group of of elements (edges or faces) to replicate.
6520 theNodesNot: group of nodes NOT to replicate.
6521 theAffectedElems: group of elements to which the replicated nodes
6522 should be associated to.
6523 theMakeGroup: forces the generation of a group containing new elements.
6524 theMakeNodeGroup: forces the generation of a group containing new nodes.
6527 True or created groups (one or two) if operation has been completed successfully,
6528 False or None otherwise
6531 if theMakeGroup or theMakeNodeGroup:
6532 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6534 theMakeGroup, theMakeNodeGroup)
6535 if theMakeGroup and theMakeNodeGroup:
6538 return twoGroups[ int(theMakeNodeGroup) ]
6539 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6541 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6543 Create a hole in a mesh by doubling the nodes of some particular elements.
6544 This method provided for convenience works as :meth:`DoubleNodes`.
6547 theElems: group of of elements (edges or faces) to replicate
6548 theNodesNot: group of nodes not to replicate
6549 theShape: shape to detect affected elements (element which geometric center
6550 located on or inside shape).
6551 The replicated nodes should be associated to affected elements
6554 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6556 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6557 theMakeGroup=False, theMakeNodeGroup=False):
6559 Create a hole in a mesh by doubling the nodes of some particular elements.
6560 This method provided for convenience works as :meth:`DoubleNodes`.
6563 theElems: list of groups of elements (edges or faces) to replicate
6564 theNodesNot: list of groups of nodes NOT to replicate
6565 theAffectedElems: group of elements to which the replicated nodes
6566 should be associated to
6567 theMakeGroup: forces generation of a group containing new elements.
6568 theMakeNodeGroup: forces generation of a group containing new nodes
6571 True or created groups (one or two) if operation has been completed successfully,
6572 False or None otherwise
6575 if theMakeGroup or theMakeNodeGroup:
6576 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6578 theMakeGroup, theMakeNodeGroup)
6579 if theMakeGroup and theMakeNodeGroup:
6582 return twoGroups[ int(theMakeNodeGroup) ]
6583 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6585 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6587 Create a hole in a mesh by doubling the nodes of some particular elements.
6588 This method provided for convenience works as :meth:`DoubleNodes`.
6591 theElems: list of groups of elements (edges or faces) to replicate
6592 theNodesNot: list of groups of nodes NOT to replicate
6593 theShape: shape to detect affected elements (element which geometric center
6594 located on or inside shape).
6595 The replicated nodes should be associated to affected elements
6598 True if operation has been completed successfully, False otherwise
6601 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6603 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6605 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6606 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6609 theElems: list of groups of nodes or elements (edges or faces) to replicate
6610 theNodesNot: list of groups of nodes NOT to replicate
6611 theShape: shape to detect affected elements (element which geometric center
6612 located on or inside shape).
6613 The replicated nodes should be associated to affected elements
6616 groups of affected elements in order: volumes, faces, edges
6619 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6621 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6624 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6625 The list of groups must describe a partition of the mesh volumes.
6626 The nodes of the internal faces at the boundaries of the groups are doubled.
6627 In option, the internal faces are replaced by flat elements.
6628 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6631 theDomains: list of groups of volumes
6632 createJointElems: if True, create the elements
6633 onAllBoundaries: if True, the nodes and elements are also created on
6634 the boundary between *theDomains* and the rest mesh
6637 True if operation has been completed successfully, False otherwise
6640 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6642 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6644 Double nodes on some external faces and create flat elements.
6645 Flat elements are mainly used by some types of mechanic calculations.
6647 Each group of the list must be constituted of faces.
6648 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6651 theGroupsOfFaces: list of groups of faces
6654 True if operation has been completed successfully, False otherwise
6657 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6659 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6661 Identify all the elements around a geom shape, get the faces delimiting the hole
6663 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6665 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6667 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6668 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6669 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6670 If there are several paths connecting a pair of points, the shortest path is
6671 selected by the module. Position of the cutting plane is defined by the two
6672 points and an optional vector lying on the plane specified by a PolySegment.
6673 By default the vector is defined by Mesh module as following. A middle point
6674 of the two given points is computed. The middle point is projected to the mesh.
6675 The vector goes from the middle point to the projection point. In case of planar
6676 mesh, the vector is normal to the mesh.
6678 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6681 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6682 groupName: optional name of a group where created mesh segments will be added.
6685 editor = self.editor
6687 editor = self.mesh.GetMeshEditPreviewer()
6688 segmentsRes = editor.MakePolyLine( segments, groupName )
6689 for i, seg in enumerate( segmentsRes ):
6690 segments[i].vector = seg.vector
6692 return editor.GetPreviewData()
6695 def GetFunctor(self, funcType ):
6697 Return a cached numerical functor by its type.
6700 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6701 Note that not all items correspond to numerical functors.
6704 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6707 fn = self.functors[ funcType._v ]
6709 fn = self.smeshpyD.GetFunctor(funcType)
6710 fn.SetMesh(self.mesh)
6711 self.functors[ funcType._v ] = fn
6714 def FunctorValue(self, funcType, elemId, isElem=True):
6716 Return value of a functor for a given element
6719 funcType: an item of :class:`SMESH.FunctorType` enum.
6720 elemId: element or node ID
6721 isElem: *elemId* is ID of element or node
6724 the functor value or zero in case of invalid arguments
6727 fn = self.GetFunctor( funcType )
6728 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6729 val = fn.GetValue(elemId)
6734 def GetLength(self, elemId=None):
6736 Get length of 1D element or sum of lengths of all 1D mesh elements
6739 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6742 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6747 length = self.smeshpyD.GetLength(self)
6749 length = self.FunctorValue(SMESH.FT_Length, elemId)
6752 def GetArea(self, elemId=None):
6754 Get area of 2D element or sum of areas of all 2D mesh elements
6755 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6758 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6763 area = self.smeshpyD.GetArea(self)
6765 area = self.FunctorValue(SMESH.FT_Area, elemId)
6768 def GetVolume(self, elemId=None):
6770 Get volume of 3D element or sum of volumes of all 3D mesh elements
6773 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6776 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6781 volume = self.smeshpyD.GetVolume(self)
6783 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6786 def GetMaxElementLength(self, elemId):
6788 Get maximum element length.
6791 elemId: mesh element ID
6794 element's maximum length value
6797 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6798 ftype = SMESH.FT_MaxElementLength3D
6800 ftype = SMESH.FT_MaxElementLength2D
6801 return self.FunctorValue(ftype, elemId)
6803 def GetAspectRatio(self, elemId):
6805 Get aspect ratio of 2D or 3D element.
6808 elemId: mesh element ID
6811 element's aspect ratio value
6814 if self.GetElementType(elemId, True) == SMESH.VOLUME:
6815 ftype = SMESH.FT_AspectRatio3D
6817 ftype = SMESH.FT_AspectRatio
6818 return self.FunctorValue(ftype, elemId)
6820 def GetWarping(self, elemId):
6822 Get warping angle of 2D element.
6825 elemId: mesh element ID
6828 element's warping angle value
6831 return self.FunctorValue(SMESH.FT_Warping, elemId)
6833 def GetMinimumAngle(self, elemId):
6835 Get minimum angle of 2D element.
6838 elemId: mesh element ID
6841 element's minimum angle value
6844 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6846 def GetTaper(self, elemId):
6848 Get taper of 2D element.
6851 elemId: mesh element ID
6854 element's taper value
6857 return self.FunctorValue(SMESH.FT_Taper, elemId)
6859 def GetSkew(self, elemId):
6861 Get skew of 2D element.
6864 elemId: mesh element ID
6867 element's skew value
6870 return self.FunctorValue(SMESH.FT_Skew, elemId)
6872 def GetMinMax(self, funType, meshPart=None):
6874 Return minimal and maximal value of a given functor.
6877 funType (SMESH.FunctorType): a functor type.
6878 Note that not all items of :class:`SMESH.FunctorType` corresponds
6879 to numerical functors.
6880 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6886 unRegister = genObjUnRegister()
6887 if isinstance( meshPart, list ):
6888 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6889 unRegister.set( meshPart )
6890 if isinstance( meshPart, Mesh ):
6891 meshPart = meshPart.mesh
6892 fun = self.GetFunctor( funType )
6895 if hasattr( meshPart, "SetMesh" ):
6896 meshPart.SetMesh( self.mesh ) # set mesh to filter
6897 hist = fun.GetLocalHistogram( 1, False, meshPart )
6899 hist = fun.GetHistogram( 1, False )
6901 return hist[0].min, hist[0].max
6904 pass # end of Mesh class
6907 class meshProxy(SMESH._objref_SMESH_Mesh):
6909 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6910 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6912 def __init__(self,*args):
6913 SMESH._objref_SMESH_Mesh.__init__(self,*args)
6914 def __deepcopy__(self, memo=None):
6915 new = self.__class__(self)
6917 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6918 if len( args ) == 3:
6919 args += SMESH.ALL_NODES, True
6920 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
6921 def ExportToMEDX(self, *args): # function removed
6922 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
6923 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6924 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
6925 def ExportToMED(self, *args): # function removed
6926 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
6927 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6929 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6931 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6932 def ExportPartToMED(self, *args): # 'version' parameter removed
6933 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6934 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
6935 def ExportMED(self, *args): # signature of method changed
6936 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
6938 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
6940 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
6942 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
6945 class submeshProxy(SMESH._objref_SMESH_subMesh):
6948 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
6950 def __init__(self,*args):
6951 SMESH._objref_SMESH_subMesh.__init__(self,*args)
6953 def __deepcopy__(self, memo=None):
6954 new = self.__class__(self)
6957 def Compute(self,refresh=False):
6959 Compute the sub-mesh and return the status of the computation
6962 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
6967 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
6968 :meth:`smeshBuilder.Mesh.GetSubMesh`.
6972 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
6974 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
6976 if salome.sg.hasDesktop():
6977 if refresh: salome.sg.updateObjBrowser()
6982 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
6985 class meshEditor(SMESH._objref_SMESH_MeshEditor):
6987 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
6988 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
6991 def __init__(self,*args):
6992 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
6994 def __getattr__(self, name ): # method called if an attribute not found
6995 if not self.mesh: # look for name() method in Mesh class
6996 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
6997 if hasattr( self.mesh, name ):
6998 return getattr( self.mesh, name )
6999 if name == "ExtrusionAlongPathObjX":
7000 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7001 print("meshEditor: attribute '%s' NOT FOUND" % name)
7003 def __deepcopy__(self, memo=None):
7004 new = self.__class__(self)
7006 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7007 if len( args ) == 1: args += False,
7008 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7009 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7010 if len( args ) == 2: args += False,
7011 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7012 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7013 if len( args ) == 1:
7014 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7015 NodesToKeep = args[1]
7016 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7017 unRegister = genObjUnRegister()
7019 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7020 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7021 if not isinstance( NodesToKeep, list ):
7022 NodesToKeep = [ NodesToKeep ]
7023 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7025 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7027 class Pattern(SMESH._objref_SMESH_Pattern):
7029 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7030 variables in some methods
7033 def LoadFromFile(self, patternTextOrFile ):
7034 text = patternTextOrFile
7035 if os.path.exists( text ):
7036 text = open( patternTextOrFile ).read()
7038 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7040 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7041 decrFun = lambda i: i-1
7042 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7043 theMesh.SetParameters(Parameters)
7044 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7046 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7047 decrFun = lambda i: i-1
7048 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7049 theMesh.SetParameters(Parameters)
7050 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7052 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7053 if isinstance( mesh, Mesh ):
7054 mesh = mesh.GetMesh()
7055 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7057 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7059 Registering the new proxy for Pattern
7064 Private class used to bind methods creating algorithms to the class Mesh
7067 def __init__(self, method):
7069 self.defaultAlgoType = ""
7070 self.algoTypeToClass = {}
7071 self.method = method
7073 def add(self, algoClass):
7075 Store a python class of algorithm
7077 if inspect.isclass(algoClass) and \
7078 hasattr( algoClass, "algoType"):
7079 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7080 if not self.defaultAlgoType and \
7081 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7082 self.defaultAlgoType = algoClass.algoType
7083 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7085 def copy(self, mesh):
7087 Create a copy of self and assign mesh to the copy
7090 other = algoCreator( self.method )
7091 other.defaultAlgoType = self.defaultAlgoType
7092 other.algoTypeToClass = self.algoTypeToClass
7096 def __call__(self,algo="",geom=0,*args):
7098 Create an instance of algorithm
7102 if isinstance( algo, str ):
7104 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7105 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7110 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7112 elif not algoType and isinstance( geom, str ):
7117 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7119 elif isinstance( arg, str ) and not algoType:
7122 import traceback, sys
7123 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7124 sys.stderr.write( msg + '\n' )
7125 tb = traceback.extract_stack(None,2)
7126 traceback.print_list( [tb[0]] )
7128 algoType = self.defaultAlgoType
7129 if not algoType and self.algoTypeToClass:
7130 algoType = sorted( self.algoTypeToClass.keys() )[0]
7131 if algoType in self.algoTypeToClass:
7132 #print("Create algo",algoType)
7133 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7134 raise RuntimeError( "No class found for algo type %s" % algoType)
7137 class hypMethodWrapper:
7139 Private class used to substitute and store variable parameters of hypotheses.
7142 def __init__(self, hyp, method):
7144 self.method = method
7145 #print("REBIND:", method.__name__)
7148 def __call__(self,*args):
7150 call a method of hypothesis with calling SetVarParameter() before
7154 return self.method( self.hyp, *args ) # hypothesis method with no args
7156 #print("MethWrapper.__call__", self.method.__name__, args)
7158 parsed = ParseParameters(*args) # replace variables with their values
7159 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7160 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7161 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7162 # maybe there is a replaced string arg which is not variable
7163 result = self.method( self.hyp, *args )
7164 except ValueError as detail: # raised by ParseParameters()
7166 result = self.method( self.hyp, *args )
7167 except omniORB.CORBA.BAD_PARAM:
7168 raise ValueError(detail) # wrong variable name
7173 class genObjUnRegister:
7175 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7178 def __init__(self, genObj=None):
7179 self.genObjList = []
7183 def set(self, genObj):
7184 "Store one or a list of of SALOME.GenericObj'es"
7185 if isinstance( genObj, list ):
7186 self.genObjList.extend( genObj )
7188 self.genObjList.append( genObj )
7192 for genObj in self.genObjList:
7193 if genObj and hasattr( genObj, "UnRegister" ):
7196 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7198 Bind methods creating mesher plug-ins to the Mesh class
7201 # print("pluginName: ", pluginName)
7202 pluginBuilderName = pluginName + "Builder"
7204 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7205 except Exception as e:
7206 from salome_utils import verbose
7207 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7209 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7210 plugin = eval( pluginBuilderName )
7211 # print(" plugin:" , str(plugin))
7213 # add methods creating algorithms to Mesh
7214 for k in dir( plugin ):
7215 if k[0] == '_': continue
7216 algo = getattr( plugin, k )
7217 #print(" algo:", str(algo))
7218 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7219 #print(" meshMethod:" , str(algo.meshMethod))
7220 if not hasattr( Mesh, algo.meshMethod ):
7221 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7223 _mmethod = getattr( Mesh, algo.meshMethod )
7224 if hasattr( _mmethod, "add" ):