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 order in which concurrent sub-meshes should be meshed
2078 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2081 return self.mesh.SetMeshOrder(submeshes)
2083 def Clear(self, refresh=False):
2085 Remove all nodes and elements generated on geometry. Imported elements remain.
2088 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2092 if ( salome.sg.hasDesktop() ):
2093 if refresh: salome.sg.updateObjBrowser()
2095 def ClearSubMesh(self, geomId, refresh=False):
2097 Remove all nodes and elements of indicated shape
2100 geomId: the ID of a sub-shape to remove elements on
2101 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2104 self.mesh.ClearSubMesh(geomId)
2105 if salome.sg.hasDesktop():
2106 if refresh: salome.sg.updateObjBrowser()
2108 def AutomaticTetrahedralization(self, fineness=0):
2110 Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2113 fineness: [0.0,1.0] defines mesh fineness
2119 dim = self.MeshDimension()
2121 self.RemoveGlobalHypotheses()
2122 self.Segment().AutomaticLength(fineness)
2124 self.Triangle().LengthFromEdges()
2129 return self.Compute()
2131 def AutomaticHexahedralization(self, fineness=0):
2133 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2136 fineness: [0.0, 1.0] defines mesh fineness
2142 dim = self.MeshDimension()
2143 # assign the hypotheses
2144 self.RemoveGlobalHypotheses()
2145 self.Segment().AutomaticLength(fineness)
2152 return self.Compute()
2154 def AddHypothesis(self, hyp, geom=0):
2159 hyp: a hypothesis to assign
2160 geom: a subhape of mesh geometry
2163 :class:`SMESH.Hypothesis_Status`
2166 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2167 hyp, geom = geom, hyp
2168 if isinstance( hyp, Mesh_Algorithm ):
2169 hyp = hyp.GetAlgorithm()
2174 geom = self.mesh.GetShapeToMesh()
2177 if self.mesh.HasShapeToMesh():
2178 hyp_type = hyp.GetName()
2179 lib_name = hyp.GetLibName()
2180 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2181 # if checkAll and geom:
2182 # checkAll = geom.GetType() == 37
2184 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2186 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2187 status = self.mesh.AddHypothesis(geom, hyp)
2189 status = HYP_BAD_GEOMETRY, ""
2190 hyp_name = GetName( hyp )
2193 geom_name = geom.GetName()
2194 isAlgo = hyp._narrow( SMESH_Algo )
2195 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2198 def IsUsedHypothesis(self, hyp, geom):
2200 Return True if an algorithm or hypothesis is assigned to a given shape
2203 hyp: an algorithm or hypothesis to check
2204 geom: a subhape of mesh geometry
2210 if not hyp: # or not geom
2212 if isinstance( hyp, Mesh_Algorithm ):
2213 hyp = hyp.GetAlgorithm()
2215 hyps = self.GetHypothesisList(geom)
2217 if h.GetId() == hyp.GetId():
2221 def RemoveHypothesis(self, hyp, geom=0):
2223 Unassign a hypothesis
2226 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2227 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2230 :class:`SMESH.Hypothesis_Status`
2235 if isinstance( hyp, Mesh_Algorithm ):
2236 hyp = hyp.GetAlgorithm()
2242 if self.IsUsedHypothesis( hyp, shape ):
2243 return self.mesh.RemoveHypothesis( shape, hyp )
2244 hypName = GetName( hyp )
2245 geoName = GetName( shape )
2246 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2249 def GetHypothesisList(self, geom):
2251 Get the list of hypotheses added on a geometry
2254 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2257 the sequence of :class:`SMESH.SMESH_Hypothesis`
2260 return self.mesh.GetHypothesisList( geom )
2262 def RemoveGlobalHypotheses(self):
2264 Remove all global hypotheses
2267 current_hyps = self.mesh.GetHypothesisList( self.geom )
2268 for hyp in current_hyps:
2269 self.mesh.RemoveHypothesis( self.geom, hyp )
2272 def ExportMED(self, *args, **kwargs):
2274 Export the mesh in a file in MED format
2275 allowing to overwrite the file if it exists or add the exported data to its contents
2278 fileName: is the file name
2279 auto_groups (boolean): parameter for creating/not creating
2280 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2281 the typical use is auto_groups=False.
2282 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2283 The minor must be between 0 and the current minor version of MED file library.
2284 If minor is equal to -1, the minor version is not changed (default).
2285 The major version (x, where version is x.y.z) cannot be changed.
2286 overwrite (boolean): parameter for overwriting/not overwriting the file
2287 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2288 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2290 - 1D if all mesh nodes lie on OX coordinate axis, or
2291 - 2D if all mesh nodes lie on XOY coordinate plane, or
2292 - 3D in the rest cases.
2294 If *autoDimension* is *False*, the space dimension is always 3.
2295 fields: list of GEOM fields defined on the shape to mesh.
2296 geomAssocFields: each character of this string means a need to export a
2297 corresponding field; correspondence between fields and characters
2300 - 'v' stands for "_vertices_" field;
2301 - 'e' stands for "_edges_" field;
2302 - 'f' stands for "_faces_" field;
2303 - 's' stands for "_solids_" field.
2305 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2306 close to zero within a given tolerance, the coordinate is set to zero.
2307 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2309 # process positional arguments
2310 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2312 auto_groups = args[1] if len(args) > 1 else False
2313 minor = args[2] if len(args) > 2 else -1
2314 overwrite = args[3] if len(args) > 3 else True
2315 meshPart = args[4] if len(args) > 4 else None
2316 autoDimension = args[5] if len(args) > 5 else True
2317 fields = args[6] if len(args) > 6 else []
2318 geomAssocFields = args[7] if len(args) > 7 else ''
2319 z_tolerance = args[8] if len(args) > 8 else -1.
2320 # process keywords arguments
2321 auto_groups = kwargs.get("auto_groups", auto_groups)
2322 minor = kwargs.get("minor", minor)
2323 overwrite = kwargs.get("overwrite", overwrite)
2324 meshPart = kwargs.get("meshPart", meshPart)
2325 autoDimension = kwargs.get("autoDimension", autoDimension)
2326 fields = kwargs.get("fields", fields)
2327 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2328 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2330 # invoke engine's function
2331 if meshPart or fields or geomAssocFields or z_tolerance > 0:
2332 unRegister = genObjUnRegister()
2333 if isinstance( meshPart, list ):
2334 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2335 unRegister.set( meshPart )
2337 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2338 self.mesh.SetParameters(Parameters)
2340 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2341 fields, geomAssocFields, z_tolerance)
2343 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2345 def ExportSAUV(self, f, auto_groups=0):
2347 Export the mesh in a file in SAUV format
2352 auto_groups: boolean parameter for creating/not creating
2353 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2354 the typical use is auto_groups=False.
2357 self.mesh.ExportSAUV(f, auto_groups)
2359 def ExportDAT(self, f, meshPart=None):
2361 Export the mesh in a file in DAT format
2365 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2369 unRegister = genObjUnRegister()
2370 if isinstance( meshPart, list ):
2371 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2372 unRegister.set( meshPart )
2373 self.mesh.ExportPartToDAT( meshPart, f )
2375 self.mesh.ExportDAT(f)
2377 def ExportUNV(self, f, meshPart=None):
2379 Export the mesh in a file in UNV format
2383 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2387 unRegister = genObjUnRegister()
2388 if isinstance( meshPart, list ):
2389 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2390 unRegister.set( meshPart )
2391 self.mesh.ExportPartToUNV( meshPart, f )
2393 self.mesh.ExportUNV(f)
2395 def ExportSTL(self, f, ascii=1, meshPart=None):
2397 Export the mesh in a file in STL format
2401 ascii: defines the file encoding
2402 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2406 unRegister = genObjUnRegister()
2407 if isinstance( meshPart, list ):
2408 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2409 unRegister.set( meshPart )
2410 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2412 self.mesh.ExportSTL(f, ascii)
2414 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2416 Export the mesh in a file in CGNS format
2420 overwrite: boolean parameter for overwriting/not overwriting the file
2421 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2422 groupElemsByType: if True all elements of same entity type are exported at ones,
2423 else elements are exported in order of their IDs which can cause creation
2424 of multiple cgns sections
2427 unRegister = genObjUnRegister()
2428 if isinstance( meshPart, list ):
2429 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2430 unRegister.set( meshPart )
2431 if isinstance( meshPart, Mesh ):
2432 meshPart = meshPart.mesh
2434 meshPart = self.mesh
2435 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2437 def ExportGMF(self, f, meshPart=None):
2439 Export the mesh in a file in GMF format.
2440 GMF files must have .mesh extension for the ASCII format and .meshb for
2441 the bynary format. Other extensions are not allowed.
2445 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2448 unRegister = genObjUnRegister()
2449 if isinstance( meshPart, list ):
2450 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2451 unRegister.set( meshPart )
2452 if isinstance( meshPart, Mesh ):
2453 meshPart = meshPart.mesh
2455 meshPart = self.mesh
2456 self.mesh.ExportGMF(meshPart, f, True)
2458 def ExportToMED(self, *args, **kwargs):
2460 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2461 Export the mesh in a file in MED format
2462 allowing to overwrite the file if it exists or add the exported data to its contents
2465 fileName: the file name
2466 opt (boolean): parameter for creating/not creating
2467 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2468 overwrite: boolean parameter for overwriting/not overwriting the file
2469 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2471 - 1D if all mesh nodes lie on OX coordinate axis, or
2472 - 2D if all mesh nodes lie on XOY coordinate plane, or
2473 - 3D in the rest cases.
2475 If **autoDimension** is *False*, the space dimension is always 3.
2478 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2479 # process positional arguments
2480 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2482 auto_groups = args[1] if len(args) > 1 else False
2483 overwrite = args[2] if len(args) > 2 else True
2484 autoDimension = args[3] if len(args) > 3 else True
2485 # process keywords arguments
2486 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2487 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2488 overwrite = kwargs.get("overwrite", overwrite)
2489 autoDimension = kwargs.get("autoDimension", autoDimension)
2491 # invoke engine's function
2492 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2494 def ExportToMEDX(self, *args, **kwargs):
2496 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2497 Export the mesh in a file in MED format
2500 fileName: the file name
2501 opt (boolean): parameter for creating/not creating
2502 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2503 overwrite: boolean parameter for overwriting/not overwriting the file
2504 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2506 - 1D if all mesh nodes lie on OX coordinate axis, or
2507 - 2D if all mesh nodes lie on XOY coordinate plane, or
2508 - 3D in the rest cases.
2510 If **autoDimension** is *False*, the space dimension is always 3.
2513 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2514 # process positional arguments
2515 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2517 auto_groups = args[1] if len(args) > 1 else False
2518 overwrite = args[2] if len(args) > 2 else True
2519 autoDimension = args[3] if len(args) > 3 else True
2520 # process keywords arguments
2521 auto_groups = kwargs.get("auto_groups", auto_groups)
2522 overwrite = kwargs.get("overwrite", overwrite)
2523 autoDimension = kwargs.get("autoDimension", autoDimension)
2525 # invoke engine's function
2526 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2530 def Append(self, meshes, uniteIdenticalGroups = True,
2531 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2533 Append given meshes into this mesh.
2534 All groups of input meshes will be created in this mesh.
2537 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2538 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2539 mergeNodesAndElements: if True, equal nodes and elements are merged
2540 mergeTolerance: tolerance for merging nodes
2541 allGroups: forces creation of groups corresponding to every input mesh
2543 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2544 mergeNodesAndElements, mergeTolerance, allGroups,
2545 meshToAppendTo = self.GetMesh() )
2547 # Operations with groups:
2548 # ----------------------
2549 def CreateEmptyGroup(self, elementType, name):
2551 Create an empty standalone mesh group
2554 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2555 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2556 name: the name of the mesh group
2559 :class:`SMESH.SMESH_Group`
2562 return self.mesh.CreateGroup(elementType, name)
2564 def Group(self, grp, name=""):
2566 Create a mesh group based on the geometric object *grp*
2567 and give it a *name*.
2568 If *name* is not defined the name of the geometric group is used
2571 Works like :meth:`GroupOnGeom`.
2574 grp: a geometric group, a vertex, an edge, a face or a solid
2575 name: the name of the mesh group
2578 :class:`SMESH.SMESH_GroupOnGeom`
2581 return self.GroupOnGeom(grp, name)
2583 def GroupOnGeom(self, grp, name="", typ=None):
2585 Create a mesh group based on the geometrical object *grp*
2586 and give it a *name*.
2587 if *name* is not defined the name of the geometric group is used
2590 grp: a geometrical group, a vertex, an edge, a face or a solid
2591 name: the name of the mesh group
2592 typ: the type of elements in the group; either of
2593 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2594 automatically detected by the type of the geometry
2597 :class:`SMESH.SMESH_GroupOnGeom`
2600 AssureGeomPublished( self, grp, name )
2602 name = grp.GetName()
2604 typ = self._groupTypeFromShape( grp )
2605 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2607 def _groupTypeFromShape( self, shape ):
2609 Pivate method to get a type of group on geometry
2611 tgeo = str(shape.GetShapeType())
2612 if tgeo == "VERTEX":
2614 elif tgeo == "EDGE":
2616 elif tgeo == "FACE" or tgeo == "SHELL":
2618 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2620 elif tgeo == "COMPOUND":
2621 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2623 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2624 return self._groupTypeFromShape( sub[0] )
2626 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2629 def GroupOnFilter(self, typ, name, filter):
2631 Create a mesh group with given *name* based on the *filter*.
2632 It is a special type of group dynamically updating it's contents during
2636 typ: the type of elements in the group; either of
2637 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2638 name: the name of the mesh group
2639 filter (SMESH.Filter): the filter defining group contents
2642 :class:`SMESH.SMESH_GroupOnFilter`
2645 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2647 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2649 Create a mesh group by the given ids of elements
2652 groupName: the name of the mesh group
2653 elementType: the type of elements in the group; either of
2654 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2655 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2658 :class:`SMESH.SMESH_Group`
2661 group = self.mesh.CreateGroup(elementType, groupName)
2662 if isinstance( elemIDs, Mesh ):
2663 elemIDs = elemIDs.GetMesh()
2664 if hasattr( elemIDs, "GetIDs" ):
2665 if hasattr( elemIDs, "SetMesh" ):
2666 elemIDs.SetMesh( self.GetMesh() )
2667 group.AddFrom( elemIDs )
2675 CritType=FT_Undefined,
2678 UnaryOp=FT_Undefined,
2681 Create a mesh group by the given conditions
2684 groupName: the name of the mesh group
2685 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2686 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2687 Note that the items starting from FT_LessThan are not suitable for CritType.
2688 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2689 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2690 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2691 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2692 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2695 :class:`SMESH.SMESH_GroupOnFilter`
2698 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2699 group = self.MakeGroupByCriterion(groupName, aCriterion)
2702 def MakeGroupByCriterion(self, groupName, Criterion):
2704 Create a mesh group by the given criterion
2707 groupName: the name of the mesh group
2708 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2711 :class:`SMESH.SMESH_GroupOnFilter`
2714 :meth:`smeshBuilder.GetCriterion`
2717 return self.MakeGroupByCriteria( groupName, [Criterion] )
2719 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2721 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2724 groupName: the name of the mesh group
2725 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2726 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2729 :class:`SMESH.SMESH_GroupOnFilter`
2732 :meth:`smeshBuilder.GetCriterion`
2735 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2736 group = self.MakeGroupByFilter(groupName, aFilter)
2739 def MakeGroupByFilter(self, groupName, theFilter):
2741 Create a mesh group by the given filter
2744 groupName (string): the name of the mesh group
2745 theFilter (SMESH.Filter): the filter
2748 :class:`SMESH.SMESH_GroupOnFilter`
2751 :meth:`smeshBuilder.GetFilter`
2754 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2755 #theFilter.SetMesh( self.mesh )
2756 #group.AddFrom( theFilter )
2757 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2760 def RemoveGroup(self, group):
2765 group (SMESH.SMESH_GroupBase): group to remove
2768 self.mesh.RemoveGroup(group)
2770 def RemoveGroupWithContents(self, group):
2772 Remove a group with its contents
2775 group (SMESH.SMESH_GroupBase): group to remove
2778 self.mesh.RemoveGroupWithContents(group)
2780 def GetGroups(self, elemType = SMESH.ALL):
2782 Get the list of groups existing in the mesh in the order of creation
2783 (starting from the oldest one)
2786 elemType (SMESH.ElementType): type of elements the groups contain;
2787 by default groups of elements of all types are returned
2790 a list of :class:`SMESH.SMESH_GroupBase`
2793 groups = self.mesh.GetGroups()
2794 if elemType == SMESH.ALL:
2798 if g.GetType() == elemType:
2799 typedGroups.append( g )
2806 Get the number of groups existing in the mesh
2809 the quantity of groups as an integer value
2812 return self.mesh.NbGroups()
2814 def GetGroupNames(self):
2816 Get the list of names of groups existing in the mesh
2822 groups = self.GetGroups()
2824 for group in groups:
2825 names.append(group.GetName())
2828 def GetGroupByName(self, name, elemType = None):
2830 Find groups by name and type
2833 name (string): name of the group of interest
2834 elemType (SMESH.ElementType): type of elements the groups contain;
2835 by default one group of any type is returned;
2836 if elemType == SMESH.ALL then all groups of any type are returned
2839 a list of :class:`SMESH.SMESH_GroupBase`
2843 for group in self.GetGroups():
2844 if group.GetName() == name:
2845 if elemType is None:
2847 if ( elemType == SMESH.ALL or
2848 group.GetType() == elemType ):
2849 groups.append( group )
2852 def UnionGroups(self, group1, group2, name):
2854 Produce a union of two groups.
2855 A new group is created. All mesh elements that are
2856 present in the initial groups are added to the new one
2859 group1 (SMESH.SMESH_GroupBase): a group
2860 group2 (SMESH.SMESH_GroupBase): another group
2863 instance of :class:`SMESH.SMESH_Group`
2866 return self.mesh.UnionGroups(group1, group2, name)
2868 def UnionListOfGroups(self, groups, name):
2870 Produce a union list of groups.
2871 New group is created. All mesh elements that are present in
2872 initial groups are added to the new one
2875 groups: list of :class:`SMESH.SMESH_GroupBase`
2878 instance of :class:`SMESH.SMESH_Group`
2880 return self.mesh.UnionListOfGroups(groups, name)
2882 def IntersectGroups(self, group1, group2, name):
2884 Prodice an intersection of two groups.
2885 A new group is created. All mesh elements that are common
2886 for the two initial groups are added to the new one.
2889 group1 (SMESH.SMESH_GroupBase): a group
2890 group2 (SMESH.SMESH_GroupBase): another group
2893 instance of :class:`SMESH.SMESH_Group`
2896 return self.mesh.IntersectGroups(group1, group2, name)
2898 def IntersectListOfGroups(self, groups, name):
2900 Produce an intersection of groups.
2901 New group is created. All mesh elements that are present in all
2902 initial groups simultaneously are added to the new one
2905 groups: a list of :class:`SMESH.SMESH_GroupBase`
2908 instance of :class:`SMESH.SMESH_Group`
2910 return self.mesh.IntersectListOfGroups(groups, name)
2912 def CutGroups(self, main_group, tool_group, name):
2914 Produce a cut of two groups.
2915 A new group is created. All mesh elements that are present in
2916 the main group but are not present in the tool group are added to the new one
2919 main_group (SMESH.SMESH_GroupBase): a group to cut from
2920 tool_group (SMESH.SMESH_GroupBase): a group to cut by
2923 an instance of :class:`SMESH.SMESH_Group`
2926 return self.mesh.CutGroups(main_group, tool_group, name)
2928 def CutListOfGroups(self, main_groups, tool_groups, name):
2930 Produce a cut of groups.
2931 A new group is created. All mesh elements that are present in main groups
2932 but do not present in tool groups are added to the new one
2935 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
2936 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
2939 an instance of :class:`SMESH.SMESH_Group`
2942 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2944 def CreateDimGroup(self, groups, elemType, name,
2945 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2947 Create a standalone group of entities basing on nodes of other groups.
2950 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2951 elemType: a type of elements to include to the new group; either of
2952 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2953 name: a name of the new group.
2954 nbCommonNodes: a criterion of inclusion of an element to the new group
2955 basing on number of element nodes common with reference *groups*.
2956 Meaning of possible values are:
2958 - SMESH.ALL_NODES - include if all nodes are common,
2959 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2960 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2961 - SMEHS.MAJORITY - include if half of nodes or more are common.
2962 underlyingOnly: if *True* (default), an element is included to the
2963 new group provided that it is based on nodes of an element of *groups*;
2964 in this case the reference *groups* are supposed to be of higher dimension
2965 than *elemType*, which can be useful for example to get all faces lying on
2966 volumes of the reference *groups*.
2969 an instance of :class:`SMESH.SMESH_Group`
2972 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2974 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2976 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2978 Distribute all faces of the mesh among groups using sharp edges and optionally
2979 existing 1D elements as group boundaries.
2982 sharpAngle: edge is considered sharp if an angle between normals of
2983 adjacent faces is more than \a sharpAngle in degrees.
2984 createEdges (boolean): to create 1D elements for detected sharp edges.
2985 useExistingEdges (boolean): to use existing edges as group boundaries
2987 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2989 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2990 self.mesh.SetParameters(Parameters)
2991 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2993 def ConvertToStandalone(self, group):
2995 Convert group on geom into standalone group
2998 return self.mesh.ConvertToStandalone(group)
3000 # Get some info about mesh:
3001 # ------------------------
3003 def GetLog(self, clearAfterGet):
3005 Return the log of nodes and elements added or removed
3006 since the previous clear of the log.
3009 clearAfterGet: log is emptied after Get (safe if concurrents access)
3012 list of SMESH.log_block structures { commandType, number, coords, indexes }
3015 return self.mesh.GetLog(clearAfterGet)
3019 Clear the log of nodes and elements added or removed since the previous
3020 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3023 self.mesh.ClearLog()
3025 def SetAutoColor(self, theAutoColor):
3027 Toggle auto color mode on the object.
3028 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3031 theAutoColor (boolean): the flag which toggles auto color mode.
3034 self.mesh.SetAutoColor(theAutoColor)
3036 def GetAutoColor(self):
3038 Get flag of object auto color mode.
3044 return self.mesh.GetAutoColor()
3051 integer value, which is the internal Id of the mesh
3054 return self.mesh.GetId()
3056 def HasDuplicatedGroupNamesMED(self):
3058 Check the group names for duplications.
3059 Consider the maximum group name length stored in MED file.
3065 return self.mesh.HasDuplicatedGroupNamesMED()
3067 def GetMeshEditor(self):
3069 Obtain the mesh editor tool
3072 an instance of :class:`SMESH.SMESH_MeshEditor`
3077 def GetIDSource(self, ids, elemType = SMESH.ALL):
3079 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3080 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3084 elemType: type of elements; this parameter is used to distinguish
3085 IDs of nodes from IDs of elements; by default ids are treated as
3086 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3089 an instance of :class:`SMESH.SMESH_IDSource`
3092 call UnRegister() for the returned object as soon as it is no more useful::
3094 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3095 mesh.DoSomething( idSrc )
3099 if isinstance( ids, int ):
3101 return self.editor.MakeIDSource(ids, elemType)
3104 # Get information about mesh contents:
3105 # ------------------------------------
3107 def GetMeshInfo(self, obj = None):
3109 Get the mesh statistic.
3112 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3115 if not obj: obj = self.mesh
3116 return self.smeshpyD.GetMeshInfo(obj)
3120 Return the number of nodes in the mesh
3126 return self.mesh.NbNodes()
3128 def NbElements(self):
3130 Return the number of elements in the mesh
3136 return self.mesh.NbElements()
3138 def Nb0DElements(self):
3140 Return the number of 0d elements in the mesh
3146 return self.mesh.Nb0DElements()
3150 Return the number of ball discrete elements in the mesh
3156 return self.mesh.NbBalls()
3160 Return the number of edges in the mesh
3166 return self.mesh.NbEdges()
3168 def NbEdgesOfOrder(self, elementOrder):
3170 Return the number of edges with the given order in the mesh
3173 elementOrder: the order of elements
3174 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3180 return self.mesh.NbEdgesOfOrder(elementOrder)
3184 Return the number of faces in the mesh
3190 return self.mesh.NbFaces()
3192 def NbFacesOfOrder(self, elementOrder):
3194 Return the number of faces with the given order in the mesh
3197 elementOrder: the order of elements
3198 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3204 return self.mesh.NbFacesOfOrder(elementOrder)
3206 def NbTriangles(self):
3208 Return the number of triangles in the mesh
3214 return self.mesh.NbTriangles()
3216 def NbTrianglesOfOrder(self, elementOrder):
3218 Return the number of triangles with the given order in the mesh
3221 elementOrder: is the order of elements
3222 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3228 return self.mesh.NbTrianglesOfOrder(elementOrder)
3230 def NbBiQuadTriangles(self):
3232 Return the number of biquadratic triangles in the mesh
3238 return self.mesh.NbBiQuadTriangles()
3240 def NbQuadrangles(self):
3242 Return the number of quadrangles in the mesh
3248 return self.mesh.NbQuadrangles()
3250 def NbQuadranglesOfOrder(self, elementOrder):
3252 Return the number of quadrangles with the given order in the mesh
3255 elementOrder: the order of elements
3256 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3262 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3264 def NbBiQuadQuadrangles(self):
3266 Return the number of biquadratic quadrangles in the mesh
3272 return self.mesh.NbBiQuadQuadrangles()
3274 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3276 Return the number of polygons of given order in the mesh
3279 elementOrder: the order of elements
3280 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3286 return self.mesh.NbPolygonsOfOrder(elementOrder)
3288 def NbVolumes(self):
3290 Return the number of volumes in the mesh
3296 return self.mesh.NbVolumes()
3299 def NbVolumesOfOrder(self, elementOrder):
3301 Return the number of volumes with the given order in the mesh
3304 elementOrder: the order of elements
3305 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3311 return self.mesh.NbVolumesOfOrder(elementOrder)
3315 Return the number of tetrahedrons in the mesh
3321 return self.mesh.NbTetras()
3323 def NbTetrasOfOrder(self, elementOrder):
3325 Return the number of tetrahedrons with the given order in the mesh
3328 elementOrder: the order of elements
3329 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3335 return self.mesh.NbTetrasOfOrder(elementOrder)
3339 Return the number of hexahedrons in the mesh
3345 return self.mesh.NbHexas()
3347 def NbHexasOfOrder(self, elementOrder):
3349 Return the number of hexahedrons with the given order in the mesh
3352 elementOrder: the order of elements
3353 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3359 return self.mesh.NbHexasOfOrder(elementOrder)
3361 def NbTriQuadraticHexas(self):
3363 Return the number of triquadratic hexahedrons in the mesh
3369 return self.mesh.NbTriQuadraticHexas()
3371 def NbPyramids(self):
3373 Return the number of pyramids in the mesh
3379 return self.mesh.NbPyramids()
3381 def NbPyramidsOfOrder(self, elementOrder):
3383 Return the number of pyramids with the given order in the mesh
3386 elementOrder: the order of elements
3387 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3393 return self.mesh.NbPyramidsOfOrder(elementOrder)
3397 Return the number of prisms in the mesh
3403 return self.mesh.NbPrisms()
3405 def NbPrismsOfOrder(self, elementOrder):
3407 Return the number of prisms with the given order in the mesh
3410 elementOrder: the order of elements
3411 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3417 return self.mesh.NbPrismsOfOrder(elementOrder)
3419 def NbHexagonalPrisms(self):
3421 Return the number of hexagonal prisms in the mesh
3427 return self.mesh.NbHexagonalPrisms()
3429 def NbPolyhedrons(self):
3431 Return the number of polyhedrons in the mesh
3437 return self.mesh.NbPolyhedrons()
3439 def NbSubMesh(self):
3441 Return the number of submeshes in the mesh
3447 return self.mesh.NbSubMesh()
3449 def GetElementsId(self):
3451 Return the list of all mesh elements IDs
3454 the list of integer values
3457 :meth:`GetElementsByType`
3460 return self.mesh.GetElementsId()
3462 def GetElementsByType(self, elementType):
3464 Return the list of IDs of mesh elements with the given type
3467 elementType (SMESH.ElementType): the required type of elements
3470 list of integer values
3473 return self.mesh.GetElementsByType(elementType)
3475 def GetNodesId(self):
3477 Return the list of mesh nodes IDs
3480 the list of integer values
3483 return self.mesh.GetNodesId()
3485 # Get the information about mesh elements:
3486 # ------------------------------------
3488 def GetElementType(self, id, iselem=True):
3490 Return the type of mesh element or node
3493 the value from :class:`SMESH.ElementType` enumeration.
3494 Return SMESH.ALL if element or node with the given ID does not exist
3497 return self.mesh.GetElementType(id, iselem)
3499 def GetElementGeomType(self, id):
3501 Return the geometric type of mesh element
3504 the value from :class:`SMESH.EntityType` enumeration.
3507 return self.mesh.GetElementGeomType(id)
3509 def GetElementShape(self, id):
3511 Return the shape type of mesh element
3514 the value from :class:`SMESH.GeometryType` enumeration.
3517 return self.mesh.GetElementShape(id)
3519 def GetSubMeshElementsId(self, Shape):
3521 Return the list of sub-mesh elements IDs
3524 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3525 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3528 list of integer values
3531 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3532 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3535 return self.mesh.GetSubMeshElementsId(ShapeID)
3537 def GetSubMeshNodesId(self, Shape, all):
3539 Return the list of sub-mesh nodes IDs
3542 Shape: a geom object (sub-shape).
3543 *Shape* must be the sub-shape of a :meth:`GetShape`
3544 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3547 list of integer values
3550 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3551 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3554 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3556 def GetSubMeshElementType(self, Shape):
3558 Return type of elements on given shape
3561 Shape: a geom object (sub-shape).
3562 *Shape* must be a sub-shape of a ShapeToMesh()
3565 :class:`SMESH.ElementType`
3568 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3569 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3572 return self.mesh.GetSubMeshElementType(ShapeID)
3576 Get the mesh description
3582 return self.mesh.Dump()
3585 # Get the information about nodes and elements of a mesh by its IDs:
3586 # -----------------------------------------------------------
3588 def GetNodeXYZ(self, id):
3590 Get XYZ coordinates of a node.
3591 If there is no node for the given ID - return an empty list
3594 list of float values
3597 return self.mesh.GetNodeXYZ(id)
3599 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3601 Return list of IDs of inverse elements for the given node.
3602 If there is no node for the given ID - return an empty list
3606 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3609 list of integer values
3612 return self.mesh.GetNodeInverseElements(id,elemType)
3614 def GetNodePosition(self,NodeID):
3616 Return the position of a node on the shape
3619 :class:`SMESH.NodePosition`
3622 return self.mesh.GetNodePosition(NodeID)
3624 def GetElementPosition(self,ElemID):
3626 Return the position of an element on the shape
3629 :class:`SMESH.ElementPosition`
3632 return self.mesh.GetElementPosition(ElemID)
3634 def GetShapeID(self, id):
3636 Return the ID of the shape, on which the given node was generated.
3639 an integer value > 0 or -1 if there is no node for the given
3640 ID or the node is not assigned to any geometry
3643 return self.mesh.GetShapeID(id)
3645 def GetShapeIDForElem(self,id):
3647 Return the ID of the shape, on which the given element was generated.
3650 an integer value > 0 or -1 if there is no element for the given
3651 ID or the element is not assigned to any geometry
3654 return self.mesh.GetShapeIDForElem(id)
3656 def GetElemNbNodes(self, id):
3658 Return the number of nodes of the given element
3661 an integer value > 0 or -1 if there is no element for the given ID
3664 return self.mesh.GetElemNbNodes(id)
3666 def GetElemNode(self, id, index):
3668 Return the node ID the given (zero based) index for the given element.
3670 * If there is no element for the given ID - return -1.
3671 * If there is no node for the given index - return -2.
3674 id (int): element ID
3675 index (int): node index within the element
3678 an integer value (ID)
3681 :meth:`GetElemNodes`
3684 return self.mesh.GetElemNode(id, index)
3686 def GetElemNodes(self, id):
3688 Return the IDs of nodes of the given element
3691 a list of integer values
3694 return self.mesh.GetElemNodes(id)
3696 def IsMediumNode(self, elementID, nodeID):
3698 Return true if the given node is the medium node in the given quadratic element
3701 return self.mesh.IsMediumNode(elementID, nodeID)
3703 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3705 Return true if the given node is the medium node in one of quadratic elements
3708 nodeID: ID of the node
3709 elementType: the type of elements to check a state of the node, either of
3710 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3713 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3715 def ElemNbEdges(self, id):
3717 Return the number of edges for the given element
3720 return self.mesh.ElemNbEdges(id)
3722 def ElemNbFaces(self, id):
3724 Return the number of faces for the given element
3727 return self.mesh.ElemNbFaces(id)
3729 def GetElemFaceNodes(self,elemId, faceIndex):
3731 Return nodes of given face (counted from zero) for given volumic element.
3734 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3736 def GetFaceNormal(self, faceId, normalized=False):
3738 Return three components of normal of given mesh face
3739 (or an empty array in KO case)
3742 return self.mesh.GetFaceNormal(faceId,normalized)
3744 def FindElementByNodes(self, nodes):
3746 Return an element based on all given nodes.
3749 return self.mesh.FindElementByNodes(nodes)
3751 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3753 Return elements including all given nodes.
3756 return self.mesh.GetElementsByNodes( nodes, elemType )
3758 def IsPoly(self, id):
3760 Return true if the given element is a polygon
3763 return self.mesh.IsPoly(id)
3765 def IsQuadratic(self, id):
3767 Return true if the given element is quadratic
3770 return self.mesh.IsQuadratic(id)
3772 def GetBallDiameter(self, id):
3774 Return diameter of a ball discrete element or zero in case of an invalid *id*
3777 return self.mesh.GetBallDiameter(id)
3779 def BaryCenter(self, id):
3781 Return XYZ coordinates of the barycenter of the given element.
3782 If there is no element for the given ID - return an empty list
3785 a list of three double values
3788 :meth:`smeshBuilder.GetGravityCenter`
3791 return self.mesh.BaryCenter(id)
3793 def GetIdsFromFilter(self, filter, meshParts=[] ):
3795 Pass mesh elements through the given filter and return IDs of fitting elements
3798 filter: :class:`SMESH.Filter`
3799 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3805 :meth:`SMESH.Filter.GetIDs`
3806 :meth:`SMESH.Filter.GetElementsIdFromParts`
3809 filter.SetMesh( self.mesh )
3812 if isinstance( meshParts, Mesh ):
3813 filter.SetMesh( meshParts.GetMesh() )
3814 return theFilter.GetIDs()
3815 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3816 meshParts = [ meshParts ]
3817 return filter.GetElementsIdFromParts( meshParts )
3819 return filter.GetIDs()
3821 # Get mesh measurements information:
3822 # ------------------------------------
3824 def GetFreeBorders(self):
3826 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3827 Return a list of special structures (borders).
3830 a list of :class:`SMESH.FreeEdges.Border`
3833 aFilterMgr = self.smeshpyD.CreateFilterManager()
3834 aPredicate = aFilterMgr.CreateFreeEdges()
3835 aPredicate.SetMesh(self.mesh)
3836 aBorders = aPredicate.GetBorders()
3837 aFilterMgr.UnRegister()
3840 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3842 Get minimum distance between two nodes, elements or distance to the origin
3845 id1: first node/element id
3846 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3847 isElem1: *True* if *id1* is element id, *False* if it is node id
3848 isElem2: *True* if *id2* is element id, *False* if it is node id
3851 minimum distance value
3853 :meth:`GetMinDistance`
3856 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3857 return aMeasure.value
3859 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3861 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3864 id1: first node/element id
3865 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3866 isElem1: *True* if *id1* is element id, *False* if it is node id
3867 isElem2: *True* if *id2* is element id, *False* if it is node id
3870 :class:`SMESH.Measure` structure
3876 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3878 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3881 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3883 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3888 aMeasurements = self.smeshpyD.CreateMeasurements()
3889 aMeasure = aMeasurements.MinDistance(id1, id2)
3890 genObjUnRegister([aMeasurements,id1, id2])
3893 def BoundingBox(self, objects=None, isElem=False):
3895 Get bounding box of the specified object(s)
3898 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3899 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3900 *False* specifies that *objects* are nodes
3903 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3906 :meth:`GetBoundingBox()`
3909 result = self.GetBoundingBox(objects, isElem)
3913 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3916 def GetBoundingBox(self, objects=None, isElem=False):
3918 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3921 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3922 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3923 False means that *objects* are nodes
3926 :class:`SMESH.Measure` structure
3929 :meth:`BoundingBox()`
3933 objects = [self.mesh]
3934 elif isinstance(objects, tuple):
3935 objects = list(objects)
3936 if not isinstance(objects, list):
3938 if len(objects) > 0 and isinstance(objects[0], int):
3941 unRegister = genObjUnRegister()
3943 if isinstance(o, Mesh):
3944 srclist.append(o.mesh)
3945 elif hasattr(o, "_narrow"):
3946 src = o._narrow(SMESH.SMESH_IDSource)
3947 if src: srclist.append(src)
3949 elif isinstance(o, list):
3951 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3953 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3954 unRegister.set( srclist[-1] )
3957 aMeasurements = self.smeshpyD.CreateMeasurements()
3958 unRegister.set( aMeasurements )
3959 aMeasure = aMeasurements.BoundingBox(srclist)
3962 # Mesh edition (SMESH_MeshEditor functionality):
3963 # ---------------------------------------------
3965 def RemoveElements(self, IDsOfElements):
3967 Remove the elements from the mesh by ids
3970 IDsOfElements: is a list of ids of elements to remove
3976 return self.editor.RemoveElements(IDsOfElements)
3978 def RemoveNodes(self, IDsOfNodes):
3980 Remove nodes from mesh by ids
3983 IDsOfNodes: is a list of ids of nodes to remove
3989 return self.editor.RemoveNodes(IDsOfNodes)
3991 def RemoveOrphanNodes(self):
3993 Remove all orphan (free) nodes from mesh
3996 number of the removed nodes
3999 return self.editor.RemoveOrphanNodes()
4001 def AddNode(self, x, y, z):
4003 Add a node to the mesh by coordinates
4009 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4010 if hasVars: self.mesh.SetParameters(Parameters)
4011 return self.editor.AddNode( x, y, z)
4013 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4015 Create a 0D element on a node with given number.
4018 IDOfNode: the ID of node for creation of the element.
4019 DuplicateElements: to add one more 0D element to a node or not
4022 ID of the new 0D element
4025 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4027 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4029 Create 0D elements on all nodes of the given elements except those
4030 nodes on which a 0D element already exists.
4033 theObject: an object on whose nodes 0D elements will be created.
4034 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4035 theGroupName: optional name of a group to add 0D elements created
4036 and/or found on nodes of *theObject*.
4037 DuplicateElements: to add one more 0D element to a node or not
4040 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4041 IDs of new and/or found 0D elements. IDs of 0D elements
4042 can be retrieved from the returned object by
4043 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4046 unRegister = genObjUnRegister()
4047 if isinstance( theObject, Mesh ):
4048 theObject = theObject.GetMesh()
4049 elif isinstance( theObject, list ):
4050 theObject = self.GetIDSource( theObject, SMESH.ALL )
4051 unRegister.set( theObject )
4052 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4054 def AddBall(self, IDOfNode, diameter):
4056 Create a ball element on a node with given ID.
4059 IDOfNode: the ID of node for creation of the element.
4060 diameter: the bal diameter.
4063 ID of the new ball element
4066 return self.editor.AddBall( IDOfNode, diameter )
4068 def AddEdge(self, IDsOfNodes):
4070 Create a linear or quadratic edge (this is determined
4071 by the number of given nodes).
4074 IDsOfNodes: list of node IDs for creation of the element.
4075 The order of nodes in this list should correspond to
4076 the :ref:`connectivity convention <connectivity_page>`.
4082 return self.editor.AddEdge(IDsOfNodes)
4084 def AddFace(self, IDsOfNodes):
4086 Create a linear or quadratic face (this is determined
4087 by the number of given nodes).
4090 IDsOfNodes: list of node IDs for creation of the element.
4091 The order of nodes in this list should correspond to
4092 the :ref:`connectivity convention <connectivity_page>`.
4098 return self.editor.AddFace(IDsOfNodes)
4100 def AddPolygonalFace(self, IdsOfNodes):
4102 Add a polygonal face defined by a list of node IDs
4105 IdsOfNodes: the list of node IDs for creation of the element.
4111 return self.editor.AddPolygonalFace(IdsOfNodes)
4113 def AddQuadPolygonalFace(self, IdsOfNodes):
4115 Add a quadratic polygonal face defined by a list of node IDs
4118 IdsOfNodes: the list of node IDs for creation of the element;
4119 corner nodes follow first.
4125 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4127 def AddVolume(self, IDsOfNodes):
4129 Create both simple and quadratic volume (this is determined
4130 by the number of given nodes).
4133 IDsOfNodes: list of node IDs for creation of the element.
4134 The order of nodes in this list should correspond to
4135 the :ref:`connectivity convention <connectivity_page>`.
4138 ID of the new volumic element
4141 return self.editor.AddVolume(IDsOfNodes)
4143 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4145 Create a volume of many faces, giving nodes for each face.
4148 IdsOfNodes: list of node IDs for volume creation, face by face.
4149 Quantities: list of integer values, Quantities[i]
4150 gives the quantity of nodes in face number i.
4153 ID of the new volumic element
4156 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4158 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4160 Create a volume of many faces, giving the IDs of the existing faces.
4163 The created volume will refer only to the nodes
4164 of the given faces, not to the faces themselves.
4167 IdsOfFaces: the list of face IDs for volume creation.
4170 ID of the new volumic element
4173 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4176 def SetNodeOnVertex(self, NodeID, Vertex):
4178 Bind a node to a vertex
4182 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4185 True if succeed else raises an exception
4188 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4189 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4193 self.editor.SetNodeOnVertex(NodeID, VertexID)
4194 except SALOME.SALOME_Exception as inst:
4195 raise ValueError(inst.details.text)
4199 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4201 Store the node position on an edge
4205 Edge: an edge (GEOM.GEOM_Object) or edge ID
4206 paramOnEdge: a parameter on the edge where the node is located
4209 True if succeed else raises an exception
4212 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4213 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4217 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4218 except SALOME.SALOME_Exception as inst:
4219 raise ValueError(inst.details.text)
4222 def SetNodeOnFace(self, NodeID, Face, u, v):
4224 Store node position on a face
4228 Face: a face (GEOM.GEOM_Object) or face ID
4229 u: U parameter on the face where the node is located
4230 v: V parameter on the face where the node is located
4233 True if succeed else raises an exception
4236 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4237 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4241 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4242 except SALOME.SALOME_Exception as inst:
4243 raise ValueError(inst.details.text)
4246 def SetNodeInVolume(self, NodeID, Solid):
4248 Bind a node to a solid
4252 Solid: a solid (GEOM.GEOM_Object) or solid ID
4255 True if succeed else raises an exception
4258 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4259 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4263 self.editor.SetNodeInVolume(NodeID, SolidID)
4264 except SALOME.SALOME_Exception as inst:
4265 raise ValueError(inst.details.text)
4268 def SetMeshElementOnShape(self, ElementID, Shape):
4270 Bind an element to a shape
4273 ElementID: an element ID
4274 Shape: a shape (GEOM.GEOM_Object) or shape ID
4277 True if succeed else raises an exception
4280 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4281 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4285 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4286 except SALOME.SALOME_Exception as inst:
4287 raise ValueError(inst.details.text)
4291 def MoveNode(self, NodeID, x, y, z):
4293 Move the node with the given id
4296 NodeID: the id of the node
4297 x: a new X coordinate
4298 y: a new Y coordinate
4299 z: a new Z coordinate
4302 True if succeed else False
4305 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4306 if hasVars: self.mesh.SetParameters(Parameters)
4307 return self.editor.MoveNode(NodeID, x, y, z)
4309 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4311 Find the node closest to a point and moves it to a point location
4314 x: the X coordinate of a point
4315 y: the Y coordinate of a point
4316 z: the Z coordinate of a point
4317 NodeID: if specified (>0), the node with this ID is moved,
4318 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4321 the ID of a moved node
4324 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4325 if hasVars: self.mesh.SetParameters(Parameters)
4326 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4328 def FindNodeClosestTo(self, x, y, z):
4330 Find the node closest to a point
4333 x: the X coordinate of a point
4334 y: the Y coordinate of a point
4335 z: the Z coordinate of a point
4341 return self.editor.FindNodeClosestTo(x, y, z)
4343 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4345 Find the elements where a point lays IN or ON
4348 x,y,z (float): coordinates of the point
4349 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4350 means elements of any type excluding nodes, discrete and 0D elements.
4351 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4354 list of IDs of found elements
4357 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4359 return self.editor.FindElementsByPoint(x, y, z, elementType)
4361 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4363 Project a point to a mesh object.
4364 Return ID of an element of given type where the given point is projected
4365 and coordinates of the projection point.
4366 In the case if nothing found, return -1 and []
4368 if isinstance( meshObject, Mesh ):
4369 meshObject = meshObject.GetMesh()
4371 meshObject = self.GetMesh()
4372 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4374 def GetPointState(self, x, y, z):
4376 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4377 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4378 UNKNOWN state means that either mesh is wrong or the analysis fails.
4381 return self.editor.GetPointState(x, y, z)
4383 def IsManifold(self):
4385 Check if a 2D mesh is manifold
4388 return self.editor.IsManifold()
4390 def IsCoherentOrientation2D(self):
4392 Check if orientation of 2D elements is coherent
4395 return self.editor.IsCoherentOrientation2D()
4397 def Get1DBranches( self, edges, startNode = 0 ):
4399 Partition given 1D elements into groups of contiguous edges.
4400 A node where number of meeting edges != 2 is a group end.
4401 An optional startNode is used to orient groups it belongs to.
4404 A list of edge groups and a list of corresponding node groups,
4405 where the group is a list of IDs of edges or elements, like follows
4406 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4407 If a group is closed, the first and last nodes of the group are same.
4409 if isinstance( edges, Mesh ):
4410 edges = edges.GetMesh()
4411 unRegister = genObjUnRegister()
4412 if isinstance( edges, list ):
4413 edges = self.GetIDSource( edges, SMESH.EDGE )
4414 unRegister.set( edges )
4415 return self.editor.Get1DBranches( edges, startNode )
4417 def FindSharpEdges( self, angle, addExisting=False ):
4419 Return sharp edges of faces and non-manifold ones.
4420 Optionally add existing edges.
4423 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4424 addExisting: to return existing edges (1D elements) as well
4427 list of FaceEdge structures
4429 angle = ParseParameters( angle )[0]
4430 return self.editor.FindSharpEdges( angle, addExisting )
4432 def MeshToPassThroughAPoint(self, x, y, z):
4434 Find the node closest to a point and moves it to a point location
4437 x: the X coordinate of a point
4438 y: the Y coordinate of a point
4439 z: the Z coordinate of a point
4442 the ID of a moved node
4445 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4447 def InverseDiag(self, NodeID1, NodeID2):
4449 Replace two neighbour triangles sharing Node1-Node2 link
4450 with the triangles built on the same 4 nodes but having other common link.
4453 NodeID1: the ID of the first node
4454 NodeID2: the ID of the second node
4457 False if proper faces were not found
4459 return self.editor.InverseDiag(NodeID1, NodeID2)
4461 def DeleteDiag(self, NodeID1, NodeID2):
4463 Replace two neighbour triangles sharing *Node1-Node2* link
4464 with a quadrangle built on the same 4 nodes.
4467 NodeID1: ID of the first node
4468 NodeID2: ID of the second node
4471 False if proper faces were not found
4474 return self.editor.DeleteDiag(NodeID1, NodeID2)
4476 def Reorient(self, IDsOfElements=None):
4478 Reorient elements by ids
4481 IDsOfElements: if undefined reorients all mesh elements
4484 True if succeed else False
4487 if IDsOfElements == None:
4488 IDsOfElements = self.GetElementsId()
4489 return self.editor.Reorient(IDsOfElements)
4491 def ReorientObject(self, theObject):
4493 Reorient all elements of the object
4496 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4499 True if succeed else False
4502 if ( isinstance( theObject, Mesh )):
4503 theObject = theObject.GetMesh()
4504 return self.editor.ReorientObject(theObject)
4506 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4508 Reorient faces contained in *the2DObject*.
4511 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4512 theDirection: a desired direction of normal of *theFace*.
4513 It can be either a GEOM vector or a list of coordinates [x,y,z].
4514 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4515 compared with theDirection. It can be either ID of face or a point
4516 by which the face will be found. The point can be given as either
4517 a GEOM vertex or a list of point coordinates.
4520 number of reoriented faces
4523 unRegister = genObjUnRegister()
4525 if isinstance( the2DObject, Mesh ):
4526 the2DObject = the2DObject.GetMesh()
4527 if isinstance( the2DObject, list ):
4528 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4529 unRegister.set( the2DObject )
4530 # check theDirection
4531 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4532 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4533 if isinstance( theDirection, list ):
4534 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4535 # prepare theFace and thePoint
4536 theFace = theFaceOrPoint
4537 thePoint = PointStruct(0,0,0)
4538 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4539 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4541 if isinstance( theFaceOrPoint, list ):
4542 thePoint = PointStruct( *theFaceOrPoint )
4544 if isinstance( theFaceOrPoint, PointStruct ):
4545 thePoint = theFaceOrPoint
4547 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4549 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4551 Reorient faces according to adjacent volumes.
4554 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4555 either IDs of faces or face groups.
4556 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4557 theOutsideNormal: to orient faces to have their normals
4558 pointing either *outside* or *inside* the adjacent volumes.
4561 number of reoriented faces.
4564 unRegister = genObjUnRegister()
4566 if not isinstance( the2DObject, list ):
4567 the2DObject = [ the2DObject ]
4568 elif the2DObject and isinstance( the2DObject[0], int ):
4569 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4570 unRegister.set( the2DObject )
4571 the2DObject = [ the2DObject ]
4572 for i,obj2D in enumerate( the2DObject ):
4573 if isinstance( obj2D, Mesh ):
4574 the2DObject[i] = obj2D.GetMesh()
4575 if isinstance( obj2D, list ):
4576 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4577 unRegister.set( the2DObject[i] )
4579 if isinstance( the3DObject, Mesh ):
4580 the3DObject = the3DObject.GetMesh()
4581 if isinstance( the3DObject, list ):
4582 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4583 unRegister.set( the3DObject )
4584 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4586 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4588 Fuse the neighbouring triangles into quadrangles.
4591 IDsOfElements: The triangles to be fused.
4592 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4593 applied to possible quadrangles to choose a neighbour to fuse with.
4594 Note that not all items of :class:`SMESH.FunctorType` corresponds
4595 to numerical functors.
4596 MaxAngle: is the maximum angle between element normals at which the fusion
4597 is still performed; theMaxAngle is measured in radians.
4598 Also it could be a name of variable which defines angle in degrees.
4601 True in case of success, False otherwise.
4604 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4605 self.mesh.SetParameters(Parameters)
4606 if not IDsOfElements:
4607 IDsOfElements = self.GetElementsId()
4608 Functor = self.smeshpyD.GetFunctor(theCriterion)
4609 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4611 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4613 Fuse the neighbouring triangles of the object into quadrangles
4616 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4617 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4618 applied to possible quadrangles to choose a neighbour to fuse with.
4619 Note that not all items of :class:`SMESH.FunctorType` corresponds
4620 to numerical functors.
4621 MaxAngle: a max angle between element normals at which the fusion
4622 is still performed; theMaxAngle is measured in radians.
4625 True in case of success, False otherwise.
4628 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4629 self.mesh.SetParameters(Parameters)
4630 if isinstance( theObject, Mesh ):
4631 theObject = theObject.GetMesh()
4632 Functor = self.smeshpyD.GetFunctor(theCriterion)
4633 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4635 def QuadToTri (self, IDsOfElements, theCriterion = None):
4637 Split quadrangles into triangles.
4640 IDsOfElements: the faces to be splitted.
4641 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4642 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4643 value, then quadrangles will be split by the smallest diagonal.
4644 Note that not all items of :class:`SMESH.FunctorType` corresponds
4645 to numerical functors.
4648 True in case of success, False otherwise.
4650 if IDsOfElements == []:
4651 IDsOfElements = self.GetElementsId()
4652 if theCriterion is None:
4653 theCriterion = FT_MaxElementLength2D
4654 Functor = self.smeshpyD.GetFunctor(theCriterion)
4655 return self.editor.QuadToTri(IDsOfElements, Functor)
4657 def QuadToTriObject (self, theObject, theCriterion = None):
4659 Split quadrangles into triangles.
4662 theObject: the object from which the list of elements is taken,
4663 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4664 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4665 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4666 value, then quadrangles will be split by the smallest diagonal.
4667 Note that not all items of :class:`SMESH.FunctorType` corresponds
4668 to numerical functors.
4671 True in case of success, False otherwise.
4673 if ( isinstance( theObject, Mesh )):
4674 theObject = theObject.GetMesh()
4675 if theCriterion is None:
4676 theCriterion = FT_MaxElementLength2D
4677 Functor = self.smeshpyD.GetFunctor(theCriterion)
4678 return self.editor.QuadToTriObject(theObject, Functor)
4680 def QuadTo4Tri (self, theElements=[]):
4682 Split each of given quadrangles into 4 triangles. A node is added at the center of
4686 theElements: the faces to be splitted. This can be either
4687 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4688 or a list of face IDs. By default all quadrangles are split
4690 unRegister = genObjUnRegister()
4691 if isinstance( theElements, Mesh ):
4692 theElements = theElements.mesh
4693 elif not theElements:
4694 theElements = self.mesh
4695 elif isinstance( theElements, list ):
4696 theElements = self.GetIDSource( theElements, SMESH.FACE )
4697 unRegister.set( theElements )
4698 return self.editor.QuadTo4Tri( theElements )
4700 def SplitQuad (self, IDsOfElements, Diag13):
4702 Split quadrangles into triangles.
4705 IDsOfElements: the faces to be splitted
4706 Diag13 (boolean): is used to choose a diagonal for splitting.
4709 True in case of success, False otherwise.
4711 if IDsOfElements == []:
4712 IDsOfElements = self.GetElementsId()
4713 return self.editor.SplitQuad(IDsOfElements, Diag13)
4715 def SplitQuadObject (self, theObject, Diag13):
4717 Split quadrangles into triangles.
4720 theObject: the object from which the list of elements is taken,
4721 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4722 Diag13 (boolean): is used to choose a diagonal for splitting.
4725 True in case of success, False otherwise.
4727 if ( isinstance( theObject, Mesh )):
4728 theObject = theObject.GetMesh()
4729 return self.editor.SplitQuadObject(theObject, Diag13)
4731 def BestSplit (self, IDOfQuad, theCriterion):
4733 Find a better splitting of the given quadrangle.
4736 IDOfQuad: the ID of the quadrangle to be splitted.
4737 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4738 choose a diagonal for splitting.
4739 Note that not all items of :class:`SMESH.FunctorType` corresponds
4740 to numerical functors.
4743 * 1 if 1-3 diagonal is better,
4744 * 2 if 2-4 diagonal is better,
4745 * 0 if error occurs.
4747 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4749 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4751 Split volumic elements into tetrahedrons
4754 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4755 method: flags passing splitting method:
4756 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4757 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4759 unRegister = genObjUnRegister()
4760 if isinstance( elems, Mesh ):
4761 elems = elems.GetMesh()
4762 if ( isinstance( elems, list )):
4763 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4764 unRegister.set( elems )
4765 self.editor.SplitVolumesIntoTetra(elems, method)
4768 def SplitBiQuadraticIntoLinear(self, elems=None):
4770 Split bi-quadratic elements into linear ones without creation of additional nodes:
4772 - bi-quadratic triangle will be split into 3 linear quadrangles;
4773 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4774 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4776 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
4777 will be split in order to keep the mesh conformal.
4780 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4781 if None (default), all bi-quadratic elements will be split
4783 unRegister = genObjUnRegister()
4784 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4785 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4786 unRegister.set( elems )
4788 elems = [ self.GetMesh() ]
4789 if isinstance( elems, Mesh ):
4790 elems = [ elems.GetMesh() ]
4791 if not isinstance( elems, list ):
4793 self.editor.SplitBiQuadraticIntoLinear( elems )
4795 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4796 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4798 Split hexahedra into prisms
4801 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4802 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4803 gives a normal vector defining facets to split into triangles.
4804 *startHexPoint* can be either a triple of coordinates or a vertex.
4805 facetNormal: a normal to a facet to split into triangles of a
4806 hexahedron found by *startHexPoint*.
4807 *facetNormal* can be either a triple of coordinates or an edge.
4808 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4809 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4810 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4811 to *startHexPoint* are split, else *startHexPoint*
4812 is used to find the facet to split in all domains present in *elems*.
4815 unRegister = genObjUnRegister()
4816 if isinstance( elems, Mesh ):
4817 elems = elems.GetMesh()
4818 if ( isinstance( elems, list )):
4819 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4820 unRegister.set( elems )
4823 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4824 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4825 elif isinstance( startHexPoint, list ):
4826 startHexPoint = SMESH.PointStruct( startHexPoint[0],
4829 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4830 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4831 elif isinstance( facetNormal, list ):
4832 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4835 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4837 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4839 def SplitQuadsNearTriangularFacets(self):
4841 Split quadrangle faces near triangular facets of volumes
4843 faces_array = self.GetElementsByType(SMESH.FACE)
4844 for face_id in faces_array:
4845 if self.GetElemNbNodes(face_id) == 4: # quadrangle
4846 quad_nodes = self.mesh.GetElemNodes(face_id)
4847 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4848 isVolumeFound = False
4849 for node1_elem in node1_elems:
4850 if not isVolumeFound:
4851 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4852 nb_nodes = self.GetElemNbNodes(node1_elem)
4853 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4854 volume_elem = node1_elem
4855 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4856 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4857 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4858 isVolumeFound = True
4859 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4860 self.SplitQuad([face_id], False) # diagonal 2-4
4861 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4862 isVolumeFound = True
4863 self.SplitQuad([face_id], True) # diagonal 1-3
4864 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4865 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4866 isVolumeFound = True
4867 self.SplitQuad([face_id], True) # diagonal 1-3
4869 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4871 Split hexahedrons into tetrahedrons.
4873 This operation uses :doc:`pattern_mapping` functionality for splitting.
4876 theObject: the object from which the list of hexahedrons is taken;
4877 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4878 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4879 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4880 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4881 key-point will be mapped into *theNode001*-th node of each volume.
4882 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4885 True in case of success, False otherwise.
4893 # (0,0,1) 4.---------.7 * |
4900 # (0,0,0) 0.---------.3
4901 pattern_tetra = "!!! Nb of points: \n 8 \n\
4911 !!! Indices of points of 6 tetras: \n\
4919 pattern = self.smeshpyD.GetPattern()
4920 isDone = pattern.LoadFromFile(pattern_tetra)
4922 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4925 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4926 isDone = pattern.MakeMesh(self.mesh, False, False)
4927 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4929 # split quafrangle faces near triangular facets of volumes
4930 self.SplitQuadsNearTriangularFacets()
4934 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4936 Split hexahedrons into prisms.
4938 Uses the :doc:`pattern_mapping` functionality for splitting.
4941 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4942 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4943 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4944 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4945 will be mapped into the *theNode001* -th node of each volume.
4946 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4949 True in case of success, False otherwise.
4951 # Pattern: 5.---------.6
4956 # (0,0,1) 4.---------.7 |
4963 # (0,0,0) 0.---------.3
4964 pattern_prism = "!!! Nb of points: \n 8 \n\
4974 !!! Indices of points of 2 prisms: \n\
4978 pattern = self.smeshpyD.GetPattern()
4979 isDone = pattern.LoadFromFile(pattern_prism)
4981 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4984 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4985 isDone = pattern.MakeMesh(self.mesh, False, False)
4986 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4988 # Split quafrangle faces near triangular facets of volumes
4989 self.SplitQuadsNearTriangularFacets()
4993 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4994 MaxNbOfIterations, MaxAspectRatio, Method):
4999 IDsOfElements: the list if ids of elements to smooth
5000 IDsOfFixedNodes: the list of ids of fixed nodes.
5001 Note that nodes built on edges and boundary nodes are always fixed.
5002 MaxNbOfIterations: the maximum number of iterations
5003 MaxAspectRatio: varies in range [1.0, inf]
5004 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5005 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5008 True in case of success, False otherwise.
5011 if IDsOfElements == []:
5012 IDsOfElements = self.GetElementsId()
5013 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5014 self.mesh.SetParameters(Parameters)
5015 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5016 MaxNbOfIterations, MaxAspectRatio, Method)
5018 def SmoothObject(self, theObject, IDsOfFixedNodes,
5019 MaxNbOfIterations, MaxAspectRatio, Method):
5021 Smooth elements which belong to the given object
5024 theObject: the object to smooth
5025 IDsOfFixedNodes: the list of ids of fixed nodes.
5026 Note that nodes built on edges and boundary nodes are always fixed.
5027 MaxNbOfIterations: the maximum number of iterations
5028 MaxAspectRatio: varies in range [1.0, inf]
5029 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5030 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5033 True in case of success, False otherwise.
5036 if ( isinstance( theObject, Mesh )):
5037 theObject = theObject.GetMesh()
5038 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5039 MaxNbOfIterations, MaxAspectRatio, Method)
5041 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5042 MaxNbOfIterations, MaxAspectRatio, Method):
5044 Parametrically smooth the given elements
5047 IDsOfElements: the list if ids of elements to smooth
5048 IDsOfFixedNodes: the list of ids of fixed nodes.
5049 Note that nodes built on edges and boundary nodes are always fixed.
5050 MaxNbOfIterations: the maximum number of iterations
5051 MaxAspectRatio: varies in range [1.0, inf]
5052 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5053 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5056 True in case of success, False otherwise.
5059 if IDsOfElements == []:
5060 IDsOfElements = self.GetElementsId()
5061 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5062 self.mesh.SetParameters(Parameters)
5063 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5064 MaxNbOfIterations, MaxAspectRatio, Method)
5066 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5067 MaxNbOfIterations, MaxAspectRatio, Method):
5069 Parametrically smooth the elements which belong to the given object
5072 theObject: the object to smooth
5073 IDsOfFixedNodes: the list of ids of fixed nodes.
5074 Note that nodes built on edges and boundary nodes are always fixed.
5075 MaxNbOfIterations: the maximum number of iterations
5076 MaxAspectRatio: varies in range [1.0, inf]
5077 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5078 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5081 True in case of success, False otherwise.
5084 if ( isinstance( theObject, Mesh )):
5085 theObject = theObject.GetMesh()
5086 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5087 MaxNbOfIterations, MaxAspectRatio, Method)
5089 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5091 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5092 them with quadratic with the same id.
5095 theForce3d: method of new node creation:
5097 * False - the medium node lies at the geometrical entity from which the mesh element is built
5098 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5099 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5100 theToBiQuad: If True, converts the mesh to bi-quadratic
5103 :class:`SMESH.ComputeError` which can hold a warning
5106 If *theSubMesh* is provided, the mesh can become non-conformal
5109 if isinstance( theSubMesh, Mesh ):
5110 theSubMesh = theSubMesh.mesh
5112 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5115 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5117 self.editor.ConvertToQuadratic(theForce3d)
5118 error = self.editor.GetLastError()
5119 if error and error.comment:
5120 print(error.comment)
5123 def ConvertFromQuadratic(self, theSubMesh=None):
5125 Convert the mesh from quadratic to ordinary,
5126 deletes old quadratic elements,
5127 replacing them with ordinary mesh elements with the same id.
5130 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5133 If *theSubMesh* is provided, the mesh can become non-conformal
5137 self.editor.ConvertFromQuadraticObject(theSubMesh)
5139 return self.editor.ConvertFromQuadratic()
5141 def Make2DMeshFrom3D(self):
5143 Create 2D mesh as skin on boundary faces of a 3D mesh
5146 True if operation has been completed successfully, False otherwise
5149 return self.editor.Make2DMeshFrom3D()
5151 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5152 toCopyElements=False, toCopyExistingBondary=False):
5154 Create missing boundary elements
5157 elements: elements whose boundary is to be checked:
5158 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5159 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5160 dimension: defines type of boundary elements to create, either of
5161 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5162 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5163 groupName: a name of group to store created boundary elements in,
5164 "" means not to create the group
5165 meshName: a name of new mesh to store created boundary elements in,
5166 "" means not to create the new mesh
5167 toCopyElements: if True, the checked elements will be copied into
5168 the new mesh else only boundary elements will be copied into the new mesh
5169 toCopyExistingBondary: if True, not only new but also pre-existing
5170 boundary elements will be copied into the new mesh
5173 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5176 unRegister = genObjUnRegister()
5177 if isinstance( elements, Mesh ):
5178 elements = elements.GetMesh()
5179 if ( isinstance( elements, list )):
5180 elemType = SMESH.ALL
5181 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5182 elements = self.editor.MakeIDSource(elements, elemType)
5183 unRegister.set( elements )
5184 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5185 toCopyElements,toCopyExistingBondary)
5186 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5189 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5190 toCopyAll=False, groups=[]):
5192 Create missing boundary elements around either the whole mesh or
5196 dimension: defines type of boundary elements to create, either of
5197 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5198 groupName: a name of group to store all boundary elements in,
5199 "" means not to create the group
5200 meshName: a name of a new mesh, which is a copy of the initial
5201 mesh + created boundary elements; "" means not to create the new mesh
5202 toCopyAll: if True, the whole initial mesh will be copied into
5203 the new mesh else only boundary elements will be copied into the new mesh
5204 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5207 tuple( long, mesh, group )
5208 - long - number of added boundary elements
5209 - mesh - the :class:`Mesh` where elements were added to
5210 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5213 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5215 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5216 return nb, mesh, group
5218 def RenumberNodes(self):
5220 Renumber mesh nodes to remove unused node IDs
5222 self.editor.RenumberNodes()
5224 def RenumberElements(self):
5226 Renumber mesh elements to remove unused element IDs
5228 self.editor.RenumberElements()
5230 def _getIdSourceList(self, arg, idType, unRegister):
5232 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5234 if arg and isinstance( arg, list ):
5235 if isinstance( arg[0], int ):
5236 arg = self.GetIDSource( arg, idType )
5237 unRegister.set( arg )
5238 elif isinstance( arg[0], Mesh ):
5239 arg[0] = arg[0].GetMesh()
5240 elif isinstance( arg, Mesh ):
5242 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5246 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5247 MakeGroups=False, TotalAngle=False):
5249 Generate new elements by rotation of the given elements and nodes around the axis
5252 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5253 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5254 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5255 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5256 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5257 which defines angle in degrees
5258 NbOfSteps: the number of steps
5259 Tolerance: tolerance
5260 MakeGroups: forces the generation of new groups from existing ones
5261 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5262 of all steps, else - size of each step
5265 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5268 unRegister = genObjUnRegister()
5269 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5270 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5271 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5273 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5274 Axis = self.smeshpyD.GetAxisStruct( Axis )
5275 if isinstance( Axis, list ):
5276 Axis = SMESH.AxisStruct( *Axis )
5278 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5279 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5280 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5281 self.mesh.SetParameters(Parameters)
5282 if TotalAngle and NbOfSteps:
5283 AngleInRadians /= NbOfSteps
5284 return self.editor.RotationSweepObjects( nodes, edges, faces,
5285 Axis, AngleInRadians,
5286 NbOfSteps, Tolerance, MakeGroups)
5288 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5289 MakeGroups=False, TotalAngle=False):
5291 Generate new elements by rotation of the elements around the axis
5294 IDsOfElements: the list of ids of elements to sweep
5295 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5296 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5297 NbOfSteps: the number of steps
5298 Tolerance: tolerance
5299 MakeGroups: forces the generation of new groups from existing ones
5300 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5301 of all steps, else - size of each step
5304 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5307 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5308 AngleInRadians, NbOfSteps, Tolerance,
5309 MakeGroups, TotalAngle)
5311 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5312 MakeGroups=False, TotalAngle=False):
5314 Generate new elements by rotation of the elements of object around the axis
5315 theObject object which elements should be sweeped.
5316 It can be a mesh, a sub mesh or a group.
5319 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5320 AngleInRadians: the angle of Rotation
5321 NbOfSteps: number of steps
5322 Tolerance: tolerance
5323 MakeGroups: forces the generation of new groups from existing ones
5324 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5325 of all steps, else - size of each step
5328 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5331 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5332 AngleInRadians, NbOfSteps, Tolerance,
5333 MakeGroups, TotalAngle )
5335 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5336 MakeGroups=False, TotalAngle=False):
5338 Generate new elements by rotation of the elements of object around the axis
5339 theObject object which elements should be sweeped.
5340 It can be a mesh, a sub mesh or a group.
5343 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5344 AngleInRadians: the angle of Rotation
5345 NbOfSteps: number of steps
5346 Tolerance: tolerance
5347 MakeGroups: forces the generation of new groups from existing ones
5348 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5349 of all steps, else - size of each step
5352 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5353 empty list otherwise
5356 return self.RotationSweepObjects([],theObject,[], Axis,
5357 AngleInRadians, NbOfSteps, Tolerance,
5358 MakeGroups, TotalAngle)
5360 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5361 MakeGroups=False, TotalAngle=False):
5363 Generate new elements by rotation of the elements of object around the axis
5364 theObject object which elements should be sweeped.
5365 It can be a mesh, a sub mesh or a group.
5368 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5369 AngleInRadians: the angle of Rotation
5370 NbOfSteps: number of steps
5371 Tolerance: tolerance
5372 MakeGroups: forces the generation of new groups from existing ones
5373 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5374 of all steps, else - size of each step
5377 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5380 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5381 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5383 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5384 scaleFactors=[], linearVariation=False, basePoint=[],
5385 angles=[], anglesVariation=False):
5387 Generate new elements by extrusion of the given elements and nodes
5390 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5391 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5392 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5393 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5394 the direction and value of extrusion for one step (the total extrusion
5395 length will be NbOfSteps * ||StepVector||)
5396 NbOfSteps: the number of steps
5397 MakeGroups: forces the generation of new groups from existing ones
5398 scaleFactors: optional scale factors to apply during extrusion
5399 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5400 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5401 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5402 nodes and elements being extruded is used as the scaling center.
5405 - a list of tree components of the point or
5408 angles: list of angles in radians. Nodes at each extrusion step are rotated
5409 around *basePoint*, additionally to previous steps.
5410 anglesVariation: forces the computation of rotation angles as linear
5411 variation of the given *angles* along path steps
5413 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5415 Example: :ref:`tui_extrusion`
5417 unRegister = genObjUnRegister()
5418 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5419 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5420 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5422 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5423 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5424 if isinstance( StepVector, list ):
5425 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5427 if isinstance( basePoint, int):
5428 xyz = self.GetNodeXYZ( basePoint )
5430 raise RuntimeError("Invalid node ID: %s" % basePoint)
5432 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5433 basePoint = self.geompyD.PointCoordinates( basePoint )
5435 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5436 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5437 angles,angleParameters,hasVars = ParseAngles(angles)
5438 Parameters = StepVector.PS.parameters + var_separator + \
5439 Parameters + var_separator + \
5440 scaleParameters + var_separator + angleParameters
5441 self.mesh.SetParameters(Parameters)
5443 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5444 StepVector, NbOfSteps, MakeGroups,
5445 scaleFactors, linearVariation, basePoint,
5446 angles, anglesVariation )
5449 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5451 Generate new elements by extrusion of the elements with given ids
5454 IDsOfElements: the list of ids of elements or nodes for extrusion
5455 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5456 the direction and value of extrusion for one step (the total extrusion
5457 length will be NbOfSteps * ||StepVector||)
5458 NbOfSteps: the number of steps
5459 MakeGroups: forces the generation of new groups from existing ones
5460 IsNodes: is True if elements with given ids are nodes
5463 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5465 Example: :ref:`tui_extrusion`
5468 if IsNodes: n = IDsOfElements
5469 else : e,f, = IDsOfElements,IDsOfElements
5470 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5472 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5473 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5475 Generate new elements by extrusion along the normal to a discretized surface or wire
5478 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5479 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5480 StepSize: length of one extrusion step (the total extrusion
5481 length will be *NbOfSteps* *StepSize*).
5482 NbOfSteps: number of extrusion steps.
5483 ByAverageNormal: if True each node is translated by *StepSize*
5484 along the average of the normal vectors to the faces sharing the node;
5485 else each node is translated along the same average normal till
5486 intersection with the plane got by translation of the face sharing
5487 the node along its own normal by *StepSize*.
5488 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5489 for every node of *Elements*.
5490 MakeGroups: forces generation of new groups from existing ones.
5491 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5492 is not yet implemented. This parameter is used if *Elements* contains
5493 both faces and edges, i.e. *Elements* is a Mesh.
5496 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5497 empty list otherwise.
5498 Example: :ref:`tui_extrusion`
5501 unRegister = genObjUnRegister()
5502 if isinstance( Elements, Mesh ):
5503 Elements = [ Elements.GetMesh() ]
5504 if isinstance( Elements, list ):
5506 raise RuntimeError("Elements empty!")
5507 if isinstance( Elements[0], int ):
5508 Elements = self.GetIDSource( Elements, SMESH.ALL )
5509 unRegister.set( Elements )
5510 if not isinstance( Elements, list ):
5511 Elements = [ Elements ]
5512 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5513 self.mesh.SetParameters(Parameters)
5514 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5515 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5517 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5519 Generate new elements by extrusion of the elements or nodes which belong to the object
5522 theObject: the object whose elements or nodes should be processed.
5523 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5524 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5525 the direction and value of extrusion for one step (the total extrusion
5526 length will be NbOfSteps * ||StepVector||)
5527 NbOfSteps: the number of steps
5528 MakeGroups: forces the generation of new groups from existing ones
5529 IsNodes: is True if elements to extrude are nodes
5532 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5533 Example: :ref:`tui_extrusion`
5537 if IsNodes: n = theObject
5538 else : e,f, = theObject,theObject
5539 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5541 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5543 Generate new elements by extrusion of edges which belong to the object
5546 theObject: object whose 1D elements should be processed.
5547 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5548 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5549 the direction and value of extrusion for one step (the total extrusion
5550 length will be NbOfSteps * ||StepVector||)
5551 NbOfSteps: the number of steps
5552 MakeGroups: to generate new groups from existing ones
5555 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5556 Example: :ref:`tui_extrusion`
5559 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5561 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5563 Generate new elements by extrusion of faces which belong to the object
5566 theObject: object whose 2D elements should be processed.
5567 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5568 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5569 the direction and value of extrusion for one step (the total extrusion
5570 length will be NbOfSteps * ||StepVector||)
5571 NbOfSteps: the number of steps
5572 MakeGroups: forces the generation of new groups from existing ones
5575 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5576 Example: :ref:`tui_extrusion`
5579 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5581 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5582 ExtrFlags, SewTolerance, MakeGroups=False):
5584 Generate new elements by extrusion of the elements with given ids
5587 IDsOfElements: is ids of elements
5588 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5589 the direction and value of extrusion for one step (the total extrusion
5590 length will be NbOfSteps * ||StepVector||)
5591 NbOfSteps: the number of steps
5592 ExtrFlags: sets flags for extrusion
5593 SewTolerance: uses for comparing locations of nodes if flag
5594 EXTRUSION_FLAG_SEW is set
5595 MakeGroups: forces the generation of new groups from existing ones
5598 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5601 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5602 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5603 if isinstance( StepVector, list ):
5604 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5605 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5606 ExtrFlags, SewTolerance, MakeGroups)
5608 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5609 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5610 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5611 ScaleFactors=[], ScalesVariation=False):
5613 Generate new elements by extrusion of the given elements and nodes along the path.
5614 The path of extrusion must be a meshed edge.
5617 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5618 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5619 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5620 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5621 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
5622 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5623 HasAngles: not used obsolete
5624 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5625 around *basePoint*, additionally to previous steps.
5626 LinearVariation: forces the computation of rotation angles as linear
5627 variation of the given Angles along path steps
5628 HasRefPoint: allows using the reference point
5629 RefPoint: optional scaling and rotation center (mass center of the extruded
5630 elements by default). The User can specify any point as the Reference Point.
5631 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5632 MakeGroups: forces the generation of new groups from existing ones
5633 ScaleFactors: optional scale factors to apply during extrusion
5634 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5635 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5638 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5639 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5640 Example: :ref:`tui_extrusion_along_path`
5643 unRegister = genObjUnRegister()
5644 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5645 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5646 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5648 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5649 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5650 if isinstance( RefPoint, list ):
5651 if not RefPoint: RefPoint = [0,0,0]
5652 RefPoint = SMESH.PointStruct( *RefPoint )
5653 if isinstance( PathObject, Mesh ):
5654 PathObject = PathObject.GetMesh()
5655 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5656 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5657 Parameters = AnglesParameters + var_separator + \
5658 RefPoint.parameters + var_separator + ScalesParameters
5659 self.mesh.SetParameters(Parameters)
5660 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5661 PathObject, PathShape, NodeStart,
5662 HasAngles, Angles, LinearVariation,
5663 HasRefPoint, RefPoint, MakeGroups,
5664 ScaleFactors, ScalesVariation)
5666 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5667 HasAngles=False, Angles=[], LinearVariation=False,
5668 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5669 ElemType=SMESH.FACE):
5671 Generate new elements by extrusion of the given elements.
5672 The path of extrusion must be a meshed edge.
5675 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5676 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5677 NodeStart: the start node from Path. Defines the direction of extrusion
5678 HasAngles: not used obsolete
5679 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5680 around *basePoint*, additionally to previous steps.
5681 LinearVariation: forces the computation of rotation angles as linear
5682 variation of the given Angles along path steps
5683 HasRefPoint: allows using the reference point
5684 RefPoint: the reference point around which the elements are rotated (the mass
5685 center of the elements by default).
5686 The User can specify any point as the Reference Point.
5687 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5688 MakeGroups: forces the generation of new groups from existing ones
5689 ElemType: type of elements for extrusion (if param Base is a mesh)
5692 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5693 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5694 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5696 Example: :ref:`tui_extrusion_along_path`
5700 if ElemType == SMESH.NODE: n = Base
5701 if ElemType == SMESH.EDGE: e = Base
5702 if ElemType == SMESH.FACE: f = Base
5703 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5704 HasAngles, Angles, LinearVariation,
5705 HasRefPoint, RefPoint, MakeGroups)
5706 if MakeGroups: return gr,er
5709 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5710 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5711 MakeGroups=False, LinearVariation=False):
5713 Generate new elements by extrusion of the given elements.
5714 The path of extrusion must be a meshed edge.
5717 IDsOfElements: ids of elements
5718 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5719 PathShape: shape (edge) defines the sub-mesh for the path
5720 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5721 HasAngles: not used obsolete
5722 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5723 around *basePoint*, additionally to previous steps.
5724 HasRefPoint: allows using the reference point
5725 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5726 The User can specify any point as the Reference Point.
5727 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5728 MakeGroups: forces the generation of new groups from existing ones
5729 LinearVariation: forces the computation of rotation angles as linear
5730 variation of the given Angles along path steps
5733 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5734 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5735 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5736 Example: :ref:`tui_extrusion_along_path`
5739 if not IDsOfElements:
5740 IDsOfElements = [ self.GetMesh() ]
5741 n,e,f = [],IDsOfElements,IDsOfElements
5742 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5743 NodeStart, HasAngles, Angles,
5745 HasRefPoint, RefPoint, MakeGroups)
5746 if MakeGroups: return gr,er
5749 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5750 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5751 MakeGroups=False, LinearVariation=False):
5753 Generate new elements by extrusion of the elements which belong to the object.
5754 The path of extrusion must be a meshed edge.
5757 theObject: the object whose elements should be processed.
5758 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5759 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5760 PathShape: shape (edge) defines the sub-mesh for the path
5761 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5762 HasAngles: not used obsolete
5763 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5764 around *basePoint*, additionally to previous steps.
5765 HasRefPoint: allows using the reference point
5766 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5767 The User can specify any point as the Reference Point.
5768 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5769 MakeGroups: forces the generation of new groups from existing ones
5770 LinearVariation: forces the computation of rotation angles as linear
5771 variation of the given Angles along path steps
5774 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5775 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5776 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5777 Example: :ref:`tui_extrusion_along_path`
5780 n,e,f = [],theObject,theObject
5781 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5782 HasAngles, Angles, LinearVariation,
5783 HasRefPoint, RefPoint, MakeGroups)
5784 if MakeGroups: return gr,er
5787 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5788 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5789 MakeGroups=False, LinearVariation=False):
5791 Generate new elements by extrusion of mesh segments which belong to the object.
5792 The path of extrusion must be a meshed edge.
5795 theObject: the object whose 1D elements should be processed.
5796 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5797 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5798 PathShape: shape (edge) defines the sub-mesh for the path
5799 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5800 HasAngles: not used obsolete
5801 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5802 around *basePoint*, additionally to previous steps.
5803 HasRefPoint: allows using the reference point
5804 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5805 The User can specify any point as the Reference Point.
5806 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5807 MakeGroups: forces the generation of new groups from existing ones
5808 LinearVariation: forces the computation of rotation angles as linear
5809 variation of the given Angles along path steps
5812 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5813 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5814 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5815 Example: :ref:`tui_extrusion_along_path`
5818 n,e,f = [],theObject,[]
5819 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5820 HasAngles, Angles, LinearVariation,
5821 HasRefPoint, RefPoint, MakeGroups)
5822 if MakeGroups: return gr,er
5825 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5826 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5827 MakeGroups=False, LinearVariation=False):
5829 Generate new elements by extrusion of faces which belong to the object.
5830 The path of extrusion must be a meshed edge.
5833 theObject: the object whose 2D elements should be processed.
5834 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5835 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5836 PathShape: shape (edge) defines the sub-mesh for the path
5837 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5838 HasAngles: not used obsolete
5839 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5840 around *basePoint*, additionally to previous steps.
5841 HasRefPoint: allows using the reference point
5842 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5843 The User can specify any point as the Reference Point.
5844 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5845 MakeGroups: forces the generation of new groups from existing ones
5846 LinearVariation: forces the computation of rotation angles as linear
5847 variation of the given Angles along path steps
5850 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5851 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5852 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5853 Example: :ref:`tui_extrusion_along_path`
5856 n,e,f = [],[],theObject
5857 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5858 HasAngles, Angles, LinearVariation,
5859 HasRefPoint, RefPoint, MakeGroups)
5860 if MakeGroups: return gr,er
5863 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5865 Create a symmetrical copy of mesh elements
5868 IDsOfElements: list of elements ids
5869 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5870 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5871 If the *Mirror* is a geom object this parameter is unnecessary
5872 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5873 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5876 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5879 if IDsOfElements == []:
5880 IDsOfElements = self.GetElementsId()
5881 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5882 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5883 theMirrorType = Mirror._mirrorType
5885 self.mesh.SetParameters(Mirror.parameters)
5886 if Copy and MakeGroups:
5887 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5888 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5891 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5893 Create a new mesh by a symmetrical copy of mesh elements
5896 IDsOfElements: the list of elements ids
5897 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5898 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5899 If the *Mirror* is a geom object this parameter is unnecessary
5900 MakeGroups: to generate new groups from existing ones
5901 NewMeshName: a name of the new mesh to create
5904 instance of class :class:`Mesh`
5907 if IDsOfElements == []:
5908 IDsOfElements = self.GetElementsId()
5909 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5910 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5911 theMirrorType = Mirror._mirrorType
5913 self.mesh.SetParameters(Mirror.parameters)
5914 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5915 MakeGroups, NewMeshName)
5916 return Mesh(self.smeshpyD,self.geompyD,mesh)
5918 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5920 Create a symmetrical copy of the object
5923 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5924 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5925 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5926 If the *Mirror* is a geom object this parameter is unnecessary
5927 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5928 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5931 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5934 if ( isinstance( theObject, Mesh )):
5935 theObject = theObject.GetMesh()
5936 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5937 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5938 theMirrorType = Mirror._mirrorType
5940 self.mesh.SetParameters(Mirror.parameters)
5941 if Copy and MakeGroups:
5942 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5943 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5946 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5948 Create a new mesh by a symmetrical copy of the object
5951 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5952 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5953 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5954 If the *Mirror* is a geom object this parameter is unnecessary
5955 MakeGroups: forces the generation of new groups from existing ones
5956 NewMeshName: the name of the new mesh to create
5959 instance of class :class:`Mesh`
5962 if ( isinstance( theObject, Mesh )):
5963 theObject = theObject.GetMesh()
5964 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5965 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
5966 theMirrorType = Mirror._mirrorType
5968 self.mesh.SetParameters(Mirror.parameters)
5969 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5970 MakeGroups, NewMeshName)
5971 return Mesh( self.smeshpyD,self.geompyD,mesh )
5973 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5975 Translate the elements
5978 IDsOfElements: list of elements ids
5979 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5980 Copy: allows copying the translated elements
5981 MakeGroups: forces the generation of new groups from existing ones (if Copy)
5984 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5987 if IDsOfElements == []:
5988 IDsOfElements = self.GetElementsId()
5989 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5990 Vector = self.smeshpyD.GetDirStruct(Vector)
5991 if isinstance( Vector, list ):
5992 Vector = self.smeshpyD.MakeDirStruct(*Vector)
5993 self.mesh.SetParameters(Vector.PS.parameters)
5994 if Copy and MakeGroups:
5995 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5996 self.editor.Translate(IDsOfElements, Vector, Copy)
5999 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6001 Create a new mesh of translated elements
6004 IDsOfElements: list of elements ids
6005 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6006 MakeGroups: forces the generation of new groups from existing ones
6007 NewMeshName: the name of the newly created mesh
6010 instance of class :class:`Mesh`
6013 if IDsOfElements == []:
6014 IDsOfElements = self.GetElementsId()
6015 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6016 Vector = self.smeshpyD.GetDirStruct(Vector)
6017 if isinstance( Vector, list ):
6018 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6019 self.mesh.SetParameters(Vector.PS.parameters)
6020 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6021 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6023 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6025 Translate the object
6028 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6029 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6030 Copy: allows copying the translated elements
6031 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6034 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6037 if ( isinstance( theObject, Mesh )):
6038 theObject = theObject.GetMesh()
6039 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6040 Vector = self.smeshpyD.GetDirStruct(Vector)
6041 if isinstance( Vector, list ):
6042 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6043 self.mesh.SetParameters(Vector.PS.parameters)
6044 if Copy and MakeGroups:
6045 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6046 self.editor.TranslateObject(theObject, Vector, Copy)
6049 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6051 Create a new mesh from the translated object
6054 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6055 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6056 MakeGroups: forces the generation of new groups from existing ones
6057 NewMeshName: the name of the newly created mesh
6060 instance of class :class:`Mesh`
6063 if isinstance( theObject, Mesh ):
6064 theObject = theObject.GetMesh()
6065 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6066 Vector = self.smeshpyD.GetDirStruct(Vector)
6067 if isinstance( Vector, list ):
6068 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6069 self.mesh.SetParameters(Vector.PS.parameters)
6070 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6071 return Mesh( self.smeshpyD, self.geompyD, mesh )
6075 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6080 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6081 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6082 theScaleFact: list of 1-3 scale factors for axises
6083 Copy: allows copying the translated elements
6084 MakeGroups: forces the generation of new groups from existing
6088 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6089 empty list otherwise
6091 unRegister = genObjUnRegister()
6092 if ( isinstance( theObject, Mesh )):
6093 theObject = theObject.GetMesh()
6094 if ( isinstance( theObject, list )):
6095 theObject = self.GetIDSource(theObject, SMESH.ALL)
6096 unRegister.set( theObject )
6097 if ( isinstance( thePoint, list )):
6098 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6099 if ( isinstance( theScaleFact, float )):
6100 theScaleFact = [theScaleFact]
6101 if ( isinstance( theScaleFact, int )):
6102 theScaleFact = [ float(theScaleFact)]
6104 self.mesh.SetParameters(thePoint.parameters)
6106 if Copy and MakeGroups:
6107 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6108 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6111 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6113 Create a new mesh from the translated object
6116 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6117 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6118 theScaleFact: list of 1-3 scale factors for axises
6119 MakeGroups: forces the generation of new groups from existing ones
6120 NewMeshName: the name of the newly created mesh
6123 instance of class :class:`Mesh`
6125 unRegister = genObjUnRegister()
6126 if (isinstance(theObject, Mesh)):
6127 theObject = theObject.GetMesh()
6128 if ( isinstance( theObject, list )):
6129 theObject = self.GetIDSource(theObject,SMESH.ALL)
6130 unRegister.set( theObject )
6131 if ( isinstance( thePoint, list )):
6132 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6133 if ( isinstance( theScaleFact, float )):
6134 theScaleFact = [theScaleFact]
6135 if ( isinstance( theScaleFact, int )):
6136 theScaleFact = [ float(theScaleFact)]
6138 self.mesh.SetParameters(thePoint.parameters)
6139 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6140 MakeGroups, NewMeshName)
6141 return Mesh( self.smeshpyD, self.geompyD, mesh )
6145 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6150 IDsOfElements: list of elements ids
6151 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6152 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6153 Copy: allows copying the rotated elements
6154 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6157 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6161 if IDsOfElements == []:
6162 IDsOfElements = self.GetElementsId()
6163 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6164 Axis = self.smeshpyD.GetAxisStruct(Axis)
6165 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6166 Parameters = Axis.parameters + var_separator + Parameters
6167 self.mesh.SetParameters(Parameters)
6168 if Copy and MakeGroups:
6169 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6170 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6173 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6175 Create a new mesh of rotated elements
6178 IDsOfElements: list of element ids
6179 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6180 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6181 MakeGroups: forces the generation of new groups from existing ones
6182 NewMeshName: the name of the newly created mesh
6185 instance of class :class:`Mesh`
6188 if IDsOfElements == []:
6189 IDsOfElements = self.GetElementsId()
6190 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6191 Axis = self.smeshpyD.GetAxisStruct(Axis)
6192 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6193 Parameters = Axis.parameters + var_separator + Parameters
6194 self.mesh.SetParameters(Parameters)
6195 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6196 MakeGroups, NewMeshName)
6197 return Mesh( self.smeshpyD, self.geompyD, mesh )
6199 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6204 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6205 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6206 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6207 Copy: allows copying the rotated elements
6208 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6211 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6214 if (isinstance(theObject, Mesh)):
6215 theObject = theObject.GetMesh()
6216 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6217 Axis = self.smeshpyD.GetAxisStruct(Axis)
6218 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6219 Parameters = Axis.parameters + ":" + Parameters
6220 self.mesh.SetParameters(Parameters)
6221 if Copy and MakeGroups:
6222 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6223 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6226 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6228 Create a new mesh from the rotated object
6231 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6232 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6233 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6234 MakeGroups: forces the generation of new groups from existing ones
6235 NewMeshName: the name of the newly created mesh
6238 instance of class :class:`Mesh`
6241 if (isinstance( theObject, Mesh )):
6242 theObject = theObject.GetMesh()
6243 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6244 Axis = self.smeshpyD.GetAxisStruct(Axis)
6245 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6246 Parameters = Axis.parameters + ":" + Parameters
6247 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6248 MakeGroups, NewMeshName)
6249 self.mesh.SetParameters(Parameters)
6250 return Mesh( self.smeshpyD, self.geompyD, mesh )
6252 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6254 Create an offset mesh from the given 2D object
6257 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6258 theValue (float): signed offset size
6259 MakeGroups (boolean): forces the generation of new groups from existing ones
6260 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6261 False means to remove original elements.
6262 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6265 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6268 if isinstance( theObject, Mesh ):
6269 theObject = theObject.GetMesh()
6270 theValue,Parameters,hasVars = ParseParameters(Value)
6271 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6272 self.mesh.SetParameters(Parameters)
6273 # if mesh_groups[0]:
6274 # return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6277 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6279 Find groups of adjacent nodes within Tolerance.
6282 Tolerance (float): the value of tolerance
6283 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6284 corner and medium nodes in separate groups thus preventing
6285 their further merge.
6288 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6291 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6293 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6294 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6296 Find groups of adjacent nodes within Tolerance.
6299 Tolerance: the value of tolerance
6300 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6301 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6302 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6303 corner and medium nodes in separate groups thus preventing
6304 their further merge.
6307 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6310 unRegister = genObjUnRegister()
6311 if not isinstance( SubMeshOrGroup, list ):
6312 SubMeshOrGroup = [ SubMeshOrGroup ]
6313 for i,obj in enumerate( SubMeshOrGroup ):
6314 if isinstance( obj, Mesh ):
6315 SubMeshOrGroup = [ obj.GetMesh() ]
6317 if isinstance( obj, int ):
6318 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6319 unRegister.set( SubMeshOrGroup )
6322 if not isinstance( exceptNodes, list ):
6323 exceptNodes = [ exceptNodes ]
6324 if exceptNodes and isinstance( exceptNodes[0], int ):
6325 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6326 unRegister.set( exceptNodes )
6328 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6329 exceptNodes, SeparateCornerAndMediumNodes)
6331 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6336 GroupsOfNodes: a list of groups of nodes IDs for merging.
6337 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6338 in all elements and mesh groups by nodes 1 and 25 correspondingly
6339 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6340 If *NodesToKeep* does not include a node to keep for some group to merge,
6341 then the first node in the group is kept.
6342 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6345 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6347 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6349 Find the elements built on the same nodes.
6352 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6353 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6357 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6360 unRegister = genObjUnRegister()
6361 if MeshOrSubMeshOrGroup is None:
6362 MeshOrSubMeshOrGroup = [ self.mesh ]
6363 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6364 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6365 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6366 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6367 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6368 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6369 unRegister.set( MeshOrSubMeshOrGroup )
6370 for item in MeshOrSubMeshOrGroup:
6371 if isinstance( item, Mesh ):
6372 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6374 if not isinstance( exceptElements, list ):
6375 exceptElements = [ exceptElements ]
6376 if exceptElements and isinstance( exceptElements[0], int ):
6377 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6378 unRegister.set( exceptElements )
6380 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6382 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6384 Merge elements in each given group.
6387 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6388 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6389 replaced in all mesh groups by elements 1 and 25)
6390 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6391 If *ElementsToKeep* does not include an element to keep for some group to merge,
6392 then the first element in the group is kept.
6395 unRegister = genObjUnRegister()
6397 if not isinstance( ElementsToKeep, list ):
6398 ElementsToKeep = [ ElementsToKeep ]
6399 if isinstance( ElementsToKeep[0], int ):
6400 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6401 unRegister.set( ElementsToKeep )
6403 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6405 def MergeEqualElements(self):
6407 Leave one element and remove all other elements built on the same nodes.
6410 self.editor.MergeEqualElements()
6412 def FindFreeBorders(self, ClosedOnly=True):
6414 Returns all or only closed free borders
6417 list of SMESH.FreeBorder's
6420 return self.editor.FindFreeBorders( ClosedOnly )
6422 def FillHole(self, holeNodes, groupName=""):
6424 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6427 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6428 must describe all sequential nodes of the hole border. The first and the last
6429 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6430 groupName (string): name of a group to add new faces
6432 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6436 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6437 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6438 if not isinstance( holeNodes, SMESH.FreeBorder ):
6439 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6440 return self.editor.FillHole( holeNodes, groupName )
6442 def FindCoincidentFreeBorders (self, tolerance=0.):
6444 Return groups of FreeBorder's coincident within the given tolerance.
6447 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6448 size of elements adjacent to free borders being compared is used.
6451 SMESH.CoincidentFreeBorders structure
6454 return self.editor.FindCoincidentFreeBorders( tolerance )
6456 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6458 Sew FreeBorder's of each group
6461 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6462 where each enclosed list contains node IDs of a group of coincident free
6463 borders such that each consequent triple of IDs within a group describes
6464 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6465 last node of a border.
6466 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6467 groups of coincident free borders, each group including two borders.
6468 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6469 polygons if a node of opposite border falls on a face edge, else such
6470 faces are split into several ones.
6471 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6472 polyhedra if a node of opposite border falls on a volume edge, else such
6473 volumes, if any, remain intact and the mesh becomes non-conformal.
6476 a number of successfully sewed groups
6479 if freeBorders and isinstance( freeBorders, list ):
6480 # construct SMESH.CoincidentFreeBorders
6481 if isinstance( freeBorders[0], int ):
6482 freeBorders = [freeBorders]
6484 coincidentGroups = []
6485 for nodeList in freeBorders:
6486 if not nodeList or len( nodeList ) % 3:
6487 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6490 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6491 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6492 nodeList = nodeList[3:]
6494 coincidentGroups.append( group )
6496 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6498 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6500 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6501 FirstNodeID2, SecondNodeID2, LastNodeID2,
6502 CreatePolygons, CreatePolyedrs):
6507 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6510 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6511 FirstNodeID2, SecondNodeID2, LastNodeID2,
6512 CreatePolygons, CreatePolyedrs)
6514 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6515 FirstNodeID2, SecondNodeID2):
6517 Sew conform free borders
6520 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6523 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6524 FirstNodeID2, SecondNodeID2)
6526 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6527 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6532 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6535 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6536 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6538 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6539 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6540 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6542 Sew two sides of a mesh. The nodes belonging to Side1 are
6543 merged with the nodes of elements of Side2.
6544 The number of elements in theSide1 and in theSide2 must be
6545 equal and they should have similar nodal connectivity.
6546 The nodes to merge should belong to side borders and
6547 the first node should be linked to the second.
6550 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6553 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6554 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6555 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6557 def ChangeElemNodes(self, ide, newIDs):
6559 Set new nodes for the given element.
6566 False if the number of nodes does not correspond to the type of element
6569 return self.editor.ChangeElemNodes(ide, newIDs)
6571 def GetLastCreatedNodes(self):
6573 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6574 created, this method return the list of their IDs.
6575 If new nodes were not created - return empty list
6578 the list of integer values (can be empty)
6581 return self.editor.GetLastCreatedNodes()
6583 def GetLastCreatedElems(self):
6585 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6586 created this method return the list of their IDs.
6587 If new elements were not created - return empty list
6590 the list of integer values (can be empty)
6593 return self.editor.GetLastCreatedElems()
6595 def ClearLastCreated(self):
6597 Forget what nodes and elements were created by the last mesh edition operation
6600 self.editor.ClearLastCreated()
6602 def DoubleElements(self, theElements, theGroupName=""):
6604 Create duplicates of given elements, i.e. create new elements based on the
6605 same nodes as the given ones.
6608 theElements: container of elements to duplicate. It can be a
6609 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6610 or a list of element IDs. If *theElements* is
6611 a :class:`Mesh`, elements of highest dimension are duplicated
6612 theGroupName: a name of group to contain the generated elements.
6613 If a group with such a name already exists, the new elements
6614 are added to the existing group, else a new group is created.
6615 If *theGroupName* is empty, new elements are not added
6619 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6620 None if *theGroupName* == "".
6623 unRegister = genObjUnRegister()
6624 if isinstance( theElements, Mesh ):
6625 theElements = theElements.mesh
6626 elif isinstance( theElements, list ):
6627 theElements = self.GetIDSource( theElements, SMESH.ALL )
6628 unRegister.set( theElements )
6629 return self.editor.DoubleElements(theElements, theGroupName)
6631 def DoubleNodes(self, theNodes, theModifiedElems):
6633 Create a hole in a mesh by doubling the nodes of some particular elements
6636 theNodes: IDs of nodes to be doubled
6637 theModifiedElems: IDs of elements to be updated by the new (doubled)
6638 nodes. If list of element identifiers is empty then nodes are doubled but
6639 they not assigned to elements
6642 True if operation has been completed successfully, False otherwise
6645 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6647 def DoubleNode(self, theNodeId, theModifiedElems):
6649 Create a hole in a mesh by doubling the nodes of some particular elements.
6650 This method provided for convenience works as :meth:`DoubleNodes`.
6653 theNodeId: IDs of node to double
6654 theModifiedElems: IDs of elements to update
6657 True if operation has been completed successfully, False otherwise
6660 return self.editor.DoubleNode(theNodeId, theModifiedElems)
6662 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6664 Create a hole in a mesh by doubling the nodes of some particular elements.
6665 This method provided for convenience works as :meth:`DoubleNodes`.
6668 theNodes: group of nodes to double.
6669 theModifiedElems: group of elements to update.
6670 theMakeGroup: forces the generation of a group containing new nodes.
6673 True or a created group if operation has been completed successfully,
6674 False or None otherwise
6678 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6679 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6681 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6683 Create a hole in a mesh by doubling the nodes of some particular elements.
6684 This method provided for convenience works as :meth:`DoubleNodes`.
6687 theNodes: list of groups of nodes to double.
6688 theModifiedElems: list of groups of elements to update.
6689 theMakeGroup: forces the generation of a group containing new nodes.
6692 True if operation has been completed successfully, False otherwise
6696 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6697 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6699 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6701 Create a hole in a mesh by doubling the nodes of some particular elements
6704 theElems: the list of elements (edges or faces) to replicate.
6705 The nodes for duplication could be found from these elements
6706 theNodesNot: list of nodes NOT to replicate
6707 theAffectedElems: the list of elements (cells and edges) to which the
6708 replicated nodes should be associated to
6711 True if operation has been completed successfully, False otherwise
6714 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6716 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6718 Create a hole in a mesh by doubling the nodes of some particular elements
6721 theElems: the list of elements (edges or faces) to replicate.
6722 The nodes for duplication could be found from these elements
6723 theNodesNot: list of nodes NOT to replicate
6724 theShape: shape to detect affected elements (element which geometric center
6725 located on or inside shape).
6726 The replicated nodes should be associated to affected elements.
6729 True if operation has been completed successfully, False otherwise
6732 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6734 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6735 theMakeGroup=False, theMakeNodeGroup=False):
6737 Create a hole in a mesh by doubling the nodes of some particular elements.
6738 This method provided for convenience works as :meth:`DoubleNodes`.
6741 theElems: group of of elements (edges or faces) to replicate.
6742 theNodesNot: group of nodes NOT to replicate.
6743 theAffectedElems: group of elements to which the replicated nodes
6744 should be associated to.
6745 theMakeGroup: forces the generation of a group containing new elements.
6746 theMakeNodeGroup: forces the generation of a group containing new nodes.
6749 True or created groups (one or two) if operation has been completed successfully,
6750 False or None otherwise
6753 if theMakeGroup or theMakeNodeGroup:
6754 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6756 theMakeGroup, theMakeNodeGroup)
6757 if theMakeGroup and theMakeNodeGroup:
6760 return twoGroups[ int(theMakeNodeGroup) ]
6761 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6763 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6765 Create a hole in a mesh by doubling the nodes of some particular elements.
6766 This method provided for convenience works as :meth:`DoubleNodes`.
6769 theElems: group of of elements (edges or faces) to replicate
6770 theNodesNot: group of nodes not to replicate
6771 theShape: shape to detect affected elements (element which geometric center
6772 located on or inside shape).
6773 The replicated nodes should be associated to affected elements
6776 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6778 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6779 theMakeGroup=False, theMakeNodeGroup=False):
6781 Create a hole in a mesh by doubling the nodes of some particular elements.
6782 This method provided for convenience works as :meth:`DoubleNodes`.
6785 theElems: list of groups of elements (edges or faces) to replicate
6786 theNodesNot: list of groups of nodes NOT to replicate
6787 theAffectedElems: group of elements to which the replicated nodes
6788 should be associated to
6789 theMakeGroup: forces generation of a group containing new elements.
6790 theMakeNodeGroup: forces generation of a group containing new nodes
6793 True or created groups (one or two) if operation has been completed successfully,
6794 False or None otherwise
6797 if theMakeGroup or theMakeNodeGroup:
6798 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6800 theMakeGroup, theMakeNodeGroup)
6801 if theMakeGroup and theMakeNodeGroup:
6804 return twoGroups[ int(theMakeNodeGroup) ]
6805 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6807 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6809 Create a hole in a mesh by doubling the nodes of some particular elements.
6810 This method provided for convenience works as :meth:`DoubleNodes`.
6813 theElems: list of groups of elements (edges or faces) to replicate
6814 theNodesNot: list of groups of nodes NOT to replicate
6815 theShape: shape to detect affected elements (element which geometric center
6816 located on or inside shape).
6817 The replicated nodes should be associated to affected elements
6820 True if operation has been completed successfully, False otherwise
6823 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6825 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6827 Identify the elements that will be affected by node duplication (actual duplication is not performed).
6828 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6831 theElems: list of groups of nodes or elements (edges or faces) to replicate
6832 theNodesNot: list of groups of nodes NOT to replicate
6833 theShape: shape to detect affected elements (element which geometric center
6834 located on or inside shape).
6835 The replicated nodes should be associated to affected elements
6838 groups of affected elements in order: volumes, faces, edges
6841 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6843 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6846 Double nodes on shared faces between groups of volumes and create flat elements on demand.
6847 The list of groups must describe a partition of the mesh volumes.
6848 The nodes of the internal faces at the boundaries of the groups are doubled.
6849 In option, the internal faces are replaced by flat elements.
6850 Triangles are transformed to prisms, and quadrangles to hexahedrons.
6853 theDomains: list of groups of volumes
6854 createJointElems: if True, create the elements
6855 onAllBoundaries: if True, the nodes and elements are also created on
6856 the boundary between *theDomains* and the rest mesh
6859 True if operation has been completed successfully, False otherwise
6862 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6864 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6866 Double nodes on some external faces and create flat elements.
6867 Flat elements are mainly used by some types of mechanic calculations.
6869 Each group of the list must be constituted of faces.
6870 Triangles are transformed in prisms, and quadrangles in hexahedrons.
6873 theGroupsOfFaces: list of groups of faces
6876 True if operation has been completed successfully, False otherwise
6879 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6881 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6883 Identify all the elements around a geom shape, get the faces delimiting the hole
6885 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6887 def MakePolyLine(self, segments, groupName='', isPreview=False ):
6889 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6890 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6891 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6892 If there are several paths connecting a pair of points, the shortest path is
6893 selected by the module. Position of the cutting plane is defined by the two
6894 points and an optional vector lying on the plane specified by a PolySegment.
6895 By default the vector is defined by Mesh module as following. A middle point
6896 of the two given points is computed. The middle point is projected to the mesh.
6897 The vector goes from the middle point to the projection point. In case of planar
6898 mesh, the vector is normal to the mesh.
6900 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6903 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6904 groupName: optional name of a group where created mesh segments will be added.
6907 editor = self.editor
6909 editor = self.mesh.GetMeshEditPreviewer()
6910 segmentsRes = editor.MakePolyLine( segments, groupName )
6911 for i, seg in enumerate( segmentsRes ):
6912 segments[i].vector = seg.vector
6914 return editor.GetPreviewData()
6917 def MakeSlot(self, segmentGroup, width ):
6919 Create a slot of given width around given 1D elements lying on a triangle mesh.
6920 The slot is consrtucted by cutting faces by cylindrical surfaces made
6921 around each segment. Segments are expected to be created by MakePolyLine().
6924 FaceEdge's located at the slot boundary
6926 return self.editor.MakeSlot( segmentGroup, width )
6928 def GetFunctor(self, funcType ):
6930 Return a cached numerical functor by its type.
6933 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6934 Note that not all items correspond to numerical functors.
6937 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6940 fn = self.functors[ funcType._v ]
6942 fn = self.smeshpyD.GetFunctor(funcType)
6943 fn.SetMesh(self.mesh)
6944 self.functors[ funcType._v ] = fn
6947 def FunctorValue(self, funcType, elemId, isElem=True):
6949 Return value of a functor for a given element
6952 funcType: an item of :class:`SMESH.FunctorType` enum.
6953 elemId: element or node ID
6954 isElem: *elemId* is ID of element or node
6957 the functor value or zero in case of invalid arguments
6960 fn = self.GetFunctor( funcType )
6961 if fn.GetElementType() == self.GetElementType(elemId, isElem):
6962 val = fn.GetValue(elemId)
6967 def GetLength(self, elemId=None):
6969 Get length of given 1D elements or of all 1D mesh elements
6972 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.
6975 Sum of lengths of given elements
6980 length = self.smeshpyD.GetLength(self)
6981 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
6982 length = self.smeshpyD.GetLength(elemId)
6985 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
6987 length += self.smeshpyD.GetLength(obj)
6988 elif isinstance(elemId, list) and isinstance(elemId[0], int):
6989 unRegister = genObjUnRegister()
6990 obj = self.GetIDSource( elemId )
6991 unRegister.set( obj )
6992 length = self.smeshpyD.GetLength( obj )
6994 length = self.FunctorValue(SMESH.FT_Length, elemId)
6997 def GetArea(self, elemId=None):
6999 Get area of given 2D elements or of all 2D mesh elements
7002 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.
7005 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7010 area = self.smeshpyD.GetArea(self)
7011 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7012 area = self.smeshpyD.GetArea(elemId)
7015 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7017 area += self.smeshpyD.GetArea(obj)
7018 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7019 unRegister = genObjUnRegister()
7020 obj = self.GetIDSource( elemId )
7021 unRegister.set( obj )
7022 area = self.smeshpyD.GetArea( obj )
7024 area = self.FunctorValue(SMESH.FT_Area, elemId)
7027 def GetVolume(self, elemId=None):
7029 Get volume of given 3D elements or of all 3D mesh elements
7032 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.
7035 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7040 volume= self.smeshpyD.GetVolume(self)
7041 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7042 volume= self.smeshpyD.GetVolume(elemId)
7045 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7047 volume+= self.smeshpyD.GetVolume(obj)
7048 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7049 unRegister = genObjUnRegister()
7050 obj = self.GetIDSource( elemId )
7051 unRegister.set( obj )
7052 volume= self.smeshpyD.GetVolume( obj )
7054 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7057 def GetAngle(self, node1, node2, node3 ):
7059 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7062 node1,node2,node3: IDs of the three nodes
7065 Angle in radians [0,PI]. -1 if failure case.
7067 p1 = self.GetNodeXYZ( node1 )
7068 p2 = self.GetNodeXYZ( node2 )
7069 p3 = self.GetNodeXYZ( node3 )
7070 if p1 and p2 and p3:
7071 return self.smeshpyD.GetAngle( p1,p2,p3 )
7075 def GetMaxElementLength(self, elemId):
7077 Get maximum element length.
7080 elemId: mesh element ID
7083 element's maximum length value
7086 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7087 ftype = SMESH.FT_MaxElementLength3D
7089 ftype = SMESH.FT_MaxElementLength2D
7090 return self.FunctorValue(ftype, elemId)
7092 def GetAspectRatio(self, elemId):
7094 Get aspect ratio of 2D or 3D element.
7097 elemId: mesh element ID
7100 element's aspect ratio value
7103 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7104 ftype = SMESH.FT_AspectRatio3D
7106 ftype = SMESH.FT_AspectRatio
7107 return self.FunctorValue(ftype, elemId)
7109 def GetWarping(self, elemId):
7111 Get warping angle of 2D element.
7114 elemId: mesh element ID
7117 element's warping angle value
7120 return self.FunctorValue(SMESH.FT_Warping, elemId)
7122 def GetMinimumAngle(self, elemId):
7124 Get minimum angle of 2D element.
7127 elemId: mesh element ID
7130 element's minimum angle value
7133 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7135 def GetTaper(self, elemId):
7137 Get taper of 2D element.
7140 elemId: mesh element ID
7143 element's taper value
7146 return self.FunctorValue(SMESH.FT_Taper, elemId)
7148 def GetSkew(self, elemId):
7150 Get skew of 2D element.
7153 elemId: mesh element ID
7156 element's skew value
7159 return self.FunctorValue(SMESH.FT_Skew, elemId)
7161 def GetMinMax(self, funType, meshPart=None):
7163 Return minimal and maximal value of a given functor.
7166 funType (SMESH.FunctorType): a functor type.
7167 Note that not all items of :class:`SMESH.FunctorType` corresponds
7168 to numerical functors.
7169 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7175 unRegister = genObjUnRegister()
7176 if isinstance( meshPart, list ):
7177 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7178 unRegister.set( meshPart )
7179 if isinstance( meshPart, Mesh ):
7180 meshPart = meshPart.mesh
7181 fun = self.GetFunctor( funType )
7184 if hasattr( meshPart, "SetMesh" ):
7185 meshPart.SetMesh( self.mesh ) # set mesh to filter
7186 hist = fun.GetLocalHistogram( 1, False, meshPart )
7188 hist = fun.GetHistogram( 1, False )
7190 return hist[0].min, hist[0].max
7193 pass # end of Mesh class
7196 class meshProxy(SMESH._objref_SMESH_Mesh):
7198 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7199 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7201 def __init__(self,*args):
7202 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7203 def __deepcopy__(self, memo=None):
7204 new = self.__class__(self)
7206 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7207 if len( args ) == 3:
7208 args += SMESH.ALL_NODES, True
7209 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7210 def ExportToMEDX(self, *args): # function removed
7211 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7212 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7213 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7214 def ExportToMED(self, *args): # function removed
7215 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7216 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7218 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7220 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7221 def ExportPartToMED(self, *args): # 'version' parameter removed
7222 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7223 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7224 def ExportMED(self, *args): # signature of method changed
7225 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7227 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7229 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7231 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7234 class submeshProxy(SMESH._objref_SMESH_subMesh):
7237 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7239 def __init__(self,*args):
7240 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7242 def __deepcopy__(self, memo=None):
7243 new = self.__class__(self)
7246 def Compute(self,refresh=False):
7248 Compute the sub-mesh and return the status of the computation
7251 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7256 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7257 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7261 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7263 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7265 if salome.sg.hasDesktop():
7266 if refresh: salome.sg.updateObjBrowser()
7271 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7274 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7276 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7277 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7280 def __init__(self,*args):
7281 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7283 def __getattr__(self, name ): # method called if an attribute not found
7284 if not self.mesh: # look for name() method in Mesh class
7285 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7286 if hasattr( self.mesh, name ):
7287 return getattr( self.mesh, name )
7288 if name == "ExtrusionAlongPathObjX":
7289 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7290 print("meshEditor: attribute '%s' NOT FOUND" % name)
7292 def __deepcopy__(self, memo=None):
7293 new = self.__class__(self)
7295 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7296 if len( args ) == 1: args += False,
7297 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7298 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7299 if len( args ) == 2: args += False,
7300 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7301 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7302 if len( args ) == 1:
7303 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7304 NodesToKeep = args[1]
7305 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7306 unRegister = genObjUnRegister()
7308 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7309 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7310 if not isinstance( NodesToKeep, list ):
7311 NodesToKeep = [ NodesToKeep ]
7312 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7314 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7316 class Pattern(SMESH._objref_SMESH_Pattern):
7318 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7319 variables in some methods
7322 def LoadFromFile(self, patternTextOrFile ):
7323 text = patternTextOrFile
7324 if os.path.exists( text ):
7325 text = open( patternTextOrFile ).read()
7327 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7329 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7330 decrFun = lambda i: i-1
7331 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7332 theMesh.SetParameters(Parameters)
7333 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7335 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7336 decrFun = lambda i: i-1
7337 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7338 theMesh.SetParameters(Parameters)
7339 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7341 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7342 if isinstance( mesh, Mesh ):
7343 mesh = mesh.GetMesh()
7344 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7346 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7348 Registering the new proxy for Pattern
7353 Private class used to bind methods creating algorithms to the class Mesh
7356 def __init__(self, method):
7358 self.defaultAlgoType = ""
7359 self.algoTypeToClass = {}
7360 self.method = method
7362 def add(self, algoClass):
7364 Store a python class of algorithm
7366 if inspect.isclass(algoClass) and \
7367 hasattr( algoClass, "algoType"):
7368 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7369 if not self.defaultAlgoType and \
7370 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7371 self.defaultAlgoType = algoClass.algoType
7372 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7374 def copy(self, mesh):
7376 Create a copy of self and assign mesh to the copy
7379 other = algoCreator( self.method )
7380 other.defaultAlgoType = self.defaultAlgoType
7381 other.algoTypeToClass = self.algoTypeToClass
7385 def __call__(self,algo="",geom=0,*args):
7387 Create an instance of algorithm
7391 if isinstance( algo, str ):
7393 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7394 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7399 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7401 elif not algoType and isinstance( geom, str ):
7406 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7408 elif isinstance( arg, str ) and not algoType:
7411 import traceback, sys
7412 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7413 sys.stderr.write( msg + '\n' )
7414 tb = traceback.extract_stack(None,2)
7415 traceback.print_list( [tb[0]] )
7417 algoType = self.defaultAlgoType
7418 if not algoType and self.algoTypeToClass:
7419 algoType = sorted( self.algoTypeToClass.keys() )[0]
7420 if algoType in self.algoTypeToClass:
7421 #print("Create algo",algoType)
7422 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7423 raise RuntimeError( "No class found for algo type %s" % algoType)
7426 class hypMethodWrapper:
7428 Private class used to substitute and store variable parameters of hypotheses.
7431 def __init__(self, hyp, method):
7433 self.method = method
7434 #print("REBIND:", method.__name__)
7437 def __call__(self,*args):
7439 call a method of hypothesis with calling SetVarParameter() before
7443 return self.method( self.hyp, *args ) # hypothesis method with no args
7445 #print("MethWrapper.__call__", self.method.__name__, args)
7447 parsed = ParseParameters(*args) # replace variables with their values
7448 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7449 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7450 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7451 # maybe there is a replaced string arg which is not variable
7452 result = self.method( self.hyp, *args )
7453 except ValueError as detail: # raised by ParseParameters()
7455 result = self.method( self.hyp, *args )
7456 except omniORB.CORBA.BAD_PARAM:
7457 raise ValueError(detail) # wrong variable name
7462 class genObjUnRegister:
7464 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7467 def __init__(self, genObj=None):
7468 self.genObjList = []
7472 def set(self, genObj):
7473 "Store one or a list of of SALOME.GenericObj'es"
7474 if isinstance( genObj, list ):
7475 self.genObjList.extend( genObj )
7477 self.genObjList.append( genObj )
7481 for genObj in self.genObjList:
7482 if genObj and hasattr( genObj, "UnRegister" ):
7485 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7487 Bind methods creating mesher plug-ins to the Mesh class
7490 # print("pluginName: ", pluginName)
7491 pluginBuilderName = pluginName + "Builder"
7493 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7494 except Exception as e:
7495 from salome_utils import verbose
7496 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7498 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7499 plugin = eval( pluginBuilderName )
7500 # print(" plugin:" , str(plugin))
7502 # add methods creating algorithms to Mesh
7503 for k in dir( plugin ):
7504 if k[0] == '_': continue
7505 algo = getattr( plugin, k )
7506 #print(" algo:", str(algo))
7507 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7508 #print(" meshMethod:" , str(algo.meshMethod))
7509 if not hasattr( Mesh, algo.meshMethod ):
7510 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7512 _mmethod = getattr( Mesh, algo.meshMethod )
7513 if hasattr( _mmethod, "add" ):