1 # Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def EnumToLong(self,theItem):
480 Return a long value from enumeration
485 def ColorToString(self,c):
487 Convert SALOMEDS.Color to string.
488 To be used with filters.
491 c: color value (SALOMEDS.Color)
494 a string representation of the color.
498 if isinstance(c, SALOMEDS.Color):
499 val = "%s;%s;%s" % (c.R, c.G, c.B)
500 elif isinstance(c, str):
503 raise ValueError("Color value should be of string or SALOMEDS.Color type")
506 def GetPointStruct(self,theVertex):
508 Get :class:`SMESH.PointStruct` from vertex
511 theVertex (GEOM.GEOM_Object): vertex
514 :class:`SMESH.PointStruct`
517 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518 return PointStruct(x,y,z)
520 def GetDirStruct(self,theVector):
522 Get :class:`SMESH.DirStruct` from vector
525 theVector (GEOM.GEOM_Object): vector
528 :class:`SMESH.DirStruct`
531 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532 if(len(vertices) != 2):
533 print("Error: vector object is incorrect.")
535 p1 = self.geompyD.PointCoordinates(vertices[0])
536 p2 = self.geompyD.PointCoordinates(vertices[1])
537 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538 dirst = DirStruct(pnt)
541 def MakeDirStruct(self,x,y,z):
543 Make :class:`SMESH.DirStruct` from a triplet of floats
546 x,y,z (float): vector components
549 :class:`SMESH.DirStruct`
552 pnt = PointStruct(x,y,z)
553 return DirStruct(pnt)
555 def GetAxisStruct(self,theObj):
557 Get :class:`SMESH.AxisStruct` from a geometrical object
560 theObj (GEOM.GEOM_Object): line or plane
563 :class:`SMESH.AxisStruct`
566 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
569 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571 vertex1 = self.geompyD.PointCoordinates(vertex1)
572 vertex2 = self.geompyD.PointCoordinates(vertex2)
573 vertex3 = self.geompyD.PointCoordinates(vertex3)
574 vertex4 = self.geompyD.PointCoordinates(vertex4)
575 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577 normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
578 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580 elif len(edges) == 1:
581 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582 p1 = self.geompyD.PointCoordinates( vertex1 )
583 p2 = self.geompyD.PointCoordinates( vertex2 )
584 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586 elif theObj.GetShapeType() == GEOM.VERTEX:
587 x,y,z = self.geompyD.PointCoordinates( theObj )
588 axis = AxisStruct( x,y,z, 1,0,0,)
589 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
592 # From SMESH_Gen interface:
593 # ------------------------
595 def SetName(self, obj, name):
597 Set the given name to an object
600 obj: the object to rename
601 name: a new object name
604 if isinstance( obj, Mesh ):
606 elif isinstance( obj, Mesh_Algorithm ):
607 obj = obj.GetAlgorithm()
608 ior = salome.orb.object_to_string(obj)
609 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
611 def SetEmbeddedMode( self,theMode ):
616 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
618 def IsEmbeddedMode(self):
623 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
625 def UpdateStudy( self, geompyD = None ):
627 Update the current study. Calling UpdateStudy() allows to
628 update meshes at switching GEOM->SMESH
632 from salome.geom import geomBuilder
633 geompyD = geomBuilder.geom
635 geompyD = geomBuilder.New()
638 self.SetGeomEngine(geompyD)
639 SMESH._objref_SMESH_Gen.UpdateStudy(self)
640 sb = salome.myStudy.NewBuilder()
641 sc = salome.myStudy.FindComponent("SMESH")
643 sb.LoadWith(sc, self)
646 def SetEnablePublish( self, theIsEnablePublish ):
648 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649 switch **off** publishing in the Study of mesh objects.
651 #self.SetEnablePublish(theIsEnablePublish)
652 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
654 notebook = salome_notebook.NoteBook( theIsEnablePublish )
657 def CreateMeshesFromUNV( self,theFileName ):
659 Create a Mesh object importing data from the given UNV file
662 an instance of class :class:`Mesh`
665 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
669 def CreateMeshesFromMED( self,theFileName ):
671 Create a Mesh object(s) importing data from the given MED file
674 a tuple ( list of class :class:`Mesh` instances,
675 :class:`SMESH.DriverMED_ReadStatus` )
678 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680 return aMeshes, aStatus
682 def CreateMeshesFromSAUV( self,theFileName ):
684 Create a Mesh object(s) importing data from the given SAUV file
687 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
690 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692 return aMeshes, aStatus
694 def CreateMeshesFromSTL( self, theFileName ):
696 Create a Mesh object importing data from the given STL file
699 an instance of class :class:`Mesh`
702 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
706 def CreateMeshesFromCGNS( self, theFileName ):
708 Create Mesh objects importing data from the given CGNS file
711 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
714 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716 return aMeshes, aStatus
718 def CreateMeshesFromGMF( self, theFileName ):
720 Create a Mesh object importing data from the given GMF file.
721 GMF files must have .mesh extension for the ASCII format and .meshb for
725 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
728 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
731 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732 return Mesh(self, self.geompyD, aSmeshMesh), error
734 def Concatenate( self, meshes, uniteIdenticalGroups,
735 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736 name = "", meshToAppendTo = None):
738 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
739 All groups of input meshes will be present in the new mesh.
742 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744 mergeNodesAndElements: if True, equal nodes and elements are merged
745 mergeTolerance: tolerance for merging nodes
746 allGroups: forces creation of groups corresponding to every input mesh
747 name: name of a new mesh
748 meshToAppendTo: a mesh to append all given meshes
751 an instance of class :class:`Mesh`
757 if not meshes: return None
758 if not isinstance( meshes, list ):
760 for i,m in enumerate( meshes ):
761 if isinstance( m, Mesh ):
762 meshes[i] = m.GetMesh()
763 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
764 if hasattr(meshes[0], "SetParameters"):
765 meshes[0].SetParameters( Parameters )
767 meshes[0].GetMesh().SetParameters( Parameters )
768 if isinstance( meshToAppendTo, Mesh ):
769 meshToAppendTo = meshToAppendTo.GetMesh()
771 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
772 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
773 mergeTolerance,meshToAppendTo )
775 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
776 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
777 mergeTolerance,meshToAppendTo )
779 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
782 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
784 Create a mesh by copying a part of another mesh.
787 meshPart: a part of mesh to copy, either
788 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
789 To copy nodes or elements not forming any mesh object,
790 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
791 meshName: a name of the new mesh
792 toCopyGroups: to create in the new mesh groups the copied elements belongs to
793 toKeepIDs: to preserve order of the copied elements or not
796 an instance of class :class:`Mesh`
799 if isinstance( meshPart, Mesh ):
800 meshPart = meshPart.GetMesh()
801 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
802 return Mesh(self, self.geompyD, mesh)
804 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
805 toReuseHypotheses=True, toCopyElements=True):
807 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
808 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
809 To facilitate and speed up the operation, consider using
810 "Set presentation parameters and sub-shapes from arguments" option in
811 a dialog of geometrical operation used to create the new geometry.
814 sourceMesh: the mesh to copy definition of.
815 newGeom: the new geometry.
816 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
817 toCopyGroups: to create groups in the new mesh.
818 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
819 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
822 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
823 *invalidEntries* are study entries of objects whose
824 counterparts are not found in the *newGeom*, followed by entries
825 of mesh sub-objects that are invalid because they depend on a not found
828 if isinstance( sourceMesh, Mesh ):
829 sourceMesh = sourceMesh.GetMesh()
831 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
832 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
836 return ( ok, Mesh(self, self.geompyD, newMesh),
837 newGroups, newSubMeshes, newHypotheses, invalidEntries )
839 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
841 Return IDs of sub-shapes
844 theMainObject (GEOM.GEOM_Object): a shape
845 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
847 the list of integer values
850 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
852 def GetPattern(self):
854 Create a pattern mapper.
857 an instance of :class:`SMESH.SMESH_Pattern`
859 :ref:`Example of Patterns usage <tui_pattern_mapping>`
862 return SMESH._objref_SMESH_Gen.GetPattern(self)
864 def SetBoundaryBoxSegmentation(self, nbSegments):
866 Set number of segments per diagonal of boundary box of geometry, by which
867 default segment length of appropriate 1D hypotheses is defined in GUI.
871 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
873 # Filtering. Auxiliary functions:
874 # ------------------------------
876 def GetEmptyCriterion(self):
878 Create an empty criterion
881 :class:`SMESH.Filter.Criterion`
884 Type = self.EnumToLong(FT_Undefined)
885 Compare = self.EnumToLong(FT_Undefined)
889 UnaryOp = self.EnumToLong(FT_Undefined)
890 BinaryOp = self.EnumToLong(FT_Undefined)
893 Precision = -1 ##@1e-07
894 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
895 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
897 def GetCriterion(self,elementType,
899 Compare = FT_EqualTo,
901 UnaryOp=FT_Undefined,
902 BinaryOp=FT_Undefined,
905 Create a criterion by the given parameters
906 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
909 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
910 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
911 Note that the items starting from FT_LessThan are not suitable for *CritType*.
912 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
913 Threshold: the threshold value (range of ids as string, shape, numeric)
914 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
915 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
917 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
918 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
921 :class:`SMESH.Filter.Criterion`
923 Example: :ref:`combining_filters`
926 if not CritType in SMESH.FunctorType._items:
927 raise TypeError("CritType should be of SMESH.FunctorType")
928 aCriterion = self.GetEmptyCriterion()
929 aCriterion.TypeOfElement = elementType
930 aCriterion.Type = self.EnumToLong(CritType)
931 aCriterion.Tolerance = Tolerance
933 aThreshold = Threshold
935 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
936 aCriterion.Compare = self.EnumToLong(Compare)
937 elif Compare == "=" or Compare == "==":
938 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
940 aCriterion.Compare = self.EnumToLong(FT_LessThan)
942 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
943 elif Compare != FT_Undefined:
944 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
947 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
948 FT_BelongToCylinder, FT_LyingOnGeom]:
949 # Check that Threshold is GEOM object
950 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
951 aCriterion.ThresholdStr = GetName(aThreshold)
952 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
953 if not aCriterion.ThresholdID:
954 name = aCriterion.ThresholdStr
956 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
957 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
958 # or a name of GEOM object
959 elif isinstance( aThreshold, str ):
960 aCriterion.ThresholdStr = aThreshold
962 raise TypeError("The Threshold should be a shape.")
963 if isinstance(UnaryOp,float):
964 aCriterion.Tolerance = UnaryOp
965 UnaryOp = FT_Undefined
967 elif CritType == FT_BelongToMeshGroup:
968 # Check that Threshold is a group
969 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
970 if aThreshold.GetType() != elementType:
971 raise ValueError("Group type mismatches Element type")
972 aCriterion.ThresholdStr = aThreshold.GetName()
973 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
974 study = salome.myStudy
976 so = study.FindObjectIOR( aCriterion.ThresholdID )
980 aCriterion.ThresholdID = entry
982 raise TypeError("The Threshold should be a Mesh Group")
983 elif CritType == FT_RangeOfIds:
984 # Check that Threshold is string
985 if isinstance(aThreshold, str):
986 aCriterion.ThresholdStr = aThreshold
988 raise TypeError("The Threshold should be a string.")
989 elif CritType == FT_CoplanarFaces:
990 # Check the Threshold
991 if isinstance(aThreshold, int):
992 aCriterion.ThresholdID = str(aThreshold)
993 elif isinstance(aThreshold, str):
996 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
997 aCriterion.ThresholdID = aThreshold
999 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1000 elif CritType == FT_ConnectedElements:
1001 # Check the Threshold
1002 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1003 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1004 if not aCriterion.ThresholdID:
1005 name = aThreshold.GetName()
1007 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1008 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1009 elif isinstance(aThreshold, int): # node id
1010 aCriterion.Threshold = aThreshold
1011 elif isinstance(aThreshold, list): # 3 point coordinates
1012 if len( aThreshold ) < 3:
1013 raise ValueError("too few point coordinates, must be 3")
1014 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1015 elif isinstance(aThreshold, str):
1016 if aThreshold.isdigit():
1017 aCriterion.Threshold = aThreshold # node id
1019 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1021 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1022 "or a list of point coordinates and not '%s'"%aThreshold)
1023 elif CritType == FT_ElemGeomType:
1024 # Check the Threshold
1026 aCriterion.Threshold = self.EnumToLong(aThreshold)
1027 assert( aThreshold in SMESH.GeometryType._items )
1029 if isinstance(aThreshold, int):
1030 aCriterion.Threshold = aThreshold
1032 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1035 elif CritType == FT_EntityType:
1036 # Check the Threshold
1038 aCriterion.Threshold = self.EnumToLong(aThreshold)
1039 assert( aThreshold in SMESH.EntityType._items )
1041 if isinstance(aThreshold, int):
1042 aCriterion.Threshold = aThreshold
1044 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1048 elif CritType == FT_GroupColor:
1049 # Check the Threshold
1051 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1053 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1055 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1056 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1057 FT_BareBorderFace, FT_BareBorderVolume,
1058 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1059 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1060 # At this point the Threshold is unnecessary
1061 if aThreshold == FT_LogicalNOT:
1062 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1063 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1064 aCriterion.BinaryOp = aThreshold
1068 aThreshold = float(aThreshold)
1069 aCriterion.Threshold = aThreshold
1071 raise TypeError("The Threshold should be a number.")
1074 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1075 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1077 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1078 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1080 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1081 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1083 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1084 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1088 def GetFilter(self,elementType,
1089 CritType=FT_Undefined,
1092 UnaryOp=FT_Undefined,
1096 Create a filter with the given parameters
1099 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1100 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1101 Note that the items starting from FT_LessThan are not suitable for CritType.
1102 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1103 Threshold: the threshold value (range of ids as string, shape, numeric)
1104 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1105 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1106 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1107 mesh: the mesh to initialize the filter with
1110 :class:`SMESH.Filter`
1113 See :doc:`Filters usage examples <tui_filters>`
1116 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1117 aFilterMgr = self.CreateFilterManager()
1118 aFilter = aFilterMgr.CreateFilter()
1120 aCriteria.append(aCriterion)
1121 aFilter.SetCriteria(aCriteria)
1123 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1124 else : aFilter.SetMesh( mesh )
1125 aFilterMgr.UnRegister()
1128 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1130 Create a filter from criteria
1133 criteria: a list of :class:`SMESH.Filter.Criterion`
1134 binOp: binary operator used when binary operator of criteria is undefined
1137 :class:`SMESH.Filter`
1140 See :doc:`Filters usage examples <tui_filters>`
1143 for i in range( len( criteria ) - 1 ):
1144 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1145 criteria[i].BinaryOp = self.EnumToLong( binOp )
1146 aFilterMgr = self.CreateFilterManager()
1147 aFilter = aFilterMgr.CreateFilter()
1148 aFilter.SetCriteria(criteria)
1149 aFilterMgr.UnRegister()
1152 def GetFunctor(self,theCriterion):
1154 Create a numerical functor by its type
1157 theCriterion (SMESH.FunctorType): functor type.
1158 Note that not all items correspond to numerical functors.
1161 :class:`SMESH.NumericalFunctor`
1164 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1166 aFilterMgr = self.CreateFilterManager()
1168 if theCriterion == FT_AspectRatio:
1169 functor = aFilterMgr.CreateAspectRatio()
1170 elif theCriterion == FT_AspectRatio3D:
1171 functor = aFilterMgr.CreateAspectRatio3D()
1172 elif theCriterion == FT_Warping:
1173 functor = aFilterMgr.CreateWarping()
1174 elif theCriterion == FT_MinimumAngle:
1175 functor = aFilterMgr.CreateMinimumAngle()
1176 elif theCriterion == FT_Taper:
1177 functor = aFilterMgr.CreateTaper()
1178 elif theCriterion == FT_Skew:
1179 functor = aFilterMgr.CreateSkew()
1180 elif theCriterion == FT_Area:
1181 functor = aFilterMgr.CreateArea()
1182 elif theCriterion == FT_Volume3D:
1183 functor = aFilterMgr.CreateVolume3D()
1184 elif theCriterion == FT_MaxElementLength2D:
1185 functor = aFilterMgr.CreateMaxElementLength2D()
1186 elif theCriterion == FT_MaxElementLength3D:
1187 functor = aFilterMgr.CreateMaxElementLength3D()
1188 elif theCriterion == FT_MultiConnection:
1189 functor = aFilterMgr.CreateMultiConnection()
1190 elif theCriterion == FT_MultiConnection2D:
1191 functor = aFilterMgr.CreateMultiConnection2D()
1192 elif theCriterion == FT_Length:
1193 functor = aFilterMgr.CreateLength()
1194 elif theCriterion == FT_Length2D:
1195 functor = aFilterMgr.CreateLength2D()
1196 elif theCriterion == FT_Length3D:
1197 functor = aFilterMgr.CreateLength3D()
1198 elif theCriterion == FT_Deflection2D:
1199 functor = aFilterMgr.CreateDeflection2D()
1200 elif theCriterion == FT_NodeConnectivityNumber:
1201 functor = aFilterMgr.CreateNodeConnectivityNumber()
1202 elif theCriterion == FT_BallDiameter:
1203 functor = aFilterMgr.CreateBallDiameter()
1205 print("Error: given parameter is not numerical functor type.")
1206 aFilterMgr.UnRegister()
1209 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1214 theHType (string): mesh hypothesis type
1215 theLibName (string): mesh plug-in library name
1218 created hypothesis instance
1220 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1222 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1225 # wrap hypothesis methods
1226 for meth_name in dir( hyp.__class__ ):
1227 if not meth_name.startswith("Get") and \
1228 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1229 method = getattr ( hyp.__class__, meth_name )
1230 if callable(method):
1231 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1235 def GetMeshInfo(self, obj):
1237 Get the mesh statistic.
1240 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1243 if isinstance( obj, Mesh ):
1246 if hasattr(obj, "GetMeshInfo"):
1247 values = obj.GetMeshInfo()
1248 for i in range(SMESH.Entity_Last._v):
1249 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1253 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1255 Get minimum distance between two objects
1257 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1258 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1261 src1 (SMESH.SMESH_IDSource): first source object
1262 src2 (SMESH.SMESH_IDSource): second source object
1263 id1 (int): node/element id from the first source
1264 id2 (int): node/element id from the second (or first) source
1265 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1266 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1269 minimum distance value
1272 :meth:`GetMinDistance`
1275 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1279 result = result.value
1282 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1284 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1286 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1287 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1290 src1 (SMESH.SMESH_IDSource): first source object
1291 src2 (SMESH.SMESH_IDSource): second source object
1292 id1 (int): node/element id from the first source
1293 id2 (int): node/element id from the second (or first) source
1294 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1295 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1298 :class:`SMESH.Measure` structure or None if input data is invalid
1303 if isinstance(src1, Mesh): src1 = src1.mesh
1304 if isinstance(src2, Mesh): src2 = src2.mesh
1305 if src2 is None and id2 != 0: src2 = src1
1306 if not hasattr(src1, "_narrow"): return None
1307 src1 = src1._narrow(SMESH.SMESH_IDSource)
1308 if not src1: return None
1309 unRegister = genObjUnRegister()
1312 e = m.GetMeshEditor()
1314 src1 = e.MakeIDSource([id1], SMESH.FACE)
1316 src1 = e.MakeIDSource([id1], SMESH.NODE)
1317 unRegister.set( src1 )
1319 if hasattr(src2, "_narrow"):
1320 src2 = src2._narrow(SMESH.SMESH_IDSource)
1321 if src2 and id2 != 0:
1323 e = m.GetMeshEditor()
1325 src2 = e.MakeIDSource([id2], SMESH.FACE)
1327 src2 = e.MakeIDSource([id2], SMESH.NODE)
1328 unRegister.set( src2 )
1331 aMeasurements = self.CreateMeasurements()
1332 unRegister.set( aMeasurements )
1333 result = aMeasurements.MinDistance(src1, src2)
1336 def BoundingBox(self, objects):
1338 Get bounding box of the specified object(s)
1341 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1344 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1347 :meth:`GetBoundingBox`
1350 result = self.GetBoundingBox(objects)
1354 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1357 def GetBoundingBox(self, objects):
1359 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1362 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1365 :class:`SMESH.Measure` structure
1371 if isinstance(objects, tuple):
1372 objects = list(objects)
1373 if not isinstance(objects, list):
1377 if isinstance(o, Mesh):
1378 srclist.append(o.mesh)
1379 elif hasattr(o, "_narrow"):
1380 src = o._narrow(SMESH.SMESH_IDSource)
1381 if src: srclist.append(src)
1384 aMeasurements = self.CreateMeasurements()
1385 result = aMeasurements.BoundingBox(srclist)
1386 aMeasurements.UnRegister()
1389 def GetLength(self, obj):
1391 Get sum of lengths of all 1D elements in the mesh object.
1394 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1397 sum of lengths of all 1D elements
1400 if isinstance(obj, Mesh): obj = obj.mesh
1401 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1402 aMeasurements = self.CreateMeasurements()
1403 value = aMeasurements.Length(obj)
1404 aMeasurements.UnRegister()
1407 def GetArea(self, obj):
1409 Get sum of areas of all 2D elements in the mesh object.
1412 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1415 sum of areas of all 2D elements
1418 if isinstance(obj, Mesh): obj = obj.mesh
1419 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1420 aMeasurements = self.CreateMeasurements()
1421 value = aMeasurements.Area(obj)
1422 aMeasurements.UnRegister()
1425 def GetVolume(self, obj):
1427 Get sum of volumes of all 3D elements in the mesh object.
1430 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1433 sum of volumes of all 3D elements
1436 if isinstance(obj, Mesh): obj = obj.mesh
1437 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438 aMeasurements = self.CreateMeasurements()
1439 value = aMeasurements.Volume(obj)
1440 aMeasurements.UnRegister()
1443 def GetGravityCenter(self, obj):
1445 Get gravity center of all nodes of a mesh object.
1448 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1451 Three components of the gravity center (x,y,z)
1454 :meth:`Mesh.BaryCenter`
1456 if isinstance(obj, Mesh): obj = obj.mesh
1457 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1458 aMeasurements = self.CreateMeasurements()
1459 pointStruct = aMeasurements.GravityCenter(obj)
1460 aMeasurements.UnRegister()
1461 return pointStruct.x, pointStruct.y, pointStruct.z
1463 def GetAngle(self, p1, p2, p3 ):
1465 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1468 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1474 if isinstance( p1, list ): p1 = PointStruct(*p1)
1475 if isinstance( p2, list ): p2 = PointStruct(*p2)
1476 if isinstance( p3, list ): p3 = PointStruct(*p3)
1478 aMeasurements = self.CreateMeasurements()
1479 angle = aMeasurements.Angle(p1,p2,p3)
1480 aMeasurements.UnRegister()
1485 pass # end of class smeshBuilder
1488 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1489 """Registering the new proxy for SMESH.SMESH_Gen"""
1492 def New( instance=None, instanceGeom=None):
1494 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1495 interface to create or load meshes.
1500 salome.salome_init()
1501 from salome.smesh import smeshBuilder
1502 smesh = smeshBuilder.New()
1505 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1506 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1508 :class:`smeshBuilder` instance
1513 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1515 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1520 smeshInst = smeshBuilder()
1521 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1522 smeshInst.init_smesh(instanceGeom)
1526 # Public class: Mesh
1527 # ==================
1530 class Mesh(metaclass = MeshMeta):
1532 This class allows defining and managing a mesh.
1533 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1534 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1535 new nodes and elements and by changing the existing entities), to get information
1536 about a mesh and to export a mesh in different formats.
1543 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1548 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1549 sets the GUI name of this mesh to *name*.
1552 smeshpyD: an instance of smeshBuilder class
1553 geompyD: an instance of geomBuilder class
1554 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1555 name: Study name of the mesh
1558 self.smeshpyD = smeshpyD
1559 self.geompyD = geompyD
1564 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1567 # publish geom of mesh (issue 0021122)
1568 if not self.geom.GetStudyEntry():
1572 geo_name = name + " shape"
1574 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1575 geompyD.addToStudy( self.geom, geo_name )
1576 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1578 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1581 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1583 self.smeshpyD.SetName(self.mesh, name)
1585 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1588 self.geom = self.mesh.GetShapeToMesh()
1590 self.editor = self.mesh.GetMeshEditor()
1591 self.functors = [None] * SMESH.FT_Undefined._v
1593 # set self to algoCreator's
1594 for attrName in dir(self):
1595 attr = getattr( self, attrName )
1596 if isinstance( attr, algoCreator ):
1597 setattr( self, attrName, attr.copy( self ))
1604 Destructor. Clean-up resources
1607 #self.mesh.UnRegister()
1611 def SetMesh(self, theMesh):
1613 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1616 theMesh: a :class:`SMESH.SMESH_Mesh` object
1620 # do not call Register() as this prevents mesh servant deletion at closing study
1621 #if self.mesh: self.mesh.UnRegister()
1624 #self.mesh.Register()
1625 self.geom = self.mesh.GetShapeToMesh()
1630 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1633 a :class:`SMESH.SMESH_Mesh` object
1638 def GetEngine(self):
1640 Return a smeshBuilder instance created this mesh
1642 return self.smeshpyD
1644 def GetGeomEngine(self):
1646 Return a geomBuilder instance
1652 Get the name of the mesh
1655 the name of the mesh as a string
1658 name = GetName(self.GetMesh())
1661 def SetName(self, name):
1663 Set a name to the mesh
1666 name: a new name of the mesh
1669 self.smeshpyD.SetName(self.GetMesh(), name)
1671 def GetSubMesh(self, geom, name):
1673 Get a sub-mesh object associated to a *geom* geometrical object.
1676 geom: a geometrical object (shape)
1677 name: a name for the sub-mesh in the Object Browser
1680 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1681 which lies on the given shape
1684 A sub-mesh is implicitly created when a sub-shape is specified at
1685 creating an algorithm, for example::
1687 algo1D = mesh.Segment(geom=Edge_1)
1689 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1690 The created sub-mesh can be retrieved from the algorithm::
1692 submesh = algo1D.GetSubMesh()
1695 AssureGeomPublished( self, geom, name )
1696 submesh = self.mesh.GetSubMesh( geom, name )
1701 Return the shape associated to the mesh
1709 def SetShape(self, geom):
1711 Associate the given shape to the mesh (entails the recreation of the mesh)
1714 geom: the shape to be meshed (GEOM_Object)
1717 self.mesh = self.smeshpyD.CreateMesh(geom)
1719 def HasShapeToMesh(self):
1721 Return ``True`` if this mesh is based on geometry
1723 return self.mesh.HasShapeToMesh()
1727 Load mesh from the study after opening the study
1731 def IsReadyToCompute(self, theSubObject):
1733 Return true if the hypotheses are defined well
1736 theSubObject: a sub-shape of a mesh shape
1742 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1744 def GetAlgoState(self, theSubObject):
1746 Return errors of hypotheses definition.
1747 The list of errors is empty if everything is OK.
1750 theSubObject: a sub-shape of a mesh shape
1756 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1758 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1760 Return a geometrical object on which the given element was built.
1761 The returned geometrical object, if not nil, is either found in the
1762 study or published by this method with the given name
1765 theElementID: the id of the mesh element
1766 theGeomName: the user-defined name of the geometrical object
1769 GEOM.GEOM_Object instance
1772 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1774 def MeshDimension(self):
1776 Return the mesh dimension depending on the dimension of the underlying shape
1777 or, if the mesh is not based on any shape, basing on deimension of elements
1780 mesh dimension as an integer value [0,3]
1783 if self.mesh.HasShapeToMesh():
1784 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1785 if len( shells ) > 0 :
1787 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1789 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1794 if self.NbVolumes() > 0: return 3
1795 if self.NbFaces() > 0: return 2
1796 if self.NbEdges() > 0: return 1
1799 def Evaluate(self, geom=0):
1801 Evaluate size of prospective mesh on a shape
1804 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1805 To know predicted number of e.g. edges, inquire it this way::
1807 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1810 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1812 geom = self.mesh.GetShapeToMesh()
1815 return self.smeshpyD.Evaluate(self.mesh, geom)
1818 def Compute(self, geom=0, discardModifs=False, refresh=False):
1820 Compute the mesh and return the status of the computation
1823 geom: geomtrical shape on which mesh data should be computed
1824 discardModifs: if True and the mesh has been edited since
1825 a last total re-compute and that may prevent successful partial re-compute,
1826 then the mesh is cleaned before Compute()
1827 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1833 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1835 geom = self.mesh.GetShapeToMesh()
1840 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1842 ok = self.smeshpyD.Compute(self.mesh, geom)
1843 except SALOME.SALOME_Exception as ex:
1844 print("Mesh computation failed, exception caught:")
1845 print(" ", ex.details.text)
1848 print("Mesh computation failed, exception caught:")
1849 traceback.print_exc()
1853 # Treat compute errors
1854 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1856 for err in computeErrors:
1857 if self.mesh.HasShapeToMesh():
1858 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1860 stdErrors = ["OK", #COMPERR_OK
1861 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1862 "std::exception", #COMPERR_STD_EXCEPTION
1863 "OCC exception", #COMPERR_OCC_EXCEPTION
1864 "..", #COMPERR_SLM_EXCEPTION
1865 "Unknown exception", #COMPERR_EXCEPTION
1866 "Memory allocation problem", #COMPERR_MEMORY_PB
1867 "Algorithm failed", #COMPERR_ALGO_FAILED
1868 "Unexpected geometry", #COMPERR_BAD_SHAPE
1869 "Warning", #COMPERR_WARNING
1870 "Computation cancelled",#COMPERR_CANCELED
1871 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1873 if err.code < len(stdErrors): errText = stdErrors[err.code]
1875 errText = "code %s" % -err.code
1876 if errText: errText += ". "
1877 errText += err.comment
1878 if allReasons: allReasons += "\n"
1880 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1882 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1886 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1888 if err.isGlobalAlgo:
1896 reason = '%s %sD algorithm is missing' % (glob, dim)
1897 elif err.state == HYP_MISSING:
1898 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1899 % (glob, dim, name, dim))
1900 elif err.state == HYP_NOTCONFORM:
1901 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1902 elif err.state == HYP_BAD_PARAMETER:
1903 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1904 % ( glob, dim, name ))
1905 elif err.state == HYP_BAD_GEOMETRY:
1906 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1907 'geometry' % ( glob, dim, name ))
1908 elif err.state == HYP_HIDDEN_ALGO:
1909 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1910 'algorithm of upper dimension generating %sD mesh'
1911 % ( glob, dim, name, glob, dim ))
1913 reason = ("For unknown reason. "
1914 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1916 if allReasons: allReasons += "\n"
1917 allReasons += "- " + reason
1919 if not ok or allReasons != "":
1920 msg = '"' + GetName(self.mesh) + '"'
1921 if ok: msg += " has been computed with warnings"
1922 else: msg += " has not been computed"
1923 if allReasons != "": msg += ":"
1928 if salome.sg.hasDesktop():
1929 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1930 if refresh: salome.sg.updateObjBrowser()
1934 def GetComputeErrors(self, shape=0 ):
1936 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1940 shape = self.mesh.GetShapeToMesh()
1941 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1943 def GetSubShapeName(self, subShapeID ):
1945 Return a name of a sub-shape by its ID.
1946 Possible variants (for *subShapeID* == 3):
1948 - **"Face_12"** - published sub-shape
1949 - **FACE #3** - not published sub-shape
1950 - **sub-shape #3** - invalid sub-shape ID
1951 - **#3** - error in this function
1954 subShapeID: a unique ID of a sub-shape
1957 a string describing the sub-shape
1961 if not self.mesh.HasShapeToMesh():
1965 mainIOR = salome.orb.object_to_string( self.GetShape() )
1967 mainSO = s.FindObjectIOR(mainIOR)
1970 shapeText = '"%s"' % mainSO.GetName()
1971 subIt = s.NewChildIterator(mainSO)
1973 subSO = subIt.Value()
1975 obj = subSO.GetObject()
1976 if not obj: continue
1977 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1980 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1983 if ids == subShapeID:
1984 shapeText = '"%s"' % subSO.GetName()
1987 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1989 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1991 shapeText = 'sub-shape #%s' % (subShapeID)
1993 shapeText = "#%s" % (subShapeID)
1996 def GetFailedShapes(self, publish=False):
1998 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1999 error of an algorithm
2002 publish: if *True*, the returned groups will be published in the study
2005 a list of GEOM groups each named after a failed algorithm
2010 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2011 for err in computeErrors:
2012 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2013 if not shape: continue
2014 if err.algoName in algo2shapes:
2015 algo2shapes[ err.algoName ].append( shape )
2017 algo2shapes[ err.algoName ] = [ shape ]
2021 for algoName, shapes in list(algo2shapes.items()):
2023 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2024 otherTypeShapes = []
2026 group = self.geompyD.CreateGroup( self.geom, groupType )
2027 for shape in shapes:
2028 if shape.GetShapeType() == shapes[0].GetShapeType():
2029 sameTypeShapes.append( shape )
2031 otherTypeShapes.append( shape )
2032 self.geompyD.UnionList( group, sameTypeShapes )
2034 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2036 group.SetName( algoName )
2037 groups.append( group )
2038 shapes = otherTypeShapes
2041 for group in groups:
2042 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2045 def GetMeshOrder(self):
2047 Return sub-mesh objects list in meshing order
2050 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2053 return self.mesh.GetMeshOrder()
2055 def SetMeshOrder(self, submeshes):
2057 Set order in which concurrent sub-meshes should be meshed
2060 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2063 return self.mesh.SetMeshOrder(submeshes)
2065 def Clear(self, refresh=False):
2067 Remove all nodes and elements generated on geometry. Imported elements remain.
2070 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2074 if ( salome.sg.hasDesktop() ):
2075 if refresh: salome.sg.updateObjBrowser()
2077 def ClearSubMesh(self, geomId, refresh=False):
2079 Remove all nodes and elements of indicated shape
2082 geomId: the ID of a sub-shape to remove elements on
2083 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2086 self.mesh.ClearSubMesh(geomId)
2087 if salome.sg.hasDesktop():
2088 if refresh: salome.sg.updateObjBrowser()
2090 def AutomaticTetrahedralization(self, fineness=0):
2092 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2095 fineness: [0.0,1.0] defines mesh fineness
2101 dim = self.MeshDimension()
2103 self.RemoveGlobalHypotheses()
2104 self.Segment().AutomaticLength(fineness)
2106 self.Triangle().LengthFromEdges()
2111 return self.Compute()
2113 def AutomaticHexahedralization(self, fineness=0):
2115 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2118 fineness: [0.0, 1.0] defines mesh fineness
2124 dim = self.MeshDimension()
2125 # assign the hypotheses
2126 self.RemoveGlobalHypotheses()
2127 self.Segment().AutomaticLength(fineness)
2134 return self.Compute()
2136 def AddHypothesis(self, hyp, geom=0):
2141 hyp: a hypothesis to assign
2142 geom: a subhape of mesh geometry
2145 :class:`SMESH.Hypothesis_Status`
2148 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2149 hyp, geom = geom, hyp
2150 if isinstance( hyp, Mesh_Algorithm ):
2151 hyp = hyp.GetAlgorithm()
2156 geom = self.mesh.GetShapeToMesh()
2159 if self.mesh.HasShapeToMesh():
2160 hyp_type = hyp.GetName()
2161 lib_name = hyp.GetLibName()
2162 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2163 # if checkAll and geom:
2164 # checkAll = geom.GetType() == 37
2166 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2168 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2169 status = self.mesh.AddHypothesis(geom, hyp)
2171 status = HYP_BAD_GEOMETRY, ""
2172 hyp_name = GetName( hyp )
2175 geom_name = geom.GetName()
2176 isAlgo = hyp._narrow( SMESH_Algo )
2177 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2180 def IsUsedHypothesis(self, hyp, geom):
2182 Return True if an algorithm or hypothesis is assigned to a given shape
2185 hyp: an algorithm or hypothesis to check
2186 geom: a subhape of mesh geometry
2192 if not hyp: # or not geom
2194 if isinstance( hyp, Mesh_Algorithm ):
2195 hyp = hyp.GetAlgorithm()
2197 hyps = self.GetHypothesisList(geom)
2199 if h.GetId() == hyp.GetId():
2203 def RemoveHypothesis(self, hyp, geom=0):
2205 Unassign a hypothesis
2208 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2209 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2212 :class:`SMESH.Hypothesis_Status`
2217 if isinstance( hyp, Mesh_Algorithm ):
2218 hyp = hyp.GetAlgorithm()
2224 if self.IsUsedHypothesis( hyp, shape ):
2225 return self.mesh.RemoveHypothesis( shape, hyp )
2226 hypName = GetName( hyp )
2227 geoName = GetName( shape )
2228 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2231 def GetHypothesisList(self, geom):
2233 Get the list of hypotheses added on a geometry
2236 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2239 the sequence of :class:`SMESH.SMESH_Hypothesis`
2242 return self.mesh.GetHypothesisList( geom )
2244 def RemoveGlobalHypotheses(self):
2246 Remove all global hypotheses
2249 current_hyps = self.mesh.GetHypothesisList( self.geom )
2250 for hyp in current_hyps:
2251 self.mesh.RemoveHypothesis( self.geom, hyp )
2254 def ExportMED(self, *args, **kwargs):
2256 Export the mesh in a file in MED format
2257 allowing to overwrite the file if it exists or add the exported data to its contents
2260 fileName: is the file name
2261 auto_groups (boolean): parameter for creating/not creating
2262 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2263 the typical use is auto_groups=False.
2264 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2265 The minor must be between 0 and the current minor version of MED file library.
2266 If minor is equal to -1, the minor version is not changed (default).
2267 The major version (x, where version is x.y.z) cannot be changed.
2268 overwrite (boolean): parameter for overwriting/not overwriting the file
2269 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2270 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2272 - 1D if all mesh nodes lie on OX coordinate axis, or
2273 - 2D if all mesh nodes lie on XOY coordinate plane, or
2274 - 3D in the rest cases.
2276 If *autoDimension* is *False*, the space dimension is always 3.
2277 fields: list of GEOM fields defined on the shape to mesh.
2278 geomAssocFields: each character of this string means a need to export a
2279 corresponding field; correspondence between fields and characters
2282 - 'v' stands for "_vertices_" field;
2283 - 'e' stands for "_edges_" field;
2284 - 'f' stands for "_faces_" field;
2285 - 's' stands for "_solids_" field.
2287 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2288 close to zero within a given tolerance, the coordinate is set to zero.
2289 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2291 # process positional arguments
2292 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2294 auto_groups = args[1] if len(args) > 1 else False
2295 minor = args[2] if len(args) > 2 else -1
2296 overwrite = args[3] if len(args) > 3 else True
2297 meshPart = args[4] if len(args) > 4 else None
2298 autoDimension = args[5] if len(args) > 5 else True
2299 fields = args[6] if len(args) > 6 else []
2300 geomAssocFields = args[7] if len(args) > 7 else ''
2301 z_tolerance = args[8] if len(args) > 8 else -1.
2302 # process keywords arguments
2303 auto_groups = kwargs.get("auto_groups", auto_groups)
2304 minor = kwargs.get("minor", minor)
2305 overwrite = kwargs.get("overwrite", overwrite)
2306 meshPart = kwargs.get("meshPart", meshPart)
2307 autoDimension = kwargs.get("autoDimension", autoDimension)
2308 fields = kwargs.get("fields", fields)
2309 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2310 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2312 # invoke engine's function
2313 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2314 unRegister = genObjUnRegister()
2315 if isinstance( meshPart, list ):
2316 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2317 unRegister.set( meshPart )
2319 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2320 self.mesh.SetParameters(Parameters)
2322 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2323 fields, geomAssocFields, z_tolerance)
2325 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2327 def ExportSAUV(self, f, auto_groups=0):
2329 Export the mesh in a file in SAUV format
2334 auto_groups: boolean parameter for creating/not creating
2335 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2336 the typical use is auto_groups=False.
2339 self.mesh.ExportSAUV(f, auto_groups)
2341 def ExportDAT(self, f, meshPart=None):
2343 Export the mesh in a file in DAT format
2347 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2351 unRegister = genObjUnRegister()
2352 if isinstance( meshPart, list ):
2353 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2354 unRegister.set( meshPart )
2355 self.mesh.ExportPartToDAT( meshPart, f )
2357 self.mesh.ExportDAT(f)
2359 def ExportUNV(self, f, meshPart=None):
2361 Export the mesh in a file in UNV format
2365 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2369 unRegister = genObjUnRegister()
2370 if isinstance( meshPart, list ):
2371 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2372 unRegister.set( meshPart )
2373 self.mesh.ExportPartToUNV( meshPart, f )
2375 self.mesh.ExportUNV(f)
2377 def ExportSTL(self, f, ascii=1, meshPart=None):
2379 Export the mesh in a file in STL format
2383 ascii: defines the file encoding
2384 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2388 unRegister = genObjUnRegister()
2389 if isinstance( meshPart, list ):
2390 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2391 unRegister.set( meshPart )
2392 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2394 self.mesh.ExportSTL(f, ascii)
2396 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2398 Export the mesh in a file in CGNS format
2402 overwrite: boolean parameter for overwriting/not overwriting the file
2403 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2404 groupElemsByType: if True all elements of same entity type are exported at ones,
2405 else elements are exported in order of their IDs which can cause creation
2406 of multiple cgns sections
2409 unRegister = genObjUnRegister()
2410 if isinstance( meshPart, list ):
2411 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2412 unRegister.set( meshPart )
2413 if isinstance( meshPart, Mesh ):
2414 meshPart = meshPart.mesh
2416 meshPart = self.mesh
2417 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2419 def ExportGMF(self, f, meshPart=None):
2421 Export the mesh in a file in GMF format.
2422 GMF files must have .mesh extension for the ASCII format and .meshb for
2423 the bynary format. Other extensions are not allowed.
2427 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2430 unRegister = genObjUnRegister()
2431 if isinstance( meshPart, list ):
2432 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2433 unRegister.set( meshPart )
2434 if isinstance( meshPart, Mesh ):
2435 meshPart = meshPart.mesh
2437 meshPart = self.mesh
2438 self.mesh.ExportGMF(meshPart, f, True)
2440 def ExportToMED(self, *args, **kwargs):
2442 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2443 Export the mesh in a file in MED format
2444 allowing to overwrite the file if it exists or add the exported data to its contents
2447 fileName: the file name
2448 opt (boolean): parameter for creating/not creating
2449 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2450 overwrite: boolean parameter for overwriting/not overwriting the file
2451 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2453 - 1D if all mesh nodes lie on OX coordinate axis, or
2454 - 2D if all mesh nodes lie on XOY coordinate plane, or
2455 - 3D in the rest cases.
2457 If **autoDimension** is *False*, the space dimension is always 3.
2460 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2461 # process positional arguments
2462 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2464 auto_groups = args[1] if len(args) > 1 else False
2465 overwrite = args[2] if len(args) > 2 else True
2466 autoDimension = args[3] if len(args) > 3 else True
2467 # process keywords arguments
2468 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2469 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2470 overwrite = kwargs.get("overwrite", overwrite)
2471 autoDimension = kwargs.get("autoDimension", autoDimension)
2473 # invoke engine's function
2474 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2476 def ExportToMEDX(self, *args, **kwargs):
2478 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2479 Export the mesh in a file in MED format
2482 fileName: the file name
2483 opt (boolean): parameter for creating/not creating
2484 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2485 overwrite: boolean parameter for overwriting/not overwriting the file
2486 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2488 - 1D if all mesh nodes lie on OX coordinate axis, or
2489 - 2D if all mesh nodes lie on XOY coordinate plane, or
2490 - 3D in the rest cases.
2492 If **autoDimension** is *False*, the space dimension is always 3.
2495 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2496 # process positional arguments
2497 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2499 auto_groups = args[1] if len(args) > 1 else False
2500 overwrite = args[2] if len(args) > 2 else True
2501 autoDimension = args[3] if len(args) > 3 else True
2502 # process keywords arguments
2503 auto_groups = kwargs.get("auto_groups", auto_groups)
2504 overwrite = kwargs.get("overwrite", overwrite)
2505 autoDimension = kwargs.get("autoDimension", autoDimension)
2507 # invoke engine's function
2508 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2512 def Append(self, meshes, uniteIdenticalGroups = True,
2513 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2515 Append given meshes into this mesh.
2516 All groups of input meshes will be created in this mesh.
2519 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2520 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2521 mergeNodesAndElements: if True, equal nodes and elements are merged
2522 mergeTolerance: tolerance for merging nodes
2523 allGroups: forces creation of groups corresponding to every input mesh
2525 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2526 mergeNodesAndElements, mergeTolerance, allGroups,
2527 meshToAppendTo = self.GetMesh() )
2529 # Operations with groups:
2530 # ----------------------
2531 def CreateEmptyGroup(self, elementType, name):
2533 Create an empty standalone mesh group
2536 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2537 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2538 name: the name of the mesh group
2541 :class:`SMESH.SMESH_Group`
2544 return self.mesh.CreateGroup(elementType, name)
2546 def Group(self, grp, name=""):
2548 Create a mesh group based on the geometric object *grp*
2549 and give it a *name*.
2550 If *name* is not defined the name of the geometric group is used
2553 Works like :meth:`GroupOnGeom`.
2556 grp: a geometric group, a vertex, an edge, a face or a solid
2557 name: the name of the mesh group
2560 :class:`SMESH.SMESH_GroupOnGeom`
2563 return self.GroupOnGeom(grp, name)
2565 def GroupOnGeom(self, grp, name="", typ=None):
2567 Create a mesh group based on the geometrical object *grp*
2568 and give it a *name*.
2569 if *name* is not defined the name of the geometric group is used
2572 grp: a geometrical group, a vertex, an edge, a face or a solid
2573 name: the name of the mesh group
2574 typ: the type of elements in the group; either of
2575 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2576 automatically detected by the type of the geometry
2579 :class:`SMESH.SMESH_GroupOnGeom`
2582 AssureGeomPublished( self, grp, name )
2584 name = grp.GetName()
2586 typ = self._groupTypeFromShape( grp )
2587 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2589 def _groupTypeFromShape( self, shape ):
2591 Pivate method to get a type of group on geometry
2593 tgeo = str(shape.GetShapeType())
2594 if tgeo == "VERTEX":
2596 elif tgeo == "EDGE":
2598 elif tgeo == "FACE" or tgeo == "SHELL":
2600 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2602 elif tgeo == "COMPOUND":
2603 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2605 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2606 return self._groupTypeFromShape( sub[0] )
2608 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2611 def GroupOnFilter(self, typ, name, filter):
2613 Create a mesh group with given *name* based on the *filter*.
2614 It is a special type of group dynamically updating it's contents during
2618 typ: the type of elements in the group; either of
2619 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2620 name: the name of the mesh group
2621 filter (SMESH.Filter): the filter defining group contents
2624 :class:`SMESH.SMESH_GroupOnFilter`
2627 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2629 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2631 Create a mesh group by the given ids of elements
2634 groupName: the name of the mesh group
2635 elementType: the type of elements in the group; either of
2636 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2637 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2640 :class:`SMESH.SMESH_Group`
2643 group = self.mesh.CreateGroup(elementType, groupName)
2644 if isinstance( elemIDs, Mesh ):
2645 elemIDs = elemIDs.GetMesh()
2646 if hasattr( elemIDs, "GetIDs" ):
2647 if hasattr( elemIDs, "SetMesh" ):
2648 elemIDs.SetMesh( self.GetMesh() )
2649 group.AddFrom( elemIDs )
2657 CritType=FT_Undefined,
2660 UnaryOp=FT_Undefined,
2663 Create a mesh group by the given conditions
2666 groupName: the name of the mesh group
2667 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2668 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2669 Note that the items starting from FT_LessThan are not suitable for CritType.
2670 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2671 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2672 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2673 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2674 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2677 :class:`SMESH.SMESH_GroupOnFilter`
2680 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2681 group = self.MakeGroupByCriterion(groupName, aCriterion)
2684 def MakeGroupByCriterion(self, groupName, Criterion):
2686 Create a mesh group by the given criterion
2689 groupName: the name of the mesh group
2690 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2693 :class:`SMESH.SMESH_GroupOnFilter`
2696 :meth:`smeshBuilder.GetCriterion`
2699 return self.MakeGroupByCriteria( groupName, [Criterion] )
2701 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2703 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2706 groupName: the name of the mesh group
2707 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2708 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2711 :class:`SMESH.SMESH_GroupOnFilter`
2714 :meth:`smeshBuilder.GetCriterion`
2717 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2718 group = self.MakeGroupByFilter(groupName, aFilter)
2721 def MakeGroupByFilter(self, groupName, theFilter):
2723 Create a mesh group by the given filter
2726 groupName (string): the name of the mesh group
2727 theFilter (SMESH.Filter): the filter
2730 :class:`SMESH.SMESH_GroupOnFilter`
2733 :meth:`smeshBuilder.GetFilter`
2736 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2737 #theFilter.SetMesh( self.mesh )
2738 #group.AddFrom( theFilter )
2739 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2742 def RemoveGroup(self, group):
2747 group (SMESH.SMESH_GroupBase): group to remove
2750 self.mesh.RemoveGroup(group)
2752 def RemoveGroupWithContents(self, group):
2754 Remove a group with its contents
2757 group (SMESH.SMESH_GroupBase): group to remove
2760 self.mesh.RemoveGroupWithContents(group)
2762 def GetGroups(self, elemType = SMESH.ALL):
2764 Get the list of groups existing in the mesh in the order of creation
2765 (starting from the oldest one)
2768 elemType (SMESH.ElementType): type of elements the groups contain;
2769 by default groups of elements of all types are returned
2772 a list of :class:`SMESH.SMESH_GroupBase`
2775 groups = self.mesh.GetGroups()
2776 if elemType == SMESH.ALL:
2780 if g.GetType() == elemType:
2781 typedGroups.append( g )
2788 Get the number of groups existing in the mesh
2791 the quantity of groups as an integer value
2794 return self.mesh.NbGroups()
2796 def GetGroupNames(self):
2798 Get the list of names of groups existing in the mesh
2804 groups = self.GetGroups()
2806 for group in groups:
2807 names.append(group.GetName())
2810 def GetGroupByName(self, name, elemType = None):
2812 Find groups by name and type
2815 name (string): name of the group of interest
2816 elemType (SMESH.ElementType): type of elements the groups contain;
2817 by default one group of any type is returned;
2818 if elemType == SMESH.ALL then all groups of any type are returned
2821 a list of :class:`SMESH.SMESH_GroupBase`
2825 for group in self.GetGroups():
2826 if group.GetName() == name:
2827 if elemType is None:
2829 if ( elemType == SMESH.ALL or
2830 group.GetType() == elemType ):
2831 groups.append( group )
2834 def UnionGroups(self, group1, group2, name):
2836 Produce a union of two groups.
2837 A new group is created. All mesh elements that are
2838 present in the initial groups are added to the new one
2841 group1 (SMESH.SMESH_GroupBase): a group
2842 group2 (SMESH.SMESH_GroupBase): another group
2845 instance of :class:`SMESH.SMESH_Group`
2848 return self.mesh.UnionGroups(group1, group2, name)
2850 def UnionListOfGroups(self, groups, name):
2852 Produce a union list of groups.
2853 New group is created. All mesh elements that are present in
2854 initial groups are added to the new one
2857 groups: list of :class:`SMESH.SMESH_GroupBase`
2860 instance of :class:`SMESH.SMESH_Group`
2862 return self.mesh.UnionListOfGroups(groups, name)
2864 def IntersectGroups(self, group1, group2, name):
2866 Prodice an intersection of two groups.
2867 A new group is created. All mesh elements that are common
2868 for the two initial groups are added to the new one.
2871 group1 (SMESH.SMESH_GroupBase): a group
2872 group2 (SMESH.SMESH_GroupBase): another group
2875 instance of :class:`SMESH.SMESH_Group`
2878 return self.mesh.IntersectGroups(group1, group2, name)
2880 def IntersectListOfGroups(self, groups, name):
2882 Produce an intersection of groups.
2883 New group is created. All mesh elements that are present in all
2884 initial groups simultaneously are added to the new one
2887 groups: a list of :class:`SMESH.SMESH_GroupBase`
2890 instance of :class:`SMESH.SMESH_Group`
2892 return self.mesh.IntersectListOfGroups(groups, name)
2894 def CutGroups(self, main_group, tool_group, name):
2896 Produce a cut of two groups.
2897 A new group is created. All mesh elements that are present in
2898 the main group but are not present in the tool group are added to the new one
2901 main_group (SMESH.SMESH_GroupBase): a group to cut from
2902 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2905 an instance of :class:`SMESH.SMESH_Group`
2908 return self.mesh.CutGroups(main_group, tool_group, name)
2910 def CutListOfGroups(self, main_groups, tool_groups, name):
2912 Produce a cut of groups.
2913 A new group is created. All mesh elements that are present in main groups
2914 but do not present in tool groups are added to the new one
2917 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2918 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2921 an instance of :class:`SMESH.SMESH_Group`
2924 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2926 def CreateDimGroup(self, groups, elemType, name,
2927 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2929 Create a standalone group of entities basing on nodes of other groups.
2932 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2933 elemType: a type of elements to include to the new group; either of
2934 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2935 name: a name of the new group.
2936 nbCommonNodes: a criterion of inclusion of an element to the new group
2937 basing on number of element nodes common with reference *groups*.
2938 Meaning of possible values are:
2940 - SMESH.ALL_NODES - include if all nodes are common,
2941 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2942 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2943 - SMEHS.MAJORITY - include if half of nodes or more are common.
2944 underlyingOnly: if *True* (default), an element is included to the
2945 new group provided that it is based on nodes of an element of *groups*;
2946 in this case the reference *groups* are supposed to be of higher dimension
2947 than *elemType*, which can be useful for example to get all faces lying on
2948 volumes of the reference *groups*.
2951 an instance of :class:`SMESH.SMESH_Group`
2954 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2956 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2958 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2960 Distribute all faces of the mesh among groups using sharp edges and optionally
2961 existing 1D elements as group boundaries.
2964 sharpAngle: edge is considered sharp if an angle between normals of
2965 adjacent faces is more than \a sharpAngle in degrees.
2966 createEdges (boolean): to create 1D elements for detected sharp edges.
2967 useExistingEdges (boolean): to use existing edges as group boundaries
2969 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2971 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2972 self.mesh.SetParameters(Parameters)
2973 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2975 def ConvertToStandalone(self, group):
2977 Convert group on geom into standalone group
2980 return self.mesh.ConvertToStandalone(group)
2982 # Get some info about mesh:
2983 # ------------------------
2985 def GetLog(self, clearAfterGet):
2987 Return the log of nodes and elements added or removed
2988 since the previous clear of the log.
2991 clearAfterGet: log is emptied after Get (safe if concurrents access)
2994 list of SMESH.log_block structures { commandType, number, coords, indexes }
2997 return self.mesh.GetLog(clearAfterGet)
3001 Clear the log of nodes and elements added or removed since the previous
3002 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3005 self.mesh.ClearLog()
3007 def SetAutoColor(self, theAutoColor):
3009 Toggle auto color mode on the object.
3010 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3013 theAutoColor (boolean): the flag which toggles auto color mode.
3016 self.mesh.SetAutoColor(theAutoColor)
3018 def GetAutoColor(self):
3020 Get flag of object auto color mode.
3026 return self.mesh.GetAutoColor()
3033 integer value, which is the internal Id of the mesh
3036 return self.mesh.GetId()
3038 def HasDuplicatedGroupNamesMED(self):
3040 Check the group names for duplications.
3041 Consider the maximum group name length stored in MED file.
3047 return self.mesh.HasDuplicatedGroupNamesMED()
3049 def GetMeshEditor(self):
3051 Obtain the mesh editor tool
3054 an instance of :class:`SMESH.SMESH_MeshEditor`
3059 def GetIDSource(self, ids, elemType = SMESH.ALL):
3061 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3062 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3066 elemType: type of elements; this parameter is used to distinguish
3067 IDs of nodes from IDs of elements; by default ids are treated as
3068 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3071 an instance of :class:`SMESH.SMESH_IDSource`
3074 call UnRegister() for the returned object as soon as it is no more useful::
3076 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3077 mesh.DoSomething( idSrc )
3081 if isinstance( ids, int ):
3083 return self.editor.MakeIDSource(ids, elemType)
3086 # Get information about mesh contents:
3087 # ------------------------------------
3089 def GetMeshInfo(self, obj = None):
3091 Get the mesh statistic.
3094 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3097 if not obj: obj = self.mesh
3098 return self.smeshpyD.GetMeshInfo(obj)
3102 Return the number of nodes in the mesh
3108 return self.mesh.NbNodes()
3110 def NbElements(self):
3112 Return the number of elements in the mesh
3118 return self.mesh.NbElements()
3120 def Nb0DElements(self):
3122 Return the number of 0d elements in the mesh
3128 return self.mesh.Nb0DElements()
3132 Return the number of ball discrete elements in the mesh
3138 return self.mesh.NbBalls()
3142 Return the number of edges in the mesh
3148 return self.mesh.NbEdges()
3150 def NbEdgesOfOrder(self, elementOrder):
3152 Return the number of edges with the given order in the mesh
3155 elementOrder: the order of elements
3156 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3162 return self.mesh.NbEdgesOfOrder(elementOrder)
3166 Return the number of faces in the mesh
3172 return self.mesh.NbFaces()
3174 def NbFacesOfOrder(self, elementOrder):
3176 Return the number of faces with the given order in the mesh
3179 elementOrder: the order of elements
3180 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3186 return self.mesh.NbFacesOfOrder(elementOrder)
3188 def NbTriangles(self):
3190 Return the number of triangles in the mesh
3196 return self.mesh.NbTriangles()
3198 def NbTrianglesOfOrder(self, elementOrder):
3200 Return the number of triangles with the given order in the mesh
3203 elementOrder: is the order of elements
3204 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3210 return self.mesh.NbTrianglesOfOrder(elementOrder)
3212 def NbBiQuadTriangles(self):
3214 Return the number of biquadratic triangles in the mesh
3220 return self.mesh.NbBiQuadTriangles()
3222 def NbQuadrangles(self):
3224 Return the number of quadrangles in the mesh
3230 return self.mesh.NbQuadrangles()
3232 def NbQuadranglesOfOrder(self, elementOrder):
3234 Return the number of quadrangles with the given order in the mesh
3237 elementOrder: the order of elements
3238 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3244 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3246 def NbBiQuadQuadrangles(self):
3248 Return the number of biquadratic quadrangles in the mesh
3254 return self.mesh.NbBiQuadQuadrangles()
3256 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3258 Return the number of polygons of given order in the mesh
3261 elementOrder: the order of elements
3262 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3268 return self.mesh.NbPolygonsOfOrder(elementOrder)
3270 def NbVolumes(self):
3272 Return the number of volumes in the mesh
3278 return self.mesh.NbVolumes()
3281 def NbVolumesOfOrder(self, elementOrder):
3283 Return the number of volumes with the given order in the mesh
3286 elementOrder: the order of elements
3287 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3293 return self.mesh.NbVolumesOfOrder(elementOrder)
3297 Return the number of tetrahedrons in the mesh
3303 return self.mesh.NbTetras()
3305 def NbTetrasOfOrder(self, elementOrder):
3307 Return the number of tetrahedrons with the given order in the mesh
3310 elementOrder: the order of elements
3311 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3317 return self.mesh.NbTetrasOfOrder(elementOrder)
3321 Return the number of hexahedrons in the mesh
3327 return self.mesh.NbHexas()
3329 def NbHexasOfOrder(self, elementOrder):
3331 Return the number of hexahedrons with the given order in the mesh
3334 elementOrder: the order of elements
3335 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3341 return self.mesh.NbHexasOfOrder(elementOrder)
3343 def NbTriQuadraticHexas(self):
3345 Return the number of triquadratic hexahedrons in the mesh
3351 return self.mesh.NbTriQuadraticHexas()
3353 def NbPyramids(self):
3355 Return the number of pyramids in the mesh
3361 return self.mesh.NbPyramids()
3363 def NbPyramidsOfOrder(self, elementOrder):
3365 Return the number of pyramids with the given order in the mesh
3368 elementOrder: the order of elements
3369 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3375 return self.mesh.NbPyramidsOfOrder(elementOrder)
3379 Return the number of prisms in the mesh
3385 return self.mesh.NbPrisms()
3387 def NbPrismsOfOrder(self, elementOrder):
3389 Return the number of prisms with the given order in the mesh
3392 elementOrder: the order of elements
3393 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3399 return self.mesh.NbPrismsOfOrder(elementOrder)
3401 def NbHexagonalPrisms(self):
3403 Return the number of hexagonal prisms in the mesh
3409 return self.mesh.NbHexagonalPrisms()
3411 def NbPolyhedrons(self):
3413 Return the number of polyhedrons in the mesh
3419 return self.mesh.NbPolyhedrons()
3421 def NbSubMesh(self):
3423 Return the number of submeshes in the mesh
3429 return self.mesh.NbSubMesh()
3431 def GetElementsId(self):
3433 Return the list of all mesh elements IDs
3436 the list of integer values
3439 :meth:`GetElementsByType`
3442 return self.mesh.GetElementsId()
3444 def GetElementsByType(self, elementType):
3446 Return the list of IDs of mesh elements with the given type
3449 elementType (SMESH.ElementType): the required type of elements
3452 list of integer values
3455 return self.mesh.GetElementsByType(elementType)
3457 def GetNodesId(self):
3459 Return the list of mesh nodes IDs
3462 the list of integer values
3465 return self.mesh.GetNodesId()
3467 # Get the information about mesh elements:
3468 # ------------------------------------
3470 def GetElementType(self, id, iselem=True):
3472 Return the type of mesh element or node
3475 the value from :class:`SMESH.ElementType` enumeration.
3476 Return SMESH.ALL if element or node with the given ID does not exist
3479 return self.mesh.GetElementType(id, iselem)
3481 def GetElementGeomType(self, id):
3483 Return the geometric type of mesh element
3486 the value from :class:`SMESH.EntityType` enumeration.
3489 return self.mesh.GetElementGeomType(id)
3491 def GetElementShape(self, id):
3493 Return the shape type of mesh element
3496 the value from :class:`SMESH.GeometryType` enumeration.
3499 return self.mesh.GetElementShape(id)
3501 def GetSubMeshElementsId(self, Shape):
3503 Return the list of sub-mesh elements IDs
3506 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3507 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3510 list of integer values
3513 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3514 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3517 return self.mesh.GetSubMeshElementsId(ShapeID)
3519 def GetSubMeshNodesId(self, Shape, all):
3521 Return the list of sub-mesh nodes IDs
3524 Shape: a geom object (sub-shape).
3525 *Shape* must be the sub-shape of a :meth:`GetShape`
3526 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3529 list of integer values
3532 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3533 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3536 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3538 def GetSubMeshElementType(self, Shape):
3540 Return type of elements on given shape
3543 Shape: a geom object (sub-shape).
3544 *Shape* must be a sub-shape of a ShapeToMesh()
3547 :class:`SMESH.ElementType`
3550 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3551 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3554 return self.mesh.GetSubMeshElementType(ShapeID)
3558 Get the mesh description
3564 return self.mesh.Dump()
3567 # Get the information about nodes and elements of a mesh by its IDs:
3568 # -----------------------------------------------------------
3570 def GetNodeXYZ(self, id):
3572 Get XYZ coordinates of a node.
3573 If there is no node for the given ID - return an empty list
3576 list of float values
3579 return self.mesh.GetNodeXYZ(id)
3581 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3583 Return list of IDs of inverse elements for the given node.
3584 If there is no node for the given ID - return an empty list
3588 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3591 list of integer values
3594 return self.mesh.GetNodeInverseElements(id,elemType)
3596 def GetNodePosition(self,NodeID):
3598 Return the position of a node on the shape
3601 :class:`SMESH.NodePosition`
3604 return self.mesh.GetNodePosition(NodeID)
3606 def GetElementPosition(self,ElemID):
3608 Return the position of an element on the shape
3611 :class:`SMESH.ElementPosition`
3614 return self.mesh.GetElementPosition(ElemID)
3616 def GetShapeID(self, id):
3618 Return the ID of the shape, on which the given node was generated.
3621 an integer value > 0 or -1 if there is no node for the given
3622 ID or the node is not assigned to any geometry
3625 return self.mesh.GetShapeID(id)
3627 def GetShapeIDForElem(self,id):
3629 Return the ID of the shape, on which the given element was generated.
3632 an integer value > 0 or -1 if there is no element for the given
3633 ID or the element is not assigned to any geometry
3636 return self.mesh.GetShapeIDForElem(id)
3638 def GetElemNbNodes(self, id):
3640 Return the number of nodes of the given element
3643 an integer value > 0 or -1 if there is no element for the given ID
3646 return self.mesh.GetElemNbNodes(id)
3648 def GetElemNode(self, id, index):
3650 Return the node ID the given (zero based) index for the given element.
3652 * If there is no element for the given ID - return -1.
3653 * If there is no node for the given index - return -2.
3656 id (int): element ID
3657 index (int): node index within the element
3660 an integer value (ID)
3663 :meth:`GetElemNodes`
3666 return self.mesh.GetElemNode(id, index)
3668 def GetElemNodes(self, id):
3670 Return the IDs of nodes of the given element
3673 a list of integer values
3676 return self.mesh.GetElemNodes(id)
3678 def IsMediumNode(self, elementID, nodeID):
3680 Return true if the given node is the medium node in the given quadratic element
3683 return self.mesh.IsMediumNode(elementID, nodeID)
3685 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3687 Return true if the given node is the medium node in one of quadratic elements
3690 nodeID: ID of the node
3691 elementType: the type of elements to check a state of the node, either of
3692 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3695 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3697 def ElemNbEdges(self, id):
3699 Return the number of edges for the given element
3702 return self.mesh.ElemNbEdges(id)
3704 def ElemNbFaces(self, id):
3706 Return the number of faces for the given element
3709 return self.mesh.ElemNbFaces(id)
3711 def GetElemFaceNodes(self,elemId, faceIndex):
3713 Return nodes of given face (counted from zero) for given volumic element.
3716 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3718 def GetFaceNormal(self, faceId, normalized=False):
3720 Return three components of normal of given mesh face
3721 (or an empty array in KO case)
3724 return self.mesh.GetFaceNormal(faceId,normalized)
3726 def FindElementByNodes(self, nodes):
3728 Return an element based on all given nodes.
3731 return self.mesh.FindElementByNodes(nodes)
3733 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3735 Return elements including all given nodes.
3738 return self.mesh.GetElementsByNodes( nodes, elemType )
3740 def IsPoly(self, id):
3742 Return true if the given element is a polygon
3745 return self.mesh.IsPoly(id)
3747 def IsQuadratic(self, id):
3749 Return true if the given element is quadratic
3752 return self.mesh.IsQuadratic(id)
3754 def GetBallDiameter(self, id):
3756 Return diameter of a ball discrete element or zero in case of an invalid *id*
3759 return self.mesh.GetBallDiameter(id)
3761 def BaryCenter(self, id):
3763 Return XYZ coordinates of the barycenter of the given element.
3764 If there is no element for the given ID - return an empty list
3767 a list of three double values
3770 :meth:`smeshBuilder.GetGravityCenter`
3773 return self.mesh.BaryCenter(id)
3775 def GetIdsFromFilter(self, filter, meshParts=[] ):
3777 Pass mesh elements through the given filter and return IDs of fitting elements
3780 filter: :class:`SMESH.Filter`
3781 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3787 :meth:`SMESH.Filter.GetIDs`
3788 :meth:`SMESH.Filter.GetElementsIdFromParts`
3791 filter.SetMesh( self.mesh )
3794 if isinstance( meshParts, Mesh ):
3795 filter.SetMesh( meshParts.GetMesh() )
3796 return theFilter.GetIDs()
3797 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3798 meshParts = [ meshParts ]
3799 return filter.GetElementsIdFromParts( meshParts )
3801 return filter.GetIDs()
3803 # Get mesh measurements information:
3804 # ------------------------------------
3806 def GetFreeBorders(self):
3808 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3809 Return a list of special structures (borders).
3812 a list of :class:`SMESH.FreeEdges.Border`
3815 aFilterMgr = self.smeshpyD.CreateFilterManager()
3816 aPredicate = aFilterMgr.CreateFreeEdges()
3817 aPredicate.SetMesh(self.mesh)
3818 aBorders = aPredicate.GetBorders()
3819 aFilterMgr.UnRegister()
3822 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3824 Get minimum distance between two nodes, elements or distance to the origin
3827 id1: first node/element id
3828 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3829 isElem1: *True* if *id1* is element id, *False* if it is node id
3830 isElem2: *True* if *id2* is element id, *False* if it is node id
3833 minimum distance value
3835 :meth:`GetMinDistance`
3838 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3839 return aMeasure.value
3841 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3843 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3846 id1: first node/element id
3847 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3848 isElem1: *True* if *id1* is element id, *False* if it is node id
3849 isElem2: *True* if *id2* is element id, *False* if it is node id
3852 :class:`SMESH.Measure` structure
3858 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3860 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3863 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3865 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3870 aMeasurements = self.smeshpyD.CreateMeasurements()
3871 aMeasure = aMeasurements.MinDistance(id1, id2)
3872 genObjUnRegister([aMeasurements,id1, id2])
3875 def BoundingBox(self, objects=None, isElem=False):
3877 Get bounding box of the specified object(s)
3880 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3881 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3882 *False* specifies that *objects* are nodes
3885 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3888 :meth:`GetBoundingBox()`
3891 result = self.GetBoundingBox(objects, isElem)
3895 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3898 def GetBoundingBox(self, objects=None, isElem=False):
3900 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3903 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3904 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3905 False means that *objects* are nodes
3908 :class:`SMESH.Measure` structure
3911 :meth:`BoundingBox()`
3915 objects = [self.mesh]
3916 elif isinstance(objects, tuple):
3917 objects = list(objects)
3918 if not isinstance(objects, list):
3920 if len(objects) > 0 and isinstance(objects[0], int):
3923 unRegister = genObjUnRegister()
3925 if isinstance(o, Mesh):
3926 srclist.append(o.mesh)
3927 elif hasattr(o, "_narrow"):
3928 src = o._narrow(SMESH.SMESH_IDSource)
3929 if src: srclist.append(src)
3931 elif isinstance(o, list):
3933 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3935 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3936 unRegister.set( srclist[-1] )
3939 aMeasurements = self.smeshpyD.CreateMeasurements()
3940 unRegister.set( aMeasurements )
3941 aMeasure = aMeasurements.BoundingBox(srclist)
3944 # Mesh edition (SMESH_MeshEditor functionality):
3945 # ---------------------------------------------
3947 def RemoveElements(self, IDsOfElements):
3949 Remove the elements from the mesh by ids
3952 IDsOfElements: is a list of ids of elements to remove
3958 return self.editor.RemoveElements(IDsOfElements)
3960 def RemoveNodes(self, IDsOfNodes):
3962 Remove nodes from mesh by ids
3965 IDsOfNodes: is a list of ids of nodes to remove
3971 return self.editor.RemoveNodes(IDsOfNodes)
3973 def RemoveOrphanNodes(self):
3975 Remove all orphan (free) nodes from mesh
3978 number of the removed nodes
3981 return self.editor.RemoveOrphanNodes()
3983 def AddNode(self, x, y, z):
3985 Add a node to the mesh by coordinates
3991 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3992 if hasVars: self.mesh.SetParameters(Parameters)
3993 return self.editor.AddNode( x, y, z)
3995 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3997 Create a 0D element on a node with given number.
4000 IDOfNode: the ID of node for creation of the element.
4001 DuplicateElements: to add one more 0D element to a node or not
4004 ID of the new 0D element
4007 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4009 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4011 Create 0D elements on all nodes of the given elements except those
4012 nodes on which a 0D element already exists.
4015 theObject: an object on whose nodes 0D elements will be created.
4016 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4017 theGroupName: optional name of a group to add 0D elements created
4018 and/or found on nodes of *theObject*.
4019 DuplicateElements: to add one more 0D element to a node or not
4022 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4023 IDs of new and/or found 0D elements. IDs of 0D elements
4024 can be retrieved from the returned object by
4025 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4028 unRegister = genObjUnRegister()
4029 if isinstance( theObject, Mesh ):
4030 theObject = theObject.GetMesh()
4031 elif isinstance( theObject, list ):
4032 theObject = self.GetIDSource( theObject, SMESH.ALL )
4033 unRegister.set( theObject )
4034 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4036 def AddBall(self, IDOfNode, diameter):
4038 Create a ball element on a node with given ID.
4041 IDOfNode: the ID of node for creation of the element.
4042 diameter: the bal diameter.
4045 ID of the new ball element
4048 return self.editor.AddBall( IDOfNode, diameter )
4050 def AddEdge(self, IDsOfNodes):
4052 Create a linear or quadratic edge (this is determined
4053 by the number of given nodes).
4056 IDsOfNodes: list of node IDs for creation of the element.
4057 The order of nodes in this list should correspond to
4058 the :ref:`connectivity convention <connectivity_page>`.
4064 return self.editor.AddEdge(IDsOfNodes)
4066 def AddFace(self, IDsOfNodes):
4068 Create a linear or quadratic face (this is determined
4069 by the number of given nodes).
4072 IDsOfNodes: list of node IDs for creation of the element.
4073 The order of nodes in this list should correspond to
4074 the :ref:`connectivity convention <connectivity_page>`.
4080 return self.editor.AddFace(IDsOfNodes)
4082 def AddPolygonalFace(self, IdsOfNodes):
4084 Add a polygonal face defined by a list of node IDs
4087 IdsOfNodes: the list of node IDs for creation of the element.
4093 return self.editor.AddPolygonalFace(IdsOfNodes)
4095 def AddQuadPolygonalFace(self, IdsOfNodes):
4097 Add a quadratic polygonal face defined by a list of node IDs
4100 IdsOfNodes: the list of node IDs for creation of the element;
4101 corner nodes follow first.
4107 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4109 def AddVolume(self, IDsOfNodes):
4111 Create both simple and quadratic volume (this is determined
4112 by the number of given nodes).
4115 IDsOfNodes: list of node IDs for creation of the element.
4116 The order of nodes in this list should correspond to
4117 the :ref:`connectivity convention <connectivity_page>`.
4120 ID of the new volumic element
4123 return self.editor.AddVolume(IDsOfNodes)
4125 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4127 Create a volume of many faces, giving nodes for each face.
4130 IdsOfNodes: list of node IDs for volume creation, face by face.
4131 Quantities: list of integer values, Quantities[i]
4132 gives the quantity of nodes in face number i.
4135 ID of the new volumic element
4138 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4140 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4142 Create a volume of many faces, giving the IDs of the existing faces.
4145 The created volume will refer only to the nodes
4146 of the given faces, not to the faces themselves.
4149 IdsOfFaces: the list of face IDs for volume creation.
4152 ID of the new volumic element
4155 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4158 def SetNodeOnVertex(self, NodeID, Vertex):
4160 Bind a node to a vertex
4164 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4167 True if succeed else raises an exception
4170 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4171 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4175 self.editor.SetNodeOnVertex(NodeID, VertexID)
4176 except SALOME.SALOME_Exception as inst:
4177 raise ValueError(inst.details.text)
4181 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4183 Store the node position on an edge
4187 Edge: an edge (GEOM.GEOM_Object) or edge ID
4188 paramOnEdge: a parameter on the edge where the node is located
4191 True if succeed else raises an exception
4194 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4195 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4199 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4200 except SALOME.SALOME_Exception as inst:
4201 raise ValueError(inst.details.text)
4204 def SetNodeOnFace(self, NodeID, Face, u, v):
4206 Store node position on a face
4210 Face: a face (GEOM.GEOM_Object) or face ID
4211 u: U parameter on the face where the node is located
4212 v: V parameter on the face where the node is located
4215 True if succeed else raises an exception
4218 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4219 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4223 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4224 except SALOME.SALOME_Exception as inst:
4225 raise ValueError(inst.details.text)
4228 def SetNodeInVolume(self, NodeID, Solid):
4230 Bind a node to a solid
4234 Solid: a solid (GEOM.GEOM_Object) or solid ID
4237 True if succeed else raises an exception
4240 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4241 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4245 self.editor.SetNodeInVolume(NodeID, SolidID)
4246 except SALOME.SALOME_Exception as inst:
4247 raise ValueError(inst.details.text)
4250 def SetMeshElementOnShape(self, ElementID, Shape):
4252 Bind an element to a shape
4255 ElementID: an element ID
4256 Shape: a shape (GEOM.GEOM_Object) or shape ID
4259 True if succeed else raises an exception
4262 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4263 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4267 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4268 except SALOME.SALOME_Exception as inst:
4269 raise ValueError(inst.details.text)
4273 def MoveNode(self, NodeID, x, y, z):
4275 Move the node with the given id
4278 NodeID: the id of the node
4279 x: a new X coordinate
4280 y: a new Y coordinate
4281 z: a new Z coordinate
4284 True if succeed else False
4287 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4288 if hasVars: self.mesh.SetParameters(Parameters)
4289 return self.editor.MoveNode(NodeID, x, y, z)
4291 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4293 Find the node closest to a point and moves it to a point location
4296 x: the X coordinate of a point
4297 y: the Y coordinate of a point
4298 z: the Z coordinate of a point
4299 NodeID: if specified (>0), the node with this ID is moved,
4300 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4303 the ID of a moved node
4306 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4307 if hasVars: self.mesh.SetParameters(Parameters)
4308 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4310 def FindNodeClosestTo(self, x, y, z):
4312 Find the node closest to a point
4315 x: the X coordinate of a point
4316 y: the Y coordinate of a point
4317 z: the Z coordinate of a point
4323 return self.editor.FindNodeClosestTo(x, y, z)
4325 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4327 Find the elements where a point lays IN or ON
4330 x,y,z (float): coordinates of the point
4331 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4332 means elements of any type excluding nodes, discrete and 0D elements.
4333 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4336 list of IDs of found elements
4339 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4341 return self.editor.FindElementsByPoint(x, y, z, elementType)
4343 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4345 Project a point to a mesh object.
4346 Return ID of an element of given type where the given point is projected
4347 and coordinates of the projection point.
4348 In the case if nothing found, return -1 and []
4350 if isinstance( meshObject, Mesh ):
4351 meshObject = meshObject.GetMesh()
4353 meshObject = self.GetMesh()
4354 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4356 def GetPointState(self, x, y, z):
4358 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4359 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4360 UNKNOWN state means that either mesh is wrong or the analysis fails.
4363 return self.editor.GetPointState(x, y, z)
4365 def IsManifold(self):
4367 Check if a 2D mesh is manifold
4370 return self.editor.IsManifold()
4372 def IsCoherentOrientation2D(self):
4374 Check if orientation of 2D elements is coherent
4377 return self.editor.IsCoherentOrientation2D()
4379 def Get1DBranches( self, edges, startNode = 0 ):
4381 Partition given 1D elements into groups of contiguous edges.
4382 A node where number of meeting edges != 2 is a group end.
4383 An optional startNode is used to orient groups it belongs to.
4386 A list of edge groups and a list of corresponding node groups,
4387 where the group is a list of IDs of edges or elements, like follows
4388 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4389 If a group is closed, the first and last nodes of the group are same.
4391 if isinstance( edges, Mesh ):
4392 edges = edges.GetMesh()
4393 unRegister = genObjUnRegister()
4394 if isinstance( edges, list ):
4395 edges = self.GetIDSource( edges, SMESH.EDGE )
4396 unRegister.set( edges )
4397 return self.editor.Get1DBranches( edges, startNode )
4399 def FindSharpEdges( self, angle, addExisting=False ):
4401 Return sharp edges of faces and non-manifold ones.
4402 Optionally add existing edges.
4405 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4406 addExisting: to return existing edges (1D elements) as well
4409 list of FaceEdge structures
4411 angle = ParseParameters( angle )[0]
4412 return self.editor.FindSharpEdges( angle, addExisting )
4414 def MeshToPassThroughAPoint(self, x, y, z):
4416 Find the node closest to a point and moves it to a point location
4419 x: the X coordinate of a point
4420 y: the Y coordinate of a point
4421 z: the Z coordinate of a point
4424 the ID of a moved node
4427 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4429 def InverseDiag(self, NodeID1, NodeID2):
4431 Replace two neighbour triangles sharing Node1-Node2 link
4432 with the triangles built on the same 4 nodes but having other common link.
4435 NodeID1: the ID of the first node
4436 NodeID2: the ID of the second node
4439 False if proper faces were not found
4441 return self.editor.InverseDiag(NodeID1, NodeID2)
4443 def DeleteDiag(self, NodeID1, NodeID2):
4445 Replace two neighbour triangles sharing *Node1-Node2* link
4446 with a quadrangle built on the same 4 nodes.
4449 NodeID1: ID of the first node
4450 NodeID2: ID of the second node
4453 False if proper faces were not found
4456 return self.editor.DeleteDiag(NodeID1, NodeID2)
4458 def Reorient(self, IDsOfElements=None):
4460 Reorient elements by ids
4463 IDsOfElements: if undefined reorients all mesh elements
4466 True if succeed else False
4469 if IDsOfElements == None:
4470 IDsOfElements = self.GetElementsId()
4471 return self.editor.Reorient(IDsOfElements)
4473 def ReorientObject(self, theObject):
4475 Reorient all elements of the object
4478 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4481 True if succeed else False
4484 if ( isinstance( theObject, Mesh )):
4485 theObject = theObject.GetMesh()
4486 return self.editor.ReorientObject(theObject)
4488 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4490 Reorient faces contained in *the2DObject*.
4493 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4494 theDirection: a desired direction of normal of *theFace*.
4495 It can be either a GEOM vector or a list of coordinates [x,y,z].
4496 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4497 compared with theDirection. It can be either ID of face or a point
4498 by which the face will be found. The point can be given as either
4499 a GEOM vertex or a list of point coordinates.
4502 number of reoriented faces
4505 unRegister = genObjUnRegister()
4507 if isinstance( the2DObject, Mesh ):
4508 the2DObject = the2DObject.GetMesh()
4509 if isinstance( the2DObject, list ):
4510 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4511 unRegister.set( the2DObject )
4512 # check theDirection
4513 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4514 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4515 if isinstance( theDirection, list ):
4516 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4517 # prepare theFace and thePoint
4518 theFace = theFaceOrPoint
4519 thePoint = PointStruct(0,0,0)
4520 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4521 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4523 if isinstance( theFaceOrPoint, list ):
4524 thePoint = PointStruct( *theFaceOrPoint )
4526 if isinstance( theFaceOrPoint, PointStruct ):
4527 thePoint = theFaceOrPoint
4529 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4531 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4533 Reorient faces according to adjacent volumes.
4536 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4537 either IDs of faces or face groups.
4538 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4539 theOutsideNormal: to orient faces to have their normals
4540 pointing either *outside* or *inside* the adjacent volumes.
4543 number of reoriented faces.
4546 unRegister = genObjUnRegister()
4548 if not isinstance( the2DObject, list ):
4549 the2DObject = [ the2DObject ]
4550 elif the2DObject and isinstance( the2DObject[0], int ):
4551 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4552 unRegister.set( the2DObject )
4553 the2DObject = [ the2DObject ]
4554 for i,obj2D in enumerate( the2DObject ):
4555 if isinstance( obj2D, Mesh ):
4556 the2DObject[i] = obj2D.GetMesh()
4557 if isinstance( obj2D, list ):
4558 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4559 unRegister.set( the2DObject[i] )
4561 if isinstance( the3DObject, Mesh ):
4562 the3DObject = the3DObject.GetMesh()
4563 if isinstance( the3DObject, list ):
4564 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4565 unRegister.set( the3DObject )
4566 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4568 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4570 Fuse the neighbouring triangles into quadrangles.
4573 IDsOfElements: The triangles to be fused.
4574 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4575 applied to possible quadrangles to choose a neighbour to fuse with.
4576 Note that not all items of :class:`SMESH.FunctorType` corresponds
4577 to numerical functors.
4578 MaxAngle: is the maximum angle between element normals at which the fusion
4579 is still performed; theMaxAngle is measured in radians.
4580 Also it could be a name of variable which defines angle in degrees.
4583 True in case of success, False otherwise.
4586 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4587 self.mesh.SetParameters(Parameters)
4588 if not IDsOfElements:
4589 IDsOfElements = self.GetElementsId()
4590 Functor = self.smeshpyD.GetFunctor(theCriterion)
4591 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4593 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4595 Fuse the neighbouring triangles of the object into quadrangles
4598 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4599 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4600 applied to possible quadrangles to choose a neighbour to fuse with.
4601 Note that not all items of :class:`SMESH.FunctorType` corresponds
4602 to numerical functors.
4603 MaxAngle: a max angle between element normals at which the fusion
4604 is still performed; theMaxAngle is measured in radians.
4607 True in case of success, False otherwise.
4610 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4611 self.mesh.SetParameters(Parameters)
4612 if isinstance( theObject, Mesh ):
4613 theObject = theObject.GetMesh()
4614 Functor = self.smeshpyD.GetFunctor(theCriterion)
4615 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4617 def QuadToTri (self, IDsOfElements, theCriterion = None):
4619 Split quadrangles into triangles.
4622 IDsOfElements: the faces to be splitted.
4623 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4624 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4625 value, then quadrangles will be split by the smallest diagonal.
4626 Note that not all items of :class:`SMESH.FunctorType` corresponds
4627 to numerical functors.
4630 True in case of success, False otherwise.
4632 if IDsOfElements == []:
4633 IDsOfElements = self.GetElementsId()
4634 if theCriterion is None:
4635 theCriterion = FT_MaxElementLength2D
4636 Functor = self.smeshpyD.GetFunctor(theCriterion)
4637 return self.editor.QuadToTri(IDsOfElements, Functor)
4639 def QuadToTriObject (self, theObject, theCriterion = None):
4641 Split quadrangles into triangles.
4644 theObject: the object from which the list of elements is taken,
4645 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4646 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4647 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4648 value, then quadrangles will be split by the smallest diagonal.
4649 Note that not all items of :class:`SMESH.FunctorType` corresponds
4650 to numerical functors.
4653 True in case of success, False otherwise.
4655 if ( isinstance( theObject, Mesh )):
4656 theObject = theObject.GetMesh()
4657 if theCriterion is None:
4658 theCriterion = FT_MaxElementLength2D
4659 Functor = self.smeshpyD.GetFunctor(theCriterion)
4660 return self.editor.QuadToTriObject(theObject, Functor)
4662 def QuadTo4Tri (self, theElements=[]):
4664 Split each of given quadrangles into 4 triangles. A node is added at the center of
4668 theElements: the faces to be splitted. This can be either
4669 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4670 or a list of face IDs. By default all quadrangles are split
4672 unRegister = genObjUnRegister()
4673 if isinstance( theElements, Mesh ):
4674 theElements = theElements.mesh
4675 elif not theElements:
4676 theElements = self.mesh
4677 elif isinstance( theElements, list ):
4678 theElements = self.GetIDSource( theElements, SMESH.FACE )
4679 unRegister.set( theElements )
4680 return self.editor.QuadTo4Tri( theElements )
4682 def SplitQuad (self, IDsOfElements, Diag13):
4684 Split quadrangles into triangles.
4687 IDsOfElements: the faces to be splitted
4688 Diag13 (boolean): is used to choose a diagonal for splitting.
4691 True in case of success, False otherwise.
4693 if IDsOfElements == []:
4694 IDsOfElements = self.GetElementsId()
4695 return self.editor.SplitQuad(IDsOfElements, Diag13)
4697 def SplitQuadObject (self, theObject, Diag13):
4699 Split quadrangles into triangles.
4702 theObject: the object from which the list of elements is taken,
4703 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4704 Diag13 (boolean): is used to choose a diagonal for splitting.
4707 True in case of success, False otherwise.
4709 if ( isinstance( theObject, Mesh )):
4710 theObject = theObject.GetMesh()
4711 return self.editor.SplitQuadObject(theObject, Diag13)
4713 def BestSplit (self, IDOfQuad, theCriterion):
4715 Find a better splitting of the given quadrangle.
4718 IDOfQuad: the ID of the quadrangle to be splitted.
4719 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4720 choose a diagonal for splitting.
4721 Note that not all items of :class:`SMESH.FunctorType` corresponds
4722 to numerical functors.
4725 * 1 if 1-3 diagonal is better,
4726 * 2 if 2-4 diagonal is better,
4727 * 0 if error occurs.
4729 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4731 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4733 Split volumic elements into tetrahedrons
4736 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4737 method: flags passing splitting method:
4738 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4739 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4741 unRegister = genObjUnRegister()
4742 if isinstance( elems, Mesh ):
4743 elems = elems.GetMesh()
4744 if ( isinstance( elems, list )):
4745 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4746 unRegister.set( elems )
4747 self.editor.SplitVolumesIntoTetra(elems, method)
4750 def SplitBiQuadraticIntoLinear(self, elems=None):
4752 Split bi-quadratic elements into linear ones without creation of additional nodes:
4754 - bi-quadratic triangle will be split into 3 linear quadrangles;
4755 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4756 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4758 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4759 will be split in order to keep the mesh conformal.
4762 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4763 if None (default), all bi-quadratic elements will be split
4765 unRegister = genObjUnRegister()
4766 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4767 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4768 unRegister.set( elems )
4770 elems = [ self.GetMesh() ]
4771 if isinstance( elems, Mesh ):
4772 elems = [ elems.GetMesh() ]
4773 if not isinstance( elems, list ):
4775 self.editor.SplitBiQuadraticIntoLinear( elems )
4777 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4778 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4780 Split hexahedra into prisms
4783 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4784 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4785 gives a normal vector defining facets to split into triangles.
4786 *startHexPoint* can be either a triple of coordinates or a vertex.
4787 facetNormal: a normal to a facet to split into triangles of a
4788 hexahedron found by *startHexPoint*.
4789 *facetNormal* can be either a triple of coordinates or an edge.
4790 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4791 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4792 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4793 to *startHexPoint* are split, else *startHexPoint*
4794 is used to find the facet to split in all domains present in *elems*.
4797 unRegister = genObjUnRegister()
4798 if isinstance( elems, Mesh ):
4799 elems = elems.GetMesh()
4800 if ( isinstance( elems, list )):
4801 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4802 unRegister.set( elems )
4805 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4806 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4807 elif isinstance( startHexPoint, list ):
4808 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4811 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4812 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4813 elif isinstance( facetNormal, list ):
4814 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4817 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4819 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4821 def SplitQuadsNearTriangularFacets(self):
4823 Split quadrangle faces near triangular facets of volumes
4825 faces_array = self.GetElementsByType(SMESH.FACE)
4826 for face_id in faces_array:
4827 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4828 quad_nodes = self.mesh.GetElemNodes(face_id)
4829 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4830 isVolumeFound = False
4831 for node1_elem in node1_elems:
4832 if not isVolumeFound:
4833 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4834 nb_nodes = self.GetElemNbNodes(node1_elem)
4835 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4836 volume_elem = node1_elem
4837 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4838 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4839 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4840 isVolumeFound = True
4841 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4842 self.SplitQuad([face_id], False) # diagonal 2-4
4843 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4844 isVolumeFound = True
4845 self.SplitQuad([face_id], True) # diagonal 1-3
4846 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4847 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4848 isVolumeFound = True
4849 self.SplitQuad([face_id], True) # diagonal 1-3
4851 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4853 Split hexahedrons into tetrahedrons.
4855 This operation uses :doc:`pattern_mapping` functionality for splitting.
4858 theObject: the object from which the list of hexahedrons is taken;
4859 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4860 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4861 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4862 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4863 key-point will be mapped into *theNode001*-th node of each volume.
4864 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4867 True in case of success, False otherwise.
4875 # (0,0,1) 4.---------.7 * |
4882 # (0,0,0) 0.---------.3
4883 pattern_tetra = "!!! Nb of points: \n 8 \n\
4893 !!! Indices of points of 6 tetras: \n\
4901 pattern = self.smeshpyD.GetPattern()
4902 isDone = pattern.LoadFromFile(pattern_tetra)
4904 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4907 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4908 isDone = pattern.MakeMesh(self.mesh, False, False)
4909 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4911 # split quafrangle faces near triangular facets of volumes
4912 self.SplitQuadsNearTriangularFacets()
4916 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4918 Split hexahedrons into prisms.
4920 Uses the :doc:`pattern_mapping` functionality for splitting.
4923 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4924 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4925 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4926 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4927 will be mapped into the *theNode001* -th node of each volume.
4928 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4931 True in case of success, False otherwise.
4933 # Pattern: 5.---------.6
4938 # (0,0,1) 4.---------.7 |
4945 # (0,0,0) 0.---------.3
4946 pattern_prism = "!!! Nb of points: \n 8 \n\
4956 !!! Indices of points of 2 prisms: \n\
4960 pattern = self.smeshpyD.GetPattern()
4961 isDone = pattern.LoadFromFile(pattern_prism)
4963 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4966 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4967 isDone = pattern.MakeMesh(self.mesh, False, False)
4968 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4970 # Split quafrangle faces near triangular facets of volumes
4971 self.SplitQuadsNearTriangularFacets()
4975 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4976 MaxNbOfIterations, MaxAspectRatio, Method):
4981 IDsOfElements: the list if ids of elements to smooth
4982 IDsOfFixedNodes: the list of ids of fixed nodes.
4983 Note that nodes built on edges and boundary nodes are always fixed.
4984 MaxNbOfIterations: the maximum number of iterations
4985 MaxAspectRatio: varies in range [1.0, inf]
4986 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4987 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4990 True in case of success, False otherwise.
4993 if IDsOfElements == []:
4994 IDsOfElements = self.GetElementsId()
4995 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4996 self.mesh.SetParameters(Parameters)
4997 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4998 MaxNbOfIterations, MaxAspectRatio, Method)
5000 def SmoothObject(self, theObject, IDsOfFixedNodes,
5001 MaxNbOfIterations, MaxAspectRatio, Method):
5003 Smooth elements which belong to the given object
5006 theObject: the object to smooth
5007 IDsOfFixedNodes: the list of ids of fixed nodes.
5008 Note that nodes built on edges and boundary nodes are always fixed.
5009 MaxNbOfIterations: the maximum number of iterations
5010 MaxAspectRatio: varies in range [1.0, inf]
5011 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5012 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5015 True in case of success, False otherwise.
5018 if ( isinstance( theObject, Mesh )):
5019 theObject = theObject.GetMesh()
5020 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5021 MaxNbOfIterations, MaxAspectRatio, Method)
5023 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5024 MaxNbOfIterations, MaxAspectRatio, Method):
5026 Parametrically smooth the given elements
5029 IDsOfElements: the list if ids of elements to smooth
5030 IDsOfFixedNodes: the list of ids of fixed nodes.
5031 Note that nodes built on edges and boundary nodes are always fixed.
5032 MaxNbOfIterations: the maximum number of iterations
5033 MaxAspectRatio: varies in range [1.0, inf]
5034 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5035 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5038 True in case of success, False otherwise.
5041 if IDsOfElements == []:
5042 IDsOfElements = self.GetElementsId()
5043 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5044 self.mesh.SetParameters(Parameters)
5045 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5046 MaxNbOfIterations, MaxAspectRatio, Method)
5048 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5049 MaxNbOfIterations, MaxAspectRatio, Method):
5051 Parametrically smooth the elements which belong to the given object
5054 theObject: the object to smooth
5055 IDsOfFixedNodes: the list of ids of fixed nodes.
5056 Note that nodes built on edges and boundary nodes are always fixed.
5057 MaxNbOfIterations: the maximum number of iterations
5058 MaxAspectRatio: varies in range [1.0, inf]
5059 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5060 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5063 True in case of success, False otherwise.
5066 if ( isinstance( theObject, Mesh )):
5067 theObject = theObject.GetMesh()
5068 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5069 MaxNbOfIterations, MaxAspectRatio, Method)
5071 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5073 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5074 them with quadratic with the same id.
5077 theForce3d: method of new node creation:
5079 * False - the medium node lies at the geometrical entity from which the mesh element is built
5080 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5081 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5082 theToBiQuad: If True, converts the mesh to bi-quadratic
5085 :class:`SMESH.ComputeError` which can hold a warning
5088 If *theSubMesh* is provided, the mesh can become non-conformal
5091 if isinstance( theSubMesh, Mesh ):
5092 theSubMesh = theSubMesh.mesh
5094 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5097 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5099 self.editor.ConvertToQuadratic(theForce3d)
5100 error = self.editor.GetLastError()
5101 if error and error.comment:
5102 print(error.comment)
5105 def ConvertFromQuadratic(self, theSubMesh=None):
5107 Convert the mesh from quadratic to ordinary,
5108 deletes old quadratic elements,
5109 replacing them with ordinary mesh elements with the same id.
5112 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5115 If *theSubMesh* is provided, the mesh can become non-conformal
5119 self.editor.ConvertFromQuadraticObject(theSubMesh)
5121 return self.editor.ConvertFromQuadratic()
5123 def Make2DMeshFrom3D(self):
5125 Create 2D mesh as skin on boundary faces of a 3D mesh
5128 True if operation has been completed successfully, False otherwise
5131 return self.editor.Make2DMeshFrom3D()
5133 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5134 toCopyElements=False, toCopyExistingBondary=False):
5136 Create missing boundary elements
5139 elements: elements whose boundary is to be checked:
5140 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5141 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5142 dimension: defines type of boundary elements to create, either of
5143 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5144 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5145 groupName: a name of group to store created boundary elements in,
5146 "" means not to create the group
5147 meshName: a name of new mesh to store created boundary elements in,
5148 "" means not to create the new mesh
5149 toCopyElements: if True, the checked elements will be copied into
5150 the new mesh else only boundary elements will be copied into the new mesh
5151 toCopyExistingBondary: if True, not only new but also pre-existing
5152 boundary elements will be copied into the new mesh
5155 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5158 unRegister = genObjUnRegister()
5159 if isinstance( elements, Mesh ):
5160 elements = elements.GetMesh()
5161 if ( isinstance( elements, list )):
5162 elemType = SMESH.ALL
5163 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5164 elements = self.editor.MakeIDSource(elements, elemType)
5165 unRegister.set( elements )
5166 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5167 toCopyElements,toCopyExistingBondary)
5168 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5171 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5172 toCopyAll=False, groups=[]):
5174 Create missing boundary elements around either the whole mesh or
5178 dimension: defines type of boundary elements to create, either of
5179 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5180 groupName: a name of group to store all boundary elements in,
5181 "" means not to create the group
5182 meshName: a name of a new mesh, which is a copy of the initial
5183 mesh + created boundary elements; "" means not to create the new mesh
5184 toCopyAll: if True, the whole initial mesh will be copied into
5185 the new mesh else only boundary elements will be copied into the new mesh
5186 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5189 tuple( long, mesh, group )
5190 - long - number of added boundary elements
5191 - mesh - the :class:`Mesh` where elements were added to
5192 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5195 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5197 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5198 return nb, mesh, group
5200 def RenumberNodes(self):
5202 Renumber mesh nodes to remove unused node IDs
5204 self.editor.RenumberNodes()
5206 def RenumberElements(self):
5208 Renumber mesh elements to remove unused element IDs
5210 self.editor.RenumberElements()
5212 def _getIdSourceList(self, arg, idType, unRegister):
5214 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5216 if arg and isinstance( arg, list ):
5217 if isinstance( arg[0], int ):
5218 arg = self.GetIDSource( arg, idType )
5219 unRegister.set( arg )
5220 elif isinstance( arg[0], Mesh ):
5221 arg[0] = arg[0].GetMesh()
5222 elif isinstance( arg, Mesh ):
5224 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5228 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5229 MakeGroups=False, TotalAngle=False):
5231 Generate new elements by rotation of the given elements and nodes around the axis
5234 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5235 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5236 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5237 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5238 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5239 which defines angle in degrees
5240 NbOfSteps: the number of steps
5241 Tolerance: tolerance
5242 MakeGroups: forces the generation of new groups from existing ones
5243 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5244 of all steps, else - size of each step
5247 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5250 unRegister = genObjUnRegister()
5251 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5252 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5253 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5255 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5256 Axis = self.smeshpyD.GetAxisStruct( Axis )
5257 if isinstance( Axis, list ):
5258 Axis = SMESH.AxisStruct( *Axis )
5260 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5261 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5262 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5263 self.mesh.SetParameters(Parameters)
5264 if TotalAngle and NbOfSteps:
5265 AngleInRadians /= NbOfSteps
5266 return self.editor.RotationSweepObjects( nodes, edges, faces,
5267 Axis, AngleInRadians,
5268 NbOfSteps, Tolerance, MakeGroups)
5270 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5271 MakeGroups=False, TotalAngle=False):
5273 Generate new elements by rotation of the elements around the axis
5276 IDsOfElements: the list of ids of elements to sweep
5277 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5278 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5279 NbOfSteps: the number of steps
5280 Tolerance: tolerance
5281 MakeGroups: forces the generation of new groups from existing ones
5282 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5283 of all steps, else - size of each step
5286 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5289 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5290 AngleInRadians, NbOfSteps, Tolerance,
5291 MakeGroups, TotalAngle)
5293 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5294 MakeGroups=False, TotalAngle=False):
5296 Generate new elements by rotation of the elements of object around the axis
5297 theObject object which elements should be sweeped.
5298 It can be a mesh, a sub mesh or a group.
5301 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5302 AngleInRadians: the angle of Rotation
5303 NbOfSteps: number of steps
5304 Tolerance: tolerance
5305 MakeGroups: forces the generation of new groups from existing ones
5306 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5307 of all steps, else - size of each step
5310 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5313 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5314 AngleInRadians, NbOfSteps, Tolerance,
5315 MakeGroups, TotalAngle )
5317 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5318 MakeGroups=False, TotalAngle=False):
5320 Generate new elements by rotation of the elements of object around the axis
5321 theObject object which elements should be sweeped.
5322 It can be a mesh, a sub mesh or a group.
5325 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5326 AngleInRadians: the angle of Rotation
5327 NbOfSteps: number of steps
5328 Tolerance: tolerance
5329 MakeGroups: forces the generation of new groups from existing ones
5330 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5331 of all steps, else - size of each step
5334 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5335 empty list otherwise
5338 return self.RotationSweepObjects([],theObject,[], Axis,
5339 AngleInRadians, NbOfSteps, Tolerance,
5340 MakeGroups, TotalAngle)
5342 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5343 MakeGroups=False, TotalAngle=False):
5345 Generate new elements by rotation of the elements of object around the axis
5346 theObject object which elements should be sweeped.
5347 It can be a mesh, a sub mesh or a group.
5350 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5351 AngleInRadians: the angle of Rotation
5352 NbOfSteps: number of steps
5353 Tolerance: tolerance
5354 MakeGroups: forces the generation of new groups from existing ones
5355 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5356 of all steps, else - size of each step
5359 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5362 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5363 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5365 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5366 scaleFactors=[], linearVariation=False, basePoint=[],
5367 angles=[], anglesVariation=False):
5369 Generate new elements by extrusion of the given elements and nodes
5372 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5373 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5374 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5375 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5376 the direction and value of extrusion for one step (the total extrusion
5377 length will be NbOfSteps * ||StepVector||)
5378 NbOfSteps: the number of steps
5379 MakeGroups: forces the generation of new groups from existing ones
5380 scaleFactors: optional scale factors to apply during extrusion
5381 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5382 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5383 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5384 nodes and elements being extruded is used as the scaling center.
5387 - a list of tree components of the point or
5390 angles: list of angles in radians. Nodes at each extrusion step are rotated
5391 around *basePoint*, additionally to previous steps.
5392 anglesVariation: forces the computation of rotation angles as linear
5393 variation of the given *angles* along path steps
5395 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5397 Example: :ref:`tui_extrusion`
5399 unRegister = genObjUnRegister()
5400 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5401 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5402 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5404 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5405 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5406 if isinstance( StepVector, list ):
5407 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5409 if isinstance( basePoint, int):
5410 xyz = self.GetNodeXYZ( basePoint )
5412 raise RuntimeError("Invalid node ID: %s" % basePoint)
5414 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5415 basePoint = self.geompyD.PointCoordinates( basePoint )
5417 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5418 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5419 angles,angleParameters,hasVars = ParseAngles(angles)
5420 Parameters = StepVector.PS.parameters + var_separator + \
5421 Parameters + var_separator + \
5422 scaleParameters + var_separator + angleParameters
5423 self.mesh.SetParameters(Parameters)
5425 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5426 StepVector, NbOfSteps, MakeGroups,
5427 scaleFactors, linearVariation, basePoint,
5428 angles, anglesVariation )
5431 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5433 Generate new elements by extrusion of the elements with given ids
5436 IDsOfElements: the list of ids of elements or nodes for extrusion
5437 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5438 the direction and value of extrusion for one step (the total extrusion
5439 length will be NbOfSteps * ||StepVector||)
5440 NbOfSteps: the number of steps
5441 MakeGroups: forces the generation of new groups from existing ones
5442 IsNodes: is True if elements with given ids are nodes
5445 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5447 Example: :ref:`tui_extrusion`
5450 if IsNodes: n = IDsOfElements
5451 else : e,f, = IDsOfElements,IDsOfElements
5452 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5454 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5455 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5457 Generate new elements by extrusion along the normal to a discretized surface or wire
5460 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5461 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5462 StepSize: length of one extrusion step (the total extrusion
5463 length will be *NbOfSteps* *StepSize*).
5464 NbOfSteps: number of extrusion steps.
5465 ByAverageNormal: if True each node is translated by *StepSize*
5466 along the average of the normal vectors to the faces sharing the node;
5467 else each node is translated along the same average normal till
5468 intersection with the plane got by translation of the face sharing
5469 the node along its own normal by *StepSize*.
5470 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5471 for every node of *Elements*.
5472 MakeGroups: forces generation of new groups from existing ones.
5473 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5474 is not yet implemented. This parameter is used if *Elements* contains
5475 both faces and edges, i.e. *Elements* is a Mesh.
5478 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5479 empty list otherwise.
5480 Example: :ref:`tui_extrusion`
5483 unRegister = genObjUnRegister()
5484 if isinstance( Elements, Mesh ):
5485 Elements = [ Elements.GetMesh() ]
5486 if isinstance( Elements, list ):
5488 raise RuntimeError("Elements empty!")
5489 if isinstance( Elements[0], int ):
5490 Elements = self.GetIDSource( Elements, SMESH.ALL )
5491 unRegister.set( Elements )
5492 if not isinstance( Elements, list ):
5493 Elements = [ Elements ]
5494 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5495 self.mesh.SetParameters(Parameters)
5496 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5497 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5499 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5501 Generate new elements by extrusion of the elements or nodes which belong to the object
5504 theObject: the object whose elements or nodes should be processed.
5505 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5506 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5507 the direction and value of extrusion for one step (the total extrusion
5508 length will be NbOfSteps * ||StepVector||)
5509 NbOfSteps: the number of steps
5510 MakeGroups: forces the generation of new groups from existing ones
5511 IsNodes: is True if elements to extrude are nodes
5514 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5515 Example: :ref:`tui_extrusion`
5519 if IsNodes: n = theObject
5520 else : e,f, = theObject,theObject
5521 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5523 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5525 Generate new elements by extrusion of edges which belong to the object
5528 theObject: object whose 1D elements should be processed.
5529 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5530 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5531 the direction and value of extrusion for one step (the total extrusion
5532 length will be NbOfSteps * ||StepVector||)
5533 NbOfSteps: the number of steps
5534 MakeGroups: to generate new groups from existing ones
5537 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5538 Example: :ref:`tui_extrusion`
5541 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5543 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5545 Generate new elements by extrusion of faces which belong to the object
5548 theObject: object whose 2D elements should be processed.
5549 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5550 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5551 the direction and value of extrusion for one step (the total extrusion
5552 length will be NbOfSteps * ||StepVector||)
5553 NbOfSteps: the number of steps
5554 MakeGroups: forces the generation of new groups from existing ones
5557 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5558 Example: :ref:`tui_extrusion`
5561 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5563 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5564 ExtrFlags, SewTolerance, MakeGroups=False):
5566 Generate new elements by extrusion of the elements with given ids
5569 IDsOfElements: is ids of elements
5570 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5571 the direction and value of extrusion for one step (the total extrusion
5572 length will be NbOfSteps * ||StepVector||)
5573 NbOfSteps: the number of steps
5574 ExtrFlags: sets flags for extrusion
5575 SewTolerance: uses for comparing locations of nodes if flag
5576 EXTRUSION_FLAG_SEW is set
5577 MakeGroups: forces the generation of new groups from existing ones
5580 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5583 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5584 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5585 if isinstance( StepVector, list ):
5586 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5587 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5588 ExtrFlags, SewTolerance, MakeGroups)
5590 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5591 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5592 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5593 ScaleFactors=[], ScalesVariation=False):
5595 Generate new elements by extrusion of the given elements and nodes along the path.
5596 The path of extrusion must be a meshed edge.
5599 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5600 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5601 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5602 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5603 PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None
5604 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5605 HasAngles: not used obsolete
5606 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5607 around *basePoint*, additionally to previous steps.
5608 LinearVariation: forces the computation of rotation angles as linear
5609 variation of the given Angles along path steps
5610 HasRefPoint: allows using the reference point
5611 RefPoint: optional scaling and rotation center (mass center of the extruded
5612 elements by default). The User can specify any point as the Reference Point.
5613 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5614 MakeGroups: forces the generation of new groups from existing ones
5615 ScaleFactors: optional scale factors to apply during extrusion
5616 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5617 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5620 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5621 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5622 Example: :ref:`tui_extrusion_along_path`
5625 unRegister = genObjUnRegister()
5626 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5627 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5628 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5630 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5631 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5632 if isinstance( RefPoint, list ):
5633 if not RefPoint: RefPoint = [0,0,0]
5634 RefPoint = SMESH.PointStruct( *RefPoint )
5635 if isinstance( PathObject, Mesh ):
5636 PathObject = PathObject.GetMesh()
5637 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5638 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5639 Parameters = AnglesParameters + var_separator + \
5640 RefPoint.parameters + var_separator + ScalesParameters
5641 self.mesh.SetParameters(Parameters)
5642 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5643 PathObject, PathShape, NodeStart,
5644 HasAngles, Angles, LinearVariation,
5645 HasRefPoint, RefPoint, MakeGroups,
5646 ScaleFactors, ScalesVariation)
5648 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5649 HasAngles=False, Angles=[], LinearVariation=False,
5650 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5651 ElemType=SMESH.FACE):
5653 Generate new elements by extrusion of the given elements.
5654 The path of extrusion must be a meshed edge.
5657 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5658 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5659 NodeStart: the start node from Path. Defines the direction of extrusion
5660 HasAngles: not used obsolete
5661 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5662 around *basePoint*, additionally to previous steps.
5663 LinearVariation: forces the computation of rotation angles as linear
5664 variation of the given Angles along path steps
5665 HasRefPoint: allows using the reference point
5666 RefPoint: the reference point around which the elements are rotated (the mass
5667 center of the elements by default).
5668 The User can specify any point as the Reference Point.
5669 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5670 MakeGroups: forces the generation of new groups from existing ones
5671 ElemType: type of elements for extrusion (if param Base is a mesh)
5674 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5675 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5676 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5678 Example: :ref:`tui_extrusion_along_path`
5682 if ElemType == SMESH.NODE: n = Base
5683 if ElemType == SMESH.EDGE: e = Base
5684 if ElemType == SMESH.FACE: f = Base
5685 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5686 HasAngles, Angles, LinearVariation,
5687 HasRefPoint, RefPoint, MakeGroups)
5688 if MakeGroups: return gr,er
5691 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5692 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5693 MakeGroups=False, LinearVariation=False):
5695 Generate new elements by extrusion of the given elements.
5696 The path of extrusion must be a meshed edge.
5699 IDsOfElements: ids of elements
5700 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5701 PathShape: shape (edge) defines the sub-mesh for the path
5702 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5703 HasAngles: not used obsolete
5704 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5705 around *basePoint*, additionally to previous steps.
5706 HasRefPoint: allows using the reference point
5707 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5708 The User can specify any point as the Reference Point.
5709 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5710 MakeGroups: forces the generation of new groups from existing ones
5711 LinearVariation: forces the computation of rotation angles as linear
5712 variation of the given Angles along path steps
5715 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5716 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5717 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5718 Example: :ref:`tui_extrusion_along_path`
5721 if not IDsOfElements:
5722 IDsOfElements = [ self.GetMesh() ]
5723 n,e,f = [],IDsOfElements,IDsOfElements
5724 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5725 NodeStart, HasAngles, Angles,
5727 HasRefPoint, RefPoint, MakeGroups)
5728 if MakeGroups: return gr,er
5731 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5732 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5733 MakeGroups=False, LinearVariation=False):
5735 Generate new elements by extrusion of the elements which belong to the object.
5736 The path of extrusion must be a meshed edge.
5739 theObject: the object whose elements should be processed.
5740 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5741 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5742 PathShape: shape (edge) defines the sub-mesh for the path
5743 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5744 HasAngles: not used obsolete
5745 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5746 around *basePoint*, additionally to previous steps.
5747 HasRefPoint: allows using the reference point
5748 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5749 The User can specify any point as the Reference Point.
5750 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5751 MakeGroups: forces the generation of new groups from existing ones
5752 LinearVariation: forces the computation of rotation angles as linear
5753 variation of the given Angles along path steps
5756 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5757 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5758 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5759 Example: :ref:`tui_extrusion_along_path`
5762 n,e,f = [],theObject,theObject
5763 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5764 HasAngles, Angles, LinearVariation,
5765 HasRefPoint, RefPoint, MakeGroups)
5766 if MakeGroups: return gr,er
5769 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5770 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5771 MakeGroups=False, LinearVariation=False):
5773 Generate new elements by extrusion of mesh segments which belong to the object.
5774 The path of extrusion must be a meshed edge.
5777 theObject: the object whose 1D elements should be processed.
5778 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5779 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5780 PathShape: shape (edge) defines the sub-mesh for the path
5781 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5782 HasAngles: not used obsolete
5783 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5784 around *basePoint*, additionally to previous steps.
5785 HasRefPoint: allows using the reference point
5786 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5787 The User can specify any point as the Reference Point.
5788 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5789 MakeGroups: forces the generation of new groups from existing ones
5790 LinearVariation: forces the computation of rotation angles as linear
5791 variation of the given Angles along path steps
5794 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5795 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5796 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5797 Example: :ref:`tui_extrusion_along_path`
5800 n,e,f = [],theObject,[]
5801 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5802 HasAngles, Angles, LinearVariation,
5803 HasRefPoint, RefPoint, MakeGroups)
5804 if MakeGroups: return gr,er
5807 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5808 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5809 MakeGroups=False, LinearVariation=False):
5811 Generate new elements by extrusion of faces which belong to the object.
5812 The path of extrusion must be a meshed edge.
5815 theObject: the object whose 2D elements should be processed.
5816 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5817 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5818 PathShape: shape (edge) defines the sub-mesh for the path
5819 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5820 HasAngles: not used obsolete
5821 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5822 around *basePoint*, additionally to previous steps.
5823 HasRefPoint: allows using the reference point
5824 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5825 The User can specify any point as the Reference Point.
5826 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5827 MakeGroups: forces the generation of new groups from existing ones
5828 LinearVariation: forces the computation of rotation angles as linear
5829 variation of the given Angles along path steps
5832 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5833 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5834 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5835 Example: :ref:`tui_extrusion_along_path`
5838 n,e,f = [],[],theObject
5839 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5840 HasAngles, Angles, LinearVariation,
5841 HasRefPoint, RefPoint, MakeGroups)
5842 if MakeGroups: return gr,er
5845 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5847 Create a symmetrical copy of mesh elements
5850 IDsOfElements: list of elements ids
5851 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5852 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5853 If the *Mirror* is a geom object this parameter is unnecessary
5854 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5855 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5858 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5861 if IDsOfElements == []:
5862 IDsOfElements = self.GetElementsId()
5863 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5864 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5865 theMirrorType = Mirror._mirrorType
5867 self.mesh.SetParameters(Mirror.parameters)
5868 if Copy and MakeGroups:
5869 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5870 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5873 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5875 Create a new mesh by a symmetrical copy of mesh elements
5878 IDsOfElements: the list of elements ids
5879 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5880 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5881 If the *Mirror* is a geom object this parameter is unnecessary
5882 MakeGroups: to generate new groups from existing ones
5883 NewMeshName: a name of the new mesh to create
5886 instance of class :class:`Mesh`
5889 if IDsOfElements == []:
5890 IDsOfElements = self.GetElementsId()
5891 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5892 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5893 theMirrorType = Mirror._mirrorType
5895 self.mesh.SetParameters(Mirror.parameters)
5896 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5897 MakeGroups, NewMeshName)
5898 return Mesh(self.smeshpyD,self.geompyD,mesh)
5900 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5902 Create a symmetrical copy of the object
5905 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5906 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5907 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5908 If the *Mirror* is a geom object this parameter is unnecessary
5909 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5910 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5913 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5916 if ( isinstance( theObject, Mesh )):
5917 theObject = theObject.GetMesh()
5918 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5919 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5920 theMirrorType = Mirror._mirrorType
5922 self.mesh.SetParameters(Mirror.parameters)
5923 if Copy and MakeGroups:
5924 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5925 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5928 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5930 Create a new mesh by a symmetrical copy of the object
5933 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5934 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5935 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5936 If the *Mirror* is a geom object this parameter is unnecessary
5937 MakeGroups: forces the generation of new groups from existing ones
5938 NewMeshName: the name of the new mesh to create
5941 instance of class :class:`Mesh`
5944 if ( isinstance( theObject, Mesh )):
5945 theObject = theObject.GetMesh()
5946 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5947 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5948 theMirrorType = Mirror._mirrorType
5950 self.mesh.SetParameters(Mirror.parameters)
5951 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5952 MakeGroups, NewMeshName)
5953 return Mesh( self.smeshpyD,self.geompyD,mesh )
5955 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5957 Translate the elements
5960 IDsOfElements: list of elements ids
5961 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5962 Copy: allows copying the translated elements
5963 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5966 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5969 if IDsOfElements == []:
5970 IDsOfElements = self.GetElementsId()
5971 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5972 Vector = self.smeshpyD.GetDirStruct(Vector)
5973 if isinstance( Vector, list ):
5974 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5975 self.mesh.SetParameters(Vector.PS.parameters)
5976 if Copy and MakeGroups:
5977 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5978 self.editor.Translate(IDsOfElements, Vector, Copy)
5981 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5983 Create a new mesh of translated elements
5986 IDsOfElements: list of elements ids
5987 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5988 MakeGroups: forces the generation of new groups from existing ones
5989 NewMeshName: the name of the newly created mesh
5992 instance of class :class:`Mesh`
5995 if IDsOfElements == []:
5996 IDsOfElements = self.GetElementsId()
5997 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5998 Vector = self.smeshpyD.GetDirStruct(Vector)
5999 if isinstance( Vector, list ):
6000 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6001 self.mesh.SetParameters(Vector.PS.parameters)
6002 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6003 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6005 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6007 Translate the object
6010 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6011 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6012 Copy: allows copying the translated elements
6013 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6016 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6019 if ( isinstance( theObject, Mesh )):
6020 theObject = theObject.GetMesh()
6021 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6022 Vector = self.smeshpyD.GetDirStruct(Vector)
6023 if isinstance( Vector, list ):
6024 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6025 self.mesh.SetParameters(Vector.PS.parameters)
6026 if Copy and MakeGroups:
6027 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6028 self.editor.TranslateObject(theObject, Vector, Copy)
6031 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6033 Create a new mesh from the translated object
6036 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6037 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6038 MakeGroups: forces the generation of new groups from existing ones
6039 NewMeshName: the name of the newly created mesh
6042 instance of class :class:`Mesh`
6045 if isinstance( theObject, Mesh ):
6046 theObject = theObject.GetMesh()
6047 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6048 Vector = self.smeshpyD.GetDirStruct(Vector)
6049 if isinstance( Vector, list ):
6050 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6051 self.mesh.SetParameters(Vector.PS.parameters)
6052 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6053 return Mesh( self.smeshpyD, self.geompyD, mesh )
6057 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6062 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6063 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6064 theScaleFact: list of 1-3 scale factors for axises
6065 Copy: allows copying the translated elements
6066 MakeGroups: forces the generation of new groups from existing
6070 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6071 empty list otherwise
6073 unRegister = genObjUnRegister()
6074 if ( isinstance( theObject, Mesh )):
6075 theObject = theObject.GetMesh()
6076 if ( isinstance( theObject, list )):
6077 theObject = self.GetIDSource(theObject, SMESH.ALL)
6078 unRegister.set( theObject )
6079 if ( isinstance( thePoint, list )):
6080 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6081 if ( isinstance( theScaleFact, float )):
6082 theScaleFact = [theScaleFact]
6083 if ( isinstance( theScaleFact, int )):
6084 theScaleFact = [ float(theScaleFact)]
6086 self.mesh.SetParameters(thePoint.parameters)
6088 if Copy and MakeGroups:
6089 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6090 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6093 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6095 Create a new mesh from the translated object
6098 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6099 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6100 theScaleFact: list of 1-3 scale factors for axises
6101 MakeGroups: forces the generation of new groups from existing ones
6102 NewMeshName: the name of the newly created mesh
6105 instance of class :class:`Mesh`
6107 unRegister = genObjUnRegister()
6108 if (isinstance(theObject, Mesh)):
6109 theObject = theObject.GetMesh()
6110 if ( isinstance( theObject, list )):
6111 theObject = self.GetIDSource(theObject,SMESH.ALL)
6112 unRegister.set( theObject )
6113 if ( isinstance( thePoint, list )):
6114 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6115 if ( isinstance( theScaleFact, float )):
6116 theScaleFact = [theScaleFact]
6117 if ( isinstance( theScaleFact, int )):
6118 theScaleFact = [ float(theScaleFact)]
6120 self.mesh.SetParameters(thePoint.parameters)
6121 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6122 MakeGroups, NewMeshName)
6123 return Mesh( self.smeshpyD, self.geompyD, mesh )
6127 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6132 IDsOfElements: list of elements ids
6133 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6134 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6135 Copy: allows copying the rotated elements
6136 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6139 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6143 if IDsOfElements == []:
6144 IDsOfElements = self.GetElementsId()
6145 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6146 Axis = self.smeshpyD.GetAxisStruct(Axis)
6147 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6148 Parameters = Axis.parameters + var_separator + Parameters
6149 self.mesh.SetParameters(Parameters)
6150 if Copy and MakeGroups:
6151 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6152 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6155 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6157 Create a new mesh of rotated elements
6160 IDsOfElements: list of element ids
6161 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6162 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6163 MakeGroups: forces the generation of new groups from existing ones
6164 NewMeshName: the name of the newly created mesh
6167 instance of class :class:`Mesh`
6170 if IDsOfElements == []:
6171 IDsOfElements = self.GetElementsId()
6172 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6173 Axis = self.smeshpyD.GetAxisStruct(Axis)
6174 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6175 Parameters = Axis.parameters + var_separator + Parameters
6176 self.mesh.SetParameters(Parameters)
6177 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6178 MakeGroups, NewMeshName)
6179 return Mesh( self.smeshpyD, self.geompyD, mesh )
6181 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6186 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6187 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6188 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6189 Copy: allows copying the rotated elements
6190 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6193 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6196 if (isinstance(theObject, Mesh)):
6197 theObject = theObject.GetMesh()
6198 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6199 Axis = self.smeshpyD.GetAxisStruct(Axis)
6200 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6201 Parameters = Axis.parameters + ":" + Parameters
6202 self.mesh.SetParameters(Parameters)
6203 if Copy and MakeGroups:
6204 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6205 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6208 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6210 Create a new mesh from the rotated object
6213 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6214 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6215 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6216 MakeGroups: forces the generation of new groups from existing ones
6217 NewMeshName: the name of the newly created mesh
6220 instance of class :class:`Mesh`
6223 if (isinstance( theObject, Mesh )):
6224 theObject = theObject.GetMesh()
6225 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6226 Axis = self.smeshpyD.GetAxisStruct(Axis)
6227 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6228 Parameters = Axis.parameters + ":" + Parameters
6229 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6230 MakeGroups, NewMeshName)
6231 self.mesh.SetParameters(Parameters)
6232 return Mesh( self.smeshpyD, self.geompyD, mesh )
6234 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6236 Create an offset mesh from the given 2D object
6239 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6240 theValue (float): signed offset size
6241 MakeGroups (boolean): forces the generation of new groups from existing ones
6242 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6243 False means to remove original elements.
6244 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6247 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6250 if isinstance( theObject, Mesh ):
6251 theObject = theObject.GetMesh()
6252 theValue,Parameters,hasVars = ParseParameters(Value)
6253 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6254 self.mesh.SetParameters(Parameters)
6255 # if mesh_groups[0]:
6256 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6259 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6261 Find groups of adjacent nodes within Tolerance.
6264 Tolerance (float): the value of tolerance
6265 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6266 corner and medium nodes in separate groups thus preventing
6267 their further merge.
6270 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6273 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6275 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6276 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6278 Find groups of adjacent nodes within Tolerance.
6281 Tolerance: the value of tolerance
6282 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6283 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6284 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6285 corner and medium nodes in separate groups thus preventing
6286 their further merge.
6289 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6292 unRegister = genObjUnRegister()
6293 if not isinstance( SubMeshOrGroup, list ):
6294 SubMeshOrGroup = [ SubMeshOrGroup ]
6295 for i,obj in enumerate( SubMeshOrGroup ):
6296 if isinstance( obj, Mesh ):
6297 SubMeshOrGroup = [ obj.GetMesh() ]
6299 if isinstance( obj, int ):
6300 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6301 unRegister.set( SubMeshOrGroup )
6304 if not isinstance( exceptNodes, list ):
6305 exceptNodes = [ exceptNodes ]
6306 if exceptNodes and isinstance( exceptNodes[0], int ):
6307 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6308 unRegister.set( exceptNodes )
6310 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6311 exceptNodes, SeparateCornerAndMediumNodes)
6313 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6318 GroupsOfNodes: a list of groups of nodes IDs for merging.
6319 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6320 in all elements and mesh groups by nodes 1 and 25 correspondingly
6321 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6322 If *NodesToKeep* does not include a node to keep for some group to merge,
6323 then the first node in the group is kept.
6324 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6327 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6329 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6331 Find the elements built on the same nodes.
6334 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6335 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6339 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6342 unRegister = genObjUnRegister()
6343 if MeshOrSubMeshOrGroup is None:
6344 MeshOrSubMeshOrGroup = [ self.mesh ]
6345 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6346 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6347 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6348 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6349 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6350 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6351 unRegister.set( MeshOrSubMeshOrGroup )
6352 for item in MeshOrSubMeshOrGroup:
6353 if isinstance( item, Mesh ):
6354 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6356 if not isinstance( exceptElements, list ):
6357 exceptElements = [ exceptElements ]
6358 if exceptElements and isinstance( exceptElements[0], int ):
6359 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6360 unRegister.set( exceptElements )
6362 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6364 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6366 Merge elements in each given group.
6369 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6370 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6371 replaced in all mesh groups by elements 1 and 25)
6372 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6373 If *ElementsToKeep* does not include an element to keep for some group to merge,
6374 then the first element in the group is kept.
6377 unRegister = genObjUnRegister()
6379 if not isinstance( ElementsToKeep, list ):
6380 ElementsToKeep = [ ElementsToKeep ]
6381 if isinstance( ElementsToKeep[0], int ):
6382 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6383 unRegister.set( ElementsToKeep )
6385 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6387 def MergeEqualElements(self):
6389 Leave one element and remove all other elements built on the same nodes.
6392 self.editor.MergeEqualElements()
6394 def FindFreeBorders(self, ClosedOnly=True):
6396 Returns all or only closed free borders
6399 list of SMESH.FreeBorder's
6402 return self.editor.FindFreeBorders( ClosedOnly )
6404 def FillHole(self, holeNodes, groupName=""):
6406 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6409 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6410 must describe all sequential nodes of the hole border. The first and the last
6411 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6412 groupName (string): name of a group to add new faces
6414 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6418 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6419 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6420 if not isinstance( holeNodes, SMESH.FreeBorder ):
6421 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6422 return self.editor.FillHole( holeNodes, groupName )
6424 def FindCoincidentFreeBorders (self, tolerance=0.):
6426 Return groups of FreeBorder's coincident within the given tolerance.
6429 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6430 size of elements adjacent to free borders being compared is used.
6433 SMESH.CoincidentFreeBorders structure
6436 return self.editor.FindCoincidentFreeBorders( tolerance )
6438 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6440 Sew FreeBorder's of each group
6443 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6444 where each enclosed list contains node IDs of a group of coincident free
6445 borders such that each consequent triple of IDs within a group describes
6446 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6447 last node of a border.
6448 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6449 groups of coincident free borders, each group including two borders.
6450 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6451 polygons if a node of opposite border falls on a face edge, else such
6452 faces are split into several ones.
6453 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6454 polyhedra if a node of opposite border falls on a volume edge, else such
6455 volumes, if any, remain intact and the mesh becomes non-conformal.
6458 a number of successfully sewed groups
6461 if freeBorders and isinstance( freeBorders, list ):
6462 # construct SMESH.CoincidentFreeBorders
6463 if isinstance( freeBorders[0], int ):
6464 freeBorders = [freeBorders]
6466 coincidentGroups = []
6467 for nodeList in freeBorders:
6468 if not nodeList or len( nodeList ) % 3:
6469 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6472 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6473 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6474 nodeList = nodeList[3:]
6476 coincidentGroups.append( group )
6478 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6480 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6482 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6483 FirstNodeID2, SecondNodeID2, LastNodeID2,
6484 CreatePolygons, CreatePolyedrs):
6489 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6492 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6493 FirstNodeID2, SecondNodeID2, LastNodeID2,
6494 CreatePolygons, CreatePolyedrs)
6496 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6497 FirstNodeID2, SecondNodeID2):
6499 Sew conform free borders
6502 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6505 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6506 FirstNodeID2, SecondNodeID2)
6508 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6509 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6514 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6517 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6518 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6520 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6521 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6522 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6524 Sew two sides of a mesh. The nodes belonging to Side1 are
6525 merged with the nodes of elements of Side2.
6526 The number of elements in theSide1 and in theSide2 must be
6527 equal and they should have similar nodal connectivity.
6528 The nodes to merge should belong to side borders and
6529 the first node should be linked to the second.
6532 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6535 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6536 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6537 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6539 def ChangeElemNodes(self, ide, newIDs):
6541 Set new nodes for the given element.
6548 False if the number of nodes does not correspond to the type of element
6551 return self.editor.ChangeElemNodes(ide, newIDs)
6553 def GetLastCreatedNodes(self):
6555 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6556 created, this method return the list of their IDs.
6557 If new nodes were not created - return empty list
6560 the list of integer values (can be empty)
6563 return self.editor.GetLastCreatedNodes()
6565 def GetLastCreatedElems(self):
6567 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6568 created this method return the list of their IDs.
6569 If new elements were not created - return empty list
6572 the list of integer values (can be empty)
6575 return self.editor.GetLastCreatedElems()
6577 def ClearLastCreated(self):
6579 Forget what nodes and elements were created by the last mesh edition operation
6582 self.editor.ClearLastCreated()
6584 def DoubleElements(self, theElements, theGroupName=""):
6586 Create duplicates of given elements, i.e. create new elements based on the
6587 same nodes as the given ones.
6590 theElements: container of elements to duplicate. It can be a
6591 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6592 or a list of element IDs. If *theElements* is
6593 a :class:`Mesh`, elements of highest dimension are duplicated
6594 theGroupName: a name of group to contain the generated elements.
6595 If a group with such a name already exists, the new elements
6596 are added to the existing group, else a new group is created.
6597 If *theGroupName* is empty, new elements are not added
6601 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6602 None if *theGroupName* == "".
6605 unRegister = genObjUnRegister()
6606 if isinstance( theElements, Mesh ):
6607 theElements = theElements.mesh
6608 elif isinstance( theElements, list ):
6609 theElements = self.GetIDSource( theElements, SMESH.ALL )
6610 unRegister.set( theElements )
6611 return self.editor.DoubleElements(theElements, theGroupName)
6613 def DoubleNodes(self, theNodes, theModifiedElems):
6615 Create a hole in a mesh by doubling the nodes of some particular elements
6618 theNodes: IDs of nodes to be doubled
6619 theModifiedElems: IDs of elements to be updated by the new (doubled)
6620 nodes. If list of element identifiers is empty then nodes are doubled but
6621 they not assigned to elements
6624 True if operation has been completed successfully, False otherwise
6627 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6629 def DoubleNode(self, theNodeId, theModifiedElems):
6631 Create a hole in a mesh by doubling the nodes of some particular elements.
6632 This method provided for convenience works as :meth:`DoubleNodes`.
6635 theNodeId: IDs of node to double
6636 theModifiedElems: IDs of elements to update
6639 True if operation has been completed successfully, False otherwise
6642 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6644 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6646 Create a hole in a mesh by doubling the nodes of some particular elements.
6647 This method provided for convenience works as :meth:`DoubleNodes`.
6650 theNodes: group of nodes to double.
6651 theModifiedElems: group of elements to update.
6652 theMakeGroup: forces the generation of a group containing new nodes.
6655 True or a created group if operation has been completed successfully,
6656 False or None otherwise
6660 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6661 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6663 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6665 Create a hole in a mesh by doubling the nodes of some particular elements.
6666 This method provided for convenience works as :meth:`DoubleNodes`.
6669 theNodes: list of groups of nodes to double.
6670 theModifiedElems: list of groups of elements to update.
6671 theMakeGroup: forces the generation of a group containing new nodes.
6674 True if operation has been completed successfully, False otherwise
6678 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6679 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6681 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6683 Create a hole in a mesh by doubling the nodes of some particular elements
6686 theElems: the list of elements (edges or faces) to replicate.
6687 The nodes for duplication could be found from these elements
6688 theNodesNot: list of nodes NOT to replicate
6689 theAffectedElems: the list of elements (cells and edges) to which the
6690 replicated nodes should be associated to
6693 True if operation has been completed successfully, False otherwise
6696 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6698 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6700 Create a hole in a mesh by doubling the nodes of some particular elements
6703 theElems: the list of elements (edges or faces) to replicate.
6704 The nodes for duplication could be found from these elements
6705 theNodesNot: list of nodes NOT to replicate
6706 theShape: shape to detect affected elements (element which geometric center
6707 located on or inside shape).
6708 The replicated nodes should be associated to affected elements.
6711 True if operation has been completed successfully, False otherwise
6714 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6716 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6717 theMakeGroup=False, theMakeNodeGroup=False):
6719 Create a hole in a mesh by doubling the nodes of some particular elements.
6720 This method provided for convenience works as :meth:`DoubleNodes`.
6723 theElems: group of of elements (edges or faces) to replicate.
6724 theNodesNot: group of nodes NOT to replicate.
6725 theAffectedElems: group of elements to which the replicated nodes
6726 should be associated to.
6727 theMakeGroup: forces the generation of a group containing new elements.
6728 theMakeNodeGroup: forces the generation of a group containing new nodes.
6731 True or created groups (one or two) if operation has been completed successfully,
6732 False or None otherwise
6735 if theMakeGroup or theMakeNodeGroup:
6736 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6738 theMakeGroup, theMakeNodeGroup)
6739 if theMakeGroup and theMakeNodeGroup:
6742 return twoGroups[ int(theMakeNodeGroup) ]
6743 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6745 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6747 Create a hole in a mesh by doubling the nodes of some particular elements.
6748 This method provided for convenience works as :meth:`DoubleNodes`.
6751 theElems: group of of elements (edges or faces) to replicate
6752 theNodesNot: group of nodes not to replicate
6753 theShape: shape to detect affected elements (element which geometric center
6754 located on or inside shape).
6755 The replicated nodes should be associated to affected elements
6758 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6760 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6761 theMakeGroup=False, theMakeNodeGroup=False):
6763 Create a hole in a mesh by doubling the nodes of some particular elements.
6764 This method provided for convenience works as :meth:`DoubleNodes`.
6767 theElems: list of groups of elements (edges or faces) to replicate
6768 theNodesNot: list of groups of nodes NOT to replicate
6769 theAffectedElems: group of elements to which the replicated nodes
6770 should be associated to
6771 theMakeGroup: forces generation of a group containing new elements.
6772 theMakeNodeGroup: forces generation of a group containing new nodes
6775 True or created groups (one or two) if operation has been completed successfully,
6776 False or None otherwise
6779 if theMakeGroup or theMakeNodeGroup:
6780 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6782 theMakeGroup, theMakeNodeGroup)
6783 if theMakeGroup and theMakeNodeGroup:
6786 return twoGroups[ int(theMakeNodeGroup) ]
6787 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6789 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6791 Create a hole in a mesh by doubling the nodes of some particular elements.
6792 This method provided for convenience works as :meth:`DoubleNodes`.
6795 theElems: list of groups of elements (edges or faces) to replicate
6796 theNodesNot: list of groups of nodes NOT to replicate
6797 theShape: shape to detect affected elements (element which geometric center
6798 located on or inside shape).
6799 The replicated nodes should be associated to affected elements
6802 True if operation has been completed successfully, False otherwise
6805 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6807 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6809 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6810 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6813 theElems: list of groups of nodes or elements (edges or faces) to replicate
6814 theNodesNot: list of groups of nodes NOT to replicate
6815 theShape: shape to detect affected elements (element which geometric center
6816 located on or inside shape).
6817 The replicated nodes should be associated to affected elements
6820 groups of affected elements in order: volumes, faces, edges
6823 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6825 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6828 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6829 The list of groups must describe a partition of the mesh volumes.
6830 The nodes of the internal faces at the boundaries of the groups are doubled.
6831 In option, the internal faces are replaced by flat elements.
6832 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6835 theDomains: list of groups of volumes
6836 createJointElems: if True, create the elements
6837 onAllBoundaries: if True, the nodes and elements are also created on
6838 the boundary between *theDomains* and the rest mesh
6841 True if operation has been completed successfully, False otherwise
6844 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6846 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6848 Double nodes on some external faces and create flat elements.
6849 Flat elements are mainly used by some types of mechanic calculations.
6851 Each group of the list must be constituted of faces.
6852 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6855 theGroupsOfFaces: list of groups of faces
6858 True if operation has been completed successfully, False otherwise
6861 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6863 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6865 Identify all the elements around a geom shape, get the faces delimiting the hole
6867 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6869 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6871 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6872 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6873 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6874 If there are several paths connecting a pair of points, the shortest path is
6875 selected by the module. Position of the cutting plane is defined by the two
6876 points and an optional vector lying on the plane specified by a PolySegment.
6877 By default the vector is defined by Mesh module as following. A middle point
6878 of the two given points is computed. The middle point is projected to the mesh.
6879 The vector goes from the middle point to the projection point. In case of planar
6880 mesh, the vector is normal to the mesh.
6882 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6885 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6886 groupName: optional name of a group where created mesh segments will be added.
6889 editor = self.editor
6891 editor = self.mesh.GetMeshEditPreviewer()
6892 segmentsRes = editor.MakePolyLine( segments, groupName )
6893 for i, seg in enumerate( segmentsRes ):
6894 segments[i].vector = seg.vector
6896 return editor.GetPreviewData()
6899 def MakeSlot(self, segmentGroup, width ):
6901 Create a slot of given width around given 1D elements lying on a triangle mesh.
6902 The slot is consrtucted by cutting faces by cylindrical surfaces made
6903 around each segment. Segments are expected to be created by MakePolyLine().
6906 FaceEdge's located at the slot boundary
6908 return self.editor.MakeSlot( segmentGroup, width )
6910 def GetFunctor(self, funcType ):
6912 Return a cached numerical functor by its type.
6915 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6916 Note that not all items correspond to numerical functors.
6919 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6922 fn = self.functors[ funcType._v ]
6924 fn = self.smeshpyD.GetFunctor(funcType)
6925 fn.SetMesh(self.mesh)
6926 self.functors[ funcType._v ] = fn
6929 def FunctorValue(self, funcType, elemId, isElem=True):
6931 Return value of a functor for a given element
6934 funcType: an item of :class:`SMESH.FunctorType` enum.
6935 elemId: element or node ID
6936 isElem: *elemId* is ID of element or node
6939 the functor value or zero in case of invalid arguments
6942 fn = self.GetFunctor( funcType )
6943 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6944 val = fn.GetValue(elemId)
6949 def GetLength(self, elemId=None):
6951 Get length of given 1D elements or of all 1D mesh elements
6954 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
6957 Sum of lengths of given elements
6962 length = self.smeshpyD.GetLength(self)
6963 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
6964 length = self.smeshpyD.GetLength(elemId)
6967 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
6969 length += self.smeshpyD.GetLength(obj)
6970 elif isinstance(elemId, list) and isinstance(elemId[0], int):
6971 unRegister = genObjUnRegister()
6972 obj = self.GetIDSource( elemId )
6973 unRegister.set( obj )
6974 length = self.smeshpyD.GetLength( obj )
6976 length = self.FunctorValue(SMESH.FT_Length, elemId)
6979 def GetArea(self, elemId=None):
6981 Get area of given 2D elements or of all 2D mesh elements
6984 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
6987 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6992 area = self.smeshpyD.GetArea(self)
6993 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
6994 area = self.smeshpyD.GetArea(elemId)
6997 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
6999 area += self.smeshpyD.GetArea(obj)
7000 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7001 unRegister = genObjUnRegister()
7002 obj = self.GetIDSource( elemId )
7003 unRegister.set( obj )
7004 area = self.smeshpyD.GetArea( obj )
7006 area = self.FunctorValue(SMESH.FT_Area, elemId)
7009 def GetVolume(self, elemId=None):
7011 Get volume of given 3D elements or of all 3D mesh elements
7014 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
7017 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7022 volume= self.smeshpyD.GetVolume(self)
7023 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7024 volume= self.smeshpyD.GetVolume(elemId)
7027 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7029 volume+= self.smeshpyD.GetVolume(obj)
7030 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7031 unRegister = genObjUnRegister()
7032 obj = self.GetIDSource( elemId )
7033 unRegister.set( obj )
7034 volume= self.smeshpyD.GetVolume( obj )
7036 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7039 def GetAngle(self, node1, node2, node3 ):
7041 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7044 node1,node2,node3: IDs of the three nodes
7047 Angle in radians [0,PI]. -1 if failure case.
7049 p1 = self.GetNodeXYZ( node1 )
7050 p2 = self.GetNodeXYZ( node2 )
7051 p3 = self.GetNodeXYZ( node3 )
7052 if p1 and p2 and p3:
7053 return self.smeshpyD.GetAngle( p1,p2,p3 )
7057 def GetMaxElementLength(self, elemId):
7059 Get maximum element length.
7062 elemId: mesh element ID
7065 element's maximum length value
7068 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7069 ftype = SMESH.FT_MaxElementLength3D
7071 ftype = SMESH.FT_MaxElementLength2D
7072 return self.FunctorValue(ftype, elemId)
7074 def GetAspectRatio(self, elemId):
7076 Get aspect ratio of 2D or 3D element.
7079 elemId: mesh element ID
7082 element's aspect ratio value
7085 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7086 ftype = SMESH.FT_AspectRatio3D
7088 ftype = SMESH.FT_AspectRatio
7089 return self.FunctorValue(ftype, elemId)
7091 def GetWarping(self, elemId):
7093 Get warping angle of 2D element.
7096 elemId: mesh element ID
7099 element's warping angle value
7102 return self.FunctorValue(SMESH.FT_Warping, elemId)
7104 def GetMinimumAngle(self, elemId):
7106 Get minimum angle of 2D element.
7109 elemId: mesh element ID
7112 element's minimum angle value
7115 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7117 def GetTaper(self, elemId):
7119 Get taper of 2D element.
7122 elemId: mesh element ID
7125 element's taper value
7128 return self.FunctorValue(SMESH.FT_Taper, elemId)
7130 def GetSkew(self, elemId):
7132 Get skew of 2D element.
7135 elemId: mesh element ID
7138 element's skew value
7141 return self.FunctorValue(SMESH.FT_Skew, elemId)
7143 def GetMinMax(self, funType, meshPart=None):
7145 Return minimal and maximal value of a given functor.
7148 funType (SMESH.FunctorType): a functor type.
7149 Note that not all items of :class:`SMESH.FunctorType` corresponds
7150 to numerical functors.
7151 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7157 unRegister = genObjUnRegister()
7158 if isinstance( meshPart, list ):
7159 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7160 unRegister.set( meshPart )
7161 if isinstance( meshPart, Mesh ):
7162 meshPart = meshPart.mesh
7163 fun = self.GetFunctor( funType )
7166 if hasattr( meshPart, "SetMesh" ):
7167 meshPart.SetMesh( self.mesh ) # set mesh to filter
7168 hist = fun.GetLocalHistogram( 1, False, meshPart )
7170 hist = fun.GetHistogram( 1, False )
7172 return hist[0].min, hist[0].max
7175 pass # end of Mesh class
7178 class meshProxy(SMESH._objref_SMESH_Mesh):
7180 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7181 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7183 def __init__(self,*args):
7184 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7185 def __deepcopy__(self, memo=None):
7186 new = self.__class__(self)
7188 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7189 if len( args ) == 3:
7190 args += SMESH.ALL_NODES, True
7191 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7192 def ExportToMEDX(self, *args): # function removed
7193 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7194 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7195 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7196 def ExportToMED(self, *args): # function removed
7197 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7198 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7200 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7202 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7203 def ExportPartToMED(self, *args): # 'version' parameter removed
7204 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7205 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7206 def ExportMED(self, *args): # signature of method changed
7207 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7209 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7211 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7213 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7216 class submeshProxy(SMESH._objref_SMESH_subMesh):
7219 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7221 def __init__(self,*args):
7222 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7224 def __deepcopy__(self, memo=None):
7225 new = self.__class__(self)
7228 def Compute(self,refresh=False):
7230 Compute the sub-mesh and return the status of the computation
7233 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7238 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7239 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7243 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7245 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7247 if salome.sg.hasDesktop():
7248 if refresh: salome.sg.updateObjBrowser()
7253 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7256 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7258 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7259 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7262 def __init__(self,*args):
7263 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7265 def __getattr__(self, name ): # method called if an attribute not found
7266 if not self.mesh: # look for name() method in Mesh class
7267 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7268 if hasattr( self.mesh, name ):
7269 return getattr( self.mesh, name )
7270 if name == "ExtrusionAlongPathObjX":
7271 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7272 print("meshEditor: attribute '%s' NOT FOUND" % name)
7274 def __deepcopy__(self, memo=None):
7275 new = self.__class__(self)
7277 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7278 if len( args ) == 1: args += False,
7279 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7280 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7281 if len( args ) == 2: args += False,
7282 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7283 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7284 if len( args ) == 1:
7285 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7286 NodesToKeep = args[1]
7287 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7288 unRegister = genObjUnRegister()
7290 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7291 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7292 if not isinstance( NodesToKeep, list ):
7293 NodesToKeep = [ NodesToKeep ]
7294 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7296 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7298 class Pattern(SMESH._objref_SMESH_Pattern):
7300 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7301 variables in some methods
7304 def LoadFromFile(self, patternTextOrFile ):
7305 text = patternTextOrFile
7306 if os.path.exists( text ):
7307 text = open( patternTextOrFile ).read()
7309 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7311 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7312 decrFun = lambda i: i-1
7313 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7314 theMesh.SetParameters(Parameters)
7315 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7317 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7318 decrFun = lambda i: i-1
7319 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7320 theMesh.SetParameters(Parameters)
7321 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7323 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7324 if isinstance( mesh, Mesh ):
7325 mesh = mesh.GetMesh()
7326 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7328 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7330 Registering the new proxy for Pattern
7335 Private class used to bind methods creating algorithms to the class Mesh
7338 def __init__(self, method):
7340 self.defaultAlgoType = ""
7341 self.algoTypeToClass = {}
7342 self.method = method
7344 def add(self, algoClass):
7346 Store a python class of algorithm
7348 if inspect.isclass(algoClass) and \
7349 hasattr( algoClass, "algoType"):
7350 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7351 if not self.defaultAlgoType and \
7352 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7353 self.defaultAlgoType = algoClass.algoType
7354 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7356 def copy(self, mesh):
7358 Create a copy of self and assign mesh to the copy
7361 other = algoCreator( self.method )
7362 other.defaultAlgoType = self.defaultAlgoType
7363 other.algoTypeToClass = self.algoTypeToClass
7367 def __call__(self,algo="",geom=0,*args):
7369 Create an instance of algorithm
7373 if isinstance( algo, str ):
7375 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7376 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7381 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7383 elif not algoType and isinstance( geom, str ):
7388 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7390 elif isinstance( arg, str ) and not algoType:
7393 import traceback, sys
7394 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7395 sys.stderr.write( msg + '\n' )
7396 tb = traceback.extract_stack(None,2)
7397 traceback.print_list( [tb[0]] )
7399 algoType = self.defaultAlgoType
7400 if not algoType and self.algoTypeToClass:
7401 algoType = sorted( self.algoTypeToClass.keys() )[0]
7402 if algoType in self.algoTypeToClass:
7403 #print("Create algo",algoType)
7404 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7405 raise RuntimeError( "No class found for algo type %s" % algoType)
7408 class hypMethodWrapper:
7410 Private class used to substitute and store variable parameters of hypotheses.
7413 def __init__(self, hyp, method):
7415 self.method = method
7416 #print("REBIND:", method.__name__)
7419 def __call__(self,*args):
7421 call a method of hypothesis with calling SetVarParameter() before
7425 return self.method( self.hyp, *args ) # hypothesis method with no args
7427 #print("MethWrapper.__call__", self.method.__name__, args)
7429 parsed = ParseParameters(*args) # replace variables with their values
7430 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7431 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7432 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7433 # maybe there is a replaced string arg which is not variable
7434 result = self.method( self.hyp, *args )
7435 except ValueError as detail: # raised by ParseParameters()
7437 result = self.method( self.hyp, *args )
7438 except omniORB.CORBA.BAD_PARAM:
7439 raise ValueError(detail) # wrong variable name
7444 class genObjUnRegister:
7446 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7449 def __init__(self, genObj=None):
7450 self.genObjList = []
7454 def set(self, genObj):
7455 "Store one or a list of of SALOME.GenericObj'es"
7456 if isinstance( genObj, list ):
7457 self.genObjList.extend( genObj )
7459 self.genObjList.append( genObj )
7463 for genObj in self.genObjList:
7464 if genObj and hasattr( genObj, "UnRegister" ):
7467 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7469 Bind methods creating mesher plug-ins to the Mesh class
7472 # print("pluginName: ", pluginName)
7473 pluginBuilderName = pluginName + "Builder"
7475 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7476 except Exception as e:
7477 from salome_utils import verbose
7478 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7480 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7481 plugin = eval( pluginBuilderName )
7482 # print(" plugin:" , str(plugin))
7484 # add methods creating algorithms to Mesh
7485 for k in dir( plugin ):
7486 if k[0] == '_': continue
7487 algo = getattr( plugin, k )
7488 #print(" algo:", str(algo))
7489 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7490 #print(" meshMethod:" , str(algo.meshMethod))
7491 if not hasattr( Mesh, algo.meshMethod ):
7492 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7494 _mmethod = getattr( Mesh, algo.meshMethod )
7495 if hasattr( _mmethod, "add" ):