1 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def EnumToLong(self,theItem):
480 Return a long value from enumeration
485 def ColorToString(self,c):
487 Convert SALOMEDS.Color to string.
488 To be used with filters.
491 c: color value (SALOMEDS.Color)
494 a string representation of the color.
498 if isinstance(c, SALOMEDS.Color):
499 val = "%s;%s;%s" % (c.R, c.G, c.B)
500 elif isinstance(c, str):
503 raise ValueError("Color value should be of string or SALOMEDS.Color type")
506 def GetPointStruct(self,theVertex):
508 Get :class:`SMESH.PointStruct` from vertex
511 theVertex (GEOM.GEOM_Object): vertex
514 :class:`SMESH.PointStruct`
517 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518 return PointStruct(x,y,z)
520 def GetDirStruct(self,theVector):
522 Get :class:`SMESH.DirStruct` from vector
525 theVector (GEOM.GEOM_Object): vector
528 :class:`SMESH.DirStruct`
531 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532 if(len(vertices) != 2):
533 print("Error: vector object is incorrect.")
535 p1 = self.geompyD.PointCoordinates(vertices[0])
536 p2 = self.geompyD.PointCoordinates(vertices[1])
537 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538 dirst = DirStruct(pnt)
541 def MakeDirStruct(self,x,y,z):
543 Make :class:`SMESH.DirStruct` from a triplet of floats
546 x,y,z (float): vector components
549 :class:`SMESH.DirStruct`
552 pnt = PointStruct(x,y,z)
553 return DirStruct(pnt)
555 def GetAxisStruct(self,theObj):
557 Get :class:`SMESH.AxisStruct` from a geometrical object
560 theObj (GEOM.GEOM_Object): line or plane
563 :class:`SMESH.AxisStruct`
566 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
569 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571 vertex1 = self.geompyD.PointCoordinates(vertex1)
572 vertex2 = self.geompyD.PointCoordinates(vertex2)
573 vertex3 = self.geompyD.PointCoordinates(vertex3)
574 vertex4 = self.geompyD.PointCoordinates(vertex4)
575 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577 normal = [ v1[1]*v2[2]-v2[1]*v1[2], v1[2]*v2[0]-v2[2]*v1[0], v1[0]*v2[1]-v2[0]*v1[1] ]
578 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580 elif len(edges) == 1:
581 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582 p1 = self.geompyD.PointCoordinates( vertex1 )
583 p2 = self.geompyD.PointCoordinates( vertex2 )
584 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586 elif theObj.GetShapeType() == GEOM.VERTEX:
587 x,y,z = self.geompyD.PointCoordinates( theObj )
588 axis = AxisStruct( x,y,z, 1,0,0,)
589 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
592 # From SMESH_Gen interface:
593 # ------------------------
595 def SetName(self, obj, name):
597 Set the given name to an object
600 obj: the object to rename
601 name: a new object name
604 if isinstance( obj, Mesh ):
606 elif isinstance( obj, Mesh_Algorithm ):
607 obj = obj.GetAlgorithm()
608 ior = salome.orb.object_to_string(obj)
609 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
611 def SetEmbeddedMode( self,theMode ):
616 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
618 def IsEmbeddedMode(self):
623 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
625 def UpdateStudy( self, geompyD = None ):
627 Update the current study. Calling UpdateStudy() allows to
628 update meshes at switching GEOM->SMESH
632 from salome.geom import geomBuilder
633 geompyD = geomBuilder.geom
635 geompyD = geomBuilder.New()
638 self.SetGeomEngine(geompyD)
639 SMESH._objref_SMESH_Gen.UpdateStudy(self)
640 sb = salome.myStudy.NewBuilder()
641 sc = salome.myStudy.FindComponent("SMESH")
643 sb.LoadWith(sc, self)
646 def SetEnablePublish( self, theIsEnablePublish ):
648 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649 switch **off** publishing in the Study of mesh objects.
651 #self.SetEnablePublish(theIsEnablePublish)
652 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
654 notebook = salome_notebook.NoteBook( theIsEnablePublish )
657 def CreateMeshesFromUNV( self,theFileName ):
659 Create a Mesh object importing data from the given UNV file
662 an instance of class :class:`Mesh`
665 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
669 def CreateMeshesFromMED( self,theFileName ):
671 Create a Mesh object(s) importing data from the given MED file
674 a tuple ( list of class :class:`Mesh` instances,
675 :class:`SMESH.DriverMED_ReadStatus` )
678 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680 return aMeshes, aStatus
682 def CreateMeshesFromSAUV( self,theFileName ):
684 Create a Mesh object(s) importing data from the given SAUV file
687 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
690 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692 return aMeshes, aStatus
694 def CreateMeshesFromSTL( self, theFileName ):
696 Create a Mesh object importing data from the given STL file
699 an instance of class :class:`Mesh`
702 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
706 def CreateMeshesFromCGNS( self, theFileName ):
708 Create Mesh objects importing data from the given CGNS file
711 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
714 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716 return aMeshes, aStatus
718 def CreateMeshesFromGMF( self, theFileName ):
720 Create a Mesh object importing data from the given GMF file.
721 GMF files must have .mesh extension for the ASCII format and .meshb for
725 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
728 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
731 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732 return Mesh(self, self.geompyD, aSmeshMesh), error
734 def Concatenate( self, meshes, uniteIdenticalGroups,
735 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736 name = "", meshToAppendTo = None):
738 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
739 All groups of input meshes will be present in the new mesh.
742 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744 mergeNodesAndElements: if True, equal nodes and elements are merged
745 mergeTolerance: tolerance for merging nodes
746 allGroups: forces creation of groups corresponding to every input mesh
747 name: name of a new mesh
748 meshToAppendTo a mesh to append all given meshes
751 an instance of class :class:`Mesh`
754 if not meshes: return None
755 if not isinstance( meshes, list ):
757 for i,m in enumerate( meshes ):
758 if isinstance( m, Mesh ):
759 meshes[i] = m.GetMesh()
760 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
761 if hasattr(meshes[0], "SetParameters"):
762 meshes[0].SetParameters( Parameters )
764 meshes[0].GetMesh().SetParameters( Parameters )
765 if isinstance( meshToAppendTo, Mesh ):
766 meshToAppendTo = meshToAppendTo.GetMesh()
768 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
769 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
770 mergeTolerance,meshToAppendTo )
772 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
773 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
774 mergeTolerance,meshToAppendTo )
776 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
779 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
781 Create a mesh by copying a part of another mesh.
784 meshPart: a part of mesh to copy, either
785 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
786 To copy nodes or elements not forming any mesh object,
787 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
788 meshName: a name of the new mesh
789 toCopyGroups: to create in the new mesh groups the copied elements belongs to
790 toKeepIDs: to preserve order of the copied elements or not
793 an instance of class :class:`Mesh`
796 if isinstance( meshPart, Mesh ):
797 meshPart = meshPart.GetMesh()
798 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
799 return Mesh(self, self.geompyD, mesh)
801 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
802 toReuseHypotheses=True, toCopyElements=True):
804 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
805 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
806 To facilitate and speed up the operation, consider using
807 "Set presentation parameters and sub-shapes from arguments" option in
808 a dialog of geometrical operation used to create the new geometry.
811 sourceMesh: the mesh to copy definition of.
812 newGeom: the new geomtry.
813 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
814 toCopyGroups: to create groups in the new mesh.
815 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
816 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
819 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
820 *invalidEntries* are study entries of objects whose
821 counterparts are not found in the *newGeom*, followed by entries
822 of mesh sub-objects that are invalid because they depend on a not found
825 if isinstance( sourceMesh, Mesh ):
826 sourceMesh = sourceMesh.GetMesh()
828 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
829 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
833 return ( ok, Mesh(self, self.geompyD, newMesh),
834 newGroups, newSubMeshes, newHypotheses, invalidEntries )
836 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
838 Return IDs of sub-shapes
841 theMainObject (GEOM.GEOM_Object): a shape
842 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
844 the list of integer values
847 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
849 def GetPattern(self):
851 Create a pattern mapper.
854 an instance of :class:`SMESH.SMESH_Pattern`
856 :ref:`Example of Patterns usage <tui_pattern_mapping>`
859 return SMESH._objref_SMESH_Gen.GetPattern(self)
861 def SetBoundaryBoxSegmentation(self, nbSegments):
863 Set number of segments per diagonal of boundary box of geometry, by which
864 default segment length of appropriate 1D hypotheses is defined in GUI.
868 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
870 # Filtering. Auxiliary functions:
871 # ------------------------------
873 def GetEmptyCriterion(self):
875 Create an empty criterion
878 :class:`SMESH.Filter.Criterion`
881 Type = self.EnumToLong(FT_Undefined)
882 Compare = self.EnumToLong(FT_Undefined)
886 UnaryOp = self.EnumToLong(FT_Undefined)
887 BinaryOp = self.EnumToLong(FT_Undefined)
890 Precision = -1 ##@1e-07
891 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
892 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
894 def GetCriterion(self,elementType,
896 Compare = FT_EqualTo,
898 UnaryOp=FT_Undefined,
899 BinaryOp=FT_Undefined,
902 Create a criterion by the given parameters
903 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
906 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
907 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
908 Note that the items starting from FT_LessThan are not suitable for *CritType*.
909 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
910 Threshold: the threshold value (range of ids as string, shape, numeric)
911 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
912 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
914 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
915 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
918 :class:`SMESH.Filter.Criterion`
920 Example: :ref:`combining_filters`
923 if not CritType in SMESH.FunctorType._items:
924 raise TypeError("CritType should be of SMESH.FunctorType")
925 aCriterion = self.GetEmptyCriterion()
926 aCriterion.TypeOfElement = elementType
927 aCriterion.Type = self.EnumToLong(CritType)
928 aCriterion.Tolerance = Tolerance
930 aThreshold = Threshold
932 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
933 aCriterion.Compare = self.EnumToLong(Compare)
934 elif Compare == "=" or Compare == "==":
935 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
937 aCriterion.Compare = self.EnumToLong(FT_LessThan)
939 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
940 elif Compare != FT_Undefined:
941 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
944 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
945 FT_BelongToCylinder, FT_LyingOnGeom]:
946 # Check that Threshold is GEOM object
947 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
948 aCriterion.ThresholdStr = GetName(aThreshold)
949 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
950 if not aCriterion.ThresholdID:
951 name = aCriterion.ThresholdStr
953 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
954 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
955 # or a name of GEOM object
956 elif isinstance( aThreshold, str ):
957 aCriterion.ThresholdStr = aThreshold
959 raise TypeError("The Threshold should be a shape.")
960 if isinstance(UnaryOp,float):
961 aCriterion.Tolerance = UnaryOp
962 UnaryOp = FT_Undefined
964 elif CritType == FT_BelongToMeshGroup:
965 # Check that Threshold is a group
966 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
967 if aThreshold.GetType() != elementType:
968 raise ValueError("Group type mismatches Element type")
969 aCriterion.ThresholdStr = aThreshold.GetName()
970 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
971 study = salome.myStudy
973 so = study.FindObjectIOR( aCriterion.ThresholdID )
977 aCriterion.ThresholdID = entry
979 raise TypeError("The Threshold should be a Mesh Group")
980 elif CritType == FT_RangeOfIds:
981 # Check that Threshold is string
982 if isinstance(aThreshold, str):
983 aCriterion.ThresholdStr = aThreshold
985 raise TypeError("The Threshold should be a string.")
986 elif CritType == FT_CoplanarFaces:
987 # Check the Threshold
988 if isinstance(aThreshold, int):
989 aCriterion.ThresholdID = str(aThreshold)
990 elif isinstance(aThreshold, str):
993 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
994 aCriterion.ThresholdID = aThreshold
996 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
997 elif CritType == FT_ConnectedElements:
998 # Check the Threshold
999 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1000 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1001 if not aCriterion.ThresholdID:
1002 name = aThreshold.GetName()
1004 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1005 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1006 elif isinstance(aThreshold, int): # node id
1007 aCriterion.Threshold = aThreshold
1008 elif isinstance(aThreshold, list): # 3 point coordinates
1009 if len( aThreshold ) < 3:
1010 raise ValueError("too few point coordinates, must be 3")
1011 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1012 elif isinstance(aThreshold, str):
1013 if aThreshold.isdigit():
1014 aCriterion.Threshold = aThreshold # node id
1016 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1018 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1019 "or a list of point coordinates and not '%s'"%aThreshold)
1020 elif CritType == FT_ElemGeomType:
1021 # Check the Threshold
1023 aCriterion.Threshold = self.EnumToLong(aThreshold)
1024 assert( aThreshold in SMESH.GeometryType._items )
1026 if isinstance(aThreshold, int):
1027 aCriterion.Threshold = aThreshold
1029 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1032 elif CritType == FT_EntityType:
1033 # Check the Threshold
1035 aCriterion.Threshold = self.EnumToLong(aThreshold)
1036 assert( aThreshold in SMESH.EntityType._items )
1038 if isinstance(aThreshold, int):
1039 aCriterion.Threshold = aThreshold
1041 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1045 elif CritType == FT_GroupColor:
1046 # Check the Threshold
1048 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1050 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1052 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1053 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1054 FT_BareBorderFace, FT_BareBorderVolume,
1055 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1056 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1057 # At this point the Threshold is unnecessary
1058 if aThreshold == FT_LogicalNOT:
1059 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1060 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1061 aCriterion.BinaryOp = aThreshold
1065 aThreshold = float(aThreshold)
1066 aCriterion.Threshold = aThreshold
1068 raise TypeError("The Threshold should be a number.")
1071 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1072 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1074 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1075 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1077 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1078 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1080 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1081 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1085 def GetFilter(self,elementType,
1086 CritType=FT_Undefined,
1089 UnaryOp=FT_Undefined,
1093 Create a filter with the given parameters
1096 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1097 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1098 Note that the items starting from FT_LessThan are not suitable for CritType.
1099 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1100 Threshold: the threshold value (range of ids as string, shape, numeric)
1101 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1102 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1103 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1104 mesh: the mesh to initialize the filter with
1107 :class:`SMESH.Filter`
1110 See :doc:`Filters usage examples <tui_filters>`
1113 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1114 aFilterMgr = self.CreateFilterManager()
1115 aFilter = aFilterMgr.CreateFilter()
1117 aCriteria.append(aCriterion)
1118 aFilter.SetCriteria(aCriteria)
1120 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1121 else : aFilter.SetMesh( mesh )
1122 aFilterMgr.UnRegister()
1125 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1127 Create a filter from criteria
1130 criteria: a list of :class:`SMESH.Filter.Criterion`
1131 binOp: binary operator used when binary operator of criteria is undefined
1134 :class:`SMESH.Filter`
1137 See :doc:`Filters usage examples <tui_filters>`
1140 for i in range( len( criteria ) - 1 ):
1141 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1142 criteria[i].BinaryOp = self.EnumToLong( binOp )
1143 aFilterMgr = self.CreateFilterManager()
1144 aFilter = aFilterMgr.CreateFilter()
1145 aFilter.SetCriteria(criteria)
1146 aFilterMgr.UnRegister()
1149 def GetFunctor(self,theCriterion):
1151 Create a numerical functor by its type
1154 theCriterion (SMESH.FunctorType): functor type.
1155 Note that not all items correspond to numerical functors.
1158 :class:`SMESH.NumericalFunctor`
1161 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1163 aFilterMgr = self.CreateFilterManager()
1165 if theCriterion == FT_AspectRatio:
1166 functor = aFilterMgr.CreateAspectRatio()
1167 elif theCriterion == FT_AspectRatio3D:
1168 functor = aFilterMgr.CreateAspectRatio3D()
1169 elif theCriterion == FT_Warping:
1170 functor = aFilterMgr.CreateWarping()
1171 elif theCriterion == FT_MinimumAngle:
1172 functor = aFilterMgr.CreateMinimumAngle()
1173 elif theCriterion == FT_Taper:
1174 functor = aFilterMgr.CreateTaper()
1175 elif theCriterion == FT_Skew:
1176 functor = aFilterMgr.CreateSkew()
1177 elif theCriterion == FT_Area:
1178 functor = aFilterMgr.CreateArea()
1179 elif theCriterion == FT_Volume3D:
1180 functor = aFilterMgr.CreateVolume3D()
1181 elif theCriterion == FT_MaxElementLength2D:
1182 functor = aFilterMgr.CreateMaxElementLength2D()
1183 elif theCriterion == FT_MaxElementLength3D:
1184 functor = aFilterMgr.CreateMaxElementLength3D()
1185 elif theCriterion == FT_MultiConnection:
1186 functor = aFilterMgr.CreateMultiConnection()
1187 elif theCriterion == FT_MultiConnection2D:
1188 functor = aFilterMgr.CreateMultiConnection2D()
1189 elif theCriterion == FT_Length:
1190 functor = aFilterMgr.CreateLength()
1191 elif theCriterion == FT_Length2D:
1192 functor = aFilterMgr.CreateLength2D()
1193 elif theCriterion == FT_Deflection2D:
1194 functor = aFilterMgr.CreateDeflection2D()
1195 elif theCriterion == FT_NodeConnectivityNumber:
1196 functor = aFilterMgr.CreateNodeConnectivityNumber()
1197 elif theCriterion == FT_BallDiameter:
1198 functor = aFilterMgr.CreateBallDiameter()
1200 print("Error: given parameter is not numerical functor type.")
1201 aFilterMgr.UnRegister()
1204 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1209 theHType (string): mesh hypothesis type
1210 theLibName (string): mesh plug-in library name
1213 created hypothesis instance
1215 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1217 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1220 # wrap hypothesis methods
1221 for meth_name in dir( hyp.__class__ ):
1222 if not meth_name.startswith("Get") and \
1223 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1224 method = getattr ( hyp.__class__, meth_name )
1225 if callable(method):
1226 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1230 def GetMeshInfo(self, obj):
1232 Get the mesh statistic.
1233 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
1234 an item of :class:`SMESH.EntityType`.
1237 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1240 if isinstance( obj, Mesh ):
1243 if hasattr(obj, "GetMeshInfo"):
1244 values = obj.GetMeshInfo()
1245 for i in range(SMESH.Entity_Last._v):
1246 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1250 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1252 Get minimum distance between two objects
1254 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1255 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1258 src1 (SMESH.SMESH_IDSource): first source object
1259 src2 (SMESH.SMESH_IDSource): second source object
1260 id1 (int): node/element id from the first source
1261 id2 (int): node/element id from the second (or first) source
1262 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1263 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1266 minimum distance value
1269 :meth:`GetMinDistance`
1272 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1276 result = result.value
1279 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1281 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1283 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1284 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1287 src1 (SMESH.SMESH_IDSource): first source object
1288 src2 (SMESH.SMESH_IDSource): second source object
1289 id1 (int): node/element id from the first source
1290 id2 (int): node/element id from the second (or first) source
1291 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1292 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1295 :class:`SMESH.Measure` structure or None if input data is invalid
1300 if isinstance(src1, Mesh): src1 = src1.mesh
1301 if isinstance(src2, Mesh): src2 = src2.mesh
1302 if src2 is None and id2 != 0: src2 = src1
1303 if not hasattr(src1, "_narrow"): return None
1304 src1 = src1._narrow(SMESH.SMESH_IDSource)
1305 if not src1: return None
1306 unRegister = genObjUnRegister()
1309 e = m.GetMeshEditor()
1311 src1 = e.MakeIDSource([id1], SMESH.FACE)
1313 src1 = e.MakeIDSource([id1], SMESH.NODE)
1314 unRegister.set( src1 )
1316 if hasattr(src2, "_narrow"):
1317 src2 = src2._narrow(SMESH.SMESH_IDSource)
1318 if src2 and id2 != 0:
1320 e = m.GetMeshEditor()
1322 src2 = e.MakeIDSource([id2], SMESH.FACE)
1324 src2 = e.MakeIDSource([id2], SMESH.NODE)
1325 unRegister.set( src2 )
1328 aMeasurements = self.CreateMeasurements()
1329 unRegister.set( aMeasurements )
1330 result = aMeasurements.MinDistance(src1, src2)
1333 def BoundingBox(self, objects):
1335 Get bounding box of the specified object(s)
1338 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1341 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1344 :meth:`GetBoundingBox`
1347 result = self.GetBoundingBox(objects)
1351 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1354 def GetBoundingBox(self, objects):
1356 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1359 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1362 :class:`SMESH.Measure` structure
1368 if isinstance(objects, tuple):
1369 objects = list(objects)
1370 if not isinstance(objects, list):
1374 if isinstance(o, Mesh):
1375 srclist.append(o.mesh)
1376 elif hasattr(o, "_narrow"):
1377 src = o._narrow(SMESH.SMESH_IDSource)
1378 if src: srclist.append(src)
1381 aMeasurements = self.CreateMeasurements()
1382 result = aMeasurements.BoundingBox(srclist)
1383 aMeasurements.UnRegister()
1386 def GetLength(self, obj):
1388 Get sum of lengths of all 1D elements in the mesh object.
1391 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1394 sum of lengths of all 1D elements
1397 if isinstance(obj, Mesh): obj = obj.mesh
1398 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1399 aMeasurements = self.CreateMeasurements()
1400 value = aMeasurements.Length(obj)
1401 aMeasurements.UnRegister()
1404 def GetArea(self, obj):
1406 Get sum of areas of all 2D elements in the mesh object.
1409 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1412 sum of areas of all 2D elements
1415 if isinstance(obj, Mesh): obj = obj.mesh
1416 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1417 aMeasurements = self.CreateMeasurements()
1418 value = aMeasurements.Area(obj)
1419 aMeasurements.UnRegister()
1422 def GetVolume(self, obj):
1424 Get sum of volumes of all 3D elements in the mesh object.
1427 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1430 sum of volumes of all 3D elements
1433 if isinstance(obj, Mesh): obj = obj.mesh
1434 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1435 aMeasurements = self.CreateMeasurements()
1436 value = aMeasurements.Volume(obj)
1437 aMeasurements.UnRegister()
1440 def GetGravityCenter(self, obj):
1442 Get gravity center of all nodes of a mesh object.
1445 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1448 Three components of the gravity center (x,y,z)
1451 :meth:`Mesh.BaryCenter`
1453 if isinstance(obj, Mesh): obj = obj.mesh
1454 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1455 aMeasurements = self.CreateMeasurements()
1456 pointStruct = aMeasurements.GravityCenter(obj)
1457 aMeasurements.UnRegister()
1458 return pointStruct.x, pointStruct.y, pointStruct.z
1460 def GetAngle(self, p1, p2, p3 ):
1462 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1465 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1471 if isinstance( p1, list ): p1 = PointStruct(*p1)
1472 if isinstance( p2, list ): p2 = PointStruct(*p2)
1473 if isinstance( p3, list ): p3 = PointStruct(*p3)
1475 aMeasurements = self.CreateMeasurements()
1476 angle = aMeasurements.Angle(p1,p2,p3)
1477 aMeasurements.UnRegister()
1482 pass # end of class smeshBuilder
1485 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1486 """Registering the new proxy for SMESH.SMESH_Gen"""
1489 def New( instance=None, instanceGeom=None):
1491 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1492 interface to create or load meshes.
1497 salome.salome_init()
1498 from salome.smesh import smeshBuilder
1499 smesh = smeshBuilder.New()
1502 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1503 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1505 :class:`smeshBuilder` instance
1510 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1512 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1517 smeshInst = smeshBuilder()
1518 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1519 smeshInst.init_smesh(instanceGeom)
1523 # Public class: Mesh
1524 # ==================
1527 class Mesh(metaclass = MeshMeta):
1529 This class allows defining and managing a mesh.
1530 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1531 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1532 new nodes and elements and by changing the existing entities), to get information
1533 about a mesh and to export a mesh in different formats.
1540 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1545 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1546 sets the GUI name of this mesh to *name*.
1549 smeshpyD: an instance of smeshBuilder class
1550 geompyD: an instance of geomBuilder class
1551 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1552 name: Study name of the mesh
1555 self.smeshpyD = smeshpyD
1556 self.geompyD = geompyD
1561 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1564 # publish geom of mesh (issue 0021122)
1565 if not self.geom.GetStudyEntry():
1569 geo_name = name + " shape"
1571 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1572 geompyD.addToStudy( self.geom, geo_name )
1573 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1575 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1578 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1580 self.smeshpyD.SetName(self.mesh, name)
1582 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1585 self.geom = self.mesh.GetShapeToMesh()
1587 self.editor = self.mesh.GetMeshEditor()
1588 self.functors = [None] * SMESH.FT_Undefined._v
1590 # set self to algoCreator's
1591 for attrName in dir(self):
1592 attr = getattr( self, attrName )
1593 if isinstance( attr, algoCreator ):
1594 setattr( self, attrName, attr.copy( self ))
1601 Destructor. Clean-up resources
1604 #self.mesh.UnRegister()
1608 def SetMesh(self, theMesh):
1610 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1613 theMesh: a :class:`SMESH.SMESH_Mesh` object
1617 # do not call Register() as this prevents mesh servant deletion at closing study
1618 #if self.mesh: self.mesh.UnRegister()
1621 #self.mesh.Register()
1622 self.geom = self.mesh.GetShapeToMesh()
1627 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1630 a :class:`SMESH.SMESH_Mesh` object
1635 def GetEngine(self):
1637 Return a smeshBuilder instance created this mesh
1639 return self.smeshpyD
1641 def GetGeomEngine(self):
1643 Return a geomBuilder instance
1649 Get the name of the mesh
1652 the name of the mesh as a string
1655 name = GetName(self.GetMesh())
1658 def SetName(self, name):
1660 Set a name to the mesh
1663 name: a new name of the mesh
1666 self.smeshpyD.SetName(self.GetMesh(), name)
1668 def GetSubMesh(self, geom, name):
1670 Get a sub-mesh object associated to a *geom* geometrical object.
1673 geom: a geometrical object (shape)
1674 name: a name for the sub-mesh in the Object Browser
1677 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1678 which lies on the given shape
1681 A sub-mesh is implicitly created when a sub-shape is specified at
1682 creating an algorithm, for example::
1684 algo1D = mesh.Segment(geom=Edge_1)
1686 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1687 The created sub-mesh can be retrieved from the algorithm::
1689 submesh = algo1D.GetSubMesh()
1692 AssureGeomPublished( self, geom, name )
1693 submesh = self.mesh.GetSubMesh( geom, name )
1698 Return the shape associated to the mesh
1706 def SetShape(self, geom):
1708 Associate the given shape to the mesh (entails the recreation of the mesh)
1711 geom: the shape to be meshed (GEOM_Object)
1714 self.mesh = self.smeshpyD.CreateMesh(geom)
1716 def HasShapeToMesh(self):
1718 Return ``True`` if this mesh is based on geometry
1720 return self.mesh.HasShapeToMesh()
1724 Load mesh from the study after opening the study
1728 def IsReadyToCompute(self, theSubObject):
1730 Return true if the hypotheses are defined well
1733 theSubObject: a sub-shape of a mesh shape
1739 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1741 def GetAlgoState(self, theSubObject):
1743 Return errors of hypotheses definition.
1744 The list of errors is empty if everything is OK.
1747 theSubObject: a sub-shape of a mesh shape
1753 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1755 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1757 Return a geometrical object on which the given element was built.
1758 The returned geometrical object, if not nil, is either found in the
1759 study or published by this method with the given name
1762 theElementID: the id of the mesh element
1763 theGeomName: the user-defined name of the geometrical object
1766 GEOM.GEOM_Object instance
1769 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1771 def MeshDimension(self):
1773 Return the mesh dimension depending on the dimension of the underlying shape
1774 or, if the mesh is not based on any shape, basing on deimension of elements
1777 mesh dimension as an integer value [0,3]
1780 if self.mesh.HasShapeToMesh():
1781 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1782 if len( shells ) > 0 :
1784 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1786 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1791 if self.NbVolumes() > 0: return 3
1792 if self.NbFaces() > 0: return 2
1793 if self.NbEdges() > 0: return 1
1796 def Evaluate(self, geom=0):
1798 Evaluate size of prospective mesh on a shape
1801 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1802 To know predicted number of e.g. edges, inquire it this way::
1804 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1807 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1809 geom = self.mesh.GetShapeToMesh()
1812 return self.smeshpyD.Evaluate(self.mesh, geom)
1815 def Compute(self, geom=0, discardModifs=False, refresh=False):
1817 Compute the mesh and return the status of the computation
1820 geom: geomtrical shape on which mesh data should be computed
1821 discardModifs: if True and the mesh has been edited since
1822 a last total re-compute and that may prevent successful partial re-compute,
1823 then the mesh is cleaned before Compute()
1824 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1830 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1832 geom = self.mesh.GetShapeToMesh()
1837 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1839 ok = self.smeshpyD.Compute(self.mesh, geom)
1840 except SALOME.SALOME_Exception as ex:
1841 print("Mesh computation failed, exception caught:")
1842 print(" ", ex.details.text)
1845 print("Mesh computation failed, exception caught:")
1846 traceback.print_exc()
1850 # Treat compute errors
1851 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1853 for err in computeErrors:
1854 if self.mesh.HasShapeToMesh():
1855 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1857 stdErrors = ["OK", #COMPERR_OK
1858 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1859 "std::exception", #COMPERR_STD_EXCEPTION
1860 "OCC exception", #COMPERR_OCC_EXCEPTION
1861 "..", #COMPERR_SLM_EXCEPTION
1862 "Unknown exception", #COMPERR_EXCEPTION
1863 "Memory allocation problem", #COMPERR_MEMORY_PB
1864 "Algorithm failed", #COMPERR_ALGO_FAILED
1865 "Unexpected geometry", #COMPERR_BAD_SHAPE
1866 "Warning", #COMPERR_WARNING
1867 "Computation cancelled",#COMPERR_CANCELED
1868 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1870 if err.code < len(stdErrors): errText = stdErrors[err.code]
1872 errText = "code %s" % -err.code
1873 if errText: errText += ". "
1874 errText += err.comment
1875 if allReasons: allReasons += "\n"
1877 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1879 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1883 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1885 if err.isGlobalAlgo:
1893 reason = '%s %sD algorithm is missing' % (glob, dim)
1894 elif err.state == HYP_MISSING:
1895 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1896 % (glob, dim, name, dim))
1897 elif err.state == HYP_NOTCONFORM:
1898 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1899 elif err.state == HYP_BAD_PARAMETER:
1900 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1901 % ( glob, dim, name ))
1902 elif err.state == HYP_BAD_GEOMETRY:
1903 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1904 'geometry' % ( glob, dim, name ))
1905 elif err.state == HYP_HIDDEN_ALGO:
1906 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1907 'algorithm of upper dimension generating %sD mesh'
1908 % ( glob, dim, name, glob, dim ))
1910 reason = ("For unknown reason. "
1911 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1913 if allReasons: allReasons += "\n"
1914 allReasons += "- " + reason
1916 if not ok or allReasons != "":
1917 msg = '"' + GetName(self.mesh) + '"'
1918 if ok: msg += " has been computed with warnings"
1919 else: msg += " has not been computed"
1920 if allReasons != "": msg += ":"
1925 if salome.sg.hasDesktop():
1926 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1927 if refresh: salome.sg.updateObjBrowser()
1931 def GetComputeErrors(self, shape=0 ):
1933 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1937 shape = self.mesh.GetShapeToMesh()
1938 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1940 def GetSubShapeName(self, subShapeID ):
1942 Return a name of a sub-shape by its ID.
1943 Possible variants (for *subShapeID* == 3):
1945 - **"Face_12"** - published sub-shape
1946 - **FACE #3** - not published sub-shape
1947 - **sub-shape #3** - invalid sub-shape ID
1948 - **#3** - error in this function
1951 subShapeID: a unique ID of a sub-shape
1954 a string describing the sub-shape
1958 if not self.mesh.HasShapeToMesh():
1962 mainIOR = salome.orb.object_to_string( self.GetShape() )
1964 mainSO = s.FindObjectIOR(mainIOR)
1967 shapeText = '"%s"' % mainSO.GetName()
1968 subIt = s.NewChildIterator(mainSO)
1970 subSO = subIt.Value()
1972 obj = subSO.GetObject()
1973 if not obj: continue
1974 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1977 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1980 if ids == subShapeID:
1981 shapeText = '"%s"' % subSO.GetName()
1984 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1986 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1988 shapeText = 'sub-shape #%s' % (subShapeID)
1990 shapeText = "#%s" % (subShapeID)
1993 def GetFailedShapes(self, publish=False):
1995 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1996 error of an algorithm
1999 publish: if *True*, the returned groups will be published in the study
2002 a list of GEOM groups each named after a failed algorithm
2007 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2008 for err in computeErrors:
2009 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2010 if not shape: continue
2011 if err.algoName in algo2shapes:
2012 algo2shapes[ err.algoName ].append( shape )
2014 algo2shapes[ err.algoName ] = [ shape ]
2018 for algoName, shapes in list(algo2shapes.items()):
2020 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2021 otherTypeShapes = []
2023 group = self.geompyD.CreateGroup( self.geom, groupType )
2024 for shape in shapes:
2025 if shape.GetShapeType() == shapes[0].GetShapeType():
2026 sameTypeShapes.append( shape )
2028 otherTypeShapes.append( shape )
2029 self.geompyD.UnionList( group, sameTypeShapes )
2031 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2033 group.SetName( algoName )
2034 groups.append( group )
2035 shapes = otherTypeShapes
2038 for group in groups:
2039 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2042 def GetMeshOrder(self):
2044 Return sub-mesh objects list in meshing order
2047 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2050 return self.mesh.GetMeshOrder()
2052 def SetMeshOrder(self, submeshes):
2054 Set order in which concurrent sub-meshes should be meshed
2057 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2060 return self.mesh.SetMeshOrder(submeshes)
2062 def Clear(self, refresh=False):
2064 Remove all nodes and elements generated on geometry. Imported elements remain.
2067 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2071 if ( salome.sg.hasDesktop() ):
2072 if refresh: salome.sg.updateObjBrowser()
2074 def ClearSubMesh(self, geomId, refresh=False):
2076 Remove all nodes and elements of indicated shape
2079 geomId: the ID of a sub-shape to remove elements on
2080 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2083 self.mesh.ClearSubMesh(geomId)
2084 if salome.sg.hasDesktop():
2085 if refresh: salome.sg.updateObjBrowser()
2087 def AutomaticTetrahedralization(self, fineness=0):
2089 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2092 fineness: [0.0,1.0] defines mesh fineness
2098 dim = self.MeshDimension()
2100 self.RemoveGlobalHypotheses()
2101 self.Segment().AutomaticLength(fineness)
2103 self.Triangle().LengthFromEdges()
2108 return self.Compute()
2110 def AutomaticHexahedralization(self, fineness=0):
2112 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2115 fineness: [0.0, 1.0] defines mesh fineness
2121 dim = self.MeshDimension()
2122 # assign the hypotheses
2123 self.RemoveGlobalHypotheses()
2124 self.Segment().AutomaticLength(fineness)
2131 return self.Compute()
2133 def AddHypothesis(self, hyp, geom=0):
2138 hyp: a hypothesis to assign
2139 geom: a subhape of mesh geometry
2142 :class:`SMESH.Hypothesis_Status`
2145 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2146 hyp, geom = geom, hyp
2147 if isinstance( hyp, Mesh_Algorithm ):
2148 hyp = hyp.GetAlgorithm()
2153 geom = self.mesh.GetShapeToMesh()
2156 if self.mesh.HasShapeToMesh():
2157 hyp_type = hyp.GetName()
2158 lib_name = hyp.GetLibName()
2159 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2160 # if checkAll and geom:
2161 # checkAll = geom.GetType() == 37
2163 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2165 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2166 status = self.mesh.AddHypothesis(geom, hyp)
2168 status = HYP_BAD_GEOMETRY, ""
2169 hyp_name = GetName( hyp )
2172 geom_name = geom.GetName()
2173 isAlgo = hyp._narrow( SMESH_Algo )
2174 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2177 def IsUsedHypothesis(self, hyp, geom):
2179 Return True if an algorithm or hypothesis is assigned to a given shape
2182 hyp: an algorithm or hypothesis to check
2183 geom: a subhape of mesh geometry
2189 if not hyp: # or not geom
2191 if isinstance( hyp, Mesh_Algorithm ):
2192 hyp = hyp.GetAlgorithm()
2194 hyps = self.GetHypothesisList(geom)
2196 if h.GetId() == hyp.GetId():
2200 def RemoveHypothesis(self, hyp, geom=0):
2202 Unassign a hypothesis
2205 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2206 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2209 :class:`SMESH.Hypothesis_Status`
2214 if isinstance( hyp, Mesh_Algorithm ):
2215 hyp = hyp.GetAlgorithm()
2221 if self.IsUsedHypothesis( hyp, shape ):
2222 return self.mesh.RemoveHypothesis( shape, hyp )
2223 hypName = GetName( hyp )
2224 geoName = GetName( shape )
2225 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2228 def GetHypothesisList(self, geom):
2230 Get the list of hypotheses added on a geometry
2233 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2236 the sequence of :class:`SMESH.SMESH_Hypothesis`
2239 return self.mesh.GetHypothesisList( geom )
2241 def RemoveGlobalHypotheses(self):
2243 Remove all global hypotheses
2246 current_hyps = self.mesh.GetHypothesisList( self.geom )
2247 for hyp in current_hyps:
2248 self.mesh.RemoveHypothesis( self.geom, hyp )
2251 def ExportMED(self, *args, **kwargs):
2253 Export the mesh in a file in MED format
2254 allowing to overwrite the file if it exists or add the exported data to its contents
2257 fileName: is the file name
2258 auto_groups (boolean): parameter for creating/not creating
2259 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2260 the typical use is auto_groups=False.
2261 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2262 The minor must be between 0 and the current minor version of MED file library.
2263 If minor is equal to -1, the minor version is not changed (default).
2264 The major version (x, where version is x.y.z) cannot be changed.
2265 overwrite (boolean): parameter for overwriting/not overwriting the file
2266 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2267 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2269 - 1D if all mesh nodes lie on OX coordinate axis, or
2270 - 2D if all mesh nodes lie on XOY coordinate plane, or
2271 - 3D in the rest cases.
2273 If *autoDimension* is *False*, the space dimension is always 3.
2274 fields: list of GEOM fields defined on the shape to mesh.
2275 geomAssocFields: each character of this string means a need to export a
2276 corresponding field; correspondence between fields and characters
2279 - 'v' stands for "_vertices_" field;
2280 - 'e' stands for "_edges_" field;
2281 - 'f' stands for "_faces_" field;
2282 - 's' stands for "_solids_" field.
2284 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2285 close to zero within a given tolerance, the coordinate is set to zero.
2286 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2288 # process positional arguments
2289 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2291 auto_groups = args[1] if len(args) > 1 else False
2292 minor = args[2] if len(args) > 2 else -1
2293 overwrite = args[3] if len(args) > 3 else True
2294 meshPart = args[4] if len(args) > 4 else None
2295 autoDimension = args[5] if len(args) > 5 else True
2296 fields = args[6] if len(args) > 6 else []
2297 geomAssocFields = args[7] if len(args) > 7 else ''
2298 z_tolerance = args[8] if len(args) > 8 else -1.
2299 # process keywords arguments
2300 auto_groups = kwargs.get("auto_groups", auto_groups)
2301 minor = kwargs.get("minor", minor)
2302 overwrite = kwargs.get("overwrite", overwrite)
2303 meshPart = kwargs.get("meshPart", meshPart)
2304 autoDimension = kwargs.get("autoDimension", autoDimension)
2305 fields = kwargs.get("fields", fields)
2306 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2307 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2309 # invoke engine's function
2310 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2311 unRegister = genObjUnRegister()
2312 if isinstance( meshPart, list ):
2313 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2314 unRegister.set( meshPart )
2316 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2317 self.mesh.SetParameters(Parameters)
2319 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2320 fields, geomAssocFields, z_tolerance)
2322 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2324 def ExportSAUV(self, f, auto_groups=0):
2326 Export the mesh in a file in SAUV format
2331 auto_groups: boolean parameter for creating/not creating
2332 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2333 the typical use is auto_groups=False.
2336 self.mesh.ExportSAUV(f, auto_groups)
2338 def ExportDAT(self, f, meshPart=None):
2340 Export the mesh in a file in DAT format
2344 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2348 unRegister = genObjUnRegister()
2349 if isinstance( meshPart, list ):
2350 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2351 unRegister.set( meshPart )
2352 self.mesh.ExportPartToDAT( meshPart, f )
2354 self.mesh.ExportDAT(f)
2356 def ExportUNV(self, f, meshPart=None):
2358 Export the mesh in a file in UNV format
2362 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2366 unRegister = genObjUnRegister()
2367 if isinstance( meshPart, list ):
2368 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369 unRegister.set( meshPart )
2370 self.mesh.ExportPartToUNV( meshPart, f )
2372 self.mesh.ExportUNV(f)
2374 def ExportSTL(self, f, ascii=1, meshPart=None):
2376 Export the mesh in a file in STL format
2380 ascii: defines the file encoding
2381 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2385 unRegister = genObjUnRegister()
2386 if isinstance( meshPart, list ):
2387 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2388 unRegister.set( meshPart )
2389 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2391 self.mesh.ExportSTL(f, ascii)
2393 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2395 Export the mesh in a file in CGNS format
2399 overwrite: boolean parameter for overwriting/not overwriting the file
2400 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2401 groupElemsByType: if True all elements of same entity type are exported at ones,
2402 else elements are exported in order of their IDs which can cause creation
2403 of multiple cgns sections
2406 unRegister = genObjUnRegister()
2407 if isinstance( meshPart, list ):
2408 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2409 unRegister.set( meshPart )
2410 if isinstance( meshPart, Mesh ):
2411 meshPart = meshPart.mesh
2413 meshPart = self.mesh
2414 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2416 def ExportGMF(self, f, meshPart=None):
2418 Export the mesh in a file in GMF format.
2419 GMF files must have .mesh extension for the ASCII format and .meshb for
2420 the bynary format. Other extensions are not allowed.
2424 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2427 unRegister = genObjUnRegister()
2428 if isinstance( meshPart, list ):
2429 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2430 unRegister.set( meshPart )
2431 if isinstance( meshPart, Mesh ):
2432 meshPart = meshPart.mesh
2434 meshPart = self.mesh
2435 self.mesh.ExportGMF(meshPart, f, True)
2437 def ExportToMED(self, *args, **kwargs):
2439 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2440 Export the mesh in a file in MED format
2441 allowing to overwrite the file if it exists or add the exported data to its contents
2444 fileName: the file name
2445 opt (boolean): parameter for creating/not creating
2446 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2447 overwrite: boolean parameter for overwriting/not overwriting the file
2448 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2450 - 1D if all mesh nodes lie on OX coordinate axis, or
2451 - 2D if all mesh nodes lie on XOY coordinate plane, or
2452 - 3D in the rest cases.
2454 If **autoDimension** is *False*, the space dimension is always 3.
2457 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2458 # process positional arguments
2459 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2461 auto_groups = args[1] if len(args) > 1 else False
2462 overwrite = args[2] if len(args) > 2 else True
2463 autoDimension = args[3] if len(args) > 3 else True
2464 # process keywords arguments
2465 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2466 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2467 overwrite = kwargs.get("overwrite", overwrite)
2468 autoDimension = kwargs.get("autoDimension", autoDimension)
2470 # invoke engine's function
2471 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2473 def ExportToMEDX(self, *args, **kwargs):
2475 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2476 Export the mesh in a file in MED format
2479 fileName: the file name
2480 opt (boolean): parameter for creating/not creating
2481 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2482 overwrite: boolean parameter for overwriting/not overwriting the file
2483 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2485 - 1D if all mesh nodes lie on OX coordinate axis, or
2486 - 2D if all mesh nodes lie on XOY coordinate plane, or
2487 - 3D in the rest cases.
2489 If **autoDimension** is *False*, the space dimension is always 3.
2492 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2493 # process positional arguments
2494 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2496 auto_groups = args[1] if len(args) > 1 else False
2497 overwrite = args[2] if len(args) > 2 else True
2498 autoDimension = args[3] if len(args) > 3 else True
2499 # process keywords arguments
2500 auto_groups = kwargs.get("auto_groups", auto_groups)
2501 overwrite = kwargs.get("overwrite", overwrite)
2502 autoDimension = kwargs.get("autoDimension", autoDimension)
2504 # invoke engine's function
2505 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2509 def Append(self, meshes, uniteIdenticalGroups = True,
2510 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2512 Append given meshes into this mesh.
2513 All groups of input meshes will be created in this mesh.
2516 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2517 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2518 mergeNodesAndElements: if True, equal nodes and elements are merged
2519 mergeTolerance: tolerance for merging nodes
2520 allGroups: forces creation of groups corresponding to every input mesh
2522 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2523 mergeNodesAndElements, mergeTolerance, allGroups,
2524 meshToAppendTo = self.GetMesh() )
2526 # Operations with groups:
2527 # ----------------------
2528 def CreateEmptyGroup(self, elementType, name):
2530 Create an empty standalone mesh group
2533 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2534 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2535 name: the name of the mesh group
2538 :class:`SMESH.SMESH_Group`
2541 return self.mesh.CreateGroup(elementType, name)
2543 def Group(self, grp, name=""):
2545 Create a mesh group based on the geometric object *grp*
2546 and give it a *name*.
2547 If *name* is not defined the name of the geometric group is used
2550 Works like :meth:`GroupOnGeom`.
2553 grp: a geometric group, a vertex, an edge, a face or a solid
2554 name: the name of the mesh group
2557 :class:`SMESH.SMESH_GroupOnGeom`
2560 return self.GroupOnGeom(grp, name)
2562 def GroupOnGeom(self, grp, name="", typ=None):
2564 Create a mesh group based on the geometrical object *grp*
2565 and give it a *name*.
2566 if *name* is not defined the name of the geometric group is used
2569 grp: a geometrical group, a vertex, an edge, a face or a solid
2570 name: the name of the mesh group
2571 typ: the type of elements in the group; either of
2572 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2573 automatically detected by the type of the geometry
2576 :class:`SMESH.SMESH_GroupOnGeom`
2579 AssureGeomPublished( self, grp, name )
2581 name = grp.GetName()
2583 typ = self._groupTypeFromShape( grp )
2584 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2586 def _groupTypeFromShape( self, shape ):
2588 Pivate method to get a type of group on geometry
2590 tgeo = str(shape.GetShapeType())
2591 if tgeo == "VERTEX":
2593 elif tgeo == "EDGE":
2595 elif tgeo == "FACE" or tgeo == "SHELL":
2597 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2599 elif tgeo == "COMPOUND":
2600 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2602 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2603 return self._groupTypeFromShape( sub[0] )
2605 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2608 def GroupOnFilter(self, typ, name, filter):
2610 Create a mesh group with given *name* based on the *filter*.
2611 It is a special type of group dynamically updating it's contents during
2615 typ: the type of elements in the group; either of
2616 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2617 name: the name of the mesh group
2618 filter (SMESH.Filter): the filter defining group contents
2621 :class:`SMESH.SMESH_GroupOnFilter`
2624 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2626 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2628 Create a mesh group by the given ids of elements
2631 groupName: the name of the mesh group
2632 elementType: the type of elements in the group; either of
2633 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2634 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2637 :class:`SMESH.SMESH_Group`
2640 group = self.mesh.CreateGroup(elementType, groupName)
2641 if isinstance( elemIDs, Mesh ):
2642 elemIDs = elemIDs.GetMesh()
2643 if hasattr( elemIDs, "GetIDs" ):
2644 if hasattr( elemIDs, "SetMesh" ):
2645 elemIDs.SetMesh( self.GetMesh() )
2646 group.AddFrom( elemIDs )
2654 CritType=FT_Undefined,
2657 UnaryOp=FT_Undefined,
2660 Create a mesh group by the given conditions
2663 groupName: the name of the mesh group
2664 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2665 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2666 Note that the items starting from FT_LessThan are not suitable for CritType.
2667 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2668 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2669 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2670 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2671 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2674 :class:`SMESH.SMESH_GroupOnFilter`
2677 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2678 group = self.MakeGroupByCriterion(groupName, aCriterion)
2681 def MakeGroupByCriterion(self, groupName, Criterion):
2683 Create a mesh group by the given criterion
2686 groupName: the name of the mesh group
2687 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2690 :class:`SMESH.SMESH_GroupOnFilter`
2693 :meth:`smeshBuilder.GetCriterion`
2696 return self.MakeGroupByCriteria( groupName, [Criterion] )
2698 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2700 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2703 groupName: the name of the mesh group
2704 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2705 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2708 :class:`SMESH.SMESH_GroupOnFilter`
2711 :meth:`smeshBuilder.GetCriterion`
2714 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2715 group = self.MakeGroupByFilter(groupName, aFilter)
2718 def MakeGroupByFilter(self, groupName, theFilter):
2720 Create a mesh group by the given filter
2723 groupName (string): the name of the mesh group
2724 theFilter (SMESH.Filter): the filter
2727 :class:`SMESH.SMESH_GroupOnFilter`
2730 :meth:`smeshBuilder.GetFilter`
2733 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2734 #theFilter.SetMesh( self.mesh )
2735 #group.AddFrom( theFilter )
2736 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2739 def RemoveGroup(self, group):
2744 group (SMESH.SMESH_GroupBase): group to remove
2747 self.mesh.RemoveGroup(group)
2749 def RemoveGroupWithContents(self, group):
2751 Remove a group with its contents
2754 group (SMESH.SMESH_GroupBase): group to remove
2757 self.mesh.RemoveGroupWithContents(group)
2759 def GetGroups(self, elemType = SMESH.ALL):
2761 Get the list of groups existing in the mesh in the order of creation
2762 (starting from the oldest one)
2765 elemType (SMESH.ElementType): type of elements the groups contain;
2766 by default groups of elements of all types are returned
2769 a list of :class:`SMESH.SMESH_GroupBase`
2772 groups = self.mesh.GetGroups()
2773 if elemType == SMESH.ALL:
2777 if g.GetType() == elemType:
2778 typedGroups.append( g )
2785 Get the number of groups existing in the mesh
2788 the quantity of groups as an integer value
2791 return self.mesh.NbGroups()
2793 def GetGroupNames(self):
2795 Get the list of names of groups existing in the mesh
2801 groups = self.GetGroups()
2803 for group in groups:
2804 names.append(group.GetName())
2807 def GetGroupByName(self, name, elemType = None):
2809 Find groups by name and type
2812 name (string): name of the group of interest
2813 elemType (SMESH.ElementType): type of elements the groups contain;
2814 by default one group of any type is returned;
2815 if elemType == SMESH.ALL then all groups of any type are returned
2818 a list of :class:`SMESH.SMESH_GroupBase`
2822 for group in self.GetGroups():
2823 if group.GetName() == name:
2824 if elemType is None:
2826 if ( elemType == SMESH.ALL or
2827 group.GetType() == elemType ):
2828 groups.append( group )
2831 def UnionGroups(self, group1, group2, name):
2833 Produce a union of two groups.
2834 A new group is created. All mesh elements that are
2835 present in the initial groups are added to the new one
2838 group1 (SMESH.SMESH_GroupBase): a group
2839 group2 (SMESH.SMESH_GroupBase): another group
2842 instance of :class:`SMESH.SMESH_Group`
2845 return self.mesh.UnionGroups(group1, group2, name)
2847 def UnionListOfGroups(self, groups, name):
2849 Produce a union list of groups.
2850 New group is created. All mesh elements that are present in
2851 initial groups are added to the new one
2854 groups: list of :class:`SMESH.SMESH_GroupBase`
2857 instance of :class:`SMESH.SMESH_Group`
2859 return self.mesh.UnionListOfGroups(groups, name)
2861 def IntersectGroups(self, group1, group2, name):
2863 Prodice an intersection of two groups.
2864 A new group is created. All mesh elements that are common
2865 for the two initial groups are added to the new one.
2868 group1 (SMESH.SMESH_GroupBase): a group
2869 group2 (SMESH.SMESH_GroupBase): another group
2872 instance of :class:`SMESH.SMESH_Group`
2875 return self.mesh.IntersectGroups(group1, group2, name)
2877 def IntersectListOfGroups(self, groups, name):
2879 Produce an intersection of groups.
2880 New group is created. All mesh elements that are present in all
2881 initial groups simultaneously are added to the new one
2884 groups: a list of :class:`SMESH.SMESH_GroupBase`
2887 instance of :class:`SMESH.SMESH_Group`
2889 return self.mesh.IntersectListOfGroups(groups, name)
2891 def CutGroups(self, main_group, tool_group, name):
2893 Produce a cut of two groups.
2894 A new group is created. All mesh elements that are present in
2895 the main group but are not present in the tool group are added to the new one
2898 main_group (SMESH.SMESH_GroupBase): a group to cut from
2899 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2902 an instance of :class:`SMESH.SMESH_Group`
2905 return self.mesh.CutGroups(main_group, tool_group, name)
2907 def CutListOfGroups(self, main_groups, tool_groups, name):
2909 Produce a cut of groups.
2910 A new group is created. All mesh elements that are present in main groups
2911 but do not present in tool groups are added to the new one
2914 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2915 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2918 an instance of :class:`SMESH.SMESH_Group`
2921 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2923 def CreateDimGroup(self, groups, elemType, name,
2924 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2926 Create a standalone group of entities basing on nodes of other groups.
2929 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2930 elemType: a type of elements to include to the new group; either of
2931 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2932 name: a name of the new group.
2933 nbCommonNodes: a criterion of inclusion of an element to the new group
2934 basing on number of element nodes common with reference *groups*.
2935 Meaning of possible values are:
2937 - SMESH.ALL_NODES - include if all nodes are common,
2938 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2939 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2940 - SMEHS.MAJORITY - include if half of nodes or more are common.
2941 underlyingOnly: if *True* (default), an element is included to the
2942 new group provided that it is based on nodes of an element of *groups*;
2943 in this case the reference *groups* are supposed to be of higher dimension
2944 than *elemType*, which can be useful for example to get all faces lying on
2945 volumes of the reference *groups*.
2948 an instance of :class:`SMESH.SMESH_Group`
2951 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2953 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2955 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2957 Distribute all faces of the mesh among groups using sharp edges and optionally
2958 existing 1D elements as group boundaries.
2961 sharpAngle: edge is considered sharp if an angle between normals of
2962 adjacent faces is more than \a sharpAngle in degrees.
2963 createEdges (boolean): to create 1D elements for detected sharp edges.
2964 useExistingEdges (boolean): to use existing edges as group boundaries
2966 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2968 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2969 self.mesh.SetParameters(Parameters)
2970 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2972 def ConvertToStandalone(self, group):
2974 Convert group on geom into standalone group
2977 return self.mesh.ConvertToStandalone(group)
2979 # Get some info about mesh:
2980 # ------------------------
2982 def GetLog(self, clearAfterGet):
2984 Return the log of nodes and elements added or removed
2985 since the previous clear of the log.
2988 clearAfterGet: log is emptied after Get (safe if concurrents access)
2991 list of SMESH.log_block structures { commandType, number, coords, indexes }
2994 return self.mesh.GetLog(clearAfterGet)
2998 Clear the log of nodes and elements added or removed since the previous
2999 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3002 self.mesh.ClearLog()
3004 def SetAutoColor(self, theAutoColor):
3006 Toggle auto color mode on the object.
3007 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3010 theAutoColor (boolean): the flag which toggles auto color mode.
3013 self.mesh.SetAutoColor(theAutoColor)
3015 def GetAutoColor(self):
3017 Get flag of object auto color mode.
3023 return self.mesh.GetAutoColor()
3030 integer value, which is the internal Id of the mesh
3033 return self.mesh.GetId()
3035 def HasDuplicatedGroupNamesMED(self):
3037 Check the group names for duplications.
3038 Consider the maximum group name length stored in MED file.
3044 return self.mesh.HasDuplicatedGroupNamesMED()
3046 def GetMeshEditor(self):
3048 Obtain the mesh editor tool
3051 an instance of :class:`SMESH.SMESH_MeshEditor`
3056 def GetIDSource(self, ids, elemType = SMESH.ALL):
3058 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3059 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3063 elemType: type of elements; this parameter is used to distinguish
3064 IDs of nodes from IDs of elements; by default ids are treated as
3065 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3068 an instance of :class:`SMESH.SMESH_IDSource`
3071 call UnRegister() for the returned object as soon as it is no more useful::
3073 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3074 mesh.DoSomething( idSrc )
3078 if isinstance( ids, int ):
3080 return self.editor.MakeIDSource(ids, elemType)
3083 # Get information about mesh contents:
3084 # ------------------------------------
3086 def GetMeshInfo(self, obj = None):
3088 Get the mesh statistic.
3089 Use :meth:`smeshBuilder.EnumToLong` to get an integer from
3090 an item of :class:`SMESH.EntityType`.
3093 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3096 if not obj: obj = self.mesh
3097 return self.smeshpyD.GetMeshInfo(obj)
3101 Return the number of nodes in the mesh
3107 return self.mesh.NbNodes()
3109 def NbElements(self):
3111 Return the number of elements in the mesh
3117 return self.mesh.NbElements()
3119 def Nb0DElements(self):
3121 Return the number of 0d elements in the mesh
3127 return self.mesh.Nb0DElements()
3131 Return the number of ball discrete elements in the mesh
3137 return self.mesh.NbBalls()
3141 Return the number of edges in the mesh
3147 return self.mesh.NbEdges()
3149 def NbEdgesOfOrder(self, elementOrder):
3151 Return the number of edges with the given order in the mesh
3154 elementOrder: the order of elements
3155 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3161 return self.mesh.NbEdgesOfOrder(elementOrder)
3165 Return the number of faces in the mesh
3171 return self.mesh.NbFaces()
3173 def NbFacesOfOrder(self, elementOrder):
3175 Return the number of faces with the given order in the mesh
3178 elementOrder: the order of elements
3179 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3185 return self.mesh.NbFacesOfOrder(elementOrder)
3187 def NbTriangles(self):
3189 Return the number of triangles in the mesh
3195 return self.mesh.NbTriangles()
3197 def NbTrianglesOfOrder(self, elementOrder):
3199 Return the number of triangles with the given order in the mesh
3202 elementOrder: is the order of elements
3203 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3209 return self.mesh.NbTrianglesOfOrder(elementOrder)
3211 def NbBiQuadTriangles(self):
3213 Return the number of biquadratic triangles in the mesh
3219 return self.mesh.NbBiQuadTriangles()
3221 def NbQuadrangles(self):
3223 Return the number of quadrangles in the mesh
3229 return self.mesh.NbQuadrangles()
3231 def NbQuadranglesOfOrder(self, elementOrder):
3233 Return the number of quadrangles with the given order in the mesh
3236 elementOrder: the order of elements
3237 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3243 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3245 def NbBiQuadQuadrangles(self):
3247 Return the number of biquadratic quadrangles in the mesh
3253 return self.mesh.NbBiQuadQuadrangles()
3255 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3257 Return the number of polygons of given order in the mesh
3260 elementOrder: the order of elements
3261 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3267 return self.mesh.NbPolygonsOfOrder(elementOrder)
3269 def NbVolumes(self):
3271 Return the number of volumes in the mesh
3277 return self.mesh.NbVolumes()
3280 def NbVolumesOfOrder(self, elementOrder):
3282 Return the number of volumes with the given order in the mesh
3285 elementOrder: the order of elements
3286 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3292 return self.mesh.NbVolumesOfOrder(elementOrder)
3296 Return the number of tetrahedrons in the mesh
3302 return self.mesh.NbTetras()
3304 def NbTetrasOfOrder(self, elementOrder):
3306 Return the number of tetrahedrons with the given order in the mesh
3309 elementOrder: the order of elements
3310 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3316 return self.mesh.NbTetrasOfOrder(elementOrder)
3320 Return the number of hexahedrons in the mesh
3326 return self.mesh.NbHexas()
3328 def NbHexasOfOrder(self, elementOrder):
3330 Return the number of hexahedrons with the given order in the mesh
3333 elementOrder: the order of elements
3334 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3340 return self.mesh.NbHexasOfOrder(elementOrder)
3342 def NbTriQuadraticHexas(self):
3344 Return the number of triquadratic hexahedrons in the mesh
3350 return self.mesh.NbTriQuadraticHexas()
3352 def NbPyramids(self):
3354 Return the number of pyramids in the mesh
3360 return self.mesh.NbPyramids()
3362 def NbPyramidsOfOrder(self, elementOrder):
3364 Return the number of pyramids with the given order in the mesh
3367 elementOrder: the order of elements
3368 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3374 return self.mesh.NbPyramidsOfOrder(elementOrder)
3378 Return the number of prisms in the mesh
3384 return self.mesh.NbPrisms()
3386 def NbPrismsOfOrder(self, elementOrder):
3388 Return the number of prisms with the given order in the mesh
3391 elementOrder: the order of elements
3392 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3398 return self.mesh.NbPrismsOfOrder(elementOrder)
3400 def NbHexagonalPrisms(self):
3402 Return the number of hexagonal prisms in the mesh
3408 return self.mesh.NbHexagonalPrisms()
3410 def NbPolyhedrons(self):
3412 Return the number of polyhedrons in the mesh
3418 return self.mesh.NbPolyhedrons()
3420 def NbSubMesh(self):
3422 Return the number of submeshes in the mesh
3428 return self.mesh.NbSubMesh()
3430 def GetElementsId(self):
3432 Return the list of all mesh elements IDs
3435 the list of integer values
3438 :meth:`GetElementsByType`
3441 return self.mesh.GetElementsId()
3443 def GetElementsByType(self, elementType):
3445 Return the list of IDs of mesh elements with the given type
3448 elementType (SMESH.ElementType): the required type of elements
3451 list of integer values
3454 return self.mesh.GetElementsByType(elementType)
3456 def GetNodesId(self):
3458 Return the list of mesh nodes IDs
3461 the list of integer values
3464 return self.mesh.GetNodesId()
3466 # Get the information about mesh elements:
3467 # ------------------------------------
3469 def GetElementType(self, id, iselem=True):
3471 Return the type of mesh element or node
3474 the value from :class:`SMESH.ElementType` enumeration.
3475 Return SMESH.ALL if element or node with the given ID does not exist
3478 return self.mesh.GetElementType(id, iselem)
3480 def GetElementGeomType(self, id):
3482 Return the geometric type of mesh element
3485 the value from :class:`SMESH.EntityType` enumeration.
3488 return self.mesh.GetElementGeomType(id)
3490 def GetElementShape(self, id):
3492 Return the shape type of mesh element
3495 the value from :class:`SMESH.GeometryType` enumeration.
3498 return self.mesh.GetElementShape(id)
3500 def GetSubMeshElementsId(self, Shape):
3502 Return the list of sub-mesh elements IDs
3505 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3506 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3509 list of integer values
3512 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3513 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3516 return self.mesh.GetSubMeshElementsId(ShapeID)
3518 def GetSubMeshNodesId(self, Shape, all):
3520 Return the list of sub-mesh nodes IDs
3523 Shape: a geom object (sub-shape).
3524 *Shape* must be the sub-shape of a :meth:`GetShape`
3525 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3528 list of integer values
3531 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3532 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3535 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3537 def GetSubMeshElementType(self, Shape):
3539 Return type of elements on given shape
3542 Shape: a geom object (sub-shape).
3543 *Shape* must be a sub-shape of a ShapeToMesh()
3546 :class:`SMESH.ElementType`
3549 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3550 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3553 return self.mesh.GetSubMeshElementType(ShapeID)
3557 Get the mesh description
3563 return self.mesh.Dump()
3566 # Get the information about nodes and elements of a mesh by its IDs:
3567 # -----------------------------------------------------------
3569 def GetNodeXYZ(self, id):
3571 Get XYZ coordinates of a node.
3572 If there is no node for the given ID - return an empty list
3575 list of float values
3578 return self.mesh.GetNodeXYZ(id)
3580 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3582 Return list of IDs of inverse elements for the given node.
3583 If there is no node for the given ID - return an empty list
3587 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3590 list of integer values
3593 return self.mesh.GetNodeInverseElements(id,elemType)
3595 def GetNodePosition(self,NodeID):
3597 Return the position of a node on the shape
3600 :class:`SMESH.NodePosition`
3603 return self.mesh.GetNodePosition(NodeID)
3605 def GetElementPosition(self,ElemID):
3607 Return the position of an element on the shape
3610 :class:`SMESH.ElementPosition`
3613 return self.mesh.GetElementPosition(ElemID)
3615 def GetShapeID(self, id):
3617 Return the ID of the shape, on which the given node was generated.
3620 an integer value > 0 or -1 if there is no node for the given
3621 ID or the node is not assigned to any geometry
3624 return self.mesh.GetShapeID(id)
3626 def GetShapeIDForElem(self,id):
3628 Return the ID of the shape, on which the given element was generated.
3631 an integer value > 0 or -1 if there is no element for the given
3632 ID or the element is not assigned to any geometry
3635 return self.mesh.GetShapeIDForElem(id)
3637 def GetElemNbNodes(self, id):
3639 Return the number of nodes of the given element
3642 an integer value > 0 or -1 if there is no element for the given ID
3645 return self.mesh.GetElemNbNodes(id)
3647 def GetElemNode(self, id, index):
3649 Return the node ID the given (zero based) index for the given element.
3651 * If there is no element for the given ID - return -1.
3652 * If there is no node for the given index - return -2.
3655 id (int): element ID
3656 index (int): node index within the element
3659 an integer value (ID)
3662 :meth:`GetElemNodes`
3665 return self.mesh.GetElemNode(id, index)
3667 def GetElemNodes(self, id):
3669 Return the IDs of nodes of the given element
3672 a list of integer values
3675 return self.mesh.GetElemNodes(id)
3677 def IsMediumNode(self, elementID, nodeID):
3679 Return true if the given node is the medium node in the given quadratic element
3682 return self.mesh.IsMediumNode(elementID, nodeID)
3684 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3686 Return true if the given node is the medium node in one of quadratic elements
3689 nodeID: ID of the node
3690 elementType: the type of elements to check a state of the node, either of
3691 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3694 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3696 def ElemNbEdges(self, id):
3698 Return the number of edges for the given element
3701 return self.mesh.ElemNbEdges(id)
3703 def ElemNbFaces(self, id):
3705 Return the number of faces for the given element
3708 return self.mesh.ElemNbFaces(id)
3710 def GetElemFaceNodes(self,elemId, faceIndex):
3712 Return nodes of given face (counted from zero) for given volumic element.
3715 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3717 def GetFaceNormal(self, faceId, normalized=False):
3719 Return three components of normal of given mesh face
3720 (or an empty array in KO case)
3723 return self.mesh.GetFaceNormal(faceId,normalized)
3725 def FindElementByNodes(self, nodes):
3727 Return an element based on all given nodes.
3730 return self.mesh.FindElementByNodes(nodes)
3732 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3734 Return elements including all given nodes.
3737 return self.mesh.GetElementsByNodes( nodes, elemType )
3739 def IsPoly(self, id):
3741 Return true if the given element is a polygon
3744 return self.mesh.IsPoly(id)
3746 def IsQuadratic(self, id):
3748 Return true if the given element is quadratic
3751 return self.mesh.IsQuadratic(id)
3753 def GetBallDiameter(self, id):
3755 Return diameter of a ball discrete element or zero in case of an invalid *id*
3758 return self.mesh.GetBallDiameter(id)
3760 def BaryCenter(self, id):
3762 Return XYZ coordinates of the barycenter of the given element.
3763 If there is no element for the given ID - return an empty list
3766 a list of three double values
3769 :meth:`smeshBuilder.GetGravityCenter`
3772 return self.mesh.BaryCenter(id)
3774 def GetIdsFromFilter(self, filter, meshParts=[] ):
3776 Pass mesh elements through the given filter and return IDs of fitting elements
3779 filter: :class:`SMESH.Filter`
3780 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3786 :meth:`SMESH.Filter.GetIDs`
3787 :meth:`SMESH.Filter.GetElementsIdFromParts`
3790 filter.SetMesh( self.mesh )
3793 if isinstance( meshParts, Mesh ):
3794 filter.SetMesh( meshParts.GetMesh() )
3795 return theFilter.GetIDs()
3796 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3797 meshParts = [ meshParts ]
3798 return filter.GetElementsIdFromParts( meshParts )
3800 return filter.GetIDs()
3802 # Get mesh measurements information:
3803 # ------------------------------------
3805 def GetFreeBorders(self):
3807 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3808 Return a list of special structures (borders).
3811 a list of :class:`SMESH.FreeEdges.Border`
3814 aFilterMgr = self.smeshpyD.CreateFilterManager()
3815 aPredicate = aFilterMgr.CreateFreeEdges()
3816 aPredicate.SetMesh(self.mesh)
3817 aBorders = aPredicate.GetBorders()
3818 aFilterMgr.UnRegister()
3821 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3823 Get minimum distance between two nodes, elements or distance to the origin
3826 id1: first node/element id
3827 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3828 isElem1: *True* if *id1* is element id, *False* if it is node id
3829 isElem2: *True* if *id2* is element id, *False* if it is node id
3832 minimum distance value
3834 :meth:`GetMinDistance`
3837 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3838 return aMeasure.value
3840 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3842 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3845 id1: first node/element id
3846 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3847 isElem1: *True* if *id1* is element id, *False* if it is node id
3848 isElem2: *True* if *id2* is element id, *False* if it is node id
3851 :class:`SMESH.Measure` structure
3857 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3859 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3862 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3864 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3869 aMeasurements = self.smeshpyD.CreateMeasurements()
3870 aMeasure = aMeasurements.MinDistance(id1, id2)
3871 genObjUnRegister([aMeasurements,id1, id2])
3874 def BoundingBox(self, objects=None, isElem=False):
3876 Get bounding box of the specified object(s)
3879 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3880 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3881 *False* specifies that *objects* are nodes
3884 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3887 :meth:`GetBoundingBox()`
3890 result = self.GetBoundingBox(objects, isElem)
3894 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3897 def GetBoundingBox(self, objects=None, isElem=False):
3899 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3902 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3903 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3904 False means that *objects* are nodes
3907 :class:`SMESH.Measure` structure
3910 :meth:`BoundingBox()`
3914 objects = [self.mesh]
3915 elif isinstance(objects, tuple):
3916 objects = list(objects)
3917 if not isinstance(objects, list):
3919 if len(objects) > 0 and isinstance(objects[0], int):
3922 unRegister = genObjUnRegister()
3924 if isinstance(o, Mesh):
3925 srclist.append(o.mesh)
3926 elif hasattr(o, "_narrow"):
3927 src = o._narrow(SMESH.SMESH_IDSource)
3928 if src: srclist.append(src)
3930 elif isinstance(o, list):
3932 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3934 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3935 unRegister.set( srclist[-1] )
3938 aMeasurements = self.smeshpyD.CreateMeasurements()
3939 unRegister.set( aMeasurements )
3940 aMeasure = aMeasurements.BoundingBox(srclist)
3943 # Mesh edition (SMESH_MeshEditor functionality):
3944 # ---------------------------------------------
3946 def RemoveElements(self, IDsOfElements):
3948 Remove the elements from the mesh by ids
3951 IDsOfElements: is a list of ids of elements to remove
3957 return self.editor.RemoveElements(IDsOfElements)
3959 def RemoveNodes(self, IDsOfNodes):
3961 Remove nodes from mesh by ids
3964 IDsOfNodes: is a list of ids of nodes to remove
3970 return self.editor.RemoveNodes(IDsOfNodes)
3972 def RemoveOrphanNodes(self):
3974 Remove all orphan (free) nodes from mesh
3977 number of the removed nodes
3980 return self.editor.RemoveOrphanNodes()
3982 def AddNode(self, x, y, z):
3984 Add a node to the mesh by coordinates
3990 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3991 if hasVars: self.mesh.SetParameters(Parameters)
3992 return self.editor.AddNode( x, y, z)
3994 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3996 Create a 0D element on a node with given number.
3999 IDOfNode: the ID of node for creation of the element.
4000 DuplicateElements: to add one more 0D element to a node or not
4003 ID of the new 0D element
4006 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4008 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4010 Create 0D elements on all nodes of the given elements except those
4011 nodes on which a 0D element already exists.
4014 theObject: an object on whose nodes 0D elements will be created.
4015 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4016 theGroupName: optional name of a group to add 0D elements created
4017 and/or found on nodes of *theObject*.
4018 DuplicateElements: to add one more 0D element to a node or not
4021 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4022 IDs of new and/or found 0D elements. IDs of 0D elements
4023 can be retrieved from the returned object by
4024 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4027 unRegister = genObjUnRegister()
4028 if isinstance( theObject, Mesh ):
4029 theObject = theObject.GetMesh()
4030 elif isinstance( theObject, list ):
4031 theObject = self.GetIDSource( theObject, SMESH.ALL )
4032 unRegister.set( theObject )
4033 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4035 def AddBall(self, IDOfNode, diameter):
4037 Create a ball element on a node with given ID.
4040 IDOfNode: the ID of node for creation of the element.
4041 diameter: the bal diameter.
4044 ID of the new ball element
4047 return self.editor.AddBall( IDOfNode, diameter )
4049 def AddEdge(self, IDsOfNodes):
4051 Create a linear or quadratic edge (this is determined
4052 by the number of given nodes).
4055 IDsOfNodes: list of node IDs for creation of the element.
4056 The order of nodes in this list should correspond to
4057 the :ref:`connectivity convention <connectivity_page>`.
4063 return self.editor.AddEdge(IDsOfNodes)
4065 def AddFace(self, IDsOfNodes):
4067 Create a linear or quadratic face (this is determined
4068 by the number of given nodes).
4071 IDsOfNodes: list of node IDs for creation of the element.
4072 The order of nodes in this list should correspond to
4073 the :ref:`connectivity convention <connectivity_page>`.
4079 return self.editor.AddFace(IDsOfNodes)
4081 def AddPolygonalFace(self, IdsOfNodes):
4083 Add a polygonal face defined by a list of node IDs
4086 IdsOfNodes: the list of node IDs for creation of the element.
4092 return self.editor.AddPolygonalFace(IdsOfNodes)
4094 def AddQuadPolygonalFace(self, IdsOfNodes):
4096 Add a quadratic polygonal face defined by a list of node IDs
4099 IdsOfNodes: the list of node IDs for creation of the element;
4100 corner nodes follow first.
4106 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4108 def AddVolume(self, IDsOfNodes):
4110 Create both simple and quadratic volume (this is determined
4111 by the number of given nodes).
4114 IDsOfNodes: list of node IDs for creation of the element.
4115 The order of nodes in this list should correspond to
4116 the :ref:`connectivity convention <connectivity_page>`.
4119 ID of the new volumic element
4122 return self.editor.AddVolume(IDsOfNodes)
4124 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4126 Create a volume of many faces, giving nodes for each face.
4129 IdsOfNodes: list of node IDs for volume creation, face by face.
4130 Quantities: list of integer values, Quantities[i]
4131 gives the quantity of nodes in face number i.
4134 ID of the new volumic element
4137 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4139 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4141 Create a volume of many faces, giving the IDs of the existing faces.
4144 The created volume will refer only to the nodes
4145 of the given faces, not to the faces themselves.
4148 IdsOfFaces: the list of face IDs for volume creation.
4151 ID of the new volumic element
4154 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4157 def SetNodeOnVertex(self, NodeID, Vertex):
4159 Bind a node to a vertex
4163 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4166 True if succeed else raises an exception
4169 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4170 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4174 self.editor.SetNodeOnVertex(NodeID, VertexID)
4175 except SALOME.SALOME_Exception as inst:
4176 raise ValueError(inst.details.text)
4180 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4182 Store the node position on an edge
4186 Edge: an edge (GEOM.GEOM_Object) or edge ID
4187 paramOnEdge: a parameter on the edge where the node is located
4190 True if succeed else raises an exception
4193 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4194 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4198 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4199 except SALOME.SALOME_Exception as inst:
4200 raise ValueError(inst.details.text)
4203 def SetNodeOnFace(self, NodeID, Face, u, v):
4205 Store node position on a face
4209 Face: a face (GEOM.GEOM_Object) or face ID
4210 u: U parameter on the face where the node is located
4211 v: V parameter on the face where the node is located
4214 True if succeed else raises an exception
4217 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4218 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4222 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4223 except SALOME.SALOME_Exception as inst:
4224 raise ValueError(inst.details.text)
4227 def SetNodeInVolume(self, NodeID, Solid):
4229 Bind a node to a solid
4233 Solid: a solid (GEOM.GEOM_Object) or solid ID
4236 True if succeed else raises an exception
4239 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4240 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4244 self.editor.SetNodeInVolume(NodeID, SolidID)
4245 except SALOME.SALOME_Exception as inst:
4246 raise ValueError(inst.details.text)
4249 def SetMeshElementOnShape(self, ElementID, Shape):
4251 Bind an element to a shape
4254 ElementID: an element ID
4255 Shape: a shape (GEOM.GEOM_Object) or shape ID
4258 True if succeed else raises an exception
4261 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4262 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4266 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4267 except SALOME.SALOME_Exception as inst:
4268 raise ValueError(inst.details.text)
4272 def MoveNode(self, NodeID, x, y, z):
4274 Move the node with the given id
4277 NodeID: the id of the node
4278 x: a new X coordinate
4279 y: a new Y coordinate
4280 z: a new Z coordinate
4283 True if succeed else False
4286 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4287 if hasVars: self.mesh.SetParameters(Parameters)
4288 return self.editor.MoveNode(NodeID, x, y, z)
4290 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4292 Find the node closest to a point and moves it to a point location
4295 x: the X coordinate of a point
4296 y: the Y coordinate of a point
4297 z: the Z coordinate of a point
4298 NodeID: if specified (>0), the node with this ID is moved,
4299 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4302 the ID of a moved node
4305 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4306 if hasVars: self.mesh.SetParameters(Parameters)
4307 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4309 def FindNodeClosestTo(self, x, y, z):
4311 Find the node closest to a point
4314 x: the X coordinate of a point
4315 y: the Y coordinate of a point
4316 z: the Z coordinate of a point
4322 return self.editor.FindNodeClosestTo(x, y, z)
4324 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4326 Find the elements where a point lays IN or ON
4329 x,y,z (float): coordinates of the point
4330 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4331 means elements of any type excluding nodes, discrete and 0D elements.
4332 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4335 list of IDs of found elements
4338 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4340 return self.editor.FindElementsByPoint(x, y, z, elementType)
4342 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4344 Project a point to a mesh object.
4345 Return ID of an element of given type where the given point is projected
4346 and coordinates of the projection point.
4347 In the case if nothing found, return -1 and []
4349 if isinstance( meshObject, Mesh ):
4350 meshObject = meshObject.GetMesh()
4352 meshObject = self.GetMesh()
4353 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4355 def GetPointState(self, x, y, z):
4357 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4358 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4359 UNKNOWN state means that either mesh is wrong or the analysis fails.
4362 return self.editor.GetPointState(x, y, z)
4364 def IsManifold(self):
4366 Check if a 2D mesh is manifold
4369 return self.editor.IsManifold()
4371 def IsCoherentOrientation2D(self):
4373 Check if orientation of 2D elements is coherent
4376 return self.editor.IsCoherentOrientation2D()
4378 def Get1DBranches( self, edges, startNode = 0 ):
4380 Partition given 1D elements into groups of contiguous edges.
4381 A node where number of meeting edges != 2 is a group end.
4382 An optional startNode is used to orient groups it belongs to.
4385 A list of edge groups and a list of corresponding node groups,
4386 where the group is a list of IDs of edges or elements.
4387 If a group is closed, the first and last nodes of the group are same.
4389 if isinstance( edges, Mesh ):
4390 edges = edges.GetMesh()
4391 unRegister = genObjUnRegister()
4392 if isinstance( edges, list ):
4393 edges = self.GetIDSource( edges, SMESH.EDGE )
4394 unRegister.set( edges )
4395 return self.editor.Get1DBranches( edges, startNode )
4397 def FindSharpEdges( self, angle, addExisting=False ):
4399 Return sharp edges of faces and non-manifold ones.
4400 Optionally add existing edges.
4403 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4404 addExisting: to return existing edges (1D elements) as well
4407 list of FaceEdge structures
4409 angle = ParseParameters( angle )[0]
4410 return self.editor.FindSharpEdges( angle, addExisting )
4412 def MeshToPassThroughAPoint(self, x, y, z):
4414 Find the node closest to a point and moves it to a point location
4417 x: the X coordinate of a point
4418 y: the Y coordinate of a point
4419 z: the Z coordinate of a point
4422 the ID of a moved node
4425 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4427 def InverseDiag(self, NodeID1, NodeID2):
4429 Replace two neighbour triangles sharing Node1-Node2 link
4430 with the triangles built on the same 4 nodes but having other common link.
4433 NodeID1: the ID of the first node
4434 NodeID2: the ID of the second node
4437 False if proper faces were not found
4439 return self.editor.InverseDiag(NodeID1, NodeID2)
4441 def DeleteDiag(self, NodeID1, NodeID2):
4443 Replace two neighbour triangles sharing *Node1-Node2* link
4444 with a quadrangle built on the same 4 nodes.
4447 NodeID1: ID of the first node
4448 NodeID2: ID of the second node
4451 False if proper faces were not found
4454 return self.editor.DeleteDiag(NodeID1, NodeID2)
4456 def Reorient(self, IDsOfElements=None):
4458 Reorient elements by ids
4461 IDsOfElements: if undefined reorients all mesh elements
4464 True if succeed else False
4467 if IDsOfElements == None:
4468 IDsOfElements = self.GetElementsId()
4469 return self.editor.Reorient(IDsOfElements)
4471 def ReorientObject(self, theObject):
4473 Reorient all elements of the object
4476 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4479 True if succeed else False
4482 if ( isinstance( theObject, Mesh )):
4483 theObject = theObject.GetMesh()
4484 return self.editor.ReorientObject(theObject)
4486 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4488 Reorient faces contained in *the2DObject*.
4491 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4492 theDirection: is a desired direction of normal of *theFace*.
4493 It can be either a GEOM vector or a list of coordinates [x,y,z].
4494 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4495 compared with theDirection. It can be either ID of face or a point
4496 by which the face will be found. The point can be given as either
4497 a GEOM vertex or a list of point coordinates.
4500 number of reoriented faces
4503 unRegister = genObjUnRegister()
4505 if isinstance( the2DObject, Mesh ):
4506 the2DObject = the2DObject.GetMesh()
4507 if isinstance( the2DObject, list ):
4508 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4509 unRegister.set( the2DObject )
4510 # check theDirection
4511 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4512 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4513 if isinstance( theDirection, list ):
4514 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4515 # prepare theFace and thePoint
4516 theFace = theFaceOrPoint
4517 thePoint = PointStruct(0,0,0)
4518 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4519 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4521 if isinstance( theFaceOrPoint, list ):
4522 thePoint = PointStruct( *theFaceOrPoint )
4524 if isinstance( theFaceOrPoint, PointStruct ):
4525 thePoint = theFaceOrPoint
4527 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4529 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4531 Reorient faces according to adjacent volumes.
4534 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4535 either IDs of faces or face groups.
4536 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4537 theOutsideNormal: to orient faces to have their normals
4538 pointing either *outside* or *inside* the adjacent volumes.
4541 number of reoriented faces.
4544 unRegister = genObjUnRegister()
4546 if not isinstance( the2DObject, list ):
4547 the2DObject = [ the2DObject ]
4548 elif the2DObject and isinstance( the2DObject[0], int ):
4549 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4550 unRegister.set( the2DObject )
4551 the2DObject = [ the2DObject ]
4552 for i,obj2D in enumerate( the2DObject ):
4553 if isinstance( obj2D, Mesh ):
4554 the2DObject[i] = obj2D.GetMesh()
4555 if isinstance( obj2D, list ):
4556 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4557 unRegister.set( the2DObject[i] )
4559 if isinstance( the3DObject, Mesh ):
4560 the3DObject = the3DObject.GetMesh()
4561 if isinstance( the3DObject, list ):
4562 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4563 unRegister.set( the3DObject )
4564 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4566 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4568 Fuse the neighbouring triangles into quadrangles.
4571 IDsOfElements: The triangles to be fused.
4572 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4573 applied to possible quadrangles to choose a neighbour to fuse with.
4574 Note that not all items of :class:`SMESH.FunctorType` corresponds
4575 to numerical functors.
4576 MaxAngle: is the maximum angle between element normals at which the fusion
4577 is still performed; theMaxAngle is measured in radians.
4578 Also it could be a name of variable which defines angle in degrees.
4581 True in case of success, False otherwise.
4584 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4585 self.mesh.SetParameters(Parameters)
4586 if not IDsOfElements:
4587 IDsOfElements = self.GetElementsId()
4588 Functor = self.smeshpyD.GetFunctor(theCriterion)
4589 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4591 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4593 Fuse the neighbouring triangles of the object into quadrangles
4596 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4597 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4598 applied to possible quadrangles to choose a neighbour to fuse with.
4599 Note that not all items of :class:`SMESH.FunctorType` corresponds
4600 to numerical functors.
4601 MaxAngle: a max angle between element normals at which the fusion
4602 is still performed; theMaxAngle is measured in radians.
4605 True in case of success, False otherwise.
4608 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4609 self.mesh.SetParameters(Parameters)
4610 if isinstance( theObject, Mesh ):
4611 theObject = theObject.GetMesh()
4612 Functor = self.smeshpyD.GetFunctor(theCriterion)
4613 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4615 def QuadToTri (self, IDsOfElements, theCriterion = None):
4617 Split quadrangles into triangles.
4620 IDsOfElements: the faces to be splitted.
4621 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4622 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4623 value, then quadrangles will be split by the smallest diagonal.
4624 Note that not all items of :class:`SMESH.FunctorType` corresponds
4625 to numerical functors.
4628 True in case of success, False otherwise.
4630 if IDsOfElements == []:
4631 IDsOfElements = self.GetElementsId()
4632 if theCriterion is None:
4633 theCriterion = FT_MaxElementLength2D
4634 Functor = self.smeshpyD.GetFunctor(theCriterion)
4635 return self.editor.QuadToTri(IDsOfElements, Functor)
4637 def QuadToTriObject (self, theObject, theCriterion = None):
4639 Split quadrangles into triangles.
4642 theObject: the object from which the list of elements is taken,
4643 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4644 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4645 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4646 value, then quadrangles will be split by the smallest diagonal.
4647 Note that not all items of :class:`SMESH.FunctorType` corresponds
4648 to numerical functors.
4651 True in case of success, False otherwise.
4653 if ( isinstance( theObject, Mesh )):
4654 theObject = theObject.GetMesh()
4655 if theCriterion is None:
4656 theCriterion = FT_MaxElementLength2D
4657 Functor = self.smeshpyD.GetFunctor(theCriterion)
4658 return self.editor.QuadToTriObject(theObject, Functor)
4660 def QuadTo4Tri (self, theElements=[]):
4662 Split each of given quadrangles into 4 triangles. A node is added at the center of
4666 theElements: the faces to be splitted. This can be either
4667 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4668 or a list of face IDs. By default all quadrangles are split
4670 unRegister = genObjUnRegister()
4671 if isinstance( theElements, Mesh ):
4672 theElements = theElements.mesh
4673 elif not theElements:
4674 theElements = self.mesh
4675 elif isinstance( theElements, list ):
4676 theElements = self.GetIDSource( theElements, SMESH.FACE )
4677 unRegister.set( theElements )
4678 return self.editor.QuadTo4Tri( theElements )
4680 def SplitQuad (self, IDsOfElements, Diag13):
4682 Split quadrangles into triangles.
4685 IDsOfElements: the faces to be splitted
4686 Diag13 (boolean): is used to choose a diagonal for splitting.
4689 True in case of success, False otherwise.
4691 if IDsOfElements == []:
4692 IDsOfElements = self.GetElementsId()
4693 return self.editor.SplitQuad(IDsOfElements, Diag13)
4695 def SplitQuadObject (self, theObject, Diag13):
4697 Split quadrangles into triangles.
4700 theObject: the object from which the list of elements is taken,
4701 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4702 Diag13 (boolean): is used to choose a diagonal for splitting.
4705 True in case of success, False otherwise.
4707 if ( isinstance( theObject, Mesh )):
4708 theObject = theObject.GetMesh()
4709 return self.editor.SplitQuadObject(theObject, Diag13)
4711 def BestSplit (self, IDOfQuad, theCriterion):
4713 Find a better splitting of the given quadrangle.
4716 IDOfQuad: the ID of the quadrangle to be splitted.
4717 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4718 choose a diagonal for splitting.
4719 Note that not all items of :class:`SMESH.FunctorType` corresponds
4720 to numerical functors.
4723 * 1 if 1-3 diagonal is better,
4724 * 2 if 2-4 diagonal is better,
4725 * 0 if error occurs.
4727 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4729 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4731 Split volumic elements into tetrahedrons
4734 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4735 method: flags passing splitting method:
4736 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4737 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4739 unRegister = genObjUnRegister()
4740 if isinstance( elems, Mesh ):
4741 elems = elems.GetMesh()
4742 if ( isinstance( elems, list )):
4743 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4744 unRegister.set( elems )
4745 self.editor.SplitVolumesIntoTetra(elems, method)
4748 def SplitBiQuadraticIntoLinear(self, elems=None):
4750 Split bi-quadratic elements into linear ones without creation of additional nodes:
4752 - bi-quadratic triangle will be split into 3 linear quadrangles;
4753 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4754 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4756 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4757 will be split in order to keep the mesh conformal.
4760 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4761 if None (default), all bi-quadratic elements will be split
4763 unRegister = genObjUnRegister()
4764 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4765 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4766 unRegister.set( elems )
4768 elems = [ self.GetMesh() ]
4769 if isinstance( elems, Mesh ):
4770 elems = [ elems.GetMesh() ]
4771 if not isinstance( elems, list ):
4773 self.editor.SplitBiQuadraticIntoLinear( elems )
4775 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4776 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4778 Split hexahedra into prisms
4781 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4782 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4783 gives a normal vector defining facets to split into triangles.
4784 *startHexPoint* can be either a triple of coordinates or a vertex.
4785 facetNormal: a normal to a facet to split into triangles of a
4786 hexahedron found by *startHexPoint*.
4787 *facetNormal* can be either a triple of coordinates or an edge.
4788 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4789 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4790 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4791 to *startHexPoint* are split, else *startHexPoint*
4792 is used to find the facet to split in all domains present in *elems*.
4795 unRegister = genObjUnRegister()
4796 if isinstance( elems, Mesh ):
4797 elems = elems.GetMesh()
4798 if ( isinstance( elems, list )):
4799 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4800 unRegister.set( elems )
4803 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4804 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4805 elif isinstance( startHexPoint, list ):
4806 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4809 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4810 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4811 elif isinstance( facetNormal, list ):
4812 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4815 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4817 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4819 def SplitQuadsNearTriangularFacets(self):
4821 Split quadrangle faces near triangular facets of volumes
4823 faces_array = self.GetElementsByType(SMESH.FACE)
4824 for face_id in faces_array:
4825 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4826 quad_nodes = self.mesh.GetElemNodes(face_id)
4827 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4828 isVolumeFound = False
4829 for node1_elem in node1_elems:
4830 if not isVolumeFound:
4831 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4832 nb_nodes = self.GetElemNbNodes(node1_elem)
4833 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4834 volume_elem = node1_elem
4835 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4836 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4837 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4838 isVolumeFound = True
4839 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4840 self.SplitQuad([face_id], False) # diagonal 2-4
4841 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4842 isVolumeFound = True
4843 self.SplitQuad([face_id], True) # diagonal 1-3
4844 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4845 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4846 isVolumeFound = True
4847 self.SplitQuad([face_id], True) # diagonal 1-3
4849 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4851 Split hexahedrons into tetrahedrons.
4853 This operation uses :doc:`pattern_mapping` functionality for splitting.
4856 theObject: the object from which the list of hexahedrons is taken;
4857 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4858 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4859 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4860 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4861 key-point will be mapped into *theNode001*-th node of each volume.
4862 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4865 True in case of success, False otherwise.
4873 # (0,0,1) 4.---------.7 * |
4880 # (0,0,0) 0.---------.3
4881 pattern_tetra = "!!! Nb of points: \n 8 \n\
4891 !!! Indices of points of 6 tetras: \n\
4899 pattern = self.smeshpyD.GetPattern()
4900 isDone = pattern.LoadFromFile(pattern_tetra)
4902 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4905 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4906 isDone = pattern.MakeMesh(self.mesh, False, False)
4907 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4909 # split quafrangle faces near triangular facets of volumes
4910 self.SplitQuadsNearTriangularFacets()
4914 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4916 Split hexahedrons into prisms.
4918 Uses the :doc:`pattern_mapping` functionality for splitting.
4921 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4922 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4923 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4924 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4925 will be mapped into the *theNode001* -th node of each volume.
4926 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4929 True in case of success, False otherwise.
4931 # Pattern: 5.---------.6
4936 # (0,0,1) 4.---------.7 |
4943 # (0,0,0) 0.---------.3
4944 pattern_prism = "!!! Nb of points: \n 8 \n\
4954 !!! Indices of points of 2 prisms: \n\
4958 pattern = self.smeshpyD.GetPattern()
4959 isDone = pattern.LoadFromFile(pattern_prism)
4961 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4964 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4965 isDone = pattern.MakeMesh(self.mesh, False, False)
4966 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4968 # Split quafrangle faces near triangular facets of volumes
4969 self.SplitQuadsNearTriangularFacets()
4973 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4974 MaxNbOfIterations, MaxAspectRatio, Method):
4979 IDsOfElements: the list if ids of elements to smooth
4980 IDsOfFixedNodes: the list of ids of fixed nodes.
4981 Note that nodes built on edges and boundary nodes are always fixed.
4982 MaxNbOfIterations: the maximum number of iterations
4983 MaxAspectRatio: varies in range [1.0, inf]
4984 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4985 or Centroidal (smesh.CENTROIDAL_SMOOTH)
4988 True in case of success, False otherwise.
4991 if IDsOfElements == []:
4992 IDsOfElements = self.GetElementsId()
4993 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4994 self.mesh.SetParameters(Parameters)
4995 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4996 MaxNbOfIterations, MaxAspectRatio, Method)
4998 def SmoothObject(self, theObject, IDsOfFixedNodes,
4999 MaxNbOfIterations, MaxAspectRatio, Method):
5001 Smooth elements which belong to the given object
5004 theObject: the object to smooth
5005 IDsOfFixedNodes: the list of ids of fixed nodes.
5006 Note that nodes built on edges and boundary nodes are always fixed.
5007 MaxNbOfIterations: the maximum number of iterations
5008 MaxAspectRatio: varies in range [1.0, inf]
5009 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5010 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5013 True in case of success, False otherwise.
5016 if ( isinstance( theObject, Mesh )):
5017 theObject = theObject.GetMesh()
5018 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5019 MaxNbOfIterations, MaxAspectRatio, Method)
5021 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5022 MaxNbOfIterations, MaxAspectRatio, Method):
5024 Parametrically smooth the given elements
5027 IDsOfElements: the list if ids of elements to smooth
5028 IDsOfFixedNodes: the list of ids of fixed nodes.
5029 Note that nodes built on edges and boundary nodes are always fixed.
5030 MaxNbOfIterations: the maximum number of iterations
5031 MaxAspectRatio: varies in range [1.0, inf]
5032 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5033 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5036 True in case of success, False otherwise.
5039 if IDsOfElements == []:
5040 IDsOfElements = self.GetElementsId()
5041 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5042 self.mesh.SetParameters(Parameters)
5043 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5044 MaxNbOfIterations, MaxAspectRatio, Method)
5046 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5047 MaxNbOfIterations, MaxAspectRatio, Method):
5049 Parametrically smooth the elements which belong to the given object
5052 theObject: the object to smooth
5053 IDsOfFixedNodes: the list of ids of fixed nodes.
5054 Note that nodes built on edges and boundary nodes are always fixed.
5055 MaxNbOfIterations: the maximum number of iterations
5056 MaxAspectRatio: varies in range [1.0, inf]
5057 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5058 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5061 True in case of success, False otherwise.
5064 if ( isinstance( theObject, Mesh )):
5065 theObject = theObject.GetMesh()
5066 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5067 MaxNbOfIterations, MaxAspectRatio, Method)
5069 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5071 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5072 them with quadratic with the same id.
5075 theForce3d: method of new node creation:
5077 * False - the medium node lies at the geometrical entity from which the mesh element is built
5078 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5079 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5080 theToBiQuad: If True, converts the mesh to bi-quadratic
5083 :class:`SMESH.ComputeError` which can hold a warning
5086 If *theSubMesh* is provided, the mesh can become non-conformal
5089 if isinstance( theSubMesh, Mesh ):
5090 theSubMesh = theSubMesh.mesh
5092 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5095 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5097 self.editor.ConvertToQuadratic(theForce3d)
5098 error = self.editor.GetLastError()
5099 if error and error.comment:
5100 print(error.comment)
5103 def ConvertFromQuadratic(self, theSubMesh=None):
5105 Convert the mesh from quadratic to ordinary,
5106 deletes old quadratic elements,
5107 replacing them with ordinary mesh elements with the same id.
5110 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5113 If *theSubMesh* is provided, the mesh can become non-conformal
5117 self.editor.ConvertFromQuadraticObject(theSubMesh)
5119 return self.editor.ConvertFromQuadratic()
5121 def Make2DMeshFrom3D(self):
5123 Create 2D mesh as skin on boundary faces of a 3D mesh
5126 True if operation has been completed successfully, False otherwise
5129 return self.editor.Make2DMeshFrom3D()
5131 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5132 toCopyElements=False, toCopyExistingBondary=False):
5134 Create missing boundary elements
5137 elements: elements whose boundary is to be checked:
5138 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5139 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5140 dimension: defines type of boundary elements to create, either of
5141 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5142 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5143 groupName: a name of group to store created boundary elements in,
5144 "" means not to create the group
5145 meshName: a name of new mesh to store created boundary elements in,
5146 "" means not to create the new mesh
5147 toCopyElements: if True, the checked elements will be copied into
5148 the new mesh else only boundary elements will be copied into the new mesh
5149 toCopyExistingBondary: if True, not only new but also pre-existing
5150 boundary elements will be copied into the new mesh
5153 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5156 unRegister = genObjUnRegister()
5157 if isinstance( elements, Mesh ):
5158 elements = elements.GetMesh()
5159 if ( isinstance( elements, list )):
5160 elemType = SMESH.ALL
5161 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5162 elements = self.editor.MakeIDSource(elements, elemType)
5163 unRegister.set( elements )
5164 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5165 toCopyElements,toCopyExistingBondary)
5166 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5169 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5170 toCopyAll=False, groups=[]):
5172 Create missing boundary elements around either the whole mesh or
5176 dimension: defines type of boundary elements to create, either of
5177 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5178 groupName: a name of group to store all boundary elements in,
5179 "" means not to create the group
5180 meshName: a name of a new mesh, which is a copy of the initial
5181 mesh + created boundary elements; "" means not to create the new mesh
5182 toCopyAll: if True, the whole initial mesh will be copied into
5183 the new mesh else only boundary elements will be copied into the new mesh
5184 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5187 tuple( long, mesh, group )
5188 - long - number of added boundary elements
5189 - mesh - the :class:`Mesh` where elements were added to
5190 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5193 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5195 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5196 return nb, mesh, group
5198 def RenumberNodes(self):
5200 Renumber mesh nodes to remove unused node IDs
5202 self.editor.RenumberNodes()
5204 def RenumberElements(self):
5206 Renumber mesh elements to remove unused element IDs
5208 self.editor.RenumberElements()
5210 def _getIdSourceList(self, arg, idType, unRegister):
5212 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5214 if arg and isinstance( arg, list ):
5215 if isinstance( arg[0], int ):
5216 arg = self.GetIDSource( arg, idType )
5217 unRegister.set( arg )
5218 elif isinstance( arg[0], Mesh ):
5219 arg[0] = arg[0].GetMesh()
5220 elif isinstance( arg, Mesh ):
5222 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5226 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5227 MakeGroups=False, TotalAngle=False):
5229 Generate new elements by rotation of the given elements and nodes around the axis
5232 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5233 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5234 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5235 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5236 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5237 which defines angle in degrees
5238 NbOfSteps: the number of steps
5239 Tolerance: tolerance
5240 MakeGroups: forces the generation of new groups from existing ones
5241 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5242 of all steps, else - size of each step
5245 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5248 unRegister = genObjUnRegister()
5249 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5250 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5251 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5253 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5254 Axis = self.smeshpyD.GetAxisStruct( Axis )
5255 if isinstance( Axis, list ):
5256 Axis = SMESH.AxisStruct( *Axis )
5258 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5259 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5260 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5261 self.mesh.SetParameters(Parameters)
5262 if TotalAngle and NbOfSteps:
5263 AngleInRadians /= NbOfSteps
5264 return self.editor.RotationSweepObjects( nodes, edges, faces,
5265 Axis, AngleInRadians,
5266 NbOfSteps, Tolerance, MakeGroups)
5268 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5269 MakeGroups=False, TotalAngle=False):
5271 Generate new elements by rotation of the elements around the axis
5274 IDsOfElements: the list of ids of elements to sweep
5275 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5276 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5277 NbOfSteps: the number of steps
5278 Tolerance: tolerance
5279 MakeGroups: forces the generation of new groups from existing ones
5280 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5281 of all steps, else - size of each step
5284 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5287 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5288 AngleInRadians, NbOfSteps, Tolerance,
5289 MakeGroups, TotalAngle)
5291 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5292 MakeGroups=False, TotalAngle=False):
5294 Generate new elements by rotation of the elements of object around the axis
5295 theObject object which elements should be sweeped.
5296 It can be a mesh, a sub mesh or a group.
5299 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5300 AngleInRadians: the angle of Rotation
5301 NbOfSteps: number of steps
5302 Tolerance: tolerance
5303 MakeGroups: forces the generation of new groups from existing ones
5304 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5305 of all steps, else - size of each step
5308 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5311 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5312 AngleInRadians, NbOfSteps, Tolerance,
5313 MakeGroups, TotalAngle )
5315 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5316 MakeGroups=False, TotalAngle=False):
5318 Generate new elements by rotation of the elements of object around the axis
5319 theObject object which elements should be sweeped.
5320 It can be a mesh, a sub mesh or a group.
5323 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5324 AngleInRadians: the angle of Rotation
5325 NbOfSteps: number of steps
5326 Tolerance: tolerance
5327 MakeGroups: forces the generation of new groups from existing ones
5328 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5329 of all steps, else - size of each step
5332 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5333 empty list otherwise
5336 return self.RotationSweepObjects([],theObject,[], Axis,
5337 AngleInRadians, NbOfSteps, Tolerance,
5338 MakeGroups, TotalAngle)
5340 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5341 MakeGroups=False, TotalAngle=False):
5343 Generate new elements by rotation of the elements of object around the axis
5344 theObject object which elements should be sweeped.
5345 It can be a mesh, a sub mesh or a group.
5348 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5349 AngleInRadians: the angle of Rotation
5350 NbOfSteps: number of steps
5351 Tolerance: tolerance
5352 MakeGroups: forces the generation of new groups from existing ones
5353 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5354 of all steps, else - size of each step
5357 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5360 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5361 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5363 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5364 scaleFactors=[], linearVariation=False, basePoint=[],
5365 angles=[], anglesVariation=False):
5367 Generate new elements by extrusion of the given elements and nodes
5370 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5371 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5372 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5373 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5374 the direction and value of extrusion for one step (the total extrusion
5375 length will be NbOfSteps * ||StepVector||)
5376 NbOfSteps: the number of steps
5377 MakeGroups: forces the generation of new groups from existing ones
5378 scaleFactors: optional scale factors to apply during extrusion
5379 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5380 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5381 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5382 nodes and elements being extruded is used as the scaling center.
5385 - a list of tree components of the point or
5388 angles: list of angles in radians. Nodes at each extrusion step are rotated
5389 around *basePoint*, additionally to previous steps.
5390 anglesVariation: forces the computation of rotation angles as linear
5391 variation of the given *angles* along path steps
5393 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5395 Example: :ref:`tui_extrusion`
5397 unRegister = genObjUnRegister()
5398 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5399 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5400 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5402 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5403 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5404 if isinstance( StepVector, list ):
5405 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5407 if isinstance( basePoint, int):
5408 xyz = self.GetNodeXYZ( basePoint )
5410 raise RuntimeError("Invalid node ID: %s" % basePoint)
5412 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5413 basePoint = self.geompyD.PointCoordinates( basePoint )
5415 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5416 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5417 angles,angleParameters,hasVars = ParseAngles(angles)
5418 Parameters = StepVector.PS.parameters + var_separator + \
5419 Parameters + var_separator + \
5420 scaleParameters + var_separator + angleParameters
5421 self.mesh.SetParameters(Parameters)
5423 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5424 StepVector, NbOfSteps, MakeGroups,
5425 scaleFactors, linearVariation, basePoint,
5426 angles, anglesVariation )
5429 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5431 Generate new elements by extrusion of the elements with given ids
5434 IDsOfElements: the list of ids of elements or nodes for extrusion
5435 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5436 the direction and value of extrusion for one step (the total extrusion
5437 length will be NbOfSteps * ||StepVector||)
5438 NbOfSteps: the number of steps
5439 MakeGroups: forces the generation of new groups from existing ones
5440 IsNodes: is True if elements with given ids are nodes
5443 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5445 Example: :ref:`tui_extrusion`
5448 if IsNodes: n = IDsOfElements
5449 else : e,f, = IDsOfElements,IDsOfElements
5450 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5452 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5453 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5455 Generate new elements by extrusion along the normal to a discretized surface or wire
5458 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5459 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5460 StepSize: length of one extrusion step (the total extrusion
5461 length will be *NbOfSteps* *StepSize*).
5462 NbOfSteps: number of extrusion steps.
5463 ByAverageNormal: if True each node is translated by *StepSize*
5464 along the average of the normal vectors to the faces sharing the node;
5465 else each node is translated along the same average normal till
5466 intersection with the plane got by translation of the face sharing
5467 the node along its own normal by *StepSize*.
5468 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5469 for every node of *Elements*.
5470 MakeGroups: forces generation of new groups from existing ones.
5471 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5472 is not yet implemented. This parameter is used if *Elements* contains
5473 both faces and edges, i.e. *Elements* is a Mesh.
5476 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5477 empty list otherwise.
5478 Example: :ref:`tui_extrusion`
5481 unRegister = genObjUnRegister()
5482 if isinstance( Elements, Mesh ):
5483 Elements = [ Elements.GetMesh() ]
5484 if isinstance( Elements, list ):
5486 raise RuntimeError("Elements empty!")
5487 if isinstance( Elements[0], int ):
5488 Elements = self.GetIDSource( Elements, SMESH.ALL )
5489 unRegister.set( Elements )
5490 if not isinstance( Elements, list ):
5491 Elements = [ Elements ]
5492 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5493 self.mesh.SetParameters(Parameters)
5494 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5495 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5497 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5499 Generate new elements by extrusion of the elements or nodes which belong to the object
5502 theObject: the object whose elements or nodes should be processed.
5503 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5504 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5505 the direction and value of extrusion for one step (the total extrusion
5506 length will be NbOfSteps * ||StepVector||)
5507 NbOfSteps: the number of steps
5508 MakeGroups: forces the generation of new groups from existing ones
5509 IsNodes: is True if elements to extrude are nodes
5512 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5513 Example: :ref:`tui_extrusion`
5517 if IsNodes: n = theObject
5518 else : e,f, = theObject,theObject
5519 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5521 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5523 Generate new elements by extrusion of edges which belong to the object
5526 theObject: object whose 1D elements should be processed.
5527 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5528 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5529 the direction and value of extrusion for one step (the total extrusion
5530 length will be NbOfSteps * ||StepVector||)
5531 NbOfSteps: the number of steps
5532 MakeGroups: to generate new groups from existing ones
5535 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5536 Example: :ref:`tui_extrusion`
5539 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5541 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5543 Generate new elements by extrusion of faces which belong to the object
5546 theObject: object whose 2D elements should be processed.
5547 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5548 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5549 the direction and value of extrusion for one step (the total extrusion
5550 length will be NbOfSteps * ||StepVector||)
5551 NbOfSteps: the number of steps
5552 MakeGroups: forces the generation of new groups from existing ones
5555 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5556 Example: :ref:`tui_extrusion`
5559 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5561 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5562 ExtrFlags, SewTolerance, MakeGroups=False):
5564 Generate new elements by extrusion of the elements with given ids
5567 IDsOfElements: is ids of elements
5568 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5569 the direction and value of extrusion for one step (the total extrusion
5570 length will be NbOfSteps * ||StepVector||)
5571 NbOfSteps: the number of steps
5572 ExtrFlags: sets flags for extrusion
5573 SewTolerance: uses for comparing locations of nodes if flag
5574 EXTRUSION_FLAG_SEW is set
5575 MakeGroups: forces the generation of new groups from existing ones
5578 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5581 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5582 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5583 if isinstance( StepVector, list ):
5584 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5585 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5586 ExtrFlags, SewTolerance, MakeGroups)
5588 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5589 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5590 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5591 ScaleFactors=[], ScalesVariation=False):
5593 Generate new elements by extrusion of the given elements and nodes along the path.
5594 The path of extrusion must be a meshed edge.
5597 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5598 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5599 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5600 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5601 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
5602 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5603 HasAngles: not used obsolete
5604 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5605 around *basePoint*, additionally to previous steps.
5606 LinearVariation: forces the computation of rotation angles as linear
5607 variation of the given Angles along path steps
5608 HasRefPoint: allows using the reference point
5609 RefPoint: optional scaling and rotation center (mass center of the extruded
5610 elements by default). The User can specify any point as the Reference Point.
5611 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5612 MakeGroups: forces the generation of new groups from existing ones
5613 ScaleFactors: optional scale factors to apply during extrusion
5614 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5615 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5618 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5619 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5620 Example: :ref:`tui_extrusion_along_path`
5623 unRegister = genObjUnRegister()
5624 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5625 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5626 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5628 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5629 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5630 if isinstance( RefPoint, list ):
5631 if not RefPoint: RefPoint = [0,0,0]
5632 RefPoint = SMESH.PointStruct( *RefPoint )
5633 if isinstance( PathObject, Mesh ):
5634 PathObject = PathObject.GetMesh()
5635 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5636 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5637 Parameters = AnglesParameters + var_separator + \
5638 RefPoint.parameters + var_separator + ScalesParameters
5639 self.mesh.SetParameters(Parameters)
5640 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5641 PathObject, PathShape, NodeStart,
5642 HasAngles, Angles, LinearVariation,
5643 HasRefPoint, RefPoint, MakeGroups,
5644 ScaleFactors, ScalesVariation)
5646 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5647 HasAngles=False, Angles=[], LinearVariation=False,
5648 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5649 ElemType=SMESH.FACE):
5651 Generate new elements by extrusion of the given elements.
5652 The path of extrusion must be a meshed edge.
5655 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5656 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5657 NodeStart: the start node from Path. Defines the direction of extrusion
5658 HasAngles: not used obsolete
5659 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5660 around *basePoint*, additionally to previous steps.
5661 LinearVariation: forces the computation of rotation angles as linear
5662 variation of the given Angles along path steps
5663 HasRefPoint: allows using the reference point
5664 RefPoint: the reference point around which the elements are rotated (the mass
5665 center of the elements by default).
5666 The User can specify any point as the Reference Point.
5667 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5668 MakeGroups: forces the generation of new groups from existing ones
5669 ElemType: type of elements for extrusion (if param Base is a mesh)
5672 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5673 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5674 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5676 Example: :ref:`tui_extrusion_along_path`
5680 if ElemType == SMESH.NODE: n = Base
5681 if ElemType == SMESH.EDGE: e = Base
5682 if ElemType == SMESH.FACE: f = Base
5683 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5684 HasAngles, Angles, LinearVariation,
5685 HasRefPoint, RefPoint, MakeGroups)
5686 if MakeGroups: return gr,er
5689 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5690 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5691 MakeGroups=False, LinearVariation=False):
5693 Generate new elements by extrusion of the given elements.
5694 The path of extrusion must be a meshed edge.
5697 IDsOfElements: ids of elements
5698 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5699 PathShape: shape (edge) defines the sub-mesh for the path
5700 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5701 HasAngles: not used obsolete
5702 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5703 around *basePoint*, additionally to previous steps.
5704 HasRefPoint: allows using the reference point
5705 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5706 The User can specify any point as the Reference Point.
5707 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5708 MakeGroups: forces the generation of new groups from existing ones
5709 LinearVariation: forces the computation of rotation angles as linear
5710 variation of the given Angles along path steps
5713 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5714 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5715 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5716 Example: :ref:`tui_extrusion_along_path`
5719 if not IDsOfElements:
5720 IDsOfElements = [ self.GetMesh() ]
5721 n,e,f = [],IDsOfElements,IDsOfElements
5722 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5723 NodeStart, HasAngles, Angles,
5725 HasRefPoint, RefPoint, MakeGroups)
5726 if MakeGroups: return gr,er
5729 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5730 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5731 MakeGroups=False, LinearVariation=False):
5733 Generate new elements by extrusion of the elements which belong to the object.
5734 The path of extrusion must be a meshed edge.
5737 theObject: the object whose elements should be processed.
5738 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5739 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5740 PathShape: shape (edge) defines the sub-mesh for the path
5741 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5742 HasAngles: not used obsolete
5743 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5744 around *basePoint*, additionally to previous steps.
5745 HasRefPoint: allows using the reference point
5746 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5747 The User can specify any point as the Reference Point.
5748 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5749 MakeGroups: forces the generation of new groups from existing ones
5750 LinearVariation: forces the computation of rotation angles as linear
5751 variation of the given Angles along path steps
5754 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5755 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5756 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5757 Example: :ref:`tui_extrusion_along_path`
5760 n,e,f = [],theObject,theObject
5761 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5762 HasAngles, Angles, LinearVariation,
5763 HasRefPoint, RefPoint, MakeGroups)
5764 if MakeGroups: return gr,er
5767 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5768 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5769 MakeGroups=False, LinearVariation=False):
5771 Generate new elements by extrusion of mesh segments which belong to the object.
5772 The path of extrusion must be a meshed edge.
5775 theObject: the object whose 1D elements should be processed.
5776 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5777 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5778 PathShape: shape (edge) defines the sub-mesh for the path
5779 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5780 HasAngles: not used obsolete
5781 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5782 around *basePoint*, additionally to previous steps.
5783 HasRefPoint: allows using the reference point
5784 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5785 The User can specify any point as the Reference Point.
5786 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5787 MakeGroups: forces the generation of new groups from existing ones
5788 LinearVariation: forces the computation of rotation angles as linear
5789 variation of the given Angles along path steps
5792 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5793 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5794 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5795 Example: :ref:`tui_extrusion_along_path`
5798 n,e,f = [],theObject,[]
5799 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5800 HasAngles, Angles, LinearVariation,
5801 HasRefPoint, RefPoint, MakeGroups)
5802 if MakeGroups: return gr,er
5805 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5806 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5807 MakeGroups=False, LinearVariation=False):
5809 Generate new elements by extrusion of faces which belong to the object.
5810 The path of extrusion must be a meshed edge.
5813 theObject: the object whose 2D elements should be processed.
5814 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5815 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5816 PathShape: shape (edge) defines the sub-mesh for the path
5817 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5818 HasAngles: not used obsolete
5819 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5820 around *basePoint*, additionally to previous steps.
5821 HasRefPoint: allows using the reference point
5822 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5823 The User can specify any point as the Reference Point.
5824 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5825 MakeGroups: forces the generation of new groups from existing ones
5826 LinearVariation: forces the computation of rotation angles as linear
5827 variation of the given Angles along path steps
5830 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5831 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5832 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5833 Example: :ref:`tui_extrusion_along_path`
5836 n,e,f = [],[],theObject
5837 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5838 HasAngles, Angles, LinearVariation,
5839 HasRefPoint, RefPoint, MakeGroups)
5840 if MakeGroups: return gr,er
5843 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5845 Create a symmetrical copy of mesh elements
5848 IDsOfElements: list of elements ids
5849 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5850 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5851 If the *Mirror* is a geom object this parameter is unnecessary
5852 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5853 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5856 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5859 if IDsOfElements == []:
5860 IDsOfElements = self.GetElementsId()
5861 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5862 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5863 theMirrorType = Mirror._mirrorType
5865 self.mesh.SetParameters(Mirror.parameters)
5866 if Copy and MakeGroups:
5867 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5868 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5871 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5873 Create a new mesh by a symmetrical copy of mesh elements
5876 IDsOfElements: the list of elements ids
5877 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5878 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5879 If the *Mirror* is a geom object this parameter is unnecessary
5880 MakeGroups: to generate new groups from existing ones
5881 NewMeshName: a name of the new mesh to create
5884 instance of class :class:`Mesh`
5887 if IDsOfElements == []:
5888 IDsOfElements = self.GetElementsId()
5889 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5890 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5891 theMirrorType = Mirror._mirrorType
5893 self.mesh.SetParameters(Mirror.parameters)
5894 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5895 MakeGroups, NewMeshName)
5896 return Mesh(self.smeshpyD,self.geompyD,mesh)
5898 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5900 Create a symmetrical copy of the object
5903 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5904 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5905 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5906 If the *Mirror* is a geom object this parameter is unnecessary
5907 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5908 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5911 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5914 if ( isinstance( theObject, Mesh )):
5915 theObject = theObject.GetMesh()
5916 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5917 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5918 theMirrorType = Mirror._mirrorType
5920 self.mesh.SetParameters(Mirror.parameters)
5921 if Copy and MakeGroups:
5922 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5923 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5926 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5928 Create a new mesh by a symmetrical copy of the object
5931 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5932 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5933 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5934 If the *Mirror* is a geom object this parameter is unnecessary
5935 MakeGroups: forces the generation of new groups from existing ones
5936 NewMeshName: the name of the new mesh to create
5939 instance of class :class:`Mesh`
5942 if ( isinstance( theObject, Mesh )):
5943 theObject = theObject.GetMesh()
5944 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5945 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5946 theMirrorType = Mirror._mirrorType
5948 self.mesh.SetParameters(Mirror.parameters)
5949 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5950 MakeGroups, NewMeshName)
5951 return Mesh( self.smeshpyD,self.geompyD,mesh )
5953 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5955 Translate the elements
5958 IDsOfElements: list of elements ids
5959 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5960 Copy: allows copying the translated elements
5961 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5964 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5967 if IDsOfElements == []:
5968 IDsOfElements = self.GetElementsId()
5969 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5970 Vector = self.smeshpyD.GetDirStruct(Vector)
5971 if isinstance( Vector, list ):
5972 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5973 self.mesh.SetParameters(Vector.PS.parameters)
5974 if Copy and MakeGroups:
5975 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5976 self.editor.Translate(IDsOfElements, Vector, Copy)
5979 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5981 Create a new mesh of translated elements
5984 IDsOfElements: list of elements ids
5985 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5986 MakeGroups: forces the generation of new groups from existing ones
5987 NewMeshName: the name of the newly created mesh
5990 instance of class :class:`Mesh`
5993 if IDsOfElements == []:
5994 IDsOfElements = self.GetElementsId()
5995 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5996 Vector = self.smeshpyD.GetDirStruct(Vector)
5997 if isinstance( Vector, list ):
5998 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5999 self.mesh.SetParameters(Vector.PS.parameters)
6000 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6001 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6003 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6005 Translate the object
6008 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6009 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6010 Copy: allows copying the translated elements
6011 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6014 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6017 if ( isinstance( theObject, Mesh )):
6018 theObject = theObject.GetMesh()
6019 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6020 Vector = self.smeshpyD.GetDirStruct(Vector)
6021 if isinstance( Vector, list ):
6022 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6023 self.mesh.SetParameters(Vector.PS.parameters)
6024 if Copy and MakeGroups:
6025 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6026 self.editor.TranslateObject(theObject, Vector, Copy)
6029 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6031 Create a new mesh from the translated object
6034 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6035 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6036 MakeGroups: forces the generation of new groups from existing ones
6037 NewMeshName: the name of the newly created mesh
6040 instance of class :class:`Mesh`
6043 if isinstance( theObject, Mesh ):
6044 theObject = theObject.GetMesh()
6045 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6046 Vector = self.smeshpyD.GetDirStruct(Vector)
6047 if isinstance( Vector, list ):
6048 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6049 self.mesh.SetParameters(Vector.PS.parameters)
6050 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6051 return Mesh( self.smeshpyD, self.geompyD, mesh )
6055 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6060 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6061 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6062 theScaleFact: list of 1-3 scale factors for axises
6063 Copy: allows copying the translated elements
6064 MakeGroups: forces the generation of new groups from existing
6068 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6069 empty list otherwise
6071 unRegister = genObjUnRegister()
6072 if ( isinstance( theObject, Mesh )):
6073 theObject = theObject.GetMesh()
6074 if ( isinstance( theObject, list )):
6075 theObject = self.GetIDSource(theObject, SMESH.ALL)
6076 unRegister.set( theObject )
6077 if ( isinstance( thePoint, list )):
6078 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6079 if ( isinstance( theScaleFact, float )):
6080 theScaleFact = [theScaleFact]
6081 if ( isinstance( theScaleFact, int )):
6082 theScaleFact = [ float(theScaleFact)]
6084 self.mesh.SetParameters(thePoint.parameters)
6086 if Copy and MakeGroups:
6087 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6088 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6091 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6093 Create a new mesh from the translated object
6096 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6097 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6098 theScaleFact: list of 1-3 scale factors for axises
6099 MakeGroups: forces the generation of new groups from existing ones
6100 NewMeshName: the name of the newly created mesh
6103 instance of class :class:`Mesh`
6105 unRegister = genObjUnRegister()
6106 if (isinstance(theObject, Mesh)):
6107 theObject = theObject.GetMesh()
6108 if ( isinstance( theObject, list )):
6109 theObject = self.GetIDSource(theObject,SMESH.ALL)
6110 unRegister.set( theObject )
6111 if ( isinstance( thePoint, list )):
6112 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6113 if ( isinstance( theScaleFact, float )):
6114 theScaleFact = [theScaleFact]
6115 if ( isinstance( theScaleFact, int )):
6116 theScaleFact = [ float(theScaleFact)]
6118 self.mesh.SetParameters(thePoint.parameters)
6119 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6120 MakeGroups, NewMeshName)
6121 return Mesh( self.smeshpyD, self.geompyD, mesh )
6125 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6130 IDsOfElements: list of elements ids
6131 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6132 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6133 Copy: allows copying the rotated elements
6134 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6137 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6141 if IDsOfElements == []:
6142 IDsOfElements = self.GetElementsId()
6143 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6144 Axis = self.smeshpyD.GetAxisStruct(Axis)
6145 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6146 Parameters = Axis.parameters + var_separator + Parameters
6147 self.mesh.SetParameters(Parameters)
6148 if Copy and MakeGroups:
6149 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6150 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6153 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6155 Create a new mesh of rotated elements
6158 IDsOfElements: list of element ids
6159 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6160 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6161 MakeGroups: forces the generation of new groups from existing ones
6162 NewMeshName: the name of the newly created mesh
6165 instance of class :class:`Mesh`
6168 if IDsOfElements == []:
6169 IDsOfElements = self.GetElementsId()
6170 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6171 Axis = self.smeshpyD.GetAxisStruct(Axis)
6172 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6173 Parameters = Axis.parameters + var_separator + Parameters
6174 self.mesh.SetParameters(Parameters)
6175 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6176 MakeGroups, NewMeshName)
6177 return Mesh( self.smeshpyD, self.geompyD, mesh )
6179 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6184 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6185 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6186 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6187 Copy: allows copying the rotated elements
6188 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6191 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6194 if (isinstance(theObject, Mesh)):
6195 theObject = theObject.GetMesh()
6196 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6197 Axis = self.smeshpyD.GetAxisStruct(Axis)
6198 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6199 Parameters = Axis.parameters + ":" + Parameters
6200 self.mesh.SetParameters(Parameters)
6201 if Copy and MakeGroups:
6202 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6203 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6206 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6208 Create a new mesh from the rotated object
6211 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6212 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6213 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6214 MakeGroups: forces the generation of new groups from existing ones
6215 NewMeshName: the name of the newly created mesh
6218 instance of class :class:`Mesh`
6221 if (isinstance( theObject, Mesh )):
6222 theObject = theObject.GetMesh()
6223 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6224 Axis = self.smeshpyD.GetAxisStruct(Axis)
6225 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6226 Parameters = Axis.parameters + ":" + Parameters
6227 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6228 MakeGroups, NewMeshName)
6229 self.mesh.SetParameters(Parameters)
6230 return Mesh( self.smeshpyD, self.geompyD, mesh )
6232 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6234 Create an offset mesh from the given 2D object
6237 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6238 theValue (float): signed offset size
6239 MakeGroups (boolean): forces the generation of new groups from existing ones
6240 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6241 False means to remove original elements.
6242 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6245 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6248 if isinstance( theObject, Mesh ):
6249 theObject = theObject.GetMesh()
6250 theValue,Parameters,hasVars = ParseParameters(Value)
6251 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6252 self.mesh.SetParameters(Parameters)
6253 # if mesh_groups[0]:
6254 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6257 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6259 Find groups of adjacent nodes within Tolerance.
6262 Tolerance (float): the value of tolerance
6263 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6264 corner and medium nodes in separate groups thus preventing
6265 their further merge.
6268 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6271 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6273 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6274 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6276 Find groups of adjacent nodes within Tolerance.
6279 Tolerance: the value of tolerance
6280 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6281 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6282 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6283 corner and medium nodes in separate groups thus preventing
6284 their further merge.
6287 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6290 unRegister = genObjUnRegister()
6291 if not isinstance( SubMeshOrGroup, list ):
6292 SubMeshOrGroup = [ SubMeshOrGroup ]
6293 for i,obj in enumerate( SubMeshOrGroup ):
6294 if isinstance( obj, Mesh ):
6295 SubMeshOrGroup = [ obj.GetMesh() ]
6297 if isinstance( obj, int ):
6298 SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE )
6299 unRegister.set( SubMeshOrGroup )
6302 if not isinstance( exceptNodes, list ):
6303 exceptNodes = [ exceptNodes ]
6304 if exceptNodes and isinstance( exceptNodes[0], int ):
6305 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6306 unRegister.set( exceptNodes )
6308 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6309 exceptNodes, SeparateCornerAndMediumNodes)
6311 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6316 GroupsOfNodes: a list of groups of nodes IDs for merging.
6317 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6318 in all elements and mesh groups by nodes 1 and 25 correspondingly
6319 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6320 If *NodesToKeep* does not include a node to keep for some group to merge,
6321 then the first node in the group is kept.
6322 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6325 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6327 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6329 Find the elements built on the same nodes.
6332 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6333 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6337 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6340 unRegister = genObjUnRegister()
6341 if MeshOrSubMeshOrGroup is None:
6342 MeshOrSubMeshOrGroup = [ self.mesh ]
6343 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6344 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6345 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6346 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6347 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6348 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6349 unRegister.set( MeshOrSubMeshOrGroup )
6350 for item in MeshOrSubMeshOrGroup:
6351 if isinstance( item, Mesh ):
6352 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6354 if not isinstance( exceptElements, list ):
6355 exceptElements = [ exceptElements ]
6356 if exceptElements and isinstance( exceptElements[0], int ):
6357 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6358 unRegister.set( exceptElements )
6360 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6362 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6364 Merge elements in each given group.
6367 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6368 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6369 replaced in all mesh groups by elements 1 and 25)
6370 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6371 If *ElementsToKeep* does not include an element to keep for some group to merge,
6372 then the first element in the group is kept.
6375 unRegister = genObjUnRegister()
6377 if not isinstance( ElementsToKeep, list ):
6378 ElementsToKeep = [ ElementsToKeep ]
6379 if isinstance( ElementsToKeep[0], int ):
6380 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6381 unRegister.set( ElementsToKeep )
6383 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6385 def MergeEqualElements(self):
6387 Leave one element and remove all other elements built on the same nodes.
6390 self.editor.MergeEqualElements()
6392 def FindFreeBorders(self, ClosedOnly=True):
6394 Returns all or only closed free borders
6397 list of SMESH.FreeBorder's
6400 return self.editor.FindFreeBorders( ClosedOnly )
6402 def FillHole(self, holeNodes, groupName=""):
6404 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6407 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6408 must describe all sequential nodes of the hole border. The first and the last
6409 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6410 groupName (string): name of a group to add new faces
6412 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6416 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6417 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6418 if not isinstance( holeNodes, SMESH.FreeBorder ):
6419 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6420 self.editor.FillHole( holeNodes, groupName )
6422 def FindCoincidentFreeBorders (self, tolerance=0.):
6424 Return groups of FreeBorder's coincident within the given tolerance.
6427 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6428 size of elements adjacent to free borders being compared is used.
6431 SMESH.CoincidentFreeBorders structure
6434 return self.editor.FindCoincidentFreeBorders( tolerance )
6436 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6438 Sew FreeBorder's of each group
6441 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6442 where each enclosed list contains node IDs of a group of coincident free
6443 borders such that each consequent triple of IDs within a group describes
6444 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6445 last node of a border.
6446 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6447 groups of coincident free borders, each group including two borders.
6448 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6449 polygons if a node of opposite border falls on a face edge, else such
6450 faces are split into several ones.
6451 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6452 polyhedra if a node of opposite border falls on a volume edge, else such
6453 volumes, if any, remain intact and the mesh becomes non-conformal.
6456 a number of successfully sewed groups
6459 if freeBorders and isinstance( freeBorders, list ):
6460 # construct SMESH.CoincidentFreeBorders
6461 if isinstance( freeBorders[0], int ):
6462 freeBorders = [freeBorders]
6464 coincidentGroups = []
6465 for nodeList in freeBorders:
6466 if not nodeList or len( nodeList ) % 3:
6467 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6470 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6471 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6472 nodeList = nodeList[3:]
6474 coincidentGroups.append( group )
6476 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6478 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6480 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6481 FirstNodeID2, SecondNodeID2, LastNodeID2,
6482 CreatePolygons, CreatePolyedrs):
6487 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6490 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6491 FirstNodeID2, SecondNodeID2, LastNodeID2,
6492 CreatePolygons, CreatePolyedrs)
6494 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6495 FirstNodeID2, SecondNodeID2):
6497 Sew conform free borders
6500 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6503 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6504 FirstNodeID2, SecondNodeID2)
6506 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6507 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6512 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6515 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6516 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6518 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6519 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6520 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6522 Sew two sides of a mesh. The nodes belonging to Side1 are
6523 merged with the nodes of elements of Side2.
6524 The number of elements in theSide1 and in theSide2 must be
6525 equal and they should have similar nodal connectivity.
6526 The nodes to merge should belong to side borders and
6527 the first node should be linked to the second.
6530 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6533 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6534 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6535 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6537 def ChangeElemNodes(self, ide, newIDs):
6539 Set new nodes for the given element.
6546 False if the number of nodes does not correspond to the type of element
6549 return self.editor.ChangeElemNodes(ide, newIDs)
6551 def GetLastCreatedNodes(self):
6553 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6554 created, this method return the list of their IDs.
6555 If new nodes were not created - return empty list
6558 the list of integer values (can be empty)
6561 return self.editor.GetLastCreatedNodes()
6563 def GetLastCreatedElems(self):
6565 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6566 created this method return the list of their IDs.
6567 If new elements were not created - return empty list
6570 the list of integer values (can be empty)
6573 return self.editor.GetLastCreatedElems()
6575 def ClearLastCreated(self):
6577 Forget what nodes and elements were created by the last mesh edition operation
6580 self.editor.ClearLastCreated()
6582 def DoubleElements(self, theElements, theGroupName=""):
6584 Create duplicates of given elements, i.e. create new elements based on the
6585 same nodes as the given ones.
6588 theElements: container of elements to duplicate. It can be a
6589 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6590 or a list of element IDs. If *theElements* is
6591 a :class:`Mesh`, elements of highest dimension are duplicated
6592 theGroupName: a name of group to contain the generated elements.
6593 If a group with such a name already exists, the new elements
6594 are added to the existing group, else a new group is created.
6595 If *theGroupName* is empty, new elements are not added
6599 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6600 None if *theGroupName* == "".
6603 unRegister = genObjUnRegister()
6604 if isinstance( theElements, Mesh ):
6605 theElements = theElements.mesh
6606 elif isinstance( theElements, list ):
6607 theElements = self.GetIDSource( theElements, SMESH.ALL )
6608 unRegister.set( theElements )
6609 return self.editor.DoubleElements(theElements, theGroupName)
6611 def DoubleNodes(self, theNodes, theModifiedElems):
6613 Create a hole in a mesh by doubling the nodes of some particular elements
6616 theNodes: IDs of nodes to be doubled
6617 theModifiedElems: IDs of elements to be updated by the new (doubled)
6618 nodes. If list of element identifiers is empty then nodes are doubled but
6619 they not assigned to elements
6622 True if operation has been completed successfully, False otherwise
6625 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6627 def DoubleNode(self, theNodeId, theModifiedElems):
6629 Create a hole in a mesh by doubling the nodes of some particular elements.
6630 This method provided for convenience works as :meth:`DoubleNodes`.
6633 theNodeId: IDs of node to double
6634 theModifiedElems: IDs of elements to update
6637 True if operation has been completed successfully, False otherwise
6640 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6642 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6644 Create a hole in a mesh by doubling the nodes of some particular elements.
6645 This method provided for convenience works as :meth:`DoubleNodes`.
6648 theNodes: group of nodes to double.
6649 theModifiedElems: group of elements to update.
6650 theMakeGroup: forces the generation of a group containing new nodes.
6653 True or a created group if operation has been completed successfully,
6654 False or None otherwise
6658 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6659 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6661 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6663 Create a hole in a mesh by doubling the nodes of some particular elements.
6664 This method provided for convenience works as :meth:`DoubleNodes`.
6667 theNodes: list of groups of nodes to double.
6668 theModifiedElems: list of groups of elements to update.
6669 theMakeGroup: forces the generation of a group containing new nodes.
6672 True if operation has been completed successfully, False otherwise
6676 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6677 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6679 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6681 Create a hole in a mesh by doubling the nodes of some particular elements
6684 theElems: the list of elements (edges or faces) to replicate.
6685 The nodes for duplication could be found from these elements
6686 theNodesNot: list of nodes NOT to replicate
6687 theAffectedElems: the list of elements (cells and edges) to which the
6688 replicated nodes should be associated to
6691 True if operation has been completed successfully, False otherwise
6694 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6696 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6698 Create a hole in a mesh by doubling the nodes of some particular elements
6701 theElems: the list of elements (edges or faces) to replicate.
6702 The nodes for duplication could be found from these elements
6703 theNodesNot: list of nodes NOT to replicate
6704 theShape: shape to detect affected elements (element which geometric center
6705 located on or inside shape).
6706 The replicated nodes should be associated to affected elements.
6709 True if operation has been completed successfully, False otherwise
6712 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6714 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6715 theMakeGroup=False, theMakeNodeGroup=False):
6717 Create a hole in a mesh by doubling the nodes of some particular elements.
6718 This method provided for convenience works as :meth:`DoubleNodes`.
6721 theElems: group of of elements (edges or faces) to replicate.
6722 theNodesNot: group of nodes NOT to replicate.
6723 theAffectedElems: group of elements to which the replicated nodes
6724 should be associated to.
6725 theMakeGroup: forces the generation of a group containing new elements.
6726 theMakeNodeGroup: forces the generation of a group containing new nodes.
6729 True or created groups (one or two) if operation has been completed successfully,
6730 False or None otherwise
6733 if theMakeGroup or theMakeNodeGroup:
6734 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6736 theMakeGroup, theMakeNodeGroup)
6737 if theMakeGroup and theMakeNodeGroup:
6740 return twoGroups[ int(theMakeNodeGroup) ]
6741 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6743 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6745 Create a hole in a mesh by doubling the nodes of some particular elements.
6746 This method provided for convenience works as :meth:`DoubleNodes`.
6749 theElems: group of of elements (edges or faces) to replicate
6750 theNodesNot: group of nodes not to replicate
6751 theShape: shape to detect affected elements (element which geometric center
6752 located on or inside shape).
6753 The replicated nodes should be associated to affected elements
6756 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6758 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6759 theMakeGroup=False, theMakeNodeGroup=False):
6761 Create a hole in a mesh by doubling the nodes of some particular elements.
6762 This method provided for convenience works as :meth:`DoubleNodes`.
6765 theElems: list of groups of elements (edges or faces) to replicate
6766 theNodesNot: list of groups of nodes NOT to replicate
6767 theAffectedElems: group of elements to which the replicated nodes
6768 should be associated to
6769 theMakeGroup: forces generation of a group containing new elements.
6770 theMakeNodeGroup: forces generation of a group containing new nodes
6773 True or created groups (one or two) if operation has been completed successfully,
6774 False or None otherwise
6777 if theMakeGroup or theMakeNodeGroup:
6778 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6780 theMakeGroup, theMakeNodeGroup)
6781 if theMakeGroup and theMakeNodeGroup:
6784 return twoGroups[ int(theMakeNodeGroup) ]
6785 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6787 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6789 Create a hole in a mesh by doubling the nodes of some particular elements.
6790 This method provided for convenience works as :meth:`DoubleNodes`.
6793 theElems: list of groups of elements (edges or faces) to replicate
6794 theNodesNot: list of groups of nodes NOT to replicate
6795 theShape: shape to detect affected elements (element which geometric center
6796 located on or inside shape).
6797 The replicated nodes should be associated to affected elements
6800 True if operation has been completed successfully, False otherwise
6803 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6805 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6807 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6808 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6811 theElems: list of groups of nodes or elements (edges or faces) to replicate
6812 theNodesNot: list of groups of nodes NOT to replicate
6813 theShape: shape to detect affected elements (element which geometric center
6814 located on or inside shape).
6815 The replicated nodes should be associated to affected elements
6818 groups of affected elements in order: volumes, faces, edges
6821 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6823 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6826 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6827 The list of groups must describe a partition of the mesh volumes.
6828 The nodes of the internal faces at the boundaries of the groups are doubled.
6829 In option, the internal faces are replaced by flat elements.
6830 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6833 theDomains: list of groups of volumes
6834 createJointElems: if True, create the elements
6835 onAllBoundaries: if True, the nodes and elements are also created on
6836 the boundary between *theDomains* and the rest mesh
6839 True if operation has been completed successfully, False otherwise
6842 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6844 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6846 Double nodes on some external faces and create flat elements.
6847 Flat elements are mainly used by some types of mechanic calculations.
6849 Each group of the list must be constituted of faces.
6850 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6853 theGroupsOfFaces: list of groups of faces
6856 True if operation has been completed successfully, False otherwise
6859 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6861 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6863 Identify all the elements around a geom shape, get the faces delimiting the hole
6865 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6867 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6869 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6870 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6871 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6872 If there are several paths connecting a pair of points, the shortest path is
6873 selected by the module. Position of the cutting plane is defined by the two
6874 points and an optional vector lying on the plane specified by a PolySegment.
6875 By default the vector is defined by Mesh module as following. A middle point
6876 of the two given points is computed. The middle point is projected to the mesh.
6877 The vector goes from the middle point to the projection point. In case of planar
6878 mesh, the vector is normal to the mesh.
6880 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6883 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6884 groupName: optional name of a group where created mesh segments will be added.
6887 editor = self.editor
6889 editor = self.mesh.GetMeshEditPreviewer()
6890 segmentsRes = editor.MakePolyLine( segments, groupName )
6891 for i, seg in enumerate( segmentsRes ):
6892 segments[i].vector = seg.vector
6894 return editor.GetPreviewData()
6897 def MakeSlot(self, segmentGroup, width ):
6899 Create a slot of given width around given 1D elements lying on a triangle mesh.
6900 The slot is consrtucted by cutting faces by cylindrical surfaces made
6901 around each segment. Segments are expected to be created by MakePolyLine().
6904 FaceEdge's located at the slot boundary
6906 return self.editor.MakeSlot( segmentGroup, width )
6908 def GetFunctor(self, funcType ):
6910 Return a cached numerical functor by its type.
6913 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6914 Note that not all items correspond to numerical functors.
6917 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6920 fn = self.functors[ funcType._v ]
6922 fn = self.smeshpyD.GetFunctor(funcType)
6923 fn.SetMesh(self.mesh)
6924 self.functors[ funcType._v ] = fn
6927 def FunctorValue(self, funcType, elemId, isElem=True):
6929 Return value of a functor for a given element
6932 funcType: an item of :class:`SMESH.FunctorType` enum.
6933 elemId: element or node ID
6934 isElem: *elemId* is ID of element or node
6937 the functor value or zero in case of invalid arguments
6940 fn = self.GetFunctor( funcType )
6941 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6942 val = fn.GetValue(elemId)
6947 def GetLength(self, elemId=None):
6949 Get length of 1D element or sum of lengths of all 1D mesh elements
6952 elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6955 element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6960 length = self.smeshpyD.GetLength(self)
6962 length = self.FunctorValue(SMESH.FT_Length, elemId)
6965 def GetArea(self, elemId=None):
6967 Get area of 2D element or sum of areas of all 2D mesh elements
6968 elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6971 element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6976 area = self.smeshpyD.GetArea(self)
6978 area = self.FunctorValue(SMESH.FT_Area, elemId)
6981 def GetVolume(self, elemId=None):
6983 Get volume of 3D element or sum of volumes of all 3D mesh elements
6986 elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6989 element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6994 volume = self.smeshpyD.GetVolume(self)
6996 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6999 def GetAngle(self, node1, node2, node3 ):
7001 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7004 node1,node2,node3: IDs of the three nodes
7007 Angle in radians [0,PI]. -1 if failure case.
7009 p1 = self.GetNodeXYZ( node1 )
7010 p2 = self.GetNodeXYZ( node2 )
7011 p3 = self.GetNodeXYZ( node3 )
7012 if p1 and p2 and p3:
7013 return self.smeshpyD.GetAngle( p1,p2,p3 )
7017 def GetMaxElementLength(self, elemId):
7019 Get maximum element length.
7022 elemId: mesh element ID
7025 element's maximum length value
7028 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7029 ftype = SMESH.FT_MaxElementLength3D
7031 ftype = SMESH.FT_MaxElementLength2D
7032 return self.FunctorValue(ftype, elemId)
7034 def GetAspectRatio(self, elemId):
7036 Get aspect ratio of 2D or 3D element.
7039 elemId: mesh element ID
7042 element's aspect ratio value
7045 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7046 ftype = SMESH.FT_AspectRatio3D
7048 ftype = SMESH.FT_AspectRatio
7049 return self.FunctorValue(ftype, elemId)
7051 def GetWarping(self, elemId):
7053 Get warping angle of 2D element.
7056 elemId: mesh element ID
7059 element's warping angle value
7062 return self.FunctorValue(SMESH.FT_Warping, elemId)
7064 def GetMinimumAngle(self, elemId):
7066 Get minimum angle of 2D element.
7069 elemId: mesh element ID
7072 element's minimum angle value
7075 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7077 def GetTaper(self, elemId):
7079 Get taper of 2D element.
7082 elemId: mesh element ID
7085 element's taper value
7088 return self.FunctorValue(SMESH.FT_Taper, elemId)
7090 def GetSkew(self, elemId):
7092 Get skew of 2D element.
7095 elemId: mesh element ID
7098 element's skew value
7101 return self.FunctorValue(SMESH.FT_Skew, elemId)
7103 def GetMinMax(self, funType, meshPart=None):
7105 Return minimal and maximal value of a given functor.
7108 funType (SMESH.FunctorType): a functor type.
7109 Note that not all items of :class:`SMESH.FunctorType` corresponds
7110 to numerical functors.
7111 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7117 unRegister = genObjUnRegister()
7118 if isinstance( meshPart, list ):
7119 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7120 unRegister.set( meshPart )
7121 if isinstance( meshPart, Mesh ):
7122 meshPart = meshPart.mesh
7123 fun = self.GetFunctor( funType )
7126 if hasattr( meshPart, "SetMesh" ):
7127 meshPart.SetMesh( self.mesh ) # set mesh to filter
7128 hist = fun.GetLocalHistogram( 1, False, meshPart )
7130 hist = fun.GetHistogram( 1, False )
7132 return hist[0].min, hist[0].max
7135 pass # end of Mesh class
7138 class meshProxy(SMESH._objref_SMESH_Mesh):
7140 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7141 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7143 def __init__(self,*args):
7144 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7145 def __deepcopy__(self, memo=None):
7146 new = self.__class__(self)
7148 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7149 if len( args ) == 3:
7150 args += SMESH.ALL_NODES, True
7151 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7152 def ExportToMEDX(self, *args): # function removed
7153 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7154 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7155 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7156 def ExportToMED(self, *args): # function removed
7157 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7158 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7160 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7162 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7163 def ExportPartToMED(self, *args): # 'version' parameter removed
7164 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7165 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7166 def ExportMED(self, *args): # signature of method changed
7167 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7169 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7171 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7173 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7176 class submeshProxy(SMESH._objref_SMESH_subMesh):
7179 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7181 def __init__(self,*args):
7182 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7184 def __deepcopy__(self, memo=None):
7185 new = self.__class__(self)
7188 def Compute(self,refresh=False):
7190 Compute the sub-mesh and return the status of the computation
7193 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7198 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7199 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7203 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7205 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7207 if salome.sg.hasDesktop():
7208 if refresh: salome.sg.updateObjBrowser()
7213 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7216 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7218 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7219 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7222 def __init__(self,*args):
7223 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7225 def __getattr__(self, name ): # method called if an attribute not found
7226 if not self.mesh: # look for name() method in Mesh class
7227 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7228 if hasattr( self.mesh, name ):
7229 return getattr( self.mesh, name )
7230 if name == "ExtrusionAlongPathObjX":
7231 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7232 print("meshEditor: attribute '%s' NOT FOUND" % name)
7234 def __deepcopy__(self, memo=None):
7235 new = self.__class__(self)
7237 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7238 if len( args ) == 1: args += False,
7239 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7240 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7241 if len( args ) == 2: args += False,
7242 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7243 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7244 if len( args ) == 1:
7245 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7246 NodesToKeep = args[1]
7247 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7248 unRegister = genObjUnRegister()
7250 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7251 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7252 if not isinstance( NodesToKeep, list ):
7253 NodesToKeep = [ NodesToKeep ]
7254 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7256 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7258 class Pattern(SMESH._objref_SMESH_Pattern):
7260 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7261 variables in some methods
7264 def LoadFromFile(self, patternTextOrFile ):
7265 text = patternTextOrFile
7266 if os.path.exists( text ):
7267 text = open( patternTextOrFile ).read()
7269 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7271 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7272 decrFun = lambda i: i-1
7273 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7274 theMesh.SetParameters(Parameters)
7275 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7277 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7278 decrFun = lambda i: i-1
7279 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7280 theMesh.SetParameters(Parameters)
7281 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7283 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7284 if isinstance( mesh, Mesh ):
7285 mesh = mesh.GetMesh()
7286 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7288 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7290 Registering the new proxy for Pattern
7295 Private class used to bind methods creating algorithms to the class Mesh
7298 def __init__(self, method):
7300 self.defaultAlgoType = ""
7301 self.algoTypeToClass = {}
7302 self.method = method
7304 def add(self, algoClass):
7306 Store a python class of algorithm
7308 if inspect.isclass(algoClass) and \
7309 hasattr( algoClass, "algoType"):
7310 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7311 if not self.defaultAlgoType and \
7312 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7313 self.defaultAlgoType = algoClass.algoType
7314 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7316 def copy(self, mesh):
7318 Create a copy of self and assign mesh to the copy
7321 other = algoCreator( self.method )
7322 other.defaultAlgoType = self.defaultAlgoType
7323 other.algoTypeToClass = self.algoTypeToClass
7327 def __call__(self,algo="",geom=0,*args):
7329 Create an instance of algorithm
7333 if isinstance( algo, str ):
7335 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7336 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7341 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7343 elif not algoType and isinstance( geom, str ):
7348 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7350 elif isinstance( arg, str ) and not algoType:
7353 import traceback, sys
7354 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7355 sys.stderr.write( msg + '\n' )
7356 tb = traceback.extract_stack(None,2)
7357 traceback.print_list( [tb[0]] )
7359 algoType = self.defaultAlgoType
7360 if not algoType and self.algoTypeToClass:
7361 algoType = sorted( self.algoTypeToClass.keys() )[0]
7362 if algoType in self.algoTypeToClass:
7363 #print("Create algo",algoType)
7364 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7365 raise RuntimeError( "No class found for algo type %s" % algoType)
7368 class hypMethodWrapper:
7370 Private class used to substitute and store variable parameters of hypotheses.
7373 def __init__(self, hyp, method):
7375 self.method = method
7376 #print("REBIND:", method.__name__)
7379 def __call__(self,*args):
7381 call a method of hypothesis with calling SetVarParameter() before
7385 return self.method( self.hyp, *args ) # hypothesis method with no args
7387 #print("MethWrapper.__call__", self.method.__name__, args)
7389 parsed = ParseParameters(*args) # replace variables with their values
7390 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7391 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7392 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7393 # maybe there is a replaced string arg which is not variable
7394 result = self.method( self.hyp, *args )
7395 except ValueError as detail: # raised by ParseParameters()
7397 result = self.method( self.hyp, *args )
7398 except omniORB.CORBA.BAD_PARAM:
7399 raise ValueError(detail) # wrong variable name
7404 class genObjUnRegister:
7406 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7409 def __init__(self, genObj=None):
7410 self.genObjList = []
7414 def set(self, genObj):
7415 "Store one or a list of of SALOME.GenericObj'es"
7416 if isinstance( genObj, list ):
7417 self.genObjList.extend( genObj )
7419 self.genObjList.append( genObj )
7423 for genObj in self.genObjList:
7424 if genObj and hasattr( genObj, "UnRegister" ):
7427 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7429 Bind methods creating mesher plug-ins to the Mesh class
7432 # print("pluginName: ", pluginName)
7433 pluginBuilderName = pluginName + "Builder"
7435 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7436 except Exception as e:
7437 from salome_utils import verbose
7438 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7440 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7441 plugin = eval( pluginBuilderName )
7442 # print(" plugin:" , str(plugin))
7444 # add methods creating algorithms to Mesh
7445 for k in dir( plugin ):
7446 if k[0] == '_': continue
7447 algo = getattr( plugin, k )
7448 #print(" algo:", str(algo))
7449 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7450 #print(" meshMethod:" , str(algo.meshMethod))
7451 if not hasattr( Mesh, algo.meshMethod ):
7452 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7454 _mmethod = getattr( Mesh, algo.meshMethod )
7455 if hasattr( _mmethod, "add" ):