1 # Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 # File : smeshBuilder.py
20 # Author : Francis KLOSS, OCC
24 from salome.geom import geomBuilder
26 import SMESH # This is necessary for back compatibility
27 import omniORB # back compatibility
28 SMESH.MED_V2_1 = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2 = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
54 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 def enumitem_eq(self, other):
58 if isinstance(other, omniORB.EnumItem):
59 if other._parent_id == self._parent_id:
60 return self._v == other._v
62 return self._parent_id == other._parent_id
64 return id(self) == id(other)
66 return id(self) == id(other)
68 def enumitem_lt(self, other):
70 if isinstance(other, omniORB.EnumItem):
71 if other._parent_id == self._parent_id:
72 return self._v < other._v
74 return self._parent_id < other._parent_id
76 return id(self) < id(other)
78 return id(self) < id(other)
80 def enumitem_le(self, other):
82 if isinstance(other, omniORB.EnumItem):
83 if other._parent_id == self._parent_id:
84 return self._v <= other._v
86 return self._parent_id <= other._parent_id
88 return id(self) <= id(other)
90 return id(self) <= id(other)
92 def enumitem_gt(self, other):
94 if isinstance(other, omniORB.EnumItem):
95 if other._parent_id == self._parent_id:
96 return self._v > other._v
98 return self._parent_id > other._parent_id
100 return id(self) > id(other)
102 return id(self) > id(other)
104 def enumitem_ge(self, other):
106 if isinstance(other, omniORB.EnumItem):
107 if other._parent_id == self._parent_id:
108 return self._v >= other._v
110 return self._parent_id >= other._parent_id
112 return id(self) >= id(other)
114 return id(self) >= id(other)
116 omniORB.EnumItem.__eq__ = enumitem_eq
117 omniORB.EnumItem.__lt__ = enumitem_lt
118 omniORB.EnumItem.__le__ = enumitem_le
119 omniORB.EnumItem.__gt__ = enumitem_gt
120 omniORB.EnumItem.__ge__ = enumitem_ge
123 class MeshMeta(type):
124 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126 def __instancecheck__(cls, inst):
127 """Implement isinstance(inst, cls)."""
128 return any(cls.__subclasscheck__(c)
129 for c in {type(inst), inst.__class__})
131 def __subclasscheck__(cls, sub):
132 """Implement issubclass(sub, cls)."""
133 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
135 def DegreesToRadians(AngleInDegrees):
136 """Convert an angle from degrees to radians
139 return AngleInDegrees * pi / 180.0
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
146 def ParseParameters(*args):
148 Return list of variable values from salome notebook.
149 The last argument, if is callable, is used to modify values got from notebook
155 if args and callable(args[-1]):
156 args, varModifFun = args[:-1], args[-1]
157 for parameter in args:
159 Parameters += str(parameter) + var_separator
161 if isinstance(parameter,str):
162 # check if there is an inexistent variable name
163 if not notebook.isVariable(parameter):
164 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165 parameter = notebook.get(parameter)
168 parameter = varModifFun(parameter)
171 Result.append(parameter)
174 Parameters = Parameters[:-1]
175 Result.append( Parameters )
176 Result.append( hasVariables )
179 def ParseAngles(*args):
181 Parse parameters while converting variables to radians
183 return ParseParameters( *( args + (DegreesToRadians, )))
185 def __initPointStruct(point,*args):
187 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188 Parameters are stored in PointStruct.parameters attribute
190 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192 SMESH.PointStruct.__init__ = __initPointStruct
194 def __initAxisStruct(ax,*args):
196 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197 Parameters are stored in AxisStruct.parameters attribute
200 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
203 SMESH.AxisStruct.__init__ = __initAxisStruct
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207 """Compare real values using smeshPrecisionConfusion as tolerance
209 if abs(val1 - val2) < tol:
217 Return a name of an object
224 if isinstance(obj, SALOMEDS._objref_SObject):
228 ior = salome.orb.object_to_string(obj)
232 sobj = salome.myStudy.FindObjectIOR(ior)
234 return sobj.GetName()
235 if hasattr(obj, "GetName"):
236 # unknown CORBA object, having GetName() method
239 # unknown CORBA object, no GetName() method
242 if hasattr(obj, "GetName"):
243 # unknown non-CORBA object, having GetName() method
246 raise RuntimeError("Null or invalid object")
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250 Print error message if a hypothesis was not assigned.
253 hypType = "algorithm"
255 hypType = "hypothesis"
258 if hasattr( status, "__getitem__" ):
259 status, reason = status[0], status[1]
260 if status == HYP_UNKNOWN_FATAL:
261 reason = "for unknown reason"
262 elif status == HYP_INCOMPATIBLE:
263 reason = "this hypothesis mismatches the algorithm"
264 elif status == HYP_NOTCONFORM:
265 reason = "a non-conform mesh would be built"
266 elif status == HYP_ALREADY_EXIST:
267 if isAlgo: return # it does not influence anything
268 reason = hypType + " of the same dimension is already assigned to this shape"
269 elif status == HYP_BAD_DIM:
270 reason = hypType + " mismatches the shape"
271 elif status == HYP_CONCURRENT :
272 reason = "there are concurrent hypotheses on sub-shapes"
273 elif status == HYP_BAD_SUBSHAPE:
274 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275 elif status == HYP_BAD_GEOMETRY:
276 reason = "the algorithm is not applicable to this geometry"
277 elif status == HYP_HIDDEN_ALGO:
278 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279 elif status == HYP_HIDING_ALGO:
280 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281 elif status == HYP_NEED_SHAPE:
282 reason = "algorithm can't work without shape"
283 elif status == HYP_INCOMPAT_HYPS:
289 where = '"%s"' % geomName
291 meshName = GetName( mesh )
292 if meshName and meshName != NO_NAME:
293 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294 if status < HYP_UNKNOWN_FATAL and where:
295 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
297 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299 print('"%s" was not assigned : %s' %( hypName, reason ))
302 def AssureGeomPublished(mesh, geom, name=''):
304 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306 if not mesh.smeshpyD.IsEnablePublish():
308 if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
310 if not geom.GetStudyEntry():
312 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313 # for all groups SubShapeName() return "Compound_-1"
314 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
316 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
321 def FirstVertexOnCurve(mesh, edge):
324 the first vertex of a geometrical edge by ignoring orientation
326 vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
328 raise TypeError("Given object has no vertices")
329 if len( vv ) == 1: return vv[0]
330 v0 = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331 xyz = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332 xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333 xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
336 dist1 += abs( xyz[i] - xyz1[i] )
337 dist2 += abs( xyz[i] - xyz2[i] )
346 smeshInst is a singleton
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
354 This class allows to create, load or manipulate meshes.
355 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356 It also has methods to get infos and measure meshes.
359 # MirrorType enumeration
360 POINT = SMESH_MeshEditor.POINT
361 AXIS = SMESH_MeshEditor.AXIS
362 PLANE = SMESH_MeshEditor.PLANE
364 # Smooth_Method enumeration
365 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
368 PrecisionConfusion = smeshPrecisionConfusion
370 # TopAbs_State enumeration
371 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
373 # Methods of splitting a hexahedron into tetrahedra
374 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
376 def __new__(cls, *args):
380 #print("==== __new__", engine, smeshInst, doLcc)
382 if smeshInst is None:
383 # smesh engine is either retrieved from engine, or created
385 # Following test avoids a recursive loop
387 if smeshInst is not None:
388 # smesh engine not created: existing engine found
392 # FindOrLoadComponent called:
393 # 1. CORBA resolution of server
394 # 2. the __new__ method is called again
395 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
398 # FindOrLoadComponent not called
399 if smeshInst is None:
400 # smeshBuilder instance is created from lcc.FindOrLoadComponent
401 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402 smeshInst = super(smeshBuilder,cls).__new__(cls)
404 # smesh engine not created: existing engine found
405 #print("==== existing ", engine, smeshInst, doLcc)
407 #print("====1 ", smeshInst)
410 #print("====2 ", smeshInst)
413 def __init__(self, *args):
415 #print("--------------- smeshbuilder __init__ ---", created)
418 SMESH._objref_SMESH_Gen.__init__(self, *args)
421 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
423 Dump component to the Python script.
424 This method overrides IDL function to allow default values for the parameters.
427 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
429 def SetDumpPythonHistorical(self, isHistorical):
431 Set mode of DumpPython(), *historical* or *snapshot*.
432 In the *historical* mode, the Python Dump script includes all commands
433 performed by SMESH engine. In the *snapshot* mode, commands
434 relating to objects removed from the Study are excluded from the script
435 as well as commands not influencing the current state of meshes
438 if isHistorical: val = "true"
440 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
442 def init_smesh(self,geompyD = None):
444 Set Geometry component
447 self.UpdateStudy(geompyD)
448 notebook.myStudy = salome.myStudy
450 def Mesh(self, obj=0, name=0):
452 Create a mesh. This mesh can be either
454 * an empty mesh not bound to geometry, if *obj* == 0
455 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
461 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
464 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
466 2. a geometrical object for meshing
468 name: the name for the new mesh.
471 an instance of class :class:`Mesh`.
474 if isinstance(obj,str):
476 return Mesh(self, self.geompyD, obj, name)
478 def RemoveMesh( self, mesh ):
482 if isinstance( mesh, Mesh ):
483 mesh = mesh.GetMesh()
485 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
486 raise TypeError("%s is not a mesh" % mesh )
487 so = salome.ObjectToSObject( mesh )
489 sb = salome.myStudy.NewBuilder()
490 sb.RemoveObjectWithChildren( so )
496 def EnumToLong(self,theItem):
498 Return a long value from enumeration
503 def ColorToString(self,c):
505 Convert SALOMEDS.Color to string.
506 To be used with filters.
509 c: color value (SALOMEDS.Color)
512 a string representation of the color.
516 if isinstance(c, SALOMEDS.Color):
517 val = "%s;%s;%s" % (c.R, c.G, c.B)
518 elif isinstance(c, str):
521 raise ValueError("Color value should be of string or SALOMEDS.Color type")
524 def GetPointStruct(self,theVertex):
526 Get :class:`SMESH.PointStruct` from vertex
529 theVertex (GEOM.GEOM_Object): vertex
532 :class:`SMESH.PointStruct`
535 [x, y, z] = self.geompyD.PointCoordinates(theVertex)
536 return PointStruct(x,y,z)
538 def GetDirStruct(self,theVector):
540 Get :class:`SMESH.DirStruct` from vector
543 theVector (GEOM.GEOM_Object): vector
546 :class:`SMESH.DirStruct`
549 vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
550 if(len(vertices) != 2):
551 print("Error: vector object is incorrect.")
553 p1 = self.geompyD.PointCoordinates(vertices[0])
554 p2 = self.geompyD.PointCoordinates(vertices[1])
555 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
556 dirst = DirStruct(pnt)
559 def MakeDirStruct(self,x,y,z):
561 Make :class:`SMESH.DirStruct` from a triplet of floats
564 x,y,z (float): vector components
567 :class:`SMESH.DirStruct`
570 pnt = PointStruct(x,y,z)
571 return DirStruct(pnt)
573 def GetAxisStruct(self,theObj):
575 Get :class:`SMESH.AxisStruct` from a geometrical object
578 theObj (GEOM.GEOM_Object): line or plane
581 :class:`SMESH.AxisStruct`
584 edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
587 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588 vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
589 vertex1 = self.geompyD.PointCoordinates(vertex1)
590 vertex2 = self.geompyD.PointCoordinates(vertex2)
591 vertex3 = self.geompyD.PointCoordinates(vertex3)
592 vertex4 = self.geompyD.PointCoordinates(vertex4)
593 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
594 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
595 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] ]
596 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
597 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
598 elif len(edges) == 1:
599 vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
600 p1 = self.geompyD.PointCoordinates( vertex1 )
601 p2 = self.geompyD.PointCoordinates( vertex2 )
602 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
603 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
604 elif theObj.GetShapeType() == GEOM.VERTEX:
605 x,y,z = self.geompyD.PointCoordinates( theObj )
606 axis = AxisStruct( x,y,z, 1,0,0,)
607 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
610 # From SMESH_Gen interface:
611 # ------------------------
613 def SetName(self, obj, name):
615 Set the given name to an object
618 obj: the object to rename
619 name: a new object name
622 if isinstance( obj, Mesh ):
624 elif isinstance( obj, Mesh_Algorithm ):
625 obj = obj.GetAlgorithm()
626 ior = salome.orb.object_to_string(obj)
627 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
629 def SetEmbeddedMode( self,theMode ):
634 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
636 def IsEmbeddedMode(self):
641 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
643 def UpdateStudy( self, geompyD = None ):
645 Update the current study. Calling UpdateStudy() allows to
646 update meshes at switching GEOM->SMESH
650 from salome.geom import geomBuilder
651 geompyD = geomBuilder.geom
653 geompyD = geomBuilder.New()
656 self.SetGeomEngine(geompyD)
657 SMESH._objref_SMESH_Gen.UpdateStudy(self)
658 sb = salome.myStudy.NewBuilder()
659 sc = salome.myStudy.FindComponent("SMESH")
661 sb.LoadWith(sc, self)
664 def SetEnablePublish( self, theIsEnablePublish ):
666 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
667 switch **off** publishing in the Study of mesh objects.
669 #self.SetEnablePublish(theIsEnablePublish)
670 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
672 notebook = salome_notebook.NoteBook( theIsEnablePublish )
675 def CreateMeshesFromUNV( self,theFileName ):
677 Create a Mesh object importing data from the given UNV file
680 an instance of class :class:`Mesh`
683 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
684 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
687 def CreateMeshesFromMED( self,theFileName ):
689 Create a Mesh object(s) importing data from the given MED file
692 a tuple ( list of class :class:`Mesh` instances,
693 :class:`SMESH.DriverMED_ReadStatus` )
696 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
697 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
698 return aMeshes, aStatus
700 def CreateMeshesFromSAUV( self,theFileName ):
702 Create a Mesh object(s) importing data from the given SAUV file
705 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
708 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
709 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710 return aMeshes, aStatus
712 def CreateMeshesFromSTL( self, theFileName ):
714 Create a Mesh object importing data from the given STL file
717 an instance of class :class:`Mesh`
720 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
721 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
724 def CreateMeshesFromCGNS( self, theFileName ):
726 Create Mesh objects importing data from the given CGNS file
729 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
732 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
733 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
734 return aMeshes, aStatus
736 def CreateMeshesFromGMF( self, theFileName ):
738 Create a Mesh object importing data from the given GMF file.
739 GMF files must have .mesh extension for the ASCII format and .meshb for
743 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
746 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
749 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
750 return Mesh(self, self.geompyD, aSmeshMesh), error
752 def Concatenate( self, meshes, uniteIdenticalGroups,
753 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
754 name = "", meshToAppendTo = None):
756 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
757 All groups of input meshes will be present in the new mesh.
760 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
761 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
762 mergeNodesAndElements: if True, equal nodes and elements are merged
763 mergeTolerance: tolerance for merging nodes
764 allGroups: forces creation of groups corresponding to every input mesh
765 name: name of a new mesh
766 meshToAppendTo: a mesh to append all given meshes
769 an instance of class :class:`Mesh`
775 if not meshes: return None
776 if not isinstance( meshes, list ):
778 for i,m in enumerate( meshes ):
779 if isinstance( m, Mesh ):
780 meshes[i] = m.GetMesh()
781 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
782 if hasattr(meshes[0], "SetParameters"):
783 meshes[0].SetParameters( Parameters )
785 meshes[0].GetMesh().SetParameters( Parameters )
786 if isinstance( meshToAppendTo, Mesh ):
787 meshToAppendTo = meshToAppendTo.GetMesh()
789 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
790 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
791 mergeTolerance,meshToAppendTo )
793 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
794 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
795 mergeTolerance,meshToAppendTo )
797 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
800 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
802 Create a mesh by copying a part of another mesh.
805 meshPart: a part of mesh to copy, either
806 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
807 To copy nodes or elements not forming any mesh object,
808 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
809 meshName: a name of the new mesh
810 toCopyGroups: to create in the new mesh groups the copied elements belongs to
811 toKeepIDs: to preserve order of the copied elements or not
814 an instance of class :class:`Mesh`
817 if isinstance( meshPart, Mesh ):
818 meshPart = meshPart.GetMesh()
819 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
820 return Mesh(self, self.geompyD, mesh)
822 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
823 toReuseHypotheses=True, toCopyElements=True):
825 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
826 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
827 To facilitate and speed up the operation, consider using
828 "Set presentation parameters and sub-shapes from arguments" option in
829 a dialog of geometrical operation used to create the new geometry.
832 sourceMesh: the mesh to copy definition of.
833 newGeom: the new geometry.
834 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
835 toCopyGroups: to create groups in the new mesh.
836 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
837 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
840 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
841 *invalidEntries* are study entries of objects whose
842 counterparts are not found in the *newGeom*, followed by entries
843 of mesh sub-objects that are invalid because they depend on a not found
846 if isinstance( sourceMesh, Mesh ):
847 sourceMesh = sourceMesh.GetMesh()
849 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
850 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
854 return ( ok, Mesh(self, self.geompyD, newMesh),
855 newGroups, newSubMeshes, newHypotheses, invalidEntries )
857 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
859 Return IDs of sub-shapes
862 theMainObject (GEOM.GEOM_Object): a shape
863 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
865 the list of integer values
868 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
870 def GetPattern(self):
872 Create a pattern mapper.
875 an instance of :class:`SMESH.SMESH_Pattern`
877 :ref:`Example of Patterns usage <tui_pattern_mapping>`
880 return SMESH._objref_SMESH_Gen.GetPattern(self)
882 def SetBoundaryBoxSegmentation(self, nbSegments):
884 Set number of segments per diagonal of boundary box of geometry, by which
885 default segment length of appropriate 1D hypotheses is defined in GUI.
889 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
891 # Filtering. Auxiliary functions:
892 # ------------------------------
894 def GetEmptyCriterion(self):
896 Create an empty criterion
899 :class:`SMESH.Filter.Criterion`
902 Type = self.EnumToLong(FT_Undefined)
903 Compare = self.EnumToLong(FT_Undefined)
907 UnaryOp = self.EnumToLong(FT_Undefined)
908 BinaryOp = self.EnumToLong(FT_Undefined)
911 Precision = -1 ##@1e-07
912 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
913 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
915 def GetCriterion(self,elementType,
917 Compare = FT_EqualTo,
919 UnaryOp=FT_Undefined,
920 BinaryOp=FT_Undefined,
923 Create a criterion by the given parameters
924 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
927 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
928 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
929 Note that the items starting from FT_LessThan are not suitable for *CritType*.
930 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
931 Threshold: the threshold value (range of ids as string, shape, numeric)
932 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
933 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
935 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
936 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
939 :class:`SMESH.Filter.Criterion`
941 Example: :ref:`combining_filters`
944 if not CritType in SMESH.FunctorType._items:
945 raise TypeError("CritType should be of SMESH.FunctorType")
946 aCriterion = self.GetEmptyCriterion()
947 aCriterion.TypeOfElement = elementType
948 aCriterion.Type = self.EnumToLong(CritType)
949 aCriterion.Tolerance = Tolerance
951 aThreshold = Threshold
953 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
954 aCriterion.Compare = self.EnumToLong(Compare)
955 elif Compare == "=" or Compare == "==":
956 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
958 aCriterion.Compare = self.EnumToLong(FT_LessThan)
960 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
961 elif Compare != FT_Undefined:
962 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
965 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
966 FT_BelongToCylinder, FT_LyingOnGeom]:
967 # Check that Threshold is GEOM object
968 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
969 aCriterion.ThresholdStr = GetName(aThreshold)
970 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
971 if not aCriterion.ThresholdID:
972 name = aCriterion.ThresholdStr
974 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
975 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
976 # or a name of GEOM object
977 elif isinstance( aThreshold, str ):
978 aCriterion.ThresholdStr = aThreshold
980 raise TypeError("The Threshold should be a shape.")
981 if isinstance(UnaryOp,float):
982 aCriterion.Tolerance = UnaryOp
983 UnaryOp = FT_Undefined
985 elif CritType == FT_BelongToMeshGroup:
986 # Check that Threshold is a group
987 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
988 if aThreshold.GetType() != elementType:
989 raise ValueError("Group type mismatches Element type")
990 aCriterion.ThresholdStr = aThreshold.GetName()
991 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
992 study = salome.myStudy
994 so = study.FindObjectIOR( aCriterion.ThresholdID )
998 aCriterion.ThresholdID = entry
1000 raise TypeError("The Threshold should be a Mesh Group")
1001 elif CritType == FT_RangeOfIds:
1002 # Check that Threshold is string
1003 if isinstance(aThreshold, str):
1004 aCriterion.ThresholdStr = aThreshold
1006 raise TypeError("The Threshold should be a string.")
1007 elif CritType == FT_CoplanarFaces:
1008 # Check the Threshold
1009 if isinstance(aThreshold, int):
1010 aCriterion.ThresholdID = str(aThreshold)
1011 elif isinstance(aThreshold, str):
1012 ID = int(aThreshold)
1014 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1015 aCriterion.ThresholdID = aThreshold
1017 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1018 elif CritType == FT_ConnectedElements:
1019 # Check the Threshold
1020 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1021 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1022 if not aCriterion.ThresholdID:
1023 name = aThreshold.GetName()
1025 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1026 aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1027 elif isinstance(aThreshold, int): # node id
1028 aCriterion.Threshold = aThreshold
1029 elif isinstance(aThreshold, list): # 3 point coordinates
1030 if len( aThreshold ) < 3:
1031 raise ValueError("too few point coordinates, must be 3")
1032 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1033 elif isinstance(aThreshold, str):
1034 if aThreshold.isdigit():
1035 aCriterion.Threshold = aThreshold # node id
1037 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1039 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1040 "or a list of point coordinates and not '%s'"%aThreshold)
1041 elif CritType == FT_ElemGeomType:
1042 # Check the Threshold
1044 aCriterion.Threshold = self.EnumToLong(aThreshold)
1045 assert( aThreshold in SMESH.GeometryType._items )
1047 if isinstance(aThreshold, int):
1048 aCriterion.Threshold = aThreshold
1050 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1053 elif CritType == FT_EntityType:
1054 # Check the Threshold
1056 aCriterion.Threshold = self.EnumToLong(aThreshold)
1057 assert( aThreshold in SMESH.EntityType._items )
1059 if isinstance(aThreshold, int):
1060 aCriterion.Threshold = aThreshold
1062 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1066 elif CritType == FT_GroupColor:
1067 # Check the Threshold
1069 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1071 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1073 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1074 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1075 FT_BareBorderFace, FT_BareBorderVolume,
1076 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1077 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1078 # At this point the Threshold is unnecessary
1079 if aThreshold == FT_LogicalNOT:
1080 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1081 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1082 aCriterion.BinaryOp = aThreshold
1086 aThreshold = float(aThreshold)
1087 aCriterion.Threshold = aThreshold
1089 raise TypeError("The Threshold should be a number.")
1092 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1093 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1095 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1096 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1098 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1099 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1101 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1102 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1106 def GetFilter(self,elementType,
1107 CritType=FT_Undefined,
1110 UnaryOp=FT_Undefined,
1114 Create a filter with the given parameters
1117 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1118 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1119 Note that the items starting from FT_LessThan are not suitable for CritType.
1120 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1121 Threshold: the threshold value (range of ids as string, shape, numeric)
1122 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1123 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1124 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1125 mesh: the mesh to initialize the filter with
1128 :class:`SMESH.Filter`
1131 See :doc:`Filters usage examples <tui_filters>`
1134 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1135 aFilterMgr = self.CreateFilterManager()
1136 aFilter = aFilterMgr.CreateFilter()
1138 aCriteria.append(aCriterion)
1139 aFilter.SetCriteria(aCriteria)
1141 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1142 else : aFilter.SetMesh( mesh )
1143 aFilterMgr.UnRegister()
1146 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1148 Create a filter from criteria
1151 criteria: a list of :class:`SMESH.Filter.Criterion`
1152 binOp: binary operator used when binary operator of criteria is undefined
1155 :class:`SMESH.Filter`
1158 See :doc:`Filters usage examples <tui_filters>`
1161 for i in range( len( criteria ) - 1 ):
1162 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1163 criteria[i].BinaryOp = self.EnumToLong( binOp )
1164 aFilterMgr = self.CreateFilterManager()
1165 aFilter = aFilterMgr.CreateFilter()
1166 aFilter.SetCriteria(criteria)
1167 aFilterMgr.UnRegister()
1170 def GetFunctor(self,theCriterion):
1172 Create a numerical functor by its type
1175 theCriterion (SMESH.FunctorType): functor type.
1176 Note that not all items correspond to numerical functors.
1179 :class:`SMESH.NumericalFunctor`
1182 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1184 aFilterMgr = self.CreateFilterManager()
1186 if theCriterion == FT_AspectRatio:
1187 functor = aFilterMgr.CreateAspectRatio()
1188 elif theCriterion == FT_AspectRatio3D:
1189 functor = aFilterMgr.CreateAspectRatio3D()
1190 elif theCriterion == FT_Warping:
1191 functor = aFilterMgr.CreateWarping()
1192 elif theCriterion == FT_MinimumAngle:
1193 functor = aFilterMgr.CreateMinimumAngle()
1194 elif theCriterion == FT_Taper:
1195 functor = aFilterMgr.CreateTaper()
1196 elif theCriterion == FT_Skew:
1197 functor = aFilterMgr.CreateSkew()
1198 elif theCriterion == FT_Area:
1199 functor = aFilterMgr.CreateArea()
1200 elif theCriterion == FT_Volume3D:
1201 functor = aFilterMgr.CreateVolume3D()
1202 elif theCriterion == FT_MaxElementLength2D:
1203 functor = aFilterMgr.CreateMaxElementLength2D()
1204 elif theCriterion == FT_MaxElementLength3D:
1205 functor = aFilterMgr.CreateMaxElementLength3D()
1206 elif theCriterion == FT_MultiConnection:
1207 functor = aFilterMgr.CreateMultiConnection()
1208 elif theCriterion == FT_MultiConnection2D:
1209 functor = aFilterMgr.CreateMultiConnection2D()
1210 elif theCriterion == FT_Length:
1211 functor = aFilterMgr.CreateLength()
1212 elif theCriterion == FT_Length2D:
1213 functor = aFilterMgr.CreateLength2D()
1214 elif theCriterion == FT_Length3D:
1215 functor = aFilterMgr.CreateLength3D()
1216 elif theCriterion == FT_Deflection2D:
1217 functor = aFilterMgr.CreateDeflection2D()
1218 elif theCriterion == FT_NodeConnectivityNumber:
1219 functor = aFilterMgr.CreateNodeConnectivityNumber()
1220 elif theCriterion == FT_BallDiameter:
1221 functor = aFilterMgr.CreateBallDiameter()
1223 print("Error: given parameter is not numerical functor type.")
1224 aFilterMgr.UnRegister()
1227 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1232 theHType (string): mesh hypothesis type
1233 theLibName (string): mesh plug-in library name
1236 created hypothesis instance
1238 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1240 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1243 # wrap hypothesis methods
1244 for meth_name in dir( hyp.__class__ ):
1245 if not meth_name.startswith("Get") and \
1246 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1247 method = getattr ( hyp.__class__, meth_name )
1248 if callable(method):
1249 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1253 def GetMeshInfo(self, obj):
1255 Get the mesh statistic.
1258 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1261 if isinstance( obj, Mesh ):
1264 if hasattr(obj, "GetMeshInfo"):
1265 values = obj.GetMeshInfo()
1266 for i in range(SMESH.Entity_Last._v):
1267 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1271 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1273 Get minimum distance between two objects
1275 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1276 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1279 src1 (SMESH.SMESH_IDSource): first source object
1280 src2 (SMESH.SMESH_IDSource): second source object
1281 id1 (int): node/element id from the first source
1282 id2 (int): node/element id from the second (or first) source
1283 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1284 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1287 minimum distance value
1290 :meth:`GetMinDistance`
1293 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1297 result = result.value
1300 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1302 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1304 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1305 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1308 src1 (SMESH.SMESH_IDSource): first source object
1309 src2 (SMESH.SMESH_IDSource): second source object
1310 id1 (int): node/element id from the first source
1311 id2 (int): node/element id from the second (or first) source
1312 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1313 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1316 :class:`SMESH.Measure` structure or None if input data is invalid
1321 if isinstance(src1, Mesh): src1 = src1.mesh
1322 if isinstance(src2, Mesh): src2 = src2.mesh
1323 if src2 is None and id2 != 0: src2 = src1
1324 if not hasattr(src1, "_narrow"): return None
1325 src1 = src1._narrow(SMESH.SMESH_IDSource)
1326 if not src1: return None
1327 unRegister = genObjUnRegister()
1330 e = m.GetMeshEditor()
1332 src1 = e.MakeIDSource([id1], SMESH.FACE)
1334 src1 = e.MakeIDSource([id1], SMESH.NODE)
1335 unRegister.set( src1 )
1337 if hasattr(src2, "_narrow"):
1338 src2 = src2._narrow(SMESH.SMESH_IDSource)
1339 if src2 and id2 != 0:
1341 e = m.GetMeshEditor()
1343 src2 = e.MakeIDSource([id2], SMESH.FACE)
1345 src2 = e.MakeIDSource([id2], SMESH.NODE)
1346 unRegister.set( src2 )
1349 aMeasurements = self.CreateMeasurements()
1350 unRegister.set( aMeasurements )
1351 result = aMeasurements.MinDistance(src1, src2)
1354 def BoundingBox(self, objects):
1356 Get bounding box of the specified object(s)
1359 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1362 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1365 :meth:`GetBoundingBox`
1368 result = self.GetBoundingBox(objects)
1372 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1375 def GetBoundingBox(self, objects):
1377 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1380 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1383 :class:`SMESH.Measure` structure
1389 if isinstance(objects, tuple):
1390 objects = list(objects)
1391 if not isinstance(objects, list):
1395 if isinstance(o, Mesh):
1396 srclist.append(o.mesh)
1397 elif hasattr(o, "_narrow"):
1398 src = o._narrow(SMESH.SMESH_IDSource)
1399 if src: srclist.append(src)
1402 aMeasurements = self.CreateMeasurements()
1403 result = aMeasurements.BoundingBox(srclist)
1404 aMeasurements.UnRegister()
1407 def GetLength(self, obj):
1409 Get sum of lengths of all 1D elements in the mesh object.
1412 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1415 sum of lengths of all 1D elements
1418 if isinstance(obj, Mesh): obj = obj.mesh
1419 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1420 aMeasurements = self.CreateMeasurements()
1421 value = aMeasurements.Length(obj)
1422 aMeasurements.UnRegister()
1425 def GetArea(self, obj):
1427 Get sum of areas of all 2D elements in the mesh object.
1430 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1433 sum of areas of all 2D elements
1436 if isinstance(obj, Mesh): obj = obj.mesh
1437 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438 aMeasurements = self.CreateMeasurements()
1439 value = aMeasurements.Area(obj)
1440 aMeasurements.UnRegister()
1443 def GetVolume(self, obj):
1445 Get sum of volumes of all 3D elements in the mesh object.
1448 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1451 sum of volumes of all 3D elements
1454 if isinstance(obj, Mesh): obj = obj.mesh
1455 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1456 aMeasurements = self.CreateMeasurements()
1457 value = aMeasurements.Volume(obj)
1458 aMeasurements.UnRegister()
1461 def GetGravityCenter(self, obj):
1463 Get gravity center of all nodes of a mesh object.
1466 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1469 Three components of the gravity center (x,y,z)
1472 :meth:`Mesh.BaryCenter`
1474 if isinstance(obj, Mesh): obj = obj.mesh
1475 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476 aMeasurements = self.CreateMeasurements()
1477 pointStruct = aMeasurements.GravityCenter(obj)
1478 aMeasurements.UnRegister()
1479 return pointStruct.x, pointStruct.y, pointStruct.z
1481 def GetAngle(self, p1, p2, p3 ):
1483 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1486 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1492 if isinstance( p1, list ): p1 = PointStruct(*p1)
1493 if isinstance( p2, list ): p2 = PointStruct(*p2)
1494 if isinstance( p3, list ): p3 = PointStruct(*p3)
1496 aMeasurements = self.CreateMeasurements()
1497 angle = aMeasurements.Angle(p1,p2,p3)
1498 aMeasurements.UnRegister()
1503 pass # end of class smeshBuilder
1506 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1507 """Registering the new proxy for SMESH.SMESH_Gen"""
1510 def New( instance=None, instanceGeom=None):
1512 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1513 interface to create or load meshes.
1518 salome.salome_init()
1519 from salome.smesh import smeshBuilder
1520 smesh = smeshBuilder.New()
1523 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1524 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1526 :class:`smeshBuilder` instance
1531 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1533 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1538 smeshInst = smeshBuilder()
1539 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1540 smeshInst.init_smesh(instanceGeom)
1544 # Public class: Mesh
1545 # ==================
1548 class Mesh(metaclass = MeshMeta):
1550 This class allows defining and managing a mesh.
1551 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1552 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1553 new nodes and elements and by changing the existing entities), to get information
1554 about a mesh and to export a mesh in different formats.
1561 def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1566 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1567 sets the GUI name of this mesh to *name*.
1570 smeshpyD: an instance of smeshBuilder class
1571 geompyD: an instance of geomBuilder class
1572 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1573 name: Study name of the mesh
1576 self.smeshpyD = smeshpyD
1577 self.geompyD = geompyD
1582 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1585 # publish geom of mesh (issue 0021122)
1586 if not self.geom.GetStudyEntry():
1590 geo_name = name + " shape"
1592 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1593 geompyD.addToStudy( self.geom, geo_name )
1594 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1596 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1599 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1601 self.smeshpyD.SetName(self.mesh, name)
1603 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1606 self.geom = self.mesh.GetShapeToMesh()
1608 self.editor = self.mesh.GetMeshEditor()
1609 self.functors = [None] * SMESH.FT_Undefined._v
1611 # set self to algoCreator's
1612 for attrName in dir(self):
1613 attr = getattr( self, attrName )
1614 if isinstance( attr, algoCreator ):
1615 setattr( self, attrName, attr.copy( self ))
1622 Destructor. Clean-up resources
1625 #self.mesh.UnRegister()
1629 def SetMesh(self, theMesh):
1631 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1634 theMesh: a :class:`SMESH.SMESH_Mesh` object
1638 # do not call Register() as this prevents mesh servant deletion at closing study
1639 #if self.mesh: self.mesh.UnRegister()
1642 #self.mesh.Register()
1643 self.geom = self.mesh.GetShapeToMesh()
1648 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1651 a :class:`SMESH.SMESH_Mesh` object
1656 def GetEngine(self):
1658 Return a smeshBuilder instance created this mesh
1660 return self.smeshpyD
1662 def GetGeomEngine(self):
1664 Return a geomBuilder instance
1670 Get the name of the mesh
1673 the name of the mesh as a string
1676 name = GetName(self.GetMesh())
1679 def SetName(self, name):
1681 Set a name to the mesh
1684 name: a new name of the mesh
1687 self.smeshpyD.SetName(self.GetMesh(), name)
1689 def GetSubMesh(self, geom, name):
1691 Get a sub-mesh object associated to a *geom* geometrical object.
1694 geom: a geometrical object (shape)
1695 name: a name for the sub-mesh in the Object Browser
1698 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1699 which lies on the given shape
1702 A sub-mesh is implicitly created when a sub-shape is specified at
1703 creating an algorithm, for example::
1705 algo1D = mesh.Segment(geom=Edge_1)
1707 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1708 The created sub-mesh can be retrieved from the algorithm::
1710 submesh = algo1D.GetSubMesh()
1713 AssureGeomPublished( self, geom, name )
1714 submesh = self.mesh.GetSubMesh( geom, name )
1719 Return the shape associated to the mesh
1727 def SetShape(self, geom):
1729 Associate the given shape to the mesh (entails the recreation of the mesh)
1732 geom: the shape to be meshed (GEOM_Object)
1735 self.mesh = self.smeshpyD.CreateMesh(geom)
1737 def HasShapeToMesh(self):
1739 Return ``True`` if this mesh is based on geometry
1741 return self.mesh.HasShapeToMesh()
1745 Load mesh from the study after opening the study
1749 def IsReadyToCompute(self, theSubObject):
1751 Return true if the hypotheses are defined well
1754 theSubObject: a sub-shape of a mesh shape
1760 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1762 def GetAlgoState(self, theSubObject):
1764 Return errors of hypotheses definition.
1765 The list of errors is empty if everything is OK.
1768 theSubObject: a sub-shape of a mesh shape
1774 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1776 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1778 Return a geometrical object on which the given element was built.
1779 The returned geometrical object, if not nil, is either found in the
1780 study or published by this method with the given name
1783 theElementID: the id of the mesh element
1784 theGeomName: the user-defined name of the geometrical object
1787 GEOM.GEOM_Object instance
1790 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1792 def MeshDimension(self):
1794 Return the mesh dimension depending on the dimension of the underlying shape
1795 or, if the mesh is not based on any shape, basing on deimension of elements
1798 mesh dimension as an integer value [0,3]
1801 if self.mesh.HasShapeToMesh():
1802 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1803 if len( shells ) > 0 :
1805 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1807 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1812 if self.NbVolumes() > 0: return 3
1813 if self.NbFaces() > 0: return 2
1814 if self.NbEdges() > 0: return 1
1817 def Evaluate(self, geom=0):
1819 Evaluate size of prospective mesh on a shape
1822 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1823 To know predicted number of e.g. edges, inquire it this way::
1825 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1828 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1830 geom = self.mesh.GetShapeToMesh()
1833 return self.smeshpyD.Evaluate(self.mesh, geom)
1836 def Compute(self, geom=0, discardModifs=False, refresh=False):
1838 Compute the mesh and return the status of the computation
1841 geom: geomtrical shape on which mesh data should be computed
1842 discardModifs: if True and the mesh has been edited since
1843 a last total re-compute and that may prevent successful partial re-compute,
1844 then the mesh is cleaned before Compute()
1845 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1851 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1853 geom = self.mesh.GetShapeToMesh()
1858 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1860 ok = self.smeshpyD.Compute(self.mesh, geom)
1861 except SALOME.SALOME_Exception as ex:
1862 print("Mesh computation failed, exception caught:")
1863 print(" ", ex.details.text)
1866 print("Mesh computation failed, exception caught:")
1867 traceback.print_exc()
1871 # Treat compute errors
1872 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1874 for err in computeErrors:
1875 if self.mesh.HasShapeToMesh():
1876 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1878 stdErrors = ["OK", #COMPERR_OK
1879 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1880 "std::exception", #COMPERR_STD_EXCEPTION
1881 "OCC exception", #COMPERR_OCC_EXCEPTION
1882 "..", #COMPERR_SLM_EXCEPTION
1883 "Unknown exception", #COMPERR_EXCEPTION
1884 "Memory allocation problem", #COMPERR_MEMORY_PB
1885 "Algorithm failed", #COMPERR_ALGO_FAILED
1886 "Unexpected geometry", #COMPERR_BAD_SHAPE
1887 "Warning", #COMPERR_WARNING
1888 "Computation cancelled",#COMPERR_CANCELED
1889 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1891 if err.code < len(stdErrors): errText = stdErrors[err.code]
1893 errText = "code %s" % -err.code
1894 if errText: errText += ". "
1895 errText += err.comment
1896 if allReasons: allReasons += "\n"
1898 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1900 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1904 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1906 if err.isGlobalAlgo:
1914 reason = '%s %sD algorithm is missing' % (glob, dim)
1915 elif err.state == HYP_MISSING:
1916 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1917 % (glob, dim, name, dim))
1918 elif err.state == HYP_NOTCONFORM:
1919 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1920 elif err.state == HYP_BAD_PARAMETER:
1921 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1922 % ( glob, dim, name ))
1923 elif err.state == HYP_BAD_GEOMETRY:
1924 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1925 'geometry' % ( glob, dim, name ))
1926 elif err.state == HYP_HIDDEN_ALGO:
1927 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1928 'algorithm of upper dimension generating %sD mesh'
1929 % ( glob, dim, name, glob, dim ))
1931 reason = ("For unknown reason. "
1932 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1934 if allReasons: allReasons += "\n"
1935 allReasons += "- " + reason
1937 if not ok or allReasons != "":
1938 msg = '"' + GetName(self.mesh) + '"'
1939 if ok: msg += " has been computed with warnings"
1940 else: msg += " has not been computed"
1941 if allReasons != "": msg += ":"
1946 if salome.sg.hasDesktop():
1947 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1948 if refresh: salome.sg.updateObjBrowser()
1952 def GetComputeErrors(self, shape=0 ):
1954 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1958 shape = self.mesh.GetShapeToMesh()
1959 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1961 def GetSubShapeName(self, subShapeID ):
1963 Return a name of a sub-shape by its ID.
1964 Possible variants (for *subShapeID* == 3):
1966 - **"Face_12"** - published sub-shape
1967 - **FACE #3** - not published sub-shape
1968 - **sub-shape #3** - invalid sub-shape ID
1969 - **#3** - error in this function
1972 subShapeID: a unique ID of a sub-shape
1975 a string describing the sub-shape
1979 if not self.mesh.HasShapeToMesh():
1983 mainIOR = salome.orb.object_to_string( self.GetShape() )
1985 mainSO = s.FindObjectIOR(mainIOR)
1988 shapeText = '"%s"' % mainSO.GetName()
1989 subIt = s.NewChildIterator(mainSO)
1991 subSO = subIt.Value()
1993 obj = subSO.GetObject()
1994 if not obj: continue
1995 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1998 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2001 if ids == subShapeID:
2002 shapeText = '"%s"' % subSO.GetName()
2005 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2007 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2009 shapeText = 'sub-shape #%s' % (subShapeID)
2011 shapeText = "#%s" % (subShapeID)
2014 def GetFailedShapes(self, publish=False):
2016 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2017 error of an algorithm
2020 publish: if *True*, the returned groups will be published in the study
2023 a list of GEOM groups each named after a failed algorithm
2028 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2029 for err in computeErrors:
2030 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2031 if not shape: continue
2032 if err.algoName in algo2shapes:
2033 algo2shapes[ err.algoName ].append( shape )
2035 algo2shapes[ err.algoName ] = [ shape ]
2039 for algoName, shapes in list(algo2shapes.items()):
2041 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2042 otherTypeShapes = []
2044 group = self.geompyD.CreateGroup( self.geom, groupType )
2045 for shape in shapes:
2046 if shape.GetShapeType() == shapes[0].GetShapeType():
2047 sameTypeShapes.append( shape )
2049 otherTypeShapes.append( shape )
2050 self.geompyD.UnionList( group, sameTypeShapes )
2052 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2054 group.SetName( algoName )
2055 groups.append( group )
2056 shapes = otherTypeShapes
2059 for group in groups:
2060 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2063 def GetMeshOrder(self):
2065 Return sub-mesh objects list in meshing order
2068 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2071 return self.mesh.GetMeshOrder()
2073 def SetMeshOrder(self, submeshes):
2075 Set priority of sub-meshes. It works in two ways:
2077 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2078 *several dimensions*, it sets the order in which the sub-meshes are computed.
2079 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2080 when looking for meshing parameters to apply to a sub-shape. To impose the
2081 order in which sub-meshes with uni-dimensional algorithms are computed,
2082 call **submesh.Compute()** in a desired order.
2085 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2088 return self.mesh.SetMeshOrder(submeshes)
2090 def Clear(self, refresh=False):
2092 Remove all nodes and elements generated on geometry. Imported elements remain.
2095 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2099 if ( salome.sg.hasDesktop() ):
2100 if refresh: salome.sg.updateObjBrowser()
2102 def ClearSubMesh(self, geomId, refresh=False):
2104 Remove all nodes and elements of indicated shape
2107 geomId: the ID of a sub-shape to remove elements on
2108 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2111 self.mesh.ClearSubMesh(geomId)
2112 if salome.sg.hasDesktop():
2113 if refresh: salome.sg.updateObjBrowser()
2115 def AutomaticTetrahedralization(self, fineness=0):
2117 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2120 fineness: [0.0,1.0] defines mesh fineness
2126 dim = self.MeshDimension()
2128 self.RemoveGlobalHypotheses()
2129 self.Segment().AutomaticLength(fineness)
2131 self.Triangle().LengthFromEdges()
2136 return self.Compute()
2138 def AutomaticHexahedralization(self, fineness=0):
2140 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2143 fineness: [0.0, 1.0] defines mesh fineness
2149 dim = self.MeshDimension()
2150 # assign the hypotheses
2151 self.RemoveGlobalHypotheses()
2152 self.Segment().AutomaticLength(fineness)
2159 return self.Compute()
2161 def AddHypothesis(self, hyp, geom=0):
2166 hyp: a hypothesis to assign
2167 geom: a subhape of mesh geometry
2170 :class:`SMESH.Hypothesis_Status`
2173 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2174 hyp, geom = geom, hyp
2175 if isinstance( hyp, Mesh_Algorithm ):
2176 hyp = hyp.GetAlgorithm()
2181 geom = self.mesh.GetShapeToMesh()
2184 if self.mesh.HasShapeToMesh():
2185 hyp_type = hyp.GetName()
2186 lib_name = hyp.GetLibName()
2187 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2188 # if checkAll and geom:
2189 # checkAll = geom.GetType() == 37
2191 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2193 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2194 status = self.mesh.AddHypothesis(geom, hyp)
2196 status = HYP_BAD_GEOMETRY, ""
2197 hyp_name = GetName( hyp )
2200 geom_name = geom.GetName()
2201 isAlgo = hyp._narrow( SMESH_Algo )
2202 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2205 def IsUsedHypothesis(self, hyp, geom):
2207 Return True if an algorithm or hypothesis is assigned to a given shape
2210 hyp: an algorithm or hypothesis to check
2211 geom: a subhape of mesh geometry
2217 if not hyp: # or not geom
2219 if isinstance( hyp, Mesh_Algorithm ):
2220 hyp = hyp.GetAlgorithm()
2222 hyps = self.GetHypothesisList(geom)
2224 if h.GetId() == hyp.GetId():
2228 def RemoveHypothesis(self, hyp, geom=0):
2230 Unassign a hypothesis
2233 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2234 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2237 :class:`SMESH.Hypothesis_Status`
2242 if isinstance( hyp, Mesh_Algorithm ):
2243 hyp = hyp.GetAlgorithm()
2249 if self.IsUsedHypothesis( hyp, shape ):
2250 return self.mesh.RemoveHypothesis( shape, hyp )
2251 hypName = GetName( hyp )
2252 geoName = GetName( shape )
2253 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2256 def GetHypothesisList(self, geom):
2258 Get the list of hypotheses added on a geometry
2261 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2264 the sequence of :class:`SMESH.SMESH_Hypothesis`
2267 return self.mesh.GetHypothesisList( geom )
2269 def RemoveGlobalHypotheses(self):
2271 Remove all global hypotheses
2274 current_hyps = self.mesh.GetHypothesisList( self.geom )
2275 for hyp in current_hyps:
2276 self.mesh.RemoveHypothesis( self.geom, hyp )
2279 def ExportMED(self, *args, **kwargs):
2281 Export the mesh in a file in MED format
2282 allowing to overwrite the file if it exists or add the exported data to its contents
2285 fileName: is the file name
2286 auto_groups (boolean): parameter for creating/not creating
2287 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2288 the typical use is auto_groups=False.
2289 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2290 The minor must be between 0 and the current minor version of MED file library.
2291 If minor is equal to -1, the minor version is not changed (default).
2292 The major version (x, where version is x.y.z) cannot be changed.
2293 overwrite (boolean): parameter for overwriting/not overwriting the file
2294 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2295 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2297 - 1D if all mesh nodes lie on OX coordinate axis, or
2298 - 2D if all mesh nodes lie on XOY coordinate plane, or
2299 - 3D in the rest cases.
2301 If *autoDimension* is *False*, the space dimension is always 3.
2302 fields: list of GEOM fields defined on the shape to mesh.
2303 geomAssocFields: each character of this string means a need to export a
2304 corresponding field; correspondence between fields and characters
2307 - 'v' stands for "_vertices_" field;
2308 - 'e' stands for "_edges_" field;
2309 - 'f' stands for "_faces_" field;
2310 - 's' stands for "_solids_" field.
2312 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2313 close to zero within a given tolerance, the coordinate is set to zero.
2314 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2316 # process positional arguments
2317 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2319 auto_groups = args[1] if len(args) > 1 else False
2320 minor = args[2] if len(args) > 2 else -1
2321 overwrite = args[3] if len(args) > 3 else True
2322 meshPart = args[4] if len(args) > 4 else None
2323 autoDimension = args[5] if len(args) > 5 else True
2324 fields = args[6] if len(args) > 6 else []
2325 geomAssocFields = args[7] if len(args) > 7 else ''
2326 z_tolerance = args[8] if len(args) > 8 else -1.
2327 # process keywords arguments
2328 auto_groups = kwargs.get("auto_groups", auto_groups)
2329 minor = kwargs.get("minor", minor)
2330 overwrite = kwargs.get("overwrite", overwrite)
2331 meshPart = kwargs.get("meshPart", meshPart)
2332 autoDimension = kwargs.get("autoDimension", autoDimension)
2333 fields = kwargs.get("fields", fields)
2334 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2335 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2337 # invoke engine's function
2338 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2339 unRegister = genObjUnRegister()
2340 if isinstance( meshPart, list ):
2341 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2342 unRegister.set( meshPart )
2344 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2345 self.mesh.SetParameters(Parameters)
2347 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2348 fields, geomAssocFields, z_tolerance)
2350 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2352 def ExportSAUV(self, f, auto_groups=0):
2354 Export the mesh in a file in SAUV format
2359 auto_groups: boolean parameter for creating/not creating
2360 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2361 the typical use is auto_groups=False.
2364 self.mesh.ExportSAUV(f, auto_groups)
2366 def ExportDAT(self, f, meshPart=None):
2368 Export the mesh in a file in DAT format
2372 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2376 unRegister = genObjUnRegister()
2377 if isinstance( meshPart, list ):
2378 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2379 unRegister.set( meshPart )
2380 self.mesh.ExportPartToDAT( meshPart, f )
2382 self.mesh.ExportDAT(f)
2384 def ExportUNV(self, f, meshPart=None):
2386 Export the mesh in a file in UNV format
2390 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2394 unRegister = genObjUnRegister()
2395 if isinstance( meshPart, list ):
2396 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2397 unRegister.set( meshPart )
2398 self.mesh.ExportPartToUNV( meshPart, f )
2400 self.mesh.ExportUNV(f)
2402 def ExportSTL(self, f, ascii=1, meshPart=None):
2404 Export the mesh in a file in STL format
2408 ascii: defines the file encoding
2409 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2413 unRegister = genObjUnRegister()
2414 if isinstance( meshPart, list ):
2415 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2416 unRegister.set( meshPart )
2417 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2419 self.mesh.ExportSTL(f, ascii)
2421 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2423 Export the mesh in a file in CGNS format
2427 overwrite: boolean parameter for overwriting/not overwriting the file
2428 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2429 groupElemsByType: if True all elements of same entity type are exported at ones,
2430 else elements are exported in order of their IDs which can cause creation
2431 of multiple cgns sections
2434 unRegister = genObjUnRegister()
2435 if isinstance( meshPart, list ):
2436 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2437 unRegister.set( meshPart )
2438 if isinstance( meshPart, Mesh ):
2439 meshPart = meshPart.mesh
2441 meshPart = self.mesh
2442 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2444 def ExportGMF(self, f, meshPart=None):
2446 Export the mesh in a file in GMF format.
2447 GMF files must have .mesh extension for the ASCII format and .meshb for
2448 the bynary format. Other extensions are not allowed.
2452 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2455 unRegister = genObjUnRegister()
2456 if isinstance( meshPart, list ):
2457 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2458 unRegister.set( meshPart )
2459 if isinstance( meshPart, Mesh ):
2460 meshPart = meshPart.mesh
2462 meshPart = self.mesh
2463 self.mesh.ExportGMF(meshPart, f, True)
2465 def ExportToMED(self, *args, **kwargs):
2467 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2468 Export the mesh in a file in MED format
2469 allowing to overwrite the file if it exists or add the exported data to its contents
2472 fileName: the file name
2473 opt (boolean): parameter for creating/not creating
2474 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2475 overwrite: boolean parameter for overwriting/not overwriting the file
2476 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2478 - 1D if all mesh nodes lie on OX coordinate axis, or
2479 - 2D if all mesh nodes lie on XOY coordinate plane, or
2480 - 3D in the rest cases.
2482 If **autoDimension** is *False*, the space dimension is always 3.
2485 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2486 # process positional arguments
2487 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2489 auto_groups = args[1] if len(args) > 1 else False
2490 overwrite = args[2] if len(args) > 2 else True
2491 autoDimension = args[3] if len(args) > 3 else True
2492 # process keywords arguments
2493 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2494 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2495 overwrite = kwargs.get("overwrite", overwrite)
2496 autoDimension = kwargs.get("autoDimension", autoDimension)
2498 # invoke engine's function
2499 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2501 def ExportToMEDX(self, *args, **kwargs):
2503 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2504 Export the mesh in a file in MED format
2507 fileName: the file name
2508 opt (boolean): parameter for creating/not creating
2509 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2510 overwrite: boolean parameter for overwriting/not overwriting the file
2511 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2513 - 1D if all mesh nodes lie on OX coordinate axis, or
2514 - 2D if all mesh nodes lie on XOY coordinate plane, or
2515 - 3D in the rest cases.
2517 If **autoDimension** is *False*, the space dimension is always 3.
2520 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2521 # process positional arguments
2522 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2524 auto_groups = args[1] if len(args) > 1 else False
2525 overwrite = args[2] if len(args) > 2 else True
2526 autoDimension = args[3] if len(args) > 3 else True
2527 # process keywords arguments
2528 auto_groups = kwargs.get("auto_groups", auto_groups)
2529 overwrite = kwargs.get("overwrite", overwrite)
2530 autoDimension = kwargs.get("autoDimension", autoDimension)
2532 # invoke engine's function
2533 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2537 def Append(self, meshes, uniteIdenticalGroups = True,
2538 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2540 Append given meshes into this mesh.
2541 All groups of input meshes will be created in this mesh.
2544 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2545 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2546 mergeNodesAndElements: if True, equal nodes and elements are merged
2547 mergeTolerance: tolerance for merging nodes
2548 allGroups: forces creation of groups corresponding to every input mesh
2550 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2551 mergeNodesAndElements, mergeTolerance, allGroups,
2552 meshToAppendTo = self.GetMesh() )
2554 # Operations with groups:
2555 # ----------------------
2556 def CreateEmptyGroup(self, elementType, name):
2558 Create an empty standalone mesh group
2561 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2562 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2563 name: the name of the mesh group
2566 :class:`SMESH.SMESH_Group`
2569 return self.mesh.CreateGroup(elementType, name)
2571 def Group(self, grp, name=""):
2573 Create a mesh group based on the geometric object *grp*
2574 and give it a *name*.
2575 If *name* is not defined the name of the geometric group is used
2578 Works like :meth:`GroupOnGeom`.
2581 grp: a geometric group, a vertex, an edge, a face or a solid
2582 name: the name of the mesh group
2585 :class:`SMESH.SMESH_GroupOnGeom`
2588 return self.GroupOnGeom(grp, name)
2590 def GroupOnGeom(self, grp, name="", typ=None):
2592 Create a mesh group based on the geometrical object *grp*
2593 and give it a *name*.
2594 if *name* is not defined the name of the geometric group is used
2597 grp: a geometrical group, a vertex, an edge, a face or a solid
2598 name: the name of the mesh group
2599 typ: the type of elements in the group; either of
2600 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2601 automatically detected by the type of the geometry
2604 :class:`SMESH.SMESH_GroupOnGeom`
2607 AssureGeomPublished( self, grp, name )
2609 name = grp.GetName()
2611 typ = self._groupTypeFromShape( grp )
2612 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2614 def _groupTypeFromShape( self, shape ):
2616 Pivate method to get a type of group on geometry
2618 tgeo = str(shape.GetShapeType())
2619 if tgeo == "VERTEX":
2621 elif tgeo == "EDGE":
2623 elif tgeo == "FACE" or tgeo == "SHELL":
2625 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2627 elif tgeo == "COMPOUND":
2628 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2630 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2631 return self._groupTypeFromShape( sub[0] )
2633 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2636 def GroupOnFilter(self, typ, name, filter):
2638 Create a mesh group with given *name* based on the *filter*.
2639 It is a special type of group dynamically updating it's contents during
2643 typ: the type of elements in the group; either of
2644 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2645 name: the name of the mesh group
2646 filter (SMESH.Filter): the filter defining group contents
2649 :class:`SMESH.SMESH_GroupOnFilter`
2652 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2654 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2656 Create a mesh group by the given ids of elements
2659 groupName: the name of the mesh group
2660 elementType: the type of elements in the group; either of
2661 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2662 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2665 :class:`SMESH.SMESH_Group`
2668 group = self.mesh.CreateGroup(elementType, groupName)
2669 if isinstance( elemIDs, Mesh ):
2670 elemIDs = elemIDs.GetMesh()
2671 if hasattr( elemIDs, "GetIDs" ):
2672 if hasattr( elemIDs, "SetMesh" ):
2673 elemIDs.SetMesh( self.GetMesh() )
2674 group.AddFrom( elemIDs )
2682 CritType=FT_Undefined,
2685 UnaryOp=FT_Undefined,
2688 Create a mesh group by the given conditions
2691 groupName: the name of the mesh group
2692 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2693 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2694 Note that the items starting from FT_LessThan are not suitable for CritType.
2695 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2696 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2697 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2698 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2699 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2702 :class:`SMESH.SMESH_GroupOnFilter`
2705 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2706 group = self.MakeGroupByCriterion(groupName, aCriterion)
2709 def MakeGroupByCriterion(self, groupName, Criterion):
2711 Create a mesh group by the given criterion
2714 groupName: the name of the mesh group
2715 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2718 :class:`SMESH.SMESH_GroupOnFilter`
2721 :meth:`smeshBuilder.GetCriterion`
2724 return self.MakeGroupByCriteria( groupName, [Criterion] )
2726 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2728 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2731 groupName: the name of the mesh group
2732 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2733 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2736 :class:`SMESH.SMESH_GroupOnFilter`
2739 :meth:`smeshBuilder.GetCriterion`
2742 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2743 group = self.MakeGroupByFilter(groupName, aFilter)
2746 def MakeGroupByFilter(self, groupName, theFilter):
2748 Create a mesh group by the given filter
2751 groupName (string): the name of the mesh group
2752 theFilter (SMESH.Filter): the filter
2755 :class:`SMESH.SMESH_GroupOnFilter`
2758 :meth:`smeshBuilder.GetFilter`
2761 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2762 #theFilter.SetMesh( self.mesh )
2763 #group.AddFrom( theFilter )
2764 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2767 def RemoveGroup(self, group):
2772 group (SMESH.SMESH_GroupBase): group to remove
2775 self.mesh.RemoveGroup(group)
2777 def RemoveGroupWithContents(self, group):
2779 Remove a group with its contents
2782 group (SMESH.SMESH_GroupBase): group to remove
2785 This operation can create gaps in numeration of nodes or elements.
2786 Call :meth:`RenumberElements` to remove the gaps.
2789 self.mesh.RemoveGroupWithContents(group)
2791 def GetGroups(self, elemType = SMESH.ALL):
2793 Get the list of groups existing in the mesh in the order of creation
2794 (starting from the oldest one)
2797 elemType (SMESH.ElementType): type of elements the groups contain;
2798 by default groups of elements of all types are returned
2801 a list of :class:`SMESH.SMESH_GroupBase`
2804 groups = self.mesh.GetGroups()
2805 if elemType == SMESH.ALL:
2809 if g.GetType() == elemType:
2810 typedGroups.append( g )
2817 Get the number of groups existing in the mesh
2820 the quantity of groups as an integer value
2823 return self.mesh.NbGroups()
2825 def GetGroupNames(self):
2827 Get the list of names of groups existing in the mesh
2833 groups = self.GetGroups()
2835 for group in groups:
2836 names.append(group.GetName())
2839 def GetGroupByName(self, name, elemType = None):
2841 Find groups by name and type
2844 name (string): name of the group of interest
2845 elemType (SMESH.ElementType): type of elements the groups contain;
2846 by default one group of any type is returned;
2847 if elemType == SMESH.ALL then all groups of any type are returned
2850 a list of :class:`SMESH.SMESH_GroupBase`
2854 for group in self.GetGroups():
2855 if group.GetName() == name:
2856 if elemType is None:
2858 if ( elemType == SMESH.ALL or
2859 group.GetType() == elemType ):
2860 groups.append( group )
2863 def UnionGroups(self, group1, group2, name):
2865 Produce a union of two groups.
2866 A new group is created. All mesh elements that are
2867 present in the initial groups are added to the new one
2870 group1 (SMESH.SMESH_GroupBase): a group
2871 group2 (SMESH.SMESH_GroupBase): another group
2874 instance of :class:`SMESH.SMESH_Group`
2877 return self.mesh.UnionGroups(group1, group2, name)
2879 def UnionListOfGroups(self, groups, name):
2881 Produce a union list of groups.
2882 New group is created. All mesh elements that are present in
2883 initial groups are added to the new one
2886 groups: list of :class:`SMESH.SMESH_GroupBase`
2889 instance of :class:`SMESH.SMESH_Group`
2891 return self.mesh.UnionListOfGroups(groups, name)
2893 def IntersectGroups(self, group1, group2, name):
2895 Prodice an intersection of two groups.
2896 A new group is created. All mesh elements that are common
2897 for the two initial groups are added to the new one.
2900 group1 (SMESH.SMESH_GroupBase): a group
2901 group2 (SMESH.SMESH_GroupBase): another group
2904 instance of :class:`SMESH.SMESH_Group`
2907 return self.mesh.IntersectGroups(group1, group2, name)
2909 def IntersectListOfGroups(self, groups, name):
2911 Produce an intersection of groups.
2912 New group is created. All mesh elements that are present in all
2913 initial groups simultaneously are added to the new one
2916 groups: a list of :class:`SMESH.SMESH_GroupBase`
2919 instance of :class:`SMESH.SMESH_Group`
2921 return self.mesh.IntersectListOfGroups(groups, name)
2923 def CutGroups(self, main_group, tool_group, name):
2925 Produce a cut of two groups.
2926 A new group is created. All mesh elements that are present in
2927 the main group but are not present in the tool group are added to the new one
2930 main_group (SMESH.SMESH_GroupBase): a group to cut from
2931 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2934 an instance of :class:`SMESH.SMESH_Group`
2937 return self.mesh.CutGroups(main_group, tool_group, name)
2939 def CutListOfGroups(self, main_groups, tool_groups, name):
2941 Produce a cut of groups.
2942 A new group is created. All mesh elements that are present in main groups
2943 but do not present in tool groups are added to the new one
2946 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2947 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2950 an instance of :class:`SMESH.SMESH_Group`
2953 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2955 def CreateDimGroup(self, groups, elemType, name,
2956 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2958 Create a standalone group of entities basing on nodes of other groups.
2961 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2962 elemType: a type of elements to include to the new group; either of
2963 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2964 name: a name of the new group.
2965 nbCommonNodes: a criterion of inclusion of an element to the new group
2966 basing on number of element nodes common with reference *groups*.
2967 Meaning of possible values are:
2969 - SMESH.ALL_NODES - include if all nodes are common,
2970 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2971 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2972 - SMEHS.MAJORITY - include if half of nodes or more are common.
2973 underlyingOnly: if *True* (default), an element is included to the
2974 new group provided that it is based on nodes of an element of *groups*;
2975 in this case the reference *groups* are supposed to be of higher dimension
2976 than *elemType*, which can be useful for example to get all faces lying on
2977 volumes of the reference *groups*.
2980 an instance of :class:`SMESH.SMESH_Group`
2983 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2985 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2987 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2989 Distribute all faces of the mesh among groups using sharp edges and optionally
2990 existing 1D elements as group boundaries.
2993 sharpAngle: edge is considered sharp if an angle between normals of
2994 adjacent faces is more than \a sharpAngle in degrees.
2995 createEdges (boolean): to create 1D elements for detected sharp edges.
2996 useExistingEdges (boolean): to use existing edges as group boundaries
2998 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3000 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3001 self.mesh.SetParameters(Parameters)
3002 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3004 def ConvertToStandalone(self, group):
3006 Convert group on geom into standalone group
3009 return self.mesh.ConvertToStandalone(group)
3011 # Get some info about mesh:
3012 # ------------------------
3014 def GetLog(self, clearAfterGet):
3016 Return the log of nodes and elements added or removed
3017 since the previous clear of the log.
3020 clearAfterGet: log is emptied after Get (safe if concurrents access)
3023 list of SMESH.log_block structures { commandType, number, coords, indexes }
3026 return self.mesh.GetLog(clearAfterGet)
3030 Clear the log of nodes and elements added or removed since the previous
3031 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3034 self.mesh.ClearLog()
3036 def SetAutoColor(self, theAutoColor):
3038 Toggle auto color mode on the object.
3039 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3042 theAutoColor (boolean): the flag which toggles auto color mode.
3045 self.mesh.SetAutoColor(theAutoColor)
3047 def GetAutoColor(self):
3049 Get flag of object auto color mode.
3055 return self.mesh.GetAutoColor()
3062 integer value, which is the internal Id of the mesh
3065 return self.mesh.GetId()
3067 def HasDuplicatedGroupNamesMED(self):
3069 Check the group names for duplications.
3070 Consider the maximum group name length stored in MED file.
3076 return self.mesh.HasDuplicatedGroupNamesMED()
3078 def GetMeshEditor(self):
3080 Obtain the mesh editor tool
3083 an instance of :class:`SMESH.SMESH_MeshEditor`
3088 def GetIDSource(self, ids, elemType = SMESH.ALL):
3090 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3091 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3095 elemType: type of elements; this parameter is used to distinguish
3096 IDs of nodes from IDs of elements; by default ids are treated as
3097 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3100 an instance of :class:`SMESH.SMESH_IDSource`
3103 call UnRegister() for the returned object as soon as it is no more useful::
3105 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3106 mesh.DoSomething( idSrc )
3110 if isinstance( ids, int ):
3112 return self.editor.MakeIDSource(ids, elemType)
3115 # Get information about mesh contents:
3116 # ------------------------------------
3118 def GetMeshInfo(self, obj = None):
3120 Get the mesh statistic.
3123 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3126 if not obj: obj = self.mesh
3127 return self.smeshpyD.GetMeshInfo(obj)
3131 Return the number of nodes in the mesh
3137 return self.mesh.NbNodes()
3139 def NbElements(self):
3141 Return the number of elements in the mesh
3147 return self.mesh.NbElements()
3149 def Nb0DElements(self):
3151 Return the number of 0d elements in the mesh
3157 return self.mesh.Nb0DElements()
3161 Return the number of ball discrete elements in the mesh
3167 return self.mesh.NbBalls()
3171 Return the number of edges in the mesh
3177 return self.mesh.NbEdges()
3179 def NbEdgesOfOrder(self, elementOrder):
3181 Return the number of edges with the given order in the mesh
3184 elementOrder: the order of elements
3185 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3191 return self.mesh.NbEdgesOfOrder(elementOrder)
3195 Return the number of faces in the mesh
3201 return self.mesh.NbFaces()
3203 def NbFacesOfOrder(self, elementOrder):
3205 Return the number of faces with the given order in the mesh
3208 elementOrder: the order of elements
3209 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3215 return self.mesh.NbFacesOfOrder(elementOrder)
3217 def NbTriangles(self):
3219 Return the number of triangles in the mesh
3225 return self.mesh.NbTriangles()
3227 def NbTrianglesOfOrder(self, elementOrder):
3229 Return the number of triangles with the given order in the mesh
3232 elementOrder: is the order of elements
3233 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3239 return self.mesh.NbTrianglesOfOrder(elementOrder)
3241 def NbBiQuadTriangles(self):
3243 Return the number of biquadratic triangles in the mesh
3249 return self.mesh.NbBiQuadTriangles()
3251 def NbQuadrangles(self):
3253 Return the number of quadrangles in the mesh
3259 return self.mesh.NbQuadrangles()
3261 def NbQuadranglesOfOrder(self, elementOrder):
3263 Return the number of quadrangles with the given order in the mesh
3266 elementOrder: the order of elements
3267 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3273 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3275 def NbBiQuadQuadrangles(self):
3277 Return the number of biquadratic quadrangles in the mesh
3283 return self.mesh.NbBiQuadQuadrangles()
3285 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3287 Return the number of polygons of given order in the mesh
3290 elementOrder: the order of elements
3291 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3297 return self.mesh.NbPolygonsOfOrder(elementOrder)
3299 def NbVolumes(self):
3301 Return the number of volumes in the mesh
3307 return self.mesh.NbVolumes()
3310 def NbVolumesOfOrder(self, elementOrder):
3312 Return the number of volumes with the given order in the mesh
3315 elementOrder: the order of elements
3316 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322 return self.mesh.NbVolumesOfOrder(elementOrder)
3326 Return the number of tetrahedrons in the mesh
3332 return self.mesh.NbTetras()
3334 def NbTetrasOfOrder(self, elementOrder):
3336 Return the number of tetrahedrons with the given order in the mesh
3339 elementOrder: the order of elements
3340 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346 return self.mesh.NbTetrasOfOrder(elementOrder)
3350 Return the number of hexahedrons in the mesh
3356 return self.mesh.NbHexas()
3358 def NbHexasOfOrder(self, elementOrder):
3360 Return the number of hexahedrons with the given order in the mesh
3363 elementOrder: the order of elements
3364 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370 return self.mesh.NbHexasOfOrder(elementOrder)
3372 def NbTriQuadraticHexas(self):
3374 Return the number of triquadratic hexahedrons in the mesh
3380 return self.mesh.NbTriQuadraticHexas()
3382 def NbPyramids(self):
3384 Return the number of pyramids in the mesh
3390 return self.mesh.NbPyramids()
3392 def NbPyramidsOfOrder(self, elementOrder):
3394 Return the number of pyramids with the given order in the mesh
3397 elementOrder: the order of elements
3398 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3404 return self.mesh.NbPyramidsOfOrder(elementOrder)
3408 Return the number of prisms in the mesh
3414 return self.mesh.NbPrisms()
3416 def NbPrismsOfOrder(self, elementOrder):
3418 Return the number of prisms with the given order in the mesh
3421 elementOrder: the order of elements
3422 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428 return self.mesh.NbPrismsOfOrder(elementOrder)
3430 def NbHexagonalPrisms(self):
3432 Return the number of hexagonal prisms in the mesh
3438 return self.mesh.NbHexagonalPrisms()
3440 def NbPolyhedrons(self):
3442 Return the number of polyhedrons in the mesh
3448 return self.mesh.NbPolyhedrons()
3450 def NbSubMesh(self):
3452 Return the number of submeshes in the mesh
3458 return self.mesh.NbSubMesh()
3460 def GetElementsId(self):
3462 Return the list of all mesh elements IDs
3465 the list of integer values
3468 :meth:`GetElementsByType`
3471 return self.mesh.GetElementsId()
3473 def GetElementsByType(self, elementType):
3475 Return the list of IDs of mesh elements with the given type
3478 elementType (SMESH.ElementType): the required type of elements
3481 list of integer values
3484 return self.mesh.GetElementsByType(elementType)
3486 def GetNodesId(self):
3488 Return the list of mesh nodes IDs
3491 the list of integer values
3494 return self.mesh.GetNodesId()
3496 # Get the information about mesh elements:
3497 # ------------------------------------
3499 def GetElementType(self, id, iselem=True):
3501 Return the type of mesh element or node
3504 the value from :class:`SMESH.ElementType` enumeration.
3505 Return SMESH.ALL if element or node with the given ID does not exist
3508 return self.mesh.GetElementType(id, iselem)
3510 def GetElementGeomType(self, id):
3512 Return the geometric type of mesh element
3515 the value from :class:`SMESH.EntityType` enumeration.
3518 return self.mesh.GetElementGeomType(id)
3520 def GetElementShape(self, id):
3522 Return the shape type of mesh element
3525 the value from :class:`SMESH.GeometryType` enumeration.
3528 return self.mesh.GetElementShape(id)
3530 def GetSubMeshElementsId(self, Shape):
3532 Return the list of sub-mesh elements IDs
3535 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3536 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3539 list of integer values
3542 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3543 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3546 return self.mesh.GetSubMeshElementsId(ShapeID)
3548 def GetSubMeshNodesId(self, Shape, all):
3550 Return the list of sub-mesh nodes IDs
3553 Shape: a geom object (sub-shape).
3554 *Shape* must be the sub-shape of a :meth:`GetShape`
3555 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3558 list of integer values
3561 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3562 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3565 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3567 def GetSubMeshElementType(self, Shape):
3569 Return type of elements on given shape
3572 Shape: a geom object (sub-shape).
3573 *Shape* must be a sub-shape of a ShapeToMesh()
3576 :class:`SMESH.ElementType`
3579 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3580 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3583 return self.mesh.GetSubMeshElementType(ShapeID)
3587 Get the mesh description
3593 return self.mesh.Dump()
3596 # Get the information about nodes and elements of a mesh by its IDs:
3597 # -----------------------------------------------------------
3599 def GetNodeXYZ(self, id):
3601 Get XYZ coordinates of a node.
3602 If there is no node for the given ID - return an empty list
3605 list of float values
3608 return self.mesh.GetNodeXYZ(id)
3610 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3612 Return list of IDs of inverse elements for the given node.
3613 If there is no node for the given ID - return an empty list
3617 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3620 list of integer values
3623 return self.mesh.GetNodeInverseElements(id,elemType)
3625 def GetNodePosition(self,NodeID):
3627 Return the position of a node on the shape
3630 :class:`SMESH.NodePosition`
3633 return self.mesh.GetNodePosition(NodeID)
3635 def GetElementPosition(self,ElemID):
3637 Return the position of an element on the shape
3640 :class:`SMESH.ElementPosition`
3643 return self.mesh.GetElementPosition(ElemID)
3645 def GetShapeID(self, id):
3647 Return the ID of the shape, on which the given node was generated.
3650 an integer value > 0 or -1 if there is no node for the given
3651 ID or the node is not assigned to any geometry
3654 return self.mesh.GetShapeID(id)
3656 def GetShapeIDForElem(self,id):
3658 Return the ID of the shape, on which the given element was generated.
3661 an integer value > 0 or -1 if there is no element for the given
3662 ID or the element is not assigned to any geometry
3665 return self.mesh.GetShapeIDForElem(id)
3667 def GetElemNbNodes(self, id):
3669 Return the number of nodes of the given element
3672 an integer value > 0 or -1 if there is no element for the given ID
3675 return self.mesh.GetElemNbNodes(id)
3677 def GetElemNode(self, id, index):
3679 Return the node ID the given (zero based) index for the given element.
3681 * If there is no element for the given ID - return -1.
3682 * If there is no node for the given index - return -2.
3685 id (int): element ID
3686 index (int): node index within the element
3689 an integer value (ID)
3692 :meth:`GetElemNodes`
3695 return self.mesh.GetElemNode(id, index)
3697 def GetElemNodes(self, id):
3699 Return the IDs of nodes of the given element
3702 a list of integer values
3705 return self.mesh.GetElemNodes(id)
3707 def IsMediumNode(self, elementID, nodeID):
3709 Return true if the given node is the medium node in the given quadratic element
3712 return self.mesh.IsMediumNode(elementID, nodeID)
3714 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3716 Return true if the given node is the medium node in one of quadratic elements
3719 nodeID: ID of the node
3720 elementType: the type of elements to check a state of the node, either of
3721 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3724 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3726 def ElemNbEdges(self, id):
3728 Return the number of edges for the given element
3731 return self.mesh.ElemNbEdges(id)
3733 def ElemNbFaces(self, id):
3735 Return the number of faces for the given element
3738 return self.mesh.ElemNbFaces(id)
3740 def GetElemFaceNodes(self,elemId, faceIndex):
3742 Return nodes of given face (counted from zero) for given volumic element.
3745 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3747 def GetFaceNormal(self, faceId, normalized=False):
3749 Return three components of normal of given mesh face
3750 (or an empty array in KO case)
3753 return self.mesh.GetFaceNormal(faceId,normalized)
3755 def FindElementByNodes(self, nodes):
3757 Return an element based on all given nodes.
3760 return self.mesh.FindElementByNodes(nodes)
3762 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3764 Return elements including all given nodes.
3767 return self.mesh.GetElementsByNodes( nodes, elemType )
3769 def IsPoly(self, id):
3771 Return true if the given element is a polygon
3774 return self.mesh.IsPoly(id)
3776 def IsQuadratic(self, id):
3778 Return true if the given element is quadratic
3781 return self.mesh.IsQuadratic(id)
3783 def GetBallDiameter(self, id):
3785 Return diameter of a ball discrete element or zero in case of an invalid *id*
3788 return self.mesh.GetBallDiameter(id)
3790 def BaryCenter(self, id):
3792 Return XYZ coordinates of the barycenter of the given element.
3793 If there is no element for the given ID - return an empty list
3796 a list of three double values
3799 :meth:`smeshBuilder.GetGravityCenter`
3802 return self.mesh.BaryCenter(id)
3804 def GetIdsFromFilter(self, filter, meshParts=[] ):
3806 Pass mesh elements through the given filter and return IDs of fitting elements
3809 filter: :class:`SMESH.Filter`
3810 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3816 :meth:`SMESH.Filter.GetIDs`
3817 :meth:`SMESH.Filter.GetElementsIdFromParts`
3820 filter.SetMesh( self.mesh )
3823 if isinstance( meshParts, Mesh ):
3824 filter.SetMesh( meshParts.GetMesh() )
3825 return theFilter.GetIDs()
3826 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3827 meshParts = [ meshParts ]
3828 return filter.GetElementsIdFromParts( meshParts )
3830 return filter.GetIDs()
3832 # Get mesh measurements information:
3833 # ------------------------------------
3835 def GetFreeBorders(self):
3837 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3838 Return a list of special structures (borders).
3841 a list of :class:`SMESH.FreeEdges.Border`
3844 aFilterMgr = self.smeshpyD.CreateFilterManager()
3845 aPredicate = aFilterMgr.CreateFreeEdges()
3846 aPredicate.SetMesh(self.mesh)
3847 aBorders = aPredicate.GetBorders()
3848 aFilterMgr.UnRegister()
3851 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3853 Get minimum distance between two nodes, elements or distance to the origin
3856 id1: first node/element id
3857 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3858 isElem1: *True* if *id1* is element id, *False* if it is node id
3859 isElem2: *True* if *id2* is element id, *False* if it is node id
3862 minimum distance value
3864 :meth:`GetMinDistance`
3867 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3868 return aMeasure.value
3870 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3872 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3875 id1: first node/element id
3876 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3877 isElem1: *True* if *id1* is element id, *False* if it is node id
3878 isElem2: *True* if *id2* is element id, *False* if it is node id
3881 :class:`SMESH.Measure` structure
3887 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3889 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3892 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3894 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3899 aMeasurements = self.smeshpyD.CreateMeasurements()
3900 aMeasure = aMeasurements.MinDistance(id1, id2)
3901 genObjUnRegister([aMeasurements,id1, id2])
3904 def BoundingBox(self, objects=None, isElem=False):
3906 Get bounding box of the specified object(s)
3909 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3910 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3911 *False* specifies that *objects* are nodes
3914 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3917 :meth:`GetBoundingBox()`
3920 result = self.GetBoundingBox(objects, isElem)
3924 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3927 def GetBoundingBox(self, objects=None, isElem=False):
3929 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3932 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3933 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3934 False means that *objects* are nodes
3937 :class:`SMESH.Measure` structure
3940 :meth:`BoundingBox()`
3944 objects = [self.mesh]
3945 elif isinstance(objects, tuple):
3946 objects = list(objects)
3947 if not isinstance(objects, list):
3949 if len(objects) > 0 and isinstance(objects[0], int):
3952 unRegister = genObjUnRegister()
3954 if isinstance(o, Mesh):
3955 srclist.append(o.mesh)
3956 elif hasattr(o, "_narrow"):
3957 src = o._narrow(SMESH.SMESH_IDSource)
3958 if src: srclist.append(src)
3960 elif isinstance(o, list):
3962 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3964 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3965 unRegister.set( srclist[-1] )
3968 aMeasurements = self.smeshpyD.CreateMeasurements()
3969 unRegister.set( aMeasurements )
3970 aMeasure = aMeasurements.BoundingBox(srclist)
3973 # Mesh edition (SMESH_MeshEditor functionality):
3974 # ---------------------------------------------
3976 def RemoveElements(self, IDsOfElements):
3978 Remove the elements from the mesh by ids
3981 IDsOfElements: is a list of ids of elements to remove
3987 This operation can create gaps in numeration of elements.
3988 Call :meth:`RenumberElements` to remove the gaps.
3991 return self.editor.RemoveElements(IDsOfElements)
3993 def RemoveNodes(self, IDsOfNodes):
3995 Remove nodes from mesh by ids
3998 IDsOfNodes: is a list of ids of nodes to remove
4004 This operation can create gaps in numeration of nodes.
4005 Call :meth:`RenumberElements` to remove the gaps.
4008 return self.editor.RemoveNodes(IDsOfNodes)
4010 def RemoveOrphanNodes(self):
4012 Remove all orphan (free) nodes from mesh
4015 number of the removed nodes
4018 This operation can create gaps in numeration of nodes.
4019 Call :meth:`RenumberElements` to remove the gaps.
4022 return self.editor.RemoveOrphanNodes()
4024 def AddNode(self, x, y, z):
4026 Add a node to the mesh by coordinates
4032 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4033 if hasVars: self.mesh.SetParameters(Parameters)
4034 return self.editor.AddNode( x, y, z)
4036 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4038 Create a 0D element on a node with given number.
4041 IDOfNode: the ID of node for creation of the element.
4042 DuplicateElements: to add one more 0D element to a node or not
4045 ID of the new 0D element
4048 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4050 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4052 Create 0D elements on all nodes of the given elements except those
4053 nodes on which a 0D element already exists.
4056 theObject: an object on whose nodes 0D elements will be created.
4057 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4058 theGroupName: optional name of a group to add 0D elements created
4059 and/or found on nodes of *theObject*.
4060 DuplicateElements: to add one more 0D element to a node or not
4063 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4064 IDs of new and/or found 0D elements. IDs of 0D elements
4065 can be retrieved from the returned object by
4066 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4069 unRegister = genObjUnRegister()
4070 if isinstance( theObject, Mesh ):
4071 theObject = theObject.GetMesh()
4072 elif isinstance( theObject, list ):
4073 theObject = self.GetIDSource( theObject, SMESH.ALL )
4074 unRegister.set( theObject )
4075 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4077 def AddBall(self, IDOfNode, diameter):
4079 Create a ball element on a node with given ID.
4082 IDOfNode: the ID of node for creation of the element.
4083 diameter: the bal diameter.
4086 ID of the new ball element
4089 return self.editor.AddBall( IDOfNode, diameter )
4091 def AddEdge(self, IDsOfNodes):
4093 Create a linear or quadratic edge (this is determined
4094 by the number of given nodes).
4097 IDsOfNodes: list of node IDs for creation of the element.
4098 The order of nodes in this list should correspond to
4099 the :ref:`connectivity convention <connectivity_page>`.
4105 return self.editor.AddEdge(IDsOfNodes)
4107 def AddFace(self, IDsOfNodes):
4109 Create a linear or quadratic face (this is determined
4110 by the number of given nodes).
4113 IDsOfNodes: list of node IDs for creation of the element.
4114 The order of nodes in this list should correspond to
4115 the :ref:`connectivity convention <connectivity_page>`.
4121 return self.editor.AddFace(IDsOfNodes)
4123 def AddPolygonalFace(self, IdsOfNodes):
4125 Add a polygonal face defined by a list of node IDs
4128 IdsOfNodes: the list of node IDs for creation of the element.
4134 return self.editor.AddPolygonalFace(IdsOfNodes)
4136 def AddQuadPolygonalFace(self, IdsOfNodes):
4138 Add a quadratic polygonal face defined by a list of node IDs
4141 IdsOfNodes: the list of node IDs for creation of the element;
4142 corner nodes follow first.
4148 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4150 def AddVolume(self, IDsOfNodes):
4152 Create both simple and quadratic volume (this is determined
4153 by the number of given nodes).
4156 IDsOfNodes: list of node IDs for creation of the element.
4157 The order of nodes in this list should correspond to
4158 the :ref:`connectivity convention <connectivity_page>`.
4161 ID of the new volumic element
4164 return self.editor.AddVolume(IDsOfNodes)
4166 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4168 Create a volume of many faces, giving nodes for each face.
4171 IdsOfNodes: list of node IDs for volume creation, face by face.
4172 Quantities: list of integer values, Quantities[i]
4173 gives the quantity of nodes in face number i.
4176 ID of the new volumic element
4179 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4181 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4183 Create a volume of many faces, giving the IDs of the existing faces.
4186 The created volume will refer only to the nodes
4187 of the given faces, not to the faces themselves.
4190 IdsOfFaces: the list of face IDs for volume creation.
4193 ID of the new volumic element
4196 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4199 def SetNodeOnVertex(self, NodeID, Vertex):
4201 Bind a node to a vertex
4205 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4208 True if succeed else raises an exception
4211 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4212 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4216 self.editor.SetNodeOnVertex(NodeID, VertexID)
4217 except SALOME.SALOME_Exception as inst:
4218 raise ValueError(inst.details.text)
4222 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4224 Store the node position on an edge
4228 Edge: an edge (GEOM.GEOM_Object) or edge ID
4229 paramOnEdge: a parameter on the edge where the node is located
4232 True if succeed else raises an exception
4235 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4236 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4240 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4241 except SALOME.SALOME_Exception as inst:
4242 raise ValueError(inst.details.text)
4245 def SetNodeOnFace(self, NodeID, Face, u, v):
4247 Store node position on a face
4251 Face: a face (GEOM.GEOM_Object) or face ID
4252 u: U parameter on the face where the node is located
4253 v: V parameter on the face where the node is located
4256 True if succeed else raises an exception
4259 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4260 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4264 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4265 except SALOME.SALOME_Exception as inst:
4266 raise ValueError(inst.details.text)
4269 def SetNodeInVolume(self, NodeID, Solid):
4271 Bind a node to a solid
4275 Solid: a solid (GEOM.GEOM_Object) or solid ID
4278 True if succeed else raises an exception
4281 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4282 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4286 self.editor.SetNodeInVolume(NodeID, SolidID)
4287 except SALOME.SALOME_Exception as inst:
4288 raise ValueError(inst.details.text)
4291 def SetMeshElementOnShape(self, ElementID, Shape):
4293 Bind an element to a shape
4296 ElementID: an element ID
4297 Shape: a shape (GEOM.GEOM_Object) or shape ID
4300 True if succeed else raises an exception
4303 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4304 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4308 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4309 except SALOME.SALOME_Exception as inst:
4310 raise ValueError(inst.details.text)
4314 def MoveNode(self, NodeID, x, y, z):
4316 Move the node with the given id
4319 NodeID: the id of the node
4320 x: a new X coordinate
4321 y: a new Y coordinate
4322 z: a new Z coordinate
4325 True if succeed else False
4328 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4329 if hasVars: self.mesh.SetParameters(Parameters)
4330 return self.editor.MoveNode(NodeID, x, y, z)
4332 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4334 Find the node closest to a point and moves it to a point location
4337 x: the X coordinate of a point
4338 y: the Y coordinate of a point
4339 z: the Z coordinate of a point
4340 NodeID: if specified (>0), the node with this ID is moved,
4341 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4344 the ID of a moved node
4347 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4348 if hasVars: self.mesh.SetParameters(Parameters)
4349 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4351 def FindNodeClosestTo(self, x, y, z):
4353 Find the node closest to a point
4356 x: the X coordinate of a point
4357 y: the Y coordinate of a point
4358 z: the Z coordinate of a point
4364 return self.editor.FindNodeClosestTo(x, y, z)
4366 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4368 Find the elements where a point lays IN or ON
4371 x,y,z (float): coordinates of the point
4372 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4373 means elements of any type excluding nodes, discrete and 0D elements.
4374 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4377 list of IDs of found elements
4380 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4382 return self.editor.FindElementsByPoint(x, y, z, elementType)
4384 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4386 Project a point to a mesh object.
4387 Return ID of an element of given type where the given point is projected
4388 and coordinates of the projection point.
4389 In the case if nothing found, return -1 and []
4391 if isinstance( meshObject, Mesh ):
4392 meshObject = meshObject.GetMesh()
4394 meshObject = self.GetMesh()
4395 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4397 def GetPointState(self, x, y, z):
4399 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4400 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4401 UNKNOWN state means that either mesh is wrong or the analysis fails.
4404 return self.editor.GetPointState(x, y, z)
4406 def IsManifold(self):
4408 Check if a 2D mesh is manifold
4411 return self.editor.IsManifold()
4413 def IsCoherentOrientation2D(self):
4415 Check if orientation of 2D elements is coherent
4418 return self.editor.IsCoherentOrientation2D()
4420 def Get1DBranches( self, edges, startNode = 0 ):
4422 Partition given 1D elements into groups of contiguous edges.
4423 A node where number of meeting edges != 2 is a group end.
4424 An optional startNode is used to orient groups it belongs to.
4427 A list of edge groups and a list of corresponding node groups,
4428 where the group is a list of IDs of edges or elements, like follows
4429 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4430 If a group is closed, the first and last nodes of the group are same.
4432 if isinstance( edges, Mesh ):
4433 edges = edges.GetMesh()
4434 unRegister = genObjUnRegister()
4435 if isinstance( edges, list ):
4436 edges = self.GetIDSource( edges, SMESH.EDGE )
4437 unRegister.set( edges )
4438 return self.editor.Get1DBranches( edges, startNode )
4440 def FindSharpEdges( self, angle, addExisting=False ):
4442 Return sharp edges of faces and non-manifold ones.
4443 Optionally add existing edges.
4446 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4447 addExisting: to return existing edges (1D elements) as well
4450 list of FaceEdge structures
4452 angle = ParseParameters( angle )[0]
4453 return self.editor.FindSharpEdges( angle, addExisting )
4455 def MeshToPassThroughAPoint(self, x, y, z):
4457 Find the node closest to a point and moves it to a point location
4460 x: the X coordinate of a point
4461 y: the Y coordinate of a point
4462 z: the Z coordinate of a point
4465 the ID of a moved node
4468 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4470 def InverseDiag(self, NodeID1, NodeID2):
4472 Replace two neighbour triangles sharing Node1-Node2 link
4473 with the triangles built on the same 4 nodes but having other common link.
4476 NodeID1: the ID of the first node
4477 NodeID2: the ID of the second node
4480 False if proper faces were not found
4482 return self.editor.InverseDiag(NodeID1, NodeID2)
4484 def DeleteDiag(self, NodeID1, NodeID2):
4486 Replace two neighbour triangles sharing *Node1-Node2* link
4487 with a quadrangle built on the same 4 nodes.
4490 NodeID1: ID of the first node
4491 NodeID2: ID of the second node
4494 False if proper faces were not found
4497 This operation can create gaps in numeration of elements.
4498 Call :meth:`RenumberElements` to remove the gaps.
4501 return self.editor.DeleteDiag(NodeID1, NodeID2)
4503 def Reorient(self, IDsOfElements=None):
4505 Reorient elements by ids
4508 IDsOfElements: if undefined reorients all mesh elements
4511 True if succeed else False
4514 if IDsOfElements == None:
4515 IDsOfElements = self.GetElementsId()
4516 return self.editor.Reorient(IDsOfElements)
4518 def ReorientObject(self, theObject):
4520 Reorient all elements of the object
4523 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4526 True if succeed else False
4529 if ( isinstance( theObject, Mesh )):
4530 theObject = theObject.GetMesh()
4531 return self.editor.ReorientObject(theObject)
4533 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4535 Reorient faces contained in *the2DObject*.
4538 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4539 theDirection: a desired direction of normal of *theFace*.
4540 It can be either a GEOM vector or a list of coordinates [x,y,z].
4541 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4542 compared with theDirection. It can be either ID of face or a point
4543 by which the face will be found. The point can be given as either
4544 a GEOM vertex or a list of point coordinates.
4547 number of reoriented faces
4550 unRegister = genObjUnRegister()
4552 if isinstance( the2DObject, Mesh ):
4553 the2DObject = the2DObject.GetMesh()
4554 if isinstance( the2DObject, list ):
4555 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4556 unRegister.set( the2DObject )
4557 # check theDirection
4558 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4559 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4560 if isinstance( theDirection, list ):
4561 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4562 # prepare theFace and thePoint
4563 theFace = theFaceOrPoint
4564 thePoint = PointStruct(0,0,0)
4565 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4566 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4568 if isinstance( theFaceOrPoint, list ):
4569 thePoint = PointStruct( *theFaceOrPoint )
4571 if isinstance( theFaceOrPoint, PointStruct ):
4572 thePoint = theFaceOrPoint
4574 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4576 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4578 Reorient faces according to adjacent volumes.
4581 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4582 either IDs of faces or face groups.
4583 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4584 theOutsideNormal: to orient faces to have their normals
4585 pointing either *outside* or *inside* the adjacent volumes.
4588 number of reoriented faces.
4591 unRegister = genObjUnRegister()
4593 if not isinstance( the2DObject, list ):
4594 the2DObject = [ the2DObject ]
4595 elif the2DObject and isinstance( the2DObject[0], int ):
4596 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4597 unRegister.set( the2DObject )
4598 the2DObject = [ the2DObject ]
4599 for i,obj2D in enumerate( the2DObject ):
4600 if isinstance( obj2D, Mesh ):
4601 the2DObject[i] = obj2D.GetMesh()
4602 if isinstance( obj2D, list ):
4603 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4604 unRegister.set( the2DObject[i] )
4606 if isinstance( the3DObject, Mesh ):
4607 the3DObject = the3DObject.GetMesh()
4608 if isinstance( the3DObject, list ):
4609 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4610 unRegister.set( the3DObject )
4611 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4613 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4615 Fuse the neighbouring triangles into quadrangles.
4618 IDsOfElements: The triangles to be fused.
4619 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4620 applied to possible quadrangles to choose a neighbour to fuse with.
4621 Note that not all items of :class:`SMESH.FunctorType` corresponds
4622 to numerical functors.
4623 MaxAngle: is the maximum angle between element normals at which the fusion
4624 is still performed; theMaxAngle is measured in radians.
4625 Also it could be a name of variable which defines angle in degrees.
4628 True in case of success, False otherwise.
4631 This operation can create gaps in numeration of elements.
4632 Call :meth:`RenumberElements` to remove the gaps.
4635 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4636 self.mesh.SetParameters(Parameters)
4637 if not IDsOfElements:
4638 IDsOfElements = self.GetElementsId()
4639 Functor = self.smeshpyD.GetFunctor(theCriterion)
4640 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4642 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4644 Fuse the neighbouring triangles of the object into quadrangles
4647 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4648 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4649 applied to possible quadrangles to choose a neighbour to fuse with.
4650 Note that not all items of :class:`SMESH.FunctorType` corresponds
4651 to numerical functors.
4652 MaxAngle: a max angle between element normals at which the fusion
4653 is still performed; theMaxAngle is measured in radians.
4656 True in case of success, False otherwise.
4659 This operation can create gaps in numeration of elements.
4660 Call :meth:`RenumberElements` to remove the gaps.
4663 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4664 self.mesh.SetParameters(Parameters)
4665 if isinstance( theObject, Mesh ):
4666 theObject = theObject.GetMesh()
4667 Functor = self.smeshpyD.GetFunctor(theCriterion)
4668 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4670 def QuadToTri (self, IDsOfElements, theCriterion = None):
4672 Split quadrangles into triangles.
4675 IDsOfElements: the faces to be splitted.
4676 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4677 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4678 value, then quadrangles will be split by the smallest diagonal.
4679 Note that not all items of :class:`SMESH.FunctorType` corresponds
4680 to numerical functors.
4683 True in case of success, False otherwise.
4686 This operation can create gaps in numeration of elements.
4687 Call :meth:`RenumberElements` to remove the gaps.
4689 if IDsOfElements == []:
4690 IDsOfElements = self.GetElementsId()
4691 if theCriterion is None:
4692 theCriterion = FT_MaxElementLength2D
4693 Functor = self.smeshpyD.GetFunctor(theCriterion)
4694 return self.editor.QuadToTri(IDsOfElements, Functor)
4696 def QuadToTriObject (self, theObject, theCriterion = None):
4698 Split quadrangles into triangles.
4701 theObject: the object from which the list of elements is taken,
4702 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4703 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4704 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4705 value, then quadrangles will be split by the smallest diagonal.
4706 Note that not all items of :class:`SMESH.FunctorType` corresponds
4707 to numerical functors.
4710 True in case of success, False otherwise.
4713 This operation can create gaps in numeration of elements.
4714 Call :meth:`RenumberElements` to remove the gaps.
4716 if ( isinstance( theObject, Mesh )):
4717 theObject = theObject.GetMesh()
4718 if theCriterion is None:
4719 theCriterion = FT_MaxElementLength2D
4720 Functor = self.smeshpyD.GetFunctor(theCriterion)
4721 return self.editor.QuadToTriObject(theObject, Functor)
4723 def QuadTo4Tri (self, theElements=[]):
4725 Split each of given quadrangles into 4 triangles. A node is added at the center of
4729 theElements: the faces to be splitted. This can be either
4730 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4731 or a list of face IDs. By default all quadrangles are split
4734 This operation can create gaps in numeration of elements.
4735 Call :meth:`RenumberElements` to remove the gaps.
4737 unRegister = genObjUnRegister()
4738 if isinstance( theElements, Mesh ):
4739 theElements = theElements.mesh
4740 elif not theElements:
4741 theElements = self.mesh
4742 elif isinstance( theElements, list ):
4743 theElements = self.GetIDSource( theElements, SMESH.FACE )
4744 unRegister.set( theElements )
4745 return self.editor.QuadTo4Tri( theElements )
4747 def SplitQuad (self, IDsOfElements, Diag13):
4749 Split quadrangles into triangles.
4752 IDsOfElements: the faces to be splitted
4753 Diag13 (boolean): is used to choose a diagonal for splitting.
4756 True in case of success, False otherwise.
4759 This operation can create gaps in numeration of elements.
4760 Call :meth:`RenumberElements` to remove the gaps.
4762 if IDsOfElements == []:
4763 IDsOfElements = self.GetElementsId()
4764 return self.editor.SplitQuad(IDsOfElements, Diag13)
4766 def SplitQuadObject (self, theObject, Diag13):
4768 Split quadrangles into triangles.
4771 theObject: the object from which the list of elements is taken,
4772 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4773 Diag13 (boolean): is used to choose a diagonal for splitting.
4776 True in case of success, False otherwise.
4779 This operation can create gaps in numeration of elements.
4780 Call :meth:`RenumberElements` to remove the gaps.
4782 if ( isinstance( theObject, Mesh )):
4783 theObject = theObject.GetMesh()
4784 return self.editor.SplitQuadObject(theObject, Diag13)
4786 def BestSplit (self, IDOfQuad, theCriterion):
4788 Find a better splitting of the given quadrangle.
4791 IDOfQuad: the ID of the quadrangle to be splitted.
4792 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4793 choose a diagonal for splitting.
4794 Note that not all items of :class:`SMESH.FunctorType` corresponds
4795 to numerical functors.
4798 * 1 if 1-3 diagonal is better,
4799 * 2 if 2-4 diagonal is better,
4800 * 0 if error occurs.
4803 This operation can create gaps in numeration of elements.
4804 Call :meth:`RenumberElements` to remove the gaps.
4806 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4808 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4810 Split volumic elements into tetrahedrons
4813 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4814 method: flags passing splitting method:
4815 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4816 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4819 This operation can create gaps in numeration of elements.
4820 Call :meth:`RenumberElements` to remove the gaps.
4822 unRegister = genObjUnRegister()
4823 if isinstance( elems, Mesh ):
4824 elems = elems.GetMesh()
4825 if ( isinstance( elems, list )):
4826 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4827 unRegister.set( elems )
4828 self.editor.SplitVolumesIntoTetra(elems, method)
4831 def SplitBiQuadraticIntoLinear(self, elems=None):
4833 Split bi-quadratic elements into linear ones without creation of additional nodes:
4835 - bi-quadratic triangle will be split into 3 linear quadrangles;
4836 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4837 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4839 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4840 will be split in order to keep the mesh conformal.
4843 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4844 if None (default), all bi-quadratic elements will be split
4847 This operation can create gaps in numeration of elements.
4848 Call :meth:`RenumberElements` to remove the gaps.
4850 unRegister = genObjUnRegister()
4851 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4852 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4853 unRegister.set( elems )
4855 elems = [ self.GetMesh() ]
4856 if isinstance( elems, Mesh ):
4857 elems = [ elems.GetMesh() ]
4858 if not isinstance( elems, list ):
4860 self.editor.SplitBiQuadraticIntoLinear( elems )
4862 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4863 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4865 Split hexahedra into prisms
4868 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4869 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4870 gives a normal vector defining facets to split into triangles.
4871 *startHexPoint* can be either a triple of coordinates or a vertex.
4872 facetNormal: a normal to a facet to split into triangles of a
4873 hexahedron found by *startHexPoint*.
4874 *facetNormal* can be either a triple of coordinates or an edge.
4875 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4876 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4877 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4878 to *startHexPoint* are split, else *startHexPoint*
4879 is used to find the facet to split in all domains present in *elems*.
4882 This operation can create gaps in numeration of elements.
4883 Call :meth:`RenumberElements` to remove the gaps.
4886 unRegister = genObjUnRegister()
4887 if isinstance( elems, Mesh ):
4888 elems = elems.GetMesh()
4889 if ( isinstance( elems, list )):
4890 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4891 unRegister.set( elems )
4894 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4895 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4896 elif isinstance( startHexPoint, list ):
4897 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4900 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4901 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4902 elif isinstance( facetNormal, list ):
4903 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4906 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4908 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4910 def SplitQuadsNearTriangularFacets(self):
4912 Split quadrangle faces near triangular facets of volumes
4915 This operation can create gaps in numeration of elements.
4916 Call :meth:`RenumberElements` to remove the gaps.
4918 faces_array = self.GetElementsByType(SMESH.FACE)
4919 for face_id in faces_array:
4920 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4921 quad_nodes = self.mesh.GetElemNodes(face_id)
4922 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4923 isVolumeFound = False
4924 for node1_elem in node1_elems:
4925 if not isVolumeFound:
4926 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4927 nb_nodes = self.GetElemNbNodes(node1_elem)
4928 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4929 volume_elem = node1_elem
4930 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4931 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4932 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4933 isVolumeFound = True
4934 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4935 self.SplitQuad([face_id], False) # diagonal 2-4
4936 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4937 isVolumeFound = True
4938 self.SplitQuad([face_id], True) # diagonal 1-3
4939 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4940 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4941 isVolumeFound = True
4942 self.SplitQuad([face_id], True) # diagonal 1-3
4944 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4946 Split hexahedrons into tetrahedrons.
4948 This operation uses :doc:`pattern_mapping` functionality for splitting.
4951 theObject: the object from which the list of hexahedrons is taken;
4952 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4953 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4954 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4955 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4956 key-point will be mapped into *theNode001*-th node of each volume.
4957 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4960 True in case of success, False otherwise.
4963 This operation can create gaps in numeration of elements.
4964 Call :meth:`RenumberElements` to remove the gaps.
4972 # (0,0,1) 4.---------.7 * |
4979 # (0,0,0) 0.---------.3
4980 pattern_tetra = "!!! Nb of points: \n 8 \n\
4990 !!! Indices of points of 6 tetras: \n\
4998 pattern = self.smeshpyD.GetPattern()
4999 isDone = pattern.LoadFromFile(pattern_tetra)
5001 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5004 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5005 isDone = pattern.MakeMesh(self.mesh, False, False)
5006 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5008 # split quafrangle faces near triangular facets of volumes
5009 self.SplitQuadsNearTriangularFacets()
5013 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5015 Split hexahedrons into prisms.
5017 Uses the :doc:`pattern_mapping` functionality for splitting.
5020 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5021 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5022 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5023 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5024 will be mapped into the *theNode001* -th node of each volume.
5025 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5028 True in case of success, False otherwise.
5031 This operation can create gaps in numeration of elements.
5032 Call :meth:`RenumberElements` to remove the gaps.
5034 # Pattern: 5.---------.6
5039 # (0,0,1) 4.---------.7 |
5046 # (0,0,0) 0.---------.3
5047 pattern_prism = "!!! Nb of points: \n 8 \n\
5057 !!! Indices of points of 2 prisms: \n\
5061 pattern = self.smeshpyD.GetPattern()
5062 isDone = pattern.LoadFromFile(pattern_prism)
5064 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5067 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5068 isDone = pattern.MakeMesh(self.mesh, False, False)
5069 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5071 # Split quafrangle faces near triangular facets of volumes
5072 self.SplitQuadsNearTriangularFacets()
5076 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5077 MaxNbOfIterations, MaxAspectRatio, Method):
5082 IDsOfElements: the list if ids of elements to smooth
5083 IDsOfFixedNodes: the list of ids of fixed nodes.
5084 Note that nodes built on edges and boundary nodes are always fixed.
5085 MaxNbOfIterations: the maximum number of iterations
5086 MaxAspectRatio: varies in range [1.0, inf]
5087 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5088 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5091 True in case of success, False otherwise.
5094 if IDsOfElements == []:
5095 IDsOfElements = self.GetElementsId()
5096 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5097 self.mesh.SetParameters(Parameters)
5098 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5099 MaxNbOfIterations, MaxAspectRatio, Method)
5101 def SmoothObject(self, theObject, IDsOfFixedNodes,
5102 MaxNbOfIterations, MaxAspectRatio, Method):
5104 Smooth elements which belong to the given object
5107 theObject: the object to smooth
5108 IDsOfFixedNodes: the list of ids of fixed nodes.
5109 Note that nodes built on edges and boundary nodes are always fixed.
5110 MaxNbOfIterations: the maximum number of iterations
5111 MaxAspectRatio: varies in range [1.0, inf]
5112 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5113 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5116 True in case of success, False otherwise.
5119 if ( isinstance( theObject, Mesh )):
5120 theObject = theObject.GetMesh()
5121 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5122 MaxNbOfIterations, MaxAspectRatio, Method)
5124 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5125 MaxNbOfIterations, MaxAspectRatio, Method):
5127 Parametrically smooth the given elements
5130 IDsOfElements: the list if ids of elements to smooth
5131 IDsOfFixedNodes: the list of ids of fixed nodes.
5132 Note that nodes built on edges and boundary nodes are always fixed.
5133 MaxNbOfIterations: the maximum number of iterations
5134 MaxAspectRatio: varies in range [1.0, inf]
5135 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5136 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5139 True in case of success, False otherwise.
5142 if IDsOfElements == []:
5143 IDsOfElements = self.GetElementsId()
5144 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5145 self.mesh.SetParameters(Parameters)
5146 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5147 MaxNbOfIterations, MaxAspectRatio, Method)
5149 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5150 MaxNbOfIterations, MaxAspectRatio, Method):
5152 Parametrically smooth the elements which belong to the given object
5155 theObject: the object to smooth
5156 IDsOfFixedNodes: the list of ids of fixed nodes.
5157 Note that nodes built on edges and boundary nodes are always fixed.
5158 MaxNbOfIterations: the maximum number of iterations
5159 MaxAspectRatio: varies in range [1.0, inf]
5160 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5161 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5164 True in case of success, False otherwise.
5167 if ( isinstance( theObject, Mesh )):
5168 theObject = theObject.GetMesh()
5169 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5170 MaxNbOfIterations, MaxAspectRatio, Method)
5172 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5174 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5175 them with quadratic with the same id.
5178 theForce3d: method of new node creation:
5180 * False - the medium node lies at the geometrical entity from which the mesh element is built
5181 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5182 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5183 theToBiQuad: If True, converts the mesh to bi-quadratic
5186 :class:`SMESH.ComputeError` which can hold a warning
5189 If *theSubMesh* is provided, the mesh can become non-conformal
5192 This operation can create gaps in numeration of nodes or elements.
5193 Call :meth:`RenumberElements` to remove the gaps.
5196 if isinstance( theSubMesh, Mesh ):
5197 theSubMesh = theSubMesh.mesh
5199 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5202 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5204 self.editor.ConvertToQuadratic(theForce3d)
5205 error = self.editor.GetLastError()
5206 if error and error.comment:
5207 print(error.comment)
5210 def ConvertFromQuadratic(self, theSubMesh=None):
5212 Convert the mesh from quadratic to ordinary,
5213 deletes old quadratic elements,
5214 replacing them with ordinary mesh elements with the same id.
5217 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5220 If *theSubMesh* is provided, the mesh can become non-conformal
5223 This operation can create gaps in numeration of nodes or elements.
5224 Call :meth:`RenumberElements` to remove the gaps.
5228 self.editor.ConvertFromQuadraticObject(theSubMesh)
5230 return self.editor.ConvertFromQuadratic()
5232 def Make2DMeshFrom3D(self):
5234 Create 2D mesh as skin on boundary faces of a 3D mesh
5237 True if operation has been completed successfully, False otherwise
5240 return self.editor.Make2DMeshFrom3D()
5242 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5243 toCopyElements=False, toCopyExistingBondary=False):
5245 Create missing boundary elements
5248 elements: elements whose boundary is to be checked:
5249 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5250 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5251 dimension: defines type of boundary elements to create, either of
5252 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5253 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5254 groupName: a name of group to store created boundary elements in,
5255 "" means not to create the group
5256 meshName: a name of new mesh to store created boundary elements in,
5257 "" means not to create the new mesh
5258 toCopyElements: if True, the checked elements will be copied into
5259 the new mesh else only boundary elements will be copied into the new mesh
5260 toCopyExistingBondary: if True, not only new but also pre-existing
5261 boundary elements will be copied into the new mesh
5264 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5267 unRegister = genObjUnRegister()
5268 if isinstance( elements, Mesh ):
5269 elements = elements.GetMesh()
5270 if ( isinstance( elements, list )):
5271 elemType = SMESH.ALL
5272 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5273 elements = self.editor.MakeIDSource(elements, elemType)
5274 unRegister.set( elements )
5275 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5276 toCopyElements,toCopyExistingBondary)
5277 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5280 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5281 toCopyAll=False, groups=[]):
5283 Create missing boundary elements around either the whole mesh or
5287 dimension: defines type of boundary elements to create, either of
5288 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5289 groupName: a name of group to store all boundary elements in,
5290 "" means not to create the group
5291 meshName: a name of a new mesh, which is a copy of the initial
5292 mesh + created boundary elements; "" means not to create the new mesh
5293 toCopyAll: if True, the whole initial mesh will be copied into
5294 the new mesh else only boundary elements will be copied into the new mesh
5295 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5298 tuple( long, mesh, group )
5299 - long - number of added boundary elements
5300 - mesh - the :class:`Mesh` where elements were added to
5301 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5304 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5306 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5307 return nb, mesh, group
5309 def RenumberNodes(self):
5311 Renumber mesh nodes to remove unused node IDs
5313 self.editor.RenumberNodes()
5315 def RenumberElements(self):
5317 Renumber mesh elements to remove unused element IDs
5319 self.editor.RenumberElements()
5321 def _getIdSourceList(self, arg, idType, unRegister):
5323 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5325 if arg and isinstance( arg, list ):
5326 if isinstance( arg[0], int ):
5327 arg = self.GetIDSource( arg, idType )
5328 unRegister.set( arg )
5329 elif isinstance( arg[0], Mesh ):
5330 arg[0] = arg[0].GetMesh()
5331 elif isinstance( arg, Mesh ):
5333 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5337 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5338 MakeGroups=False, TotalAngle=False):
5340 Generate new elements by rotation of the given elements and nodes around the axis
5343 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5344 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5345 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5346 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5347 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5348 which defines angle in degrees
5349 NbOfSteps: the number of steps
5350 Tolerance: tolerance
5351 MakeGroups: forces the generation of new groups from existing ones
5352 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5353 of all steps, else - size of each step
5356 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5359 unRegister = genObjUnRegister()
5360 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5361 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5362 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5364 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5365 Axis = self.smeshpyD.GetAxisStruct( Axis )
5366 if isinstance( Axis, list ):
5367 Axis = SMESH.AxisStruct( *Axis )
5369 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5370 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5371 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5372 self.mesh.SetParameters(Parameters)
5373 if TotalAngle and NbOfSteps:
5374 AngleInRadians /= NbOfSteps
5375 return self.editor.RotationSweepObjects( nodes, edges, faces,
5376 Axis, AngleInRadians,
5377 NbOfSteps, Tolerance, MakeGroups)
5379 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5380 MakeGroups=False, TotalAngle=False):
5382 Generate new elements by rotation of the elements around the axis
5385 IDsOfElements: the list of ids of elements to sweep
5386 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5387 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5388 NbOfSteps: the number of steps
5389 Tolerance: tolerance
5390 MakeGroups: forces the generation of new groups from existing ones
5391 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5392 of all steps, else - size of each step
5395 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5398 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5399 AngleInRadians, NbOfSteps, Tolerance,
5400 MakeGroups, TotalAngle)
5402 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5403 MakeGroups=False, TotalAngle=False):
5405 Generate new elements by rotation of the elements of object around the axis
5406 theObject object which elements should be sweeped.
5407 It can be a mesh, a sub mesh or a group.
5410 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5411 AngleInRadians: the angle of Rotation
5412 NbOfSteps: number of steps
5413 Tolerance: tolerance
5414 MakeGroups: forces the generation of new groups from existing ones
5415 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5416 of all steps, else - size of each step
5419 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5422 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5423 AngleInRadians, NbOfSteps, Tolerance,
5424 MakeGroups, TotalAngle )
5426 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5427 MakeGroups=False, TotalAngle=False):
5429 Generate new elements by rotation of the elements of object around the axis
5430 theObject object which elements should be sweeped.
5431 It can be a mesh, a sub mesh or a group.
5434 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5435 AngleInRadians: the angle of Rotation
5436 NbOfSteps: number of steps
5437 Tolerance: tolerance
5438 MakeGroups: forces the generation of new groups from existing ones
5439 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5440 of all steps, else - size of each step
5443 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5444 empty list otherwise
5447 return self.RotationSweepObjects([],theObject,[], Axis,
5448 AngleInRadians, NbOfSteps, Tolerance,
5449 MakeGroups, TotalAngle)
5451 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5452 MakeGroups=False, TotalAngle=False):
5454 Generate new elements by rotation of the elements of object around the axis
5455 theObject object which elements should be sweeped.
5456 It can be a mesh, a sub mesh or a group.
5459 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5460 AngleInRadians: the angle of Rotation
5461 NbOfSteps: number of steps
5462 Tolerance: tolerance
5463 MakeGroups: forces the generation of new groups from existing ones
5464 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5465 of all steps, else - size of each step
5468 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5471 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5472 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5474 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5475 scaleFactors=[], linearVariation=False, basePoint=[],
5476 angles=[], anglesVariation=False):
5478 Generate new elements by extrusion of the given elements and nodes
5481 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5482 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5483 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5484 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5485 the direction and value of extrusion for one step (the total extrusion
5486 length will be NbOfSteps * ||StepVector||)
5487 NbOfSteps: the number of steps
5488 MakeGroups: forces the generation of new groups from existing ones
5489 scaleFactors: optional scale factors to apply during extrusion
5490 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5491 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5492 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5493 nodes and elements being extruded is used as the scaling center.
5496 - a list of tree components of the point or
5499 angles: list of angles in radians. Nodes at each extrusion step are rotated
5500 around *basePoint*, additionally to previous steps.
5501 anglesVariation: forces the computation of rotation angles as linear
5502 variation of the given *angles* along path steps
5504 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5506 Example: :ref:`tui_extrusion`
5508 unRegister = genObjUnRegister()
5509 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5510 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5511 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5513 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5514 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5515 if isinstance( StepVector, list ):
5516 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5518 if isinstance( basePoint, int):
5519 xyz = self.GetNodeXYZ( basePoint )
5521 raise RuntimeError("Invalid node ID: %s" % basePoint)
5523 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5524 basePoint = self.geompyD.PointCoordinates( basePoint )
5526 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5527 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5528 angles,angleParameters,hasVars = ParseAngles(angles)
5529 Parameters = StepVector.PS.parameters + var_separator + \
5530 Parameters + var_separator + \
5531 scaleParameters + var_separator + angleParameters
5532 self.mesh.SetParameters(Parameters)
5534 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5535 StepVector, NbOfSteps, MakeGroups,
5536 scaleFactors, linearVariation, basePoint,
5537 angles, anglesVariation )
5540 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5542 Generate new elements by extrusion of the elements with given ids
5545 IDsOfElements: the list of ids of elements or nodes for extrusion
5546 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5547 the direction and value of extrusion for one step (the total extrusion
5548 length will be NbOfSteps * ||StepVector||)
5549 NbOfSteps: the number of steps
5550 MakeGroups: forces the generation of new groups from existing ones
5551 IsNodes: is True if elements with given ids are nodes
5554 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5556 Example: :ref:`tui_extrusion`
5559 if IsNodes: n = IDsOfElements
5560 else : e,f, = IDsOfElements,IDsOfElements
5561 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5563 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5564 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5566 Generate new elements by extrusion along the normal to a discretized surface or wire
5569 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5570 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5571 StepSize: length of one extrusion step (the total extrusion
5572 length will be *NbOfSteps* *StepSize*).
5573 NbOfSteps: number of extrusion steps.
5574 ByAverageNormal: if True each node is translated by *StepSize*
5575 along the average of the normal vectors to the faces sharing the node;
5576 else each node is translated along the same average normal till
5577 intersection with the plane got by translation of the face sharing
5578 the node along its own normal by *StepSize*.
5579 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5580 for every node of *Elements*.
5581 MakeGroups: forces generation of new groups from existing ones.
5582 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5583 is not yet implemented. This parameter is used if *Elements* contains
5584 both faces and edges, i.e. *Elements* is a Mesh.
5587 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5588 empty list otherwise.
5589 Example: :ref:`tui_extrusion`
5592 unRegister = genObjUnRegister()
5593 if isinstance( Elements, Mesh ):
5594 Elements = [ Elements.GetMesh() ]
5595 if isinstance( Elements, list ):
5597 raise RuntimeError("Elements empty!")
5598 if isinstance( Elements[0], int ):
5599 Elements = self.GetIDSource( Elements, SMESH.ALL )
5600 unRegister.set( Elements )
5601 if not isinstance( Elements, list ):
5602 Elements = [ Elements ]
5603 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5604 self.mesh.SetParameters(Parameters)
5605 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5606 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5608 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5610 Generate new elements by extrusion of the elements or nodes which belong to the object
5613 theObject: the object whose elements or nodes should be processed.
5614 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5615 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5616 the direction and value of extrusion for one step (the total extrusion
5617 length will be NbOfSteps * ||StepVector||)
5618 NbOfSteps: the number of steps
5619 MakeGroups: forces the generation of new groups from existing ones
5620 IsNodes: is True if elements to extrude are nodes
5623 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5624 Example: :ref:`tui_extrusion`
5628 if IsNodes: n = theObject
5629 else : e,f, = theObject,theObject
5630 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5632 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5634 Generate new elements by extrusion of edges which belong to the object
5637 theObject: object whose 1D elements should be processed.
5638 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5639 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5640 the direction and value of extrusion for one step (the total extrusion
5641 length will be NbOfSteps * ||StepVector||)
5642 NbOfSteps: the number of steps
5643 MakeGroups: to generate new groups from existing ones
5646 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5647 Example: :ref:`tui_extrusion`
5650 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5652 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5654 Generate new elements by extrusion of faces which belong to the object
5657 theObject: object whose 2D elements should be processed.
5658 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5659 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5660 the direction and value of extrusion for one step (the total extrusion
5661 length will be NbOfSteps * ||StepVector||)
5662 NbOfSteps: the number of steps
5663 MakeGroups: forces the generation of new groups from existing ones
5666 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5667 Example: :ref:`tui_extrusion`
5670 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5672 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5673 ExtrFlags, SewTolerance, MakeGroups=False):
5675 Generate new elements by extrusion of the elements with given ids
5678 IDsOfElements: is ids of elements
5679 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5680 the direction and value of extrusion for one step (the total extrusion
5681 length will be NbOfSteps * ||StepVector||)
5682 NbOfSteps: the number of steps
5683 ExtrFlags: sets flags for extrusion
5684 SewTolerance: uses for comparing locations of nodes if flag
5685 EXTRUSION_FLAG_SEW is set
5686 MakeGroups: forces the generation of new groups from existing ones
5689 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5692 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5693 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5694 if isinstance( StepVector, list ):
5695 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5696 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5697 ExtrFlags, SewTolerance, MakeGroups)
5699 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5700 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5701 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5702 ScaleFactors=[], ScalesVariation=False):
5704 Generate new elements by extrusion of the given elements and nodes along the path.
5705 The path of extrusion must be a meshed edge.
5708 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5709 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5710 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5711 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5712 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
5713 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5714 HasAngles: not used obsolete
5715 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5716 around *basePoint*, additionally to previous steps.
5717 LinearVariation: forces the computation of rotation angles as linear
5718 variation of the given Angles along path steps
5719 HasRefPoint: allows using the reference point
5720 RefPoint: optional scaling and rotation center (mass center of the extruded
5721 elements by default). The User can specify any point as the Reference Point.
5722 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5723 MakeGroups: forces the generation of new groups from existing ones
5724 ScaleFactors: optional scale factors to apply during extrusion
5725 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5726 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5729 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5730 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5731 Example: :ref:`tui_extrusion_along_path`
5734 unRegister = genObjUnRegister()
5735 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5736 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5737 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5739 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5740 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5741 if isinstance( RefPoint, list ):
5742 if not RefPoint: RefPoint = [0,0,0]
5743 RefPoint = SMESH.PointStruct( *RefPoint )
5744 if isinstance( PathObject, Mesh ):
5745 PathObject = PathObject.GetMesh()
5746 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5747 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5748 Parameters = AnglesParameters + var_separator + \
5749 RefPoint.parameters + var_separator + ScalesParameters
5750 self.mesh.SetParameters(Parameters)
5751 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5752 PathObject, PathShape, NodeStart,
5753 HasAngles, Angles, LinearVariation,
5754 HasRefPoint, RefPoint, MakeGroups,
5755 ScaleFactors, ScalesVariation)
5757 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5758 HasAngles=False, Angles=[], LinearVariation=False,
5759 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5760 ElemType=SMESH.FACE):
5762 Generate new elements by extrusion of the given elements.
5763 The path of extrusion must be a meshed edge.
5766 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5767 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5768 NodeStart: the start node from Path. Defines the direction of extrusion
5769 HasAngles: not used obsolete
5770 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5771 around *basePoint*, additionally to previous steps.
5772 LinearVariation: forces the computation of rotation angles as linear
5773 variation of the given Angles along path steps
5774 HasRefPoint: allows using the reference point
5775 RefPoint: the reference point around which the elements are rotated (the mass
5776 center of the elements by default).
5777 The User can specify any point as the Reference Point.
5778 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5779 MakeGroups: forces the generation of new groups from existing ones
5780 ElemType: type of elements for extrusion (if param Base is a mesh)
5783 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5784 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5785 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5787 Example: :ref:`tui_extrusion_along_path`
5791 if ElemType == SMESH.NODE: n = Base
5792 if ElemType == SMESH.EDGE: e = Base
5793 if ElemType == SMESH.FACE: f = Base
5794 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5795 HasAngles, Angles, LinearVariation,
5796 HasRefPoint, RefPoint, MakeGroups)
5797 if MakeGroups: return gr,er
5800 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5801 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5802 MakeGroups=False, LinearVariation=False):
5804 Generate new elements by extrusion of the given elements.
5805 The path of extrusion must be a meshed edge.
5808 IDsOfElements: ids of elements
5809 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5810 PathShape: shape (edge) defines the sub-mesh for the path
5811 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5812 HasAngles: not used obsolete
5813 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5814 around *basePoint*, additionally to previous steps.
5815 HasRefPoint: allows using the reference point
5816 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5817 The User can specify any point as the Reference Point.
5818 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5819 MakeGroups: forces the generation of new groups from existing ones
5820 LinearVariation: forces the computation of rotation angles as linear
5821 variation of the given Angles along path steps
5824 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5825 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5826 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5827 Example: :ref:`tui_extrusion_along_path`
5830 if not IDsOfElements:
5831 IDsOfElements = [ self.GetMesh() ]
5832 n,e,f = [],IDsOfElements,IDsOfElements
5833 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5834 NodeStart, HasAngles, Angles,
5836 HasRefPoint, RefPoint, MakeGroups)
5837 if MakeGroups: return gr,er
5840 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5841 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5842 MakeGroups=False, LinearVariation=False):
5844 Generate new elements by extrusion of the elements which belong to the object.
5845 The path of extrusion must be a meshed edge.
5848 theObject: the object whose elements should be processed.
5849 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5850 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5851 PathShape: shape (edge) defines the sub-mesh for the path
5852 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5853 HasAngles: not used obsolete
5854 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5855 around *basePoint*, additionally to previous steps.
5856 HasRefPoint: allows using the reference point
5857 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5858 The User can specify any point as the Reference Point.
5859 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5860 MakeGroups: forces the generation of new groups from existing ones
5861 LinearVariation: forces the computation of rotation angles as linear
5862 variation of the given Angles along path steps
5865 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5866 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5867 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5868 Example: :ref:`tui_extrusion_along_path`
5871 n,e,f = [],theObject,theObject
5872 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5873 HasAngles, Angles, LinearVariation,
5874 HasRefPoint, RefPoint, MakeGroups)
5875 if MakeGroups: return gr,er
5878 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5879 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5880 MakeGroups=False, LinearVariation=False):
5882 Generate new elements by extrusion of mesh segments which belong to the object.
5883 The path of extrusion must be a meshed edge.
5886 theObject: the object whose 1D elements should be processed.
5887 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5888 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5889 PathShape: shape (edge) defines the sub-mesh for the path
5890 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5891 HasAngles: not used obsolete
5892 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5893 around *basePoint*, additionally to previous steps.
5894 HasRefPoint: allows using the reference point
5895 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5896 The User can specify any point as the Reference Point.
5897 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5898 MakeGroups: forces the generation of new groups from existing ones
5899 LinearVariation: forces the computation of rotation angles as linear
5900 variation of the given Angles along path steps
5903 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5904 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5905 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5906 Example: :ref:`tui_extrusion_along_path`
5909 n,e,f = [],theObject,[]
5910 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5911 HasAngles, Angles, LinearVariation,
5912 HasRefPoint, RefPoint, MakeGroups)
5913 if MakeGroups: return gr,er
5916 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5917 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5918 MakeGroups=False, LinearVariation=False):
5920 Generate new elements by extrusion of faces which belong to the object.
5921 The path of extrusion must be a meshed edge.
5924 theObject: the object whose 2D elements should be processed.
5925 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5926 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5927 PathShape: shape (edge) defines the sub-mesh for the path
5928 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5929 HasAngles: not used obsolete
5930 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5931 around *basePoint*, additionally to previous steps.
5932 HasRefPoint: allows using the reference point
5933 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5934 The User can specify any point as the Reference Point.
5935 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5936 MakeGroups: forces the generation of new groups from existing ones
5937 LinearVariation: forces the computation of rotation angles as linear
5938 variation of the given Angles along path steps
5941 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5942 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5943 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5944 Example: :ref:`tui_extrusion_along_path`
5947 n,e,f = [],[],theObject
5948 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5949 HasAngles, Angles, LinearVariation,
5950 HasRefPoint, RefPoint, MakeGroups)
5951 if MakeGroups: return gr,er
5954 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5956 Create a symmetrical copy of mesh elements
5959 IDsOfElements: list of elements ids
5960 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5961 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5962 If the *Mirror* is a geom object this parameter is unnecessary
5963 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5964 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5967 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5970 if IDsOfElements == []:
5971 IDsOfElements = self.GetElementsId()
5972 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5973 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5974 theMirrorType = Mirror._mirrorType
5976 self.mesh.SetParameters(Mirror.parameters)
5977 if Copy and MakeGroups:
5978 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5979 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5982 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5984 Create a new mesh by a symmetrical copy of mesh elements
5987 IDsOfElements: the list of elements ids
5988 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5989 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5990 If the *Mirror* is a geom object this parameter is unnecessary
5991 MakeGroups: to generate new groups from existing ones
5992 NewMeshName: a name of the new mesh to create
5995 instance of class :class:`Mesh`
5998 if IDsOfElements == []:
5999 IDsOfElements = self.GetElementsId()
6000 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6001 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6002 theMirrorType = Mirror._mirrorType
6004 self.mesh.SetParameters(Mirror.parameters)
6005 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6006 MakeGroups, NewMeshName)
6007 return Mesh(self.smeshpyD,self.geompyD,mesh)
6009 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6011 Create a symmetrical copy of the object
6014 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6015 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6016 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6017 If the *Mirror* is a geom object this parameter is unnecessary
6018 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6019 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6022 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6025 if ( isinstance( theObject, Mesh )):
6026 theObject = theObject.GetMesh()
6027 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6028 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6029 theMirrorType = Mirror._mirrorType
6031 self.mesh.SetParameters(Mirror.parameters)
6032 if Copy and MakeGroups:
6033 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6034 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6037 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6039 Create a new mesh by a symmetrical copy of the object
6042 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6043 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6044 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6045 If the *Mirror* is a geom object this parameter is unnecessary
6046 MakeGroups: forces the generation of new groups from existing ones
6047 NewMeshName: the name of the new mesh to create
6050 instance of class :class:`Mesh`
6053 if ( isinstance( theObject, Mesh )):
6054 theObject = theObject.GetMesh()
6055 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6056 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6057 theMirrorType = Mirror._mirrorType
6059 self.mesh.SetParameters(Mirror.parameters)
6060 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6061 MakeGroups, NewMeshName)
6062 return Mesh( self.smeshpyD,self.geompyD,mesh )
6064 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6066 Translate the elements
6069 IDsOfElements: list of elements ids
6070 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6071 Copy: allows copying the translated elements
6072 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6075 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6078 if IDsOfElements == []:
6079 IDsOfElements = self.GetElementsId()
6080 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6081 Vector = self.smeshpyD.GetDirStruct(Vector)
6082 if isinstance( Vector, list ):
6083 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6084 self.mesh.SetParameters(Vector.PS.parameters)
6085 if Copy and MakeGroups:
6086 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6087 self.editor.Translate(IDsOfElements, Vector, Copy)
6090 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6092 Create a new mesh of translated elements
6095 IDsOfElements: list of elements ids
6096 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6097 MakeGroups: forces the generation of new groups from existing ones
6098 NewMeshName: the name of the newly created mesh
6101 instance of class :class:`Mesh`
6104 if IDsOfElements == []:
6105 IDsOfElements = self.GetElementsId()
6106 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6107 Vector = self.smeshpyD.GetDirStruct(Vector)
6108 if isinstance( Vector, list ):
6109 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6110 self.mesh.SetParameters(Vector.PS.parameters)
6111 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6112 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6114 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6116 Translate the object
6119 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6120 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6121 Copy: allows copying the translated elements
6122 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6125 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6128 if ( isinstance( theObject, Mesh )):
6129 theObject = theObject.GetMesh()
6130 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6131 Vector = self.smeshpyD.GetDirStruct(Vector)
6132 if isinstance( Vector, list ):
6133 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6134 self.mesh.SetParameters(Vector.PS.parameters)
6135 if Copy and MakeGroups:
6136 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6137 self.editor.TranslateObject(theObject, Vector, Copy)
6140 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6142 Create a new mesh from the translated object
6145 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6146 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6147 MakeGroups: forces the generation of new groups from existing ones
6148 NewMeshName: the name of the newly created mesh
6151 instance of class :class:`Mesh`
6154 if isinstance( theObject, Mesh ):
6155 theObject = theObject.GetMesh()
6156 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6157 Vector = self.smeshpyD.GetDirStruct(Vector)
6158 if isinstance( Vector, list ):
6159 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6160 self.mesh.SetParameters(Vector.PS.parameters)
6161 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6162 return Mesh( self.smeshpyD, self.geompyD, mesh )
6166 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6171 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6172 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6173 theScaleFact: list of 1-3 scale factors for axises
6174 Copy: allows copying the translated elements
6175 MakeGroups: forces the generation of new groups from existing
6179 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6180 empty list otherwise
6182 unRegister = genObjUnRegister()
6183 if ( isinstance( theObject, Mesh )):
6184 theObject = theObject.GetMesh()
6185 if ( isinstance( theObject, list )):
6186 theObject = self.GetIDSource(theObject, SMESH.ALL)
6187 unRegister.set( theObject )
6188 if ( isinstance( thePoint, list )):
6189 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6190 if ( isinstance( theScaleFact, float )):
6191 theScaleFact = [theScaleFact]
6192 if ( isinstance( theScaleFact, int )):
6193 theScaleFact = [ float(theScaleFact)]
6195 self.mesh.SetParameters(thePoint.parameters)
6197 if Copy and MakeGroups:
6198 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6199 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6202 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6204 Create a new mesh from the translated object
6207 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6208 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6209 theScaleFact: list of 1-3 scale factors for axises
6210 MakeGroups: forces the generation of new groups from existing ones
6211 NewMeshName: the name of the newly created mesh
6214 instance of class :class:`Mesh`
6216 unRegister = genObjUnRegister()
6217 if (isinstance(theObject, Mesh)):
6218 theObject = theObject.GetMesh()
6219 if ( isinstance( theObject, list )):
6220 theObject = self.GetIDSource(theObject,SMESH.ALL)
6221 unRegister.set( theObject )
6222 if ( isinstance( thePoint, list )):
6223 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6224 if ( isinstance( theScaleFact, float )):
6225 theScaleFact = [theScaleFact]
6226 if ( isinstance( theScaleFact, int )):
6227 theScaleFact = [ float(theScaleFact)]
6229 self.mesh.SetParameters(thePoint.parameters)
6230 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6231 MakeGroups, NewMeshName)
6232 return Mesh( self.smeshpyD, self.geompyD, mesh )
6236 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6241 IDsOfElements: list of elements ids
6242 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6243 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6244 Copy: allows copying the rotated elements
6245 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6248 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6252 if IDsOfElements == []:
6253 IDsOfElements = self.GetElementsId()
6254 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6255 Axis = self.smeshpyD.GetAxisStruct(Axis)
6256 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6257 Parameters = Axis.parameters + var_separator + Parameters
6258 self.mesh.SetParameters(Parameters)
6259 if Copy and MakeGroups:
6260 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6261 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6264 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6266 Create a new mesh of rotated elements
6269 IDsOfElements: list of element ids
6270 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6271 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6272 MakeGroups: forces the generation of new groups from existing ones
6273 NewMeshName: the name of the newly created mesh
6276 instance of class :class:`Mesh`
6279 if IDsOfElements == []:
6280 IDsOfElements = self.GetElementsId()
6281 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6282 Axis = self.smeshpyD.GetAxisStruct(Axis)
6283 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6284 Parameters = Axis.parameters + var_separator + Parameters
6285 self.mesh.SetParameters(Parameters)
6286 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6287 MakeGroups, NewMeshName)
6288 return Mesh( self.smeshpyD, self.geompyD, mesh )
6290 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6295 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6296 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6297 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6298 Copy: allows copying the rotated elements
6299 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6302 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6305 if (isinstance(theObject, Mesh)):
6306 theObject = theObject.GetMesh()
6307 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6308 Axis = self.smeshpyD.GetAxisStruct(Axis)
6309 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6310 Parameters = Axis.parameters + ":" + Parameters
6311 self.mesh.SetParameters(Parameters)
6312 if Copy and MakeGroups:
6313 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6314 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6317 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6319 Create a new mesh from the rotated object
6322 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6323 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6324 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6325 MakeGroups: forces the generation of new groups from existing ones
6326 NewMeshName: the name of the newly created mesh
6329 instance of class :class:`Mesh`
6332 if (isinstance( theObject, Mesh )):
6333 theObject = theObject.GetMesh()
6334 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6335 Axis = self.smeshpyD.GetAxisStruct(Axis)
6336 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6337 Parameters = Axis.parameters + ":" + Parameters
6338 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6339 MakeGroups, NewMeshName)
6340 self.mesh.SetParameters(Parameters)
6341 return Mesh( self.smeshpyD, self.geompyD, mesh )
6343 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6345 Create an offset mesh from the given 2D object
6348 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6349 theValue (float): signed offset size
6350 MakeGroups (boolean): forces the generation of new groups from existing ones
6351 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6352 False means to remove original elements.
6353 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6356 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6359 if isinstance( theObject, Mesh ):
6360 theObject = theObject.GetMesh()
6361 theValue,Parameters,hasVars = ParseParameters(Value)
6362 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6363 self.mesh.SetParameters(Parameters)
6364 # if mesh_groups[0]:
6365 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6368 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6370 Find groups of adjacent nodes within Tolerance.
6373 Tolerance (float): the value of tolerance
6374 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6375 corner and medium nodes in separate groups thus preventing
6376 their further merge.
6379 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6382 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6384 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6385 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6387 Find groups of adjacent nodes within Tolerance.
6390 Tolerance: the value of tolerance
6391 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6392 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6393 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6394 corner and medium nodes in separate groups thus preventing
6395 their further merge.
6398 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6401 unRegister = genObjUnRegister()
6402 if not isinstance( SubMeshOrGroup, list ):
6403 SubMeshOrGroup = [ SubMeshOrGroup ]
6404 for i,obj in enumerate( SubMeshOrGroup ):
6405 if isinstance( obj, Mesh ):
6406 SubMeshOrGroup = [ obj.GetMesh() ]
6408 if isinstance( obj, int ):
6409 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6410 unRegister.set( SubMeshOrGroup )
6413 if not isinstance( exceptNodes, list ):
6414 exceptNodes = [ exceptNodes ]
6415 if exceptNodes and isinstance( exceptNodes[0], int ):
6416 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6417 unRegister.set( exceptNodes )
6419 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6420 exceptNodes, SeparateCornerAndMediumNodes)
6422 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6427 GroupsOfNodes: a list of groups of nodes IDs for merging.
6428 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6429 in all elements and mesh groups by nodes 1 and 25 correspondingly
6430 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6431 If *NodesToKeep* does not include a node to keep for some group to merge,
6432 then the first node in the group is kept.
6433 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6437 This operation can create gaps in numeration of nodes or elements.
6438 Call :meth:`RenumberElements` to remove the gaps.
6440 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6442 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6444 Find the elements built on the same nodes.
6447 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6448 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6452 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6455 unRegister = genObjUnRegister()
6456 if MeshOrSubMeshOrGroup is None:
6457 MeshOrSubMeshOrGroup = [ self.mesh ]
6458 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6459 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6460 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6461 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6462 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6463 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6464 unRegister.set( MeshOrSubMeshOrGroup )
6465 for item in MeshOrSubMeshOrGroup:
6466 if isinstance( item, Mesh ):
6467 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6469 if not isinstance( exceptElements, list ):
6470 exceptElements = [ exceptElements ]
6471 if exceptElements and isinstance( exceptElements[0], int ):
6472 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6473 unRegister.set( exceptElements )
6475 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6477 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6479 Merge elements in each given group.
6482 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6483 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6484 replaced in all mesh groups by elements 1 and 25)
6485 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6486 If *ElementsToKeep* does not include an element to keep for some group to merge,
6487 then the first element in the group is kept.
6490 This operation can create gaps in numeration of elements.
6491 Call :meth:`RenumberElements` to remove the gaps.
6494 unRegister = genObjUnRegister()
6496 if not isinstance( ElementsToKeep, list ):
6497 ElementsToKeep = [ ElementsToKeep ]
6498 if isinstance( ElementsToKeep[0], int ):
6499 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6500 unRegister.set( ElementsToKeep )
6502 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6504 def MergeEqualElements(self):
6506 Leave one element and remove all other elements built on the same nodes.
6509 This operation can create gaps in numeration of elements.
6510 Call :meth:`RenumberElements` to remove the gaps.
6513 self.editor.MergeEqualElements()
6515 def FindFreeBorders(self, ClosedOnly=True):
6517 Returns all or only closed free borders
6520 list of SMESH.FreeBorder's
6523 return self.editor.FindFreeBorders( ClosedOnly )
6525 def FillHole(self, holeNodes, groupName=""):
6527 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6530 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6531 must describe all sequential nodes of the hole border. The first and the last
6532 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6533 groupName (string): name of a group to add new faces
6535 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6539 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6540 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6541 if not isinstance( holeNodes, SMESH.FreeBorder ):
6542 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6543 return self.editor.FillHole( holeNodes, groupName )
6545 def FindCoincidentFreeBorders (self, tolerance=0.):
6547 Return groups of FreeBorder's coincident within the given tolerance.
6550 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6551 size of elements adjacent to free borders being compared is used.
6554 SMESH.CoincidentFreeBorders structure
6557 return self.editor.FindCoincidentFreeBorders( tolerance )
6559 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6561 Sew FreeBorder's of each group
6564 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6565 where each enclosed list contains node IDs of a group of coincident free
6566 borders such that each consequent triple of IDs within a group describes
6567 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6568 last node of a border.
6569 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6570 groups of coincident free borders, each group including two borders.
6571 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6572 polygons if a node of opposite border falls on a face edge, else such
6573 faces are split into several ones.
6574 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6575 polyhedra if a node of opposite border falls on a volume edge, else such
6576 volumes, if any, remain intact and the mesh becomes non-conformal.
6579 a number of successfully sewed groups
6582 This operation can create gaps in numeration of nodes or elements.
6583 Call :meth:`RenumberElements` to remove the gaps.
6586 if freeBorders and isinstance( freeBorders, list ):
6587 # construct SMESH.CoincidentFreeBorders
6588 if isinstance( freeBorders[0], int ):
6589 freeBorders = [freeBorders]
6591 coincidentGroups = []
6592 for nodeList in freeBorders:
6593 if not nodeList or len( nodeList ) % 3:
6594 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6597 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6598 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6599 nodeList = nodeList[3:]
6601 coincidentGroups.append( group )
6603 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6605 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6607 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6608 FirstNodeID2, SecondNodeID2, LastNodeID2,
6609 CreatePolygons, CreatePolyedrs):
6614 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6617 This operation can create gaps in numeration of nodes or elements.
6618 Call :meth:`RenumberElements` to remove the gaps.
6621 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6622 FirstNodeID2, SecondNodeID2, LastNodeID2,
6623 CreatePolygons, CreatePolyedrs)
6625 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6626 FirstNodeID2, SecondNodeID2):
6628 Sew conform free borders
6631 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6634 This operation can create gaps in numeration of elements.
6635 Call :meth:`RenumberElements` to remove the gaps.
6638 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6639 FirstNodeID2, SecondNodeID2)
6641 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6642 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6647 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6650 This operation can create gaps in numeration of elements.
6651 Call :meth:`RenumberElements` to remove the gaps.
6654 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6655 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6657 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6658 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6659 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6661 Sew two sides of a mesh. The nodes belonging to Side1 are
6662 merged with the nodes of elements of Side2.
6663 The number of elements in theSide1 and in theSide2 must be
6664 equal and they should have similar nodal connectivity.
6665 The nodes to merge should belong to side borders and
6666 the first node should be linked to the second.
6669 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6672 This operation can create gaps in numeration of nodes.
6673 Call :meth:`RenumberElements` to remove the gaps.
6676 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6677 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6678 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6680 def ChangeElemNodes(self, ide, newIDs):
6682 Set new nodes for the given element. Number of nodes should be kept.
6689 False if the number of nodes does not correspond to the type of element
6692 return self.editor.ChangeElemNodes(ide, newIDs)
6694 def GetLastCreatedNodes(self):
6696 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6697 created, this method return the list of their IDs.
6698 If new nodes were not created - return empty list
6701 the list of integer values (can be empty)
6704 return self.editor.GetLastCreatedNodes()
6706 def GetLastCreatedElems(self):
6708 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6709 created this method return the list of their IDs.
6710 If new elements were not created - return empty list
6713 the list of integer values (can be empty)
6716 return self.editor.GetLastCreatedElems()
6718 def ClearLastCreated(self):
6720 Forget what nodes and elements were created by the last mesh edition operation
6723 self.editor.ClearLastCreated()
6725 def DoubleElements(self, theElements, theGroupName=""):
6727 Create duplicates of given elements, i.e. create new elements based on the
6728 same nodes as the given ones.
6731 theElements: container of elements to duplicate. It can be a
6732 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6733 or a list of element IDs. If *theElements* is
6734 a :class:`Mesh`, elements of highest dimension are duplicated
6735 theGroupName: a name of group to contain the generated elements.
6736 If a group with such a name already exists, the new elements
6737 are added to the existing group, else a new group is created.
6738 If *theGroupName* is empty, new elements are not added
6742 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6743 None if *theGroupName* == "".
6746 unRegister = genObjUnRegister()
6747 if isinstance( theElements, Mesh ):
6748 theElements = theElements.mesh
6749 elif isinstance( theElements, list ):
6750 theElements = self.GetIDSource( theElements, SMESH.ALL )
6751 unRegister.set( theElements )
6752 return self.editor.DoubleElements(theElements, theGroupName)
6754 def DoubleNodes(self, theNodes, theModifiedElems):
6756 Create a hole in a mesh by doubling the nodes of some particular elements
6759 theNodes: IDs of nodes to be doubled
6760 theModifiedElems: IDs of elements to be updated by the new (doubled)
6761 nodes. If list of element identifiers is empty then nodes are doubled but
6762 they not assigned to elements
6765 True if operation has been completed successfully, False otherwise
6768 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6770 def DoubleNode(self, theNodeId, theModifiedElems):
6772 Create a hole in a mesh by doubling the nodes of some particular elements.
6773 This method provided for convenience works as :meth:`DoubleNodes`.
6776 theNodeId: IDs of node to double
6777 theModifiedElems: IDs of elements to update
6780 True if operation has been completed successfully, False otherwise
6783 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6785 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6787 Create a hole in a mesh by doubling the nodes of some particular elements.
6788 This method provided for convenience works as :meth:`DoubleNodes`.
6791 theNodes: group of nodes to double.
6792 theModifiedElems: group of elements to update.
6793 theMakeGroup: forces the generation of a group containing new nodes.
6796 True or a created group if operation has been completed successfully,
6797 False or None otherwise
6801 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6802 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6804 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6806 Create a hole in a mesh by doubling the nodes of some particular elements.
6807 This method provided for convenience works as :meth:`DoubleNodes`.
6810 theNodes: list of groups of nodes to double.
6811 theModifiedElems: list of groups of elements to update.
6812 theMakeGroup: forces the generation of a group containing new nodes.
6815 True if operation has been completed successfully, False otherwise
6819 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6820 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6822 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6824 Create a hole in a mesh by doubling the nodes of some particular elements
6827 theElems: the list of elements (edges or faces) to replicate.
6828 The nodes for duplication could be found from these elements
6829 theNodesNot: list of nodes NOT to replicate
6830 theAffectedElems: the list of elements (cells and edges) to which the
6831 replicated nodes should be associated to
6834 True if operation has been completed successfully, False otherwise
6837 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6839 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6841 Create a hole in a mesh by doubling the nodes of some particular elements
6844 theElems: the list of elements (edges or faces) to replicate.
6845 The nodes for duplication could be found from these elements
6846 theNodesNot: list of nodes NOT to replicate
6847 theShape: shape to detect affected elements (element which geometric center
6848 located on or inside shape).
6849 The replicated nodes should be associated to affected elements.
6852 True if operation has been completed successfully, False otherwise
6855 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6857 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6858 theMakeGroup=False, theMakeNodeGroup=False):
6860 Create a hole in a mesh by doubling the nodes of some particular elements.
6861 This method provided for convenience works as :meth:`DoubleNodes`.
6864 theElems: group of of elements (edges or faces) to replicate.
6865 theNodesNot: group of nodes NOT to replicate.
6866 theAffectedElems: group of elements to which the replicated nodes
6867 should be associated to.
6868 theMakeGroup: forces the generation of a group containing new elements.
6869 theMakeNodeGroup: forces the generation of a group containing new nodes.
6872 True or created groups (one or two) if operation has been completed successfully,
6873 False or None otherwise
6876 if theMakeGroup or theMakeNodeGroup:
6877 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6879 theMakeGroup, theMakeNodeGroup)
6880 if theMakeGroup and theMakeNodeGroup:
6883 return twoGroups[ int(theMakeNodeGroup) ]
6884 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6886 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6888 Create a hole in a mesh by doubling the nodes of some particular elements.
6889 This method provided for convenience works as :meth:`DoubleNodes`.
6892 theElems: group of of elements (edges or faces) to replicate
6893 theNodesNot: group of nodes not to replicate
6894 theShape: shape to detect affected elements (element which geometric center
6895 located on or inside shape).
6896 The replicated nodes should be associated to affected elements
6899 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6901 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6902 theMakeGroup=False, theMakeNodeGroup=False):
6904 Create a hole in a mesh by doubling the nodes of some particular elements.
6905 This method provided for convenience works as :meth:`DoubleNodes`.
6908 theElems: list of groups of elements (edges or faces) to replicate
6909 theNodesNot: list of groups of nodes NOT to replicate
6910 theAffectedElems: group of elements to which the replicated nodes
6911 should be associated to
6912 theMakeGroup: forces generation of a group containing new elements.
6913 theMakeNodeGroup: forces generation of a group containing new nodes
6916 True or created groups (one or two) if operation has been completed successfully,
6917 False or None otherwise
6920 if theMakeGroup or theMakeNodeGroup:
6921 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6923 theMakeGroup, theMakeNodeGroup)
6924 if theMakeGroup and theMakeNodeGroup:
6927 return twoGroups[ int(theMakeNodeGroup) ]
6928 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6930 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6932 Create a hole in a mesh by doubling the nodes of some particular elements.
6933 This method provided for convenience works as :meth:`DoubleNodes`.
6936 theElems: list of groups of elements (edges or faces) to replicate
6937 theNodesNot: list of groups of nodes NOT to replicate
6938 theShape: shape to detect affected elements (element which geometric center
6939 located on or inside shape).
6940 The replicated nodes should be associated to affected elements
6943 True if operation has been completed successfully, False otherwise
6946 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6948 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6950 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6951 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6954 theElems: list of groups of nodes or elements (edges or faces) to replicate
6955 theNodesNot: list of groups of nodes NOT to replicate
6956 theShape: shape to detect affected elements (element which geometric center
6957 located on or inside shape).
6958 The replicated nodes should be associated to affected elements
6961 groups of affected elements in order: volumes, faces, edges
6964 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6966 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6969 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6970 The list of groups must describe a partition of the mesh volumes.
6971 The nodes of the internal faces at the boundaries of the groups are doubled.
6972 In option, the internal faces are replaced by flat elements.
6973 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6976 theDomains: list of groups of volumes
6977 createJointElems: if True, create the elements
6978 onAllBoundaries: if True, the nodes and elements are also created on
6979 the boundary between *theDomains* and the rest mesh
6982 True if operation has been completed successfully, False otherwise
6985 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6987 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6989 Double nodes on some external faces and create flat elements.
6990 Flat elements are mainly used by some types of mechanic calculations.
6992 Each group of the list must be constituted of faces.
6993 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6996 theGroupsOfFaces: list of groups of faces
6999 True if operation has been completed successfully, False otherwise
7002 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7004 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7006 Identify all the elements around a geom shape, get the faces delimiting the hole
7008 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7010 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7012 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7013 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7014 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7015 If there are several paths connecting a pair of points, the shortest path is
7016 selected by the module. Position of the cutting plane is defined by the two
7017 points and an optional vector lying on the plane specified by a PolySegment.
7018 By default the vector is defined by Mesh module as following. A middle point
7019 of the two given points is computed. The middle point is projected to the mesh.
7020 The vector goes from the middle point to the projection point. In case of planar
7021 mesh, the vector is normal to the mesh.
7023 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7026 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7027 groupName: optional name of a group where created mesh segments will be added.
7030 editor = self.editor
7032 editor = self.mesh.GetMeshEditPreviewer()
7033 segmentsRes = editor.MakePolyLine( segments, groupName )
7034 for i, seg in enumerate( segmentsRes ):
7035 segments[i].vector = seg.vector
7037 return editor.GetPreviewData()
7040 def MakeSlot(self, segmentGroup, width ):
7042 Create a slot of given width around given 1D elements lying on a triangle mesh.
7043 The slot is constructed by cutting faces by cylindrical surfaces made
7044 around each segment. Segments are expected to be created by MakePolyLine().
7047 FaceEdge's located at the slot boundary
7049 return self.editor.MakeSlot( segmentGroup, width )
7051 def GetFunctor(self, funcType ):
7053 Return a cached numerical functor by its type.
7056 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7057 Note that not all items correspond to numerical functors.
7060 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7063 fn = self.functors[ funcType._v ]
7065 fn = self.smeshpyD.GetFunctor(funcType)
7066 fn.SetMesh(self.mesh)
7067 self.functors[ funcType._v ] = fn
7070 def FunctorValue(self, funcType, elemId, isElem=True):
7072 Return value of a functor for a given element
7075 funcType: an item of :class:`SMESH.FunctorType` enum.
7076 elemId: element or node ID
7077 isElem: *elemId* is ID of element or node
7080 the functor value or zero in case of invalid arguments
7083 fn = self.GetFunctor( funcType )
7084 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7085 val = fn.GetValue(elemId)
7090 def GetLength(self, elemId=None):
7092 Get length of given 1D elements or of all 1D mesh elements
7095 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum length of all 1D elements will be calculated.
7098 Sum of lengths of given elements
7103 length = self.smeshpyD.GetLength(self)
7104 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7105 length = self.smeshpyD.GetLength(elemId)
7108 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7110 length += self.smeshpyD.GetLength(obj)
7111 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7112 unRegister = genObjUnRegister()
7113 obj = self.GetIDSource( elemId )
7114 unRegister.set( obj )
7115 length = self.smeshpyD.GetLength( obj )
7117 length = self.FunctorValue(SMESH.FT_Length, elemId)
7120 def GetArea(self, elemId=None):
7122 Get area of given 2D elements or of all 2D mesh elements
7125 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum area of all 2D elements will be calculated.
7128 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7133 area = self.smeshpyD.GetArea(self)
7134 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7135 area = self.smeshpyD.GetArea(elemId)
7138 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7140 area += self.smeshpyD.GetArea(obj)
7141 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7142 unRegister = genObjUnRegister()
7143 obj = self.GetIDSource( elemId )
7144 unRegister.set( obj )
7145 area = self.smeshpyD.GetArea( obj )
7147 area = self.FunctorValue(SMESH.FT_Area, elemId)
7150 def GetVolume(self, elemId=None):
7152 Get volume of given 3D elements or of all 3D mesh elements
7155 elemId: either a mesh element ID or a list of IDs or :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`. By default sum volume of all 3D elements will be calculated.
7158 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7163 volume= self.smeshpyD.GetVolume(self)
7164 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7165 volume= self.smeshpyD.GetVolume(elemId)
7168 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7170 volume+= self.smeshpyD.GetVolume(obj)
7171 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7172 unRegister = genObjUnRegister()
7173 obj = self.GetIDSource( elemId )
7174 unRegister.set( obj )
7175 volume= self.smeshpyD.GetVolume( obj )
7177 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7180 def GetAngle(self, node1, node2, node3 ):
7182 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7185 node1,node2,node3: IDs of the three nodes
7188 Angle in radians [0,PI]. -1 if failure case.
7190 p1 = self.GetNodeXYZ( node1 )
7191 p2 = self.GetNodeXYZ( node2 )
7192 p3 = self.GetNodeXYZ( node3 )
7193 if p1 and p2 and p3:
7194 return self.smeshpyD.GetAngle( p1,p2,p3 )
7198 def GetMaxElementLength(self, elemId):
7200 Get maximum element length.
7203 elemId: mesh element ID
7206 element's maximum length value
7209 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7210 ftype = SMESH.FT_MaxElementLength3D
7212 ftype = SMESH.FT_MaxElementLength2D
7213 return self.FunctorValue(ftype, elemId)
7215 def GetAspectRatio(self, elemId):
7217 Get aspect ratio of 2D or 3D element.
7220 elemId: mesh element ID
7223 element's aspect ratio value
7226 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7227 ftype = SMESH.FT_AspectRatio3D
7229 ftype = SMESH.FT_AspectRatio
7230 return self.FunctorValue(ftype, elemId)
7232 def GetWarping(self, elemId):
7234 Get warping angle of 2D element.
7237 elemId: mesh element ID
7240 element's warping angle value
7243 return self.FunctorValue(SMESH.FT_Warping, elemId)
7245 def GetMinimumAngle(self, elemId):
7247 Get minimum angle of 2D element.
7250 elemId: mesh element ID
7253 element's minimum angle value
7256 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7258 def GetTaper(self, elemId):
7260 Get taper of 2D element.
7263 elemId: mesh element ID
7266 element's taper value
7269 return self.FunctorValue(SMESH.FT_Taper, elemId)
7271 def GetSkew(self, elemId):
7273 Get skew of 2D element.
7276 elemId: mesh element ID
7279 element's skew value
7282 return self.FunctorValue(SMESH.FT_Skew, elemId)
7284 def GetMinMax(self, funType, meshPart=None):
7286 Return minimal and maximal value of a given functor.
7289 funType (SMESH.FunctorType): a functor type.
7290 Note that not all items of :class:`SMESH.FunctorType` corresponds
7291 to numerical functors.
7292 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7298 unRegister = genObjUnRegister()
7299 if isinstance( meshPart, list ):
7300 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7301 unRegister.set( meshPart )
7302 if isinstance( meshPart, Mesh ):
7303 meshPart = meshPart.mesh
7304 fun = self.GetFunctor( funType )
7307 if hasattr( meshPart, "SetMesh" ):
7308 meshPart.SetMesh( self.mesh ) # set mesh to filter
7309 hist = fun.GetLocalHistogram( 1, False, meshPart )
7311 hist = fun.GetHistogram( 1, False )
7313 return hist[0].min, hist[0].max
7316 pass # end of Mesh class
7319 class meshProxy(SMESH._objref_SMESH_Mesh):
7321 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7322 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7324 def __init__(self,*args):
7325 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7326 def __deepcopy__(self, memo=None):
7327 new = self.__class__(self)
7329 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7330 if len( args ) == 3:
7331 args += SMESH.ALL_NODES, True
7332 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7333 def ExportToMEDX(self, *args): # function removed
7334 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7335 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7336 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7337 def ExportToMED(self, *args): # function removed
7338 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7339 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7341 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7343 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7344 def ExportPartToMED(self, *args): # 'version' parameter removed
7345 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7346 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7347 def ExportMED(self, *args): # signature of method changed
7348 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7350 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7352 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7354 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7357 class submeshProxy(SMESH._objref_SMESH_subMesh):
7360 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7362 def __init__(self,*args):
7363 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7365 def __deepcopy__(self, memo=None):
7366 new = self.__class__(self)
7369 def Compute(self,refresh=False):
7371 Compute the sub-mesh and return the status of the computation
7374 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7379 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7380 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7384 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7386 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7388 if salome.sg.hasDesktop():
7389 if refresh: salome.sg.updateObjBrowser()
7394 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7397 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7399 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7400 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7403 def __init__(self,*args):
7404 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7406 def __getattr__(self, name ): # method called if an attribute not found
7407 if not self.mesh: # look for name() method in Mesh class
7408 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7409 if hasattr( self.mesh, name ):
7410 return getattr( self.mesh, name )
7411 if name == "ExtrusionAlongPathObjX":
7412 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7413 print("meshEditor: attribute '%s' NOT FOUND" % name)
7415 def __deepcopy__(self, memo=None):
7416 new = self.__class__(self)
7418 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7419 if len( args ) == 1: args += False,
7420 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7421 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7422 if len( args ) == 2: args += False,
7423 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7424 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7425 if len( args ) == 1:
7426 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7427 NodesToKeep = args[1]
7428 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7429 unRegister = genObjUnRegister()
7431 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7432 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7433 if not isinstance( NodesToKeep, list ):
7434 NodesToKeep = [ NodesToKeep ]
7435 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7437 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7439 class Pattern(SMESH._objref_SMESH_Pattern):
7441 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7442 variables in some methods
7445 def LoadFromFile(self, patternTextOrFile ):
7446 text = patternTextOrFile
7447 if os.path.exists( text ):
7448 text = open( patternTextOrFile ).read()
7450 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7452 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7453 decrFun = lambda i: i-1
7454 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7455 theMesh.SetParameters(Parameters)
7456 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7458 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7459 decrFun = lambda i: i-1
7460 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7461 theMesh.SetParameters(Parameters)
7462 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7464 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7465 if isinstance( mesh, Mesh ):
7466 mesh = mesh.GetMesh()
7467 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7469 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7471 Registering the new proxy for Pattern
7476 Private class used to bind methods creating algorithms to the class Mesh
7479 def __init__(self, method):
7481 self.defaultAlgoType = ""
7482 self.algoTypeToClass = {}
7483 self.method = method
7485 def add(self, algoClass):
7487 Store a python class of algorithm
7489 if inspect.isclass(algoClass) and \
7490 hasattr( algoClass, "algoType"):
7491 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7492 if not self.defaultAlgoType and \
7493 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7494 self.defaultAlgoType = algoClass.algoType
7495 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7497 def copy(self, mesh):
7499 Create a copy of self and assign mesh to the copy
7502 other = algoCreator( self.method )
7503 other.defaultAlgoType = self.defaultAlgoType
7504 other.algoTypeToClass = self.algoTypeToClass
7508 def __call__(self,algo="",geom=0,*args):
7510 Create an instance of algorithm
7514 if isinstance( algo, str ):
7516 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7517 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7522 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7524 elif not algoType and isinstance( geom, str ):
7529 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7531 elif isinstance( arg, str ) and not algoType:
7534 import traceback, sys
7535 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7536 sys.stderr.write( msg + '\n' )
7537 tb = traceback.extract_stack(None,2)
7538 traceback.print_list( [tb[0]] )
7540 algoType = self.defaultAlgoType
7541 if not algoType and self.algoTypeToClass:
7542 algoType = sorted( self.algoTypeToClass.keys() )[0]
7543 if algoType in self.algoTypeToClass:
7544 #print("Create algo",algoType)
7545 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7546 raise RuntimeError( "No class found for algo type %s" % algoType)
7549 class hypMethodWrapper:
7551 Private class used to substitute and store variable parameters of hypotheses.
7554 def __init__(self, hyp, method):
7556 self.method = method
7557 #print("REBIND:", method.__name__)
7560 def __call__(self,*args):
7562 call a method of hypothesis with calling SetVarParameter() before
7566 return self.method( self.hyp, *args ) # hypothesis method with no args
7568 #print("MethWrapper.__call__", self.method.__name__, args)
7570 parsed = ParseParameters(*args) # replace variables with their values
7571 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7572 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7573 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7574 # maybe there is a replaced string arg which is not variable
7575 result = self.method( self.hyp, *args )
7576 except ValueError as detail: # raised by ParseParameters()
7578 result = self.method( self.hyp, *args )
7579 except omniORB.CORBA.BAD_PARAM:
7580 raise ValueError(detail) # wrong variable name
7585 class genObjUnRegister:
7587 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7590 def __init__(self, genObj=None):
7591 self.genObjList = []
7595 def set(self, genObj):
7596 "Store one or a list of of SALOME.GenericObj'es"
7597 if isinstance( genObj, list ):
7598 self.genObjList.extend( genObj )
7600 self.genObjList.append( genObj )
7604 for genObj in self.genObjList:
7605 if genObj and hasattr( genObj, "UnRegister" ):
7608 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7610 Bind methods creating mesher plug-ins to the Mesh class
7613 # print("pluginName: ", pluginName)
7614 pluginBuilderName = pluginName + "Builder"
7616 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7617 except Exception as e:
7618 from salome_utils import verbose
7619 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7621 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7622 plugin = eval( pluginBuilderName )
7623 # print(" plugin:" , str(plugin))
7625 # add methods creating algorithms to Mesh
7626 for k in dir( plugin ):
7627 if k[0] == '_': continue
7628 algo = getattr( plugin, k )
7629 #print(" algo:", str(algo))
7630 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7631 #print(" meshMethod:" , str(algo.meshMethod))
7632 if not hasattr( Mesh, algo.meshMethod ):
7633 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7635 _mmethod = getattr( Mesh, algo.meshMethod )
7636 if hasattr( _mmethod, "add" ):