1 # Copyright (C) 2007-2023 CEA, EDF, 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
43 from StdMeshers import BlockCS
50 # In case the omniORBpy EnumItem class does not fully support Python 3
51 # (for instance in version 4.2.1-2), the comparison ordering methods must be
55 SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
57 def enumitem_eq(self, other):
59 if isinstance(other, omniORB.EnumItem):
60 if other._parent_id == self._parent_id:
61 return self._v == other._v
63 return self._parent_id == other._parent_id
65 return id(self) == id(other)
67 return id(self) == id(other)
69 def enumitem_lt(self, other):
71 if isinstance(other, omniORB.EnumItem):
72 if other._parent_id == self._parent_id:
73 return self._v < other._v
75 return self._parent_id < other._parent_id
77 return id(self) < id(other)
79 return id(self) < id(other)
81 def enumitem_le(self, other):
83 if isinstance(other, omniORB.EnumItem):
84 if other._parent_id == self._parent_id:
85 return self._v <= other._v
87 return self._parent_id <= other._parent_id
89 return id(self) <= id(other)
91 return id(self) <= id(other)
93 def enumitem_gt(self, other):
95 if isinstance(other, omniORB.EnumItem):
96 if other._parent_id == self._parent_id:
97 return self._v > other._v
99 return self._parent_id > other._parent_id
101 return id(self) > id(other)
103 return id(self) > id(other)
105 def enumitem_ge(self, other):
107 if isinstance(other, omniORB.EnumItem):
108 if other._parent_id == self._parent_id:
109 return self._v >= other._v
111 return self._parent_id >= other._parent_id
113 return id(self) >= id(other)
115 return id(self) >= id(other)
117 omniORB.EnumItem.__eq__ = enumitem_eq
118 omniORB.EnumItem.__lt__ = enumitem_lt
119 omniORB.EnumItem.__le__ = enumitem_le
120 omniORB.EnumItem.__gt__ = enumitem_gt
121 omniORB.EnumItem.__ge__ = enumitem_ge
124 class MeshMeta(type):
125 """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
127 def __instancecheck__(cls, inst):
128 """Implement isinstance(inst, cls)."""
129 return any(cls.__subclasscheck__(c)
130 for c in {type(inst), inst.__class__})
132 def __subclasscheck__(cls, sub):
133 """Implement issubclass(sub, cls)."""
134 return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
136 def DegreesToRadians(AngleInDegrees):
137 """Convert an angle from degrees to radians
140 return AngleInDegrees * pi / 180.0
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
147 def ParseParameters(*args):
149 Return list of variable values from salome notebook.
150 The last argument, if is callable, is used to modify values got from notebook
156 if args and callable(args[-1]):
157 args, varModifFun = args[:-1], args[-1]
158 for parameter in args:
160 Parameters += str(parameter) + var_separator
162 if isinstance(parameter,str):
163 # check if there is an inexistent variable name
164 if not notebook.isVariable(parameter):
165 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
166 parameter = notebook.get(parameter)
169 parameter = varModifFun(parameter)
172 Result.append(parameter)
175 Parameters = Parameters[:-1]
176 Result.append( Parameters )
177 Result.append( hasVariables )
180 def ParseAngles(*args):
182 Parse parameters while converting variables to radians
184 return ParseParameters( *( args + (DegreesToRadians, )))
186 def __initPointStruct(point,*args):
188 Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189 Parameters are stored in PointStruct.parameters attribute
191 point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
193 SMESH.PointStruct.__init__ = __initPointStruct
195 def __initAxisStruct(ax,*args):
197 Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198 Parameters are stored in AxisStruct.parameters attribute
201 raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
202 ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
204 SMESH.AxisStruct.__init__ = __initAxisStruct
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208 """Compare real values using smeshPrecisionConfusion as tolerance
210 if abs(val1 - val2) < tol:
218 Return a name of an object
225 if isinstance(obj, SALOMEDS._objref_SObject):
229 ior = salome.orb.object_to_string(obj)
233 sobj = salome.myStudy.FindObjectIOR(ior)
235 return sobj.GetName()
236 if hasattr(obj, "GetName"):
237 # unknown CORBA object, having GetName() method
240 # unknown CORBA object, no GetName() method
243 if hasattr(obj, "GetName"):
244 # unknown non-CORBA object, having GetName() method
247 raise RuntimeError("Null or invalid object")
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
251 Print error message if a hypothesis was not assigned.
254 hypType = "algorithm"
256 hypType = "hypothesis"
259 if hasattr( status, "__getitem__" ):
260 status, reason = status[0], status[1]
261 if status == HYP_UNKNOWN_FATAL:
262 reason = "for unknown reason"
263 elif status == HYP_INCOMPATIBLE:
264 reason = "this hypothesis mismatches the algorithm"
265 elif status == HYP_NOTCONFORM:
266 reason = "a non-conform mesh would be built"
267 elif status == HYP_ALREADY_EXIST:
268 if isAlgo: return # it does not influence anything
269 reason = hypType + " of the same dimension is already assigned to this shape"
270 elif status == HYP_BAD_DIM:
271 reason = hypType + " mismatches the shape"
272 elif status == HYP_CONCURRENT :
273 reason = "there are concurrent hypotheses on sub-shapes"
274 elif status == HYP_BAD_SUBSHAPE:
275 reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
276 elif status == HYP_BAD_GEOMETRY:
277 reason = "the algorithm is not applicable to this geometry"
278 elif status == HYP_HIDDEN_ALGO:
279 reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
280 elif status == HYP_HIDING_ALGO:
281 reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
282 elif status == HYP_NEED_SHAPE:
283 reason = "algorithm can't work without shape"
284 elif status == HYP_INCOMPAT_HYPS:
290 where = '"%s"' % geomName
292 meshName = GetName( mesh )
293 if meshName and meshName != NO_NAME:
294 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
295 if status < HYP_UNKNOWN_FATAL and where:
296 print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
298 print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
300 print('"%s" was not assigned : %s' %( hypName, reason ))
303 def AssureGeomPublished(mesh, geom, name=''):
305 Private method. Add geom (sub-shape of the main shape) into the study if not yet there
307 if not mesh.smeshpyD.IsEnablePublish():
309 if not hasattr( geom, "GetShapeType" ):
311 if not geom.GetStudyEntry():
313 if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
314 # for all groups SubShapeName() return "Compound_-1"
315 name = mesh.geompyD.SubShapeName(geom, mesh.geom)
317 name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
319 mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
322 # def FirstVertexOnCurve(mesh, edge):
325 # the first vertex of a geometrical edge by ignoring orientation
327 # return mesh.geompyD.GetVertexByIndex( edge, 0, False )
333 smeshInst is a singleton
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
341 This class allows to create, load or manipulate meshes.
342 It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
343 It also has methods to get infos and measure meshes.
346 # MirrorType enumeration
347 POINT = SMESH_MeshEditor.POINT
348 AXIS = SMESH_MeshEditor.AXIS
349 PLANE = SMESH_MeshEditor.PLANE
351 # Smooth_Method enumeration
352 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
355 PrecisionConfusion = smeshPrecisionConfusion
357 # TopAbs_State enumeration
358 [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
360 # Methods of splitting a hexahedron into tetrahedra
361 Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
363 def __new__(cls, *args):
367 #print("==== __new__", engine, smeshInst, doLcc)
369 if smeshInst is None:
370 # smesh engine is either retrieved from engine, or created
372 # Following test avoids a recursive loop
374 if smeshInst is not None:
375 # smesh engine not created: existing engine found
379 # FindOrLoadComponent called:
380 # 1. CORBA resolution of server
381 # 2. the __new__ method is called again
382 #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
383 smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
385 # FindOrLoadComponent not called
386 if smeshInst is None:
387 # smeshBuilder instance is created from lcc.FindOrLoadComponent
388 #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
389 smeshInst = super(smeshBuilder,cls).__new__(cls)
391 # smesh engine not created: existing engine found
392 #print("==== existing ", engine, smeshInst, doLcc)
394 #print("====1 ", smeshInst)
397 #print("====2 ", smeshInst)
400 def __init__(self, *args):
402 #print("--------------- smeshbuilder __init__ ---", created)
405 SMESH._objref_SMESH_Gen.__init__(self, *args)
408 def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
410 Dump component to the Python script.
411 This method overrides IDL function to allow default values for the parameters.
414 return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
416 def SetDumpPythonHistorical(self, isHistorical):
418 Set mode of DumpPython(), *historical* or *snapshot*.
419 In the *historical* mode, the Python Dump script includes all commands
420 performed by SMESH engine. In the *snapshot* mode, commands
421 relating to objects removed from the Study are excluded from the script
422 as well as commands not influencing the current state of meshes
425 if isHistorical: val = "true"
427 SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
429 def init_smesh(self,geompyD = None):
431 Set Geometry component
434 self.UpdateStudy(geompyD)
435 notebook.myStudy = salome.myStudy
437 def Mesh(self, obj=0, name=0):
439 Create a mesh. This mesh can be either
441 * an empty mesh not bound to geometry, if *obj* == 0
442 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
443 * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
448 1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
451 salome.myStudy.FindObjectID("0:1:2:3").GetObject()
453 2. a geometrical object for meshing
455 name: the name for the new mesh.
458 an instance of class :class:`Mesh`.
461 if isinstance(obj,str):
463 return Mesh(self, self.geompyD, obj, name)
465 def ParallelMesh(self, obj, name=0, split_geom=True):
467 Create a parallel mesh.
470 obj: geometrical object for meshing
471 name: the name for the new mesh.
472 split_geom: If True split the geometry and create the assoicated
476 an instance of class :class:`ParallelMesh`.
478 return ParallelMesh(self, self.geompyD, obj,
479 split_geom=split_geom, name=name)
481 def RemoveMesh( self, mesh ):
485 if isinstance( mesh, Mesh ):
486 mesh = mesh.GetMesh()
488 if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
489 raise TypeError("%s is not a mesh" % mesh )
490 so = salome.ObjectToSObject( mesh )
492 sb = salome.myStudy.NewBuilder()
493 sb.RemoveObjectWithChildren( so )
499 def EnumToLong(self,theItem):
501 Return a long value from enumeration
506 def ColorToString(self,c):
508 Convert SALOMEDS.Color to string.
509 To be used with filters.
512 c: color value (SALOMEDS.Color)
515 a string representation of the color.
519 if isinstance(c, SALOMEDS.Color):
520 val = "%s;%s;%s" % (c.R, c.G, c.B)
521 elif isinstance(c, str):
524 raise ValueError("Color value should be of string or SALOMEDS.Color type")
527 def GetPointStruct(self,theVertex):
529 Get :class:`SMESH.PointStruct` from vertex
532 theVertex (GEOM.GEOM_Object): vertex
535 :class:`SMESH.PointStruct`
537 geompyD = theVertex.GetGen()
538 [x, y, z] = geompyD.PointCoordinates(theVertex)
539 return PointStruct(x,y,z)
541 def GetDirStruct(self,theVector):
543 Get :class:`SMESH.DirStruct` from vector
546 theVector (GEOM.GEOM_Object): vector
549 :class:`SMESH.DirStruct`
551 geompyD = theVector.GetGen()
552 vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
553 if(len(vertices) != 2):
554 print("Error: vector object is incorrect.")
556 p1 = geompyD.PointCoordinates(vertices[0])
557 p2 = geompyD.PointCoordinates(vertices[1])
558 pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
559 dirst = DirStruct(pnt)
562 def MakeDirStruct(self,x,y,z):
564 Make :class:`SMESH.DirStruct` from a triplet of floats
567 x,y,z (float): vector components
570 :class:`SMESH.DirStruct`
573 pnt = PointStruct(x,y,z)
574 return DirStruct(pnt)
576 def GetAxisStruct(self,theObj):
578 Get :class:`SMESH.AxisStruct` from a geometrical object
581 theObj (GEOM.GEOM_Object): line or plane
584 :class:`SMESH.AxisStruct`
587 geompyD = theObj.GetGen()
588 edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
591 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
592 vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
593 vertex1 = geompyD.PointCoordinates(vertex1)
594 vertex2 = geompyD.PointCoordinates(vertex2)
595 vertex3 = geompyD.PointCoordinates(vertex3)
596 vertex4 = geompyD.PointCoordinates(vertex4)
597 v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
598 v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
599 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] ]
600 axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
601 axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
602 elif len(edges) == 1:
603 vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
604 p1 = geompyD.PointCoordinates( vertex1 )
605 p2 = geompyD.PointCoordinates( vertex2 )
606 axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
607 axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
608 elif theObj.GetShapeType() == GEOM.VERTEX:
609 x,y,z = geompyD.PointCoordinates( theObj )
610 axis = AxisStruct( x,y,z, 1,0,0,)
611 axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
614 # From SMESH_Gen interface:
615 # ------------------------
617 def SetName(self, obj, name):
619 Set the given name to an object
622 obj: the object to rename
623 name: a new object name
626 if isinstance( obj, Mesh ):
628 elif isinstance( obj, Mesh_Algorithm ):
629 obj = obj.GetAlgorithm()
630 ior = salome.orb.object_to_string(obj)
631 SMESH._objref_SMESH_Gen.SetName(self, ior, name)
633 def SetEmbeddedMode( self,theMode ):
638 SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
640 def IsEmbeddedMode(self):
645 return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
647 def UpdateStudy( self, geompyD = None ):
649 Update the current study. Calling UpdateStudy() allows to
650 update meshes at switching GEOM->SMESH
654 from salome.geom import geomBuilder
655 geompyD = geomBuilder.geom
657 geompyD = geomBuilder.New()
660 self.SetGeomEngine(geompyD)
661 SMESH._objref_SMESH_Gen.UpdateStudy(self)
662 sb = salome.myStudy.NewBuilder()
663 sc = salome.myStudy.FindComponent("SMESH")
665 sb.LoadWith(sc, self)
668 def SetEnablePublish( self, theIsEnablePublish ):
670 Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
671 switch **off** publishing in the Study of mesh objects.
673 #self.SetEnablePublish(theIsEnablePublish)
674 SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
676 notebook = salome_notebook.NoteBook( theIsEnablePublish )
679 def CreateMeshesFromUNV( self,theFileName ):
681 Create a Mesh object importing data from the given UNV file
684 an instance of class :class:`Mesh`
687 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
688 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
691 def CreateMeshesFromMED( self,theFileName ):
693 Create a Mesh object(s) importing data from the given MED file
696 a tuple ( list of class :class:`Mesh` instances,
697 :class:`SMESH.DriverMED_ReadStatus` )
700 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
701 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
702 return aMeshes, aStatus
704 def CreateMeshesFromSTL( self, theFileName ):
706 Create a Mesh object importing data from the given STL file
709 an instance of class :class:`Mesh`
712 aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
713 aMesh = Mesh(self, self.geompyD, aSmeshMesh)
716 def CreateMeshesFromCGNS( self, theFileName ):
718 Create Mesh objects importing data from the given CGNS file
721 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
724 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
725 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
726 return aMeshes, aStatus
728 def CreateMeshesFromGMF( self, theFileName ):
730 Create a Mesh object importing data from the given GMF file.
731 GMF files must have .mesh extension for the ASCII format and .meshb for
735 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
738 aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
741 if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
742 return Mesh(self, self.geompyD, aSmeshMesh), error
744 def Concatenate( self, meshes, uniteIdenticalGroups,
745 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
746 name = "", meshToAppendTo = None):
748 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
749 All groups of input meshes will be present in the new mesh.
752 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
753 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
754 mergeNodesAndElements: if True, equal nodes and elements are merged
755 mergeTolerance: tolerance for merging nodes
756 allGroups: forces creation of groups corresponding to every input mesh
757 name: name of a new mesh
758 meshToAppendTo: a mesh to append all given meshes
761 an instance of class :class:`Mesh`
767 if not meshes: return None
768 if not isinstance( meshes, list ):
770 for i,m in enumerate( meshes ):
771 if isinstance( m, Mesh ):
772 meshes[i] = m.GetMesh()
773 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
774 if hasattr(meshes[0], "SetParameters"):
775 meshes[0].SetParameters( Parameters )
777 meshes[0].GetMesh().SetParameters( Parameters )
778 if isinstance( meshToAppendTo, Mesh ):
779 meshToAppendTo = meshToAppendTo.GetMesh()
781 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
782 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
783 mergeTolerance,meshToAppendTo )
785 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
786 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
787 mergeTolerance,meshToAppendTo )
789 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
792 def CreateDualMesh( self, mesh, meshName, adaptToShape):
794 Create a dual of a mesh.
797 mesh: Tetrahedron mesh
798 :class:`mesh, <SMESH.SMESH_IDSource>`.
800 meshName: a name of the new mesh
801 adpatToShape: if true project boundary points on shape
804 an instance of class :class:`Mesh`
806 if isinstance( mesh, Mesh ):
807 mesh = mesh.GetMesh()
808 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
809 return Mesh(self, self.geompyD, dualMesh)
812 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
814 Create a mesh by copying a part of another mesh.
817 meshPart: a part of mesh to copy, either
818 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
819 To copy nodes or elements not forming any mesh object,
820 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
821 meshName: a name of the new mesh
822 toCopyGroups: to create in the new mesh groups the copied elements belongs to
823 toKeepIDs: to preserve order of the copied elements or not
826 an instance of class :class:`Mesh`
829 if isinstance( meshPart, Mesh ):
830 meshPart = meshPart.GetMesh()
831 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
832 return Mesh(self, self.geompyD, mesh)
834 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
835 toReuseHypotheses=True, toCopyElements=True):
837 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
838 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
839 To facilitate and speed up the operation, consider using
840 "Set presentation parameters and sub-shapes from arguments" option in
841 a dialog of geometrical operation used to create the new geometry.
844 sourceMesh: the mesh to copy definition of.
845 newGeom: the new geometry.
846 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
847 toCopyGroups: to create groups in the new mesh.
848 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
849 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
852 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
853 *invalidEntries* are study entries of objects whose
854 counterparts are not found in the *newGeom*, followed by entries
855 of mesh sub-objects that are invalid because they depend on a not found
858 if isinstance( sourceMesh, Mesh ):
859 sourceMesh = sourceMesh.GetMesh()
861 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
862 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
866 return ( ok, Mesh(self, self.geompyD, newMesh),
867 newGroups, newSubMeshes, newHypotheses, invalidEntries )
869 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
871 Return IDs of sub-shapes
874 theMainObject (GEOM.GEOM_Object): a shape
875 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
877 the list of integer values
880 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
882 def GetPattern(self):
884 Create a pattern mapper.
887 an instance of :class:`SMESH.SMESH_Pattern`
889 :ref:`Example of Patterns usage <tui_pattern_mapping>`
892 return SMESH._objref_SMESH_Gen.GetPattern(self)
894 def SetBoundaryBoxSegmentation(self, nbSegments):
896 Set number of segments per diagonal of boundary box of geometry, by which
897 default segment length of appropriate 1D hypotheses is defined in GUI.
901 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
903 # Filtering. Auxiliary functions:
904 # ------------------------------
906 def GetEmptyCriterion(self):
908 Create an empty criterion
911 :class:`SMESH.Filter.Criterion`
914 Type = self.EnumToLong(FT_Undefined)
915 Compare = self.EnumToLong(FT_Undefined)
919 UnaryOp = self.EnumToLong(FT_Undefined)
920 BinaryOp = self.EnumToLong(FT_Undefined)
923 Precision = -1 ##@1e-07
924 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
925 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
927 def GetCriterion(self,elementType,
929 Compare = FT_EqualTo,
931 UnaryOp=FT_Undefined,
932 BinaryOp=FT_Undefined,
935 Create a criterion by the given parameters
936 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
939 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
940 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
941 Note that the items starting from FT_LessThan are not suitable for *CritType*.
942 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
943 Threshold: the threshold value (range of ids as string, shape, numeric)
944 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
945 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
947 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
948 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
951 :class:`SMESH.Filter.Criterion`
953 Example: :ref:`combining_filters`
956 if not CritType in SMESH.FunctorType._items:
957 raise TypeError("CritType should be of SMESH.FunctorType")
958 aCriterion = self.GetEmptyCriterion()
959 aCriterion.TypeOfElement = elementType
960 aCriterion.Type = self.EnumToLong(CritType)
961 aCriterion.Tolerance = Tolerance
963 aThreshold = Threshold
965 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
966 aCriterion.Compare = self.EnumToLong(Compare)
967 elif Compare == "=" or Compare == "==":
968 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
970 aCriterion.Compare = self.EnumToLong(FT_LessThan)
972 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
973 elif Compare != FT_Undefined:
974 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
977 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
978 FT_BelongToCylinder, FT_LyingOnGeom]:
979 # Check that Threshold is GEOM object
980 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
981 aCriterion.ThresholdStr = GetName(aThreshold)
982 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
983 if not aCriterion.ThresholdID:
984 name = aCriterion.ThresholdStr
986 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
987 geompyD = aThreshold.GetGen()
988 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
989 # or a name of GEOM object
990 elif isinstance( aThreshold, str ):
991 aCriterion.ThresholdStr = aThreshold
993 raise TypeError("The Threshold should be a shape.")
994 if isinstance(UnaryOp,float):
995 aCriterion.Tolerance = UnaryOp
996 UnaryOp = FT_Undefined
998 elif CritType == FT_BelongToMeshGroup:
999 # Check that Threshold is a group
1000 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
1001 if aThreshold.GetType() != elementType:
1002 raise ValueError("Group type mismatches Element type")
1003 aCriterion.ThresholdStr = aThreshold.GetName()
1004 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
1005 study = salome.myStudy
1007 so = study.FindObjectIOR( aCriterion.ThresholdID )
1011 aCriterion.ThresholdID = entry
1013 raise TypeError("The Threshold should be a Mesh Group")
1014 elif CritType == FT_RangeOfIds:
1015 # Check that Threshold is string
1016 if isinstance(aThreshold, str):
1017 aCriterion.ThresholdStr = aThreshold
1019 raise TypeError("The Threshold should be a string.")
1020 elif CritType == FT_CoplanarFaces:
1021 # Check the Threshold
1022 if isinstance(aThreshold, int):
1023 aCriterion.ThresholdID = str(aThreshold)
1024 elif isinstance(aThreshold, str):
1025 ID = int(aThreshold)
1027 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1028 aCriterion.ThresholdID = aThreshold
1030 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1031 elif CritType == FT_ConnectedElements:
1032 # Check the Threshold
1033 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1034 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1035 if not aCriterion.ThresholdID:
1036 name = aThreshold.GetName()
1038 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1039 geompyD = aThreshold.GetGen()
1040 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1041 elif isinstance(aThreshold, int): # node id
1042 aCriterion.Threshold = aThreshold
1043 elif isinstance(aThreshold, list): # 3 point coordinates
1044 if len( aThreshold ) < 3:
1045 raise ValueError("too few point coordinates, must be 3")
1046 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1047 elif isinstance(aThreshold, str):
1048 if aThreshold.isdigit():
1049 aCriterion.Threshold = aThreshold # node id
1051 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1053 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1054 "or a list of point coordinates and not '%s'"%aThreshold)
1055 elif CritType == FT_ElemGeomType:
1056 # Check the Threshold
1058 aCriterion.Threshold = self.EnumToLong(aThreshold)
1059 assert( aThreshold in SMESH.GeometryType._items )
1061 if isinstance(aThreshold, int):
1062 aCriterion.Threshold = aThreshold
1064 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1067 elif CritType == FT_EntityType:
1068 # Check the Threshold
1070 aCriterion.Threshold = self.EnumToLong(aThreshold)
1071 assert( aThreshold in SMESH.EntityType._items )
1073 if isinstance(aThreshold, int):
1074 aCriterion.Threshold = aThreshold
1076 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1080 elif CritType == FT_GroupColor:
1081 # Check the Threshold
1083 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1085 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1087 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1088 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1089 FT_BareBorderFace, FT_BareBorderVolume,
1090 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1091 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1092 # At this point the Threshold is unnecessary
1093 if aThreshold == FT_LogicalNOT:
1094 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1095 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1096 aCriterion.BinaryOp = aThreshold
1100 aThreshold = float(aThreshold)
1101 aCriterion.Threshold = aThreshold
1103 raise TypeError("The Threshold should be a number.")
1106 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1107 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1109 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1110 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1112 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1113 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1115 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1116 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1120 def GetFilter(self,elementType,
1121 CritType=FT_Undefined,
1124 UnaryOp=FT_Undefined,
1128 Create a filter with the given parameters
1131 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1132 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1133 Note that the items starting from FT_LessThan are not suitable for CritType.
1134 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1135 Threshold: the threshold value (range of ids as string, shape, numeric)
1136 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1137 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1138 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1139 mesh: the mesh to initialize the filter with
1142 :class:`SMESH.Filter`
1145 See :doc:`Filters usage examples <tui_filters>`
1148 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1149 aFilterMgr = self.CreateFilterManager()
1150 aFilter = aFilterMgr.CreateFilter()
1152 aCriteria.append(aCriterion)
1153 aFilter.SetCriteria(aCriteria)
1155 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1156 else : aFilter.SetMesh( mesh )
1157 aFilterMgr.UnRegister()
1160 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1162 Create a filter from criteria
1165 criteria: a list of :class:`SMESH.Filter.Criterion`
1166 binOp: binary operator used when binary operator of criteria is undefined
1169 :class:`SMESH.Filter`
1172 See :doc:`Filters usage examples <tui_filters>`
1175 for i in range( len( criteria ) - 1 ):
1176 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1177 criteria[i].BinaryOp = self.EnumToLong( binOp )
1178 aFilterMgr = self.CreateFilterManager()
1179 aFilter = aFilterMgr.CreateFilter()
1180 aFilter.SetCriteria(criteria)
1181 aFilterMgr.UnRegister()
1184 def GetFunctor(self,theCriterion):
1186 Create a numerical functor by its type
1189 theCriterion (SMESH.FunctorType): functor type.
1190 Note that not all items correspond to numerical functors.
1193 :class:`SMESH.NumericalFunctor`
1196 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1198 aFilterMgr = self.CreateFilterManager()
1200 if theCriterion == FT_AspectRatio:
1201 functor = aFilterMgr.CreateAspectRatio()
1202 elif theCriterion == FT_AspectRatio3D:
1203 functor = aFilterMgr.CreateAspectRatio3D()
1204 elif theCriterion == FT_Warping:
1205 functor = aFilterMgr.CreateWarping()
1206 elif theCriterion == FT_MinimumAngle:
1207 functor = aFilterMgr.CreateMinimumAngle()
1208 elif theCriterion == FT_Taper:
1209 functor = aFilterMgr.CreateTaper()
1210 elif theCriterion == FT_Skew:
1211 functor = aFilterMgr.CreateSkew()
1212 elif theCriterion == FT_Area:
1213 functor = aFilterMgr.CreateArea()
1214 elif theCriterion == FT_Volume3D:
1215 functor = aFilterMgr.CreateVolume3D()
1216 elif theCriterion == FT_MaxElementLength2D:
1217 functor = aFilterMgr.CreateMaxElementLength2D()
1218 elif theCriterion == FT_MaxElementLength3D:
1219 functor = aFilterMgr.CreateMaxElementLength3D()
1220 elif theCriterion == FT_MultiConnection:
1221 functor = aFilterMgr.CreateMultiConnection()
1222 elif theCriterion == FT_MultiConnection2D:
1223 functor = aFilterMgr.CreateMultiConnection2D()
1224 elif theCriterion == FT_Length:
1225 functor = aFilterMgr.CreateLength()
1226 elif theCriterion == FT_Length2D:
1227 functor = aFilterMgr.CreateLength2D()
1228 elif theCriterion == FT_Length3D:
1229 functor = aFilterMgr.CreateLength3D()
1230 elif theCriterion == FT_Deflection2D:
1231 functor = aFilterMgr.CreateDeflection2D()
1232 elif theCriterion == FT_NodeConnectivityNumber:
1233 functor = aFilterMgr.CreateNodeConnectivityNumber()
1234 elif theCriterion == FT_BallDiameter:
1235 functor = aFilterMgr.CreateBallDiameter()
1236 elif theCriterion == FT_ScaledJacobian:
1237 functor = aFilterMgr.CreateScaledJacobian()
1239 print("Error: given parameter is not numerical functor type.")
1240 aFilterMgr.UnRegister()
1243 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1248 theHType (string): mesh hypothesis type
1249 theLibName (string): mesh plug-in library name
1252 created hypothesis instance
1254 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1256 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1259 # wrap hypothesis methods
1260 for meth_name in dir( hyp.__class__ ):
1261 if not meth_name.startswith("Get") and \
1262 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1263 method = getattr ( hyp.__class__, meth_name )
1264 if callable(method):
1265 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1269 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1271 Create hypothesis initialized according to parameters
1274 hypType (string): hypothesis type
1275 libName (string): plug-in library name
1276 mesh: optional mesh by which a hypotheses can initialize self
1277 shape: optional geometry by size of which a hypotheses can initialize self
1278 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1281 created hypothesis instance
1283 if isinstance( mesh, Mesh ):
1284 mesh = mesh.GetMesh()
1285 if isinstance( initParams, (bool,int)):
1286 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1287 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1288 mesh, shape, initParams )
1290 def GetMeshInfo(self, obj):
1292 Get the mesh statistic.
1295 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1298 if isinstance( obj, Mesh ):
1301 if hasattr(obj, "GetMeshInfo"):
1302 values = obj.GetMeshInfo()
1303 for i in range(SMESH.Entity_Last._v):
1304 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1308 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1310 Get minimum distance between two objects
1312 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1313 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1316 src1 (SMESH.SMESH_IDSource): first source object
1317 src2 (SMESH.SMESH_IDSource): second source object
1318 id1 (int): node/element id from the first source
1319 id2 (int): node/element id from the second (or first) source
1320 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1321 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1324 minimum distance value
1327 :meth:`GetMinDistance`
1330 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1334 result = result.value
1337 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1339 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1341 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1342 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1345 src1 (SMESH.SMESH_IDSource): first source object
1346 src2 (SMESH.SMESH_IDSource): second source object
1347 id1 (int): node/element id from the first source
1348 id2 (int): node/element id from the second (or first) source
1349 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1350 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1353 :class:`SMESH.Measure` structure or None if input data is invalid
1358 if isinstance(src1, Mesh): src1 = src1.mesh
1359 if isinstance(src2, Mesh): src2 = src2.mesh
1360 if src2 is None and id2 != 0: src2 = src1
1361 if not hasattr(src1, "_narrow"): return None
1362 src1 = src1._narrow(SMESH.SMESH_IDSource)
1363 if not src1: return None
1364 unRegister = genObjUnRegister()
1367 e = m.GetMeshEditor()
1369 src1 = e.MakeIDSource([id1], SMESH.FACE)
1371 src1 = e.MakeIDSource([id1], SMESH.NODE)
1372 unRegister.set( src1 )
1374 if hasattr(src2, "_narrow"):
1375 src2 = src2._narrow(SMESH.SMESH_IDSource)
1376 if src2 and id2 != 0:
1378 e = m.GetMeshEditor()
1380 src2 = e.MakeIDSource([id2], SMESH.FACE)
1382 src2 = e.MakeIDSource([id2], SMESH.NODE)
1383 unRegister.set( src2 )
1386 aMeasurements = self.CreateMeasurements()
1387 unRegister.set( aMeasurements )
1388 result = aMeasurements.MinDistance(src1, src2)
1391 def BoundingBox(self, objects):
1393 Get bounding box of the specified object(s)
1396 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1399 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1402 :meth:`GetBoundingBox`
1405 result = self.GetBoundingBox(objects)
1409 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1412 def GetBoundingBox(self, objects):
1414 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1417 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1420 :class:`SMESH.Measure` structure
1426 if isinstance(objects, tuple):
1427 objects = list(objects)
1428 if not isinstance(objects, list):
1432 if isinstance(o, Mesh):
1433 srclist.append(o.mesh)
1434 elif hasattr(o, "_narrow"):
1435 src = o._narrow(SMESH.SMESH_IDSource)
1436 if src: srclist.append(src)
1439 aMeasurements = self.CreateMeasurements()
1440 result = aMeasurements.BoundingBox(srclist)
1441 aMeasurements.UnRegister()
1444 def GetLength(self, obj):
1446 Get sum of lengths of all 1D elements in the mesh object.
1449 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1452 sum of lengths of all 1D elements
1455 if isinstance(obj, Mesh): obj = obj.mesh
1456 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1457 aMeasurements = self.CreateMeasurements()
1458 value = aMeasurements.Length(obj)
1459 aMeasurements.UnRegister()
1462 def GetArea(self, obj):
1464 Get sum of areas of all 2D elements in the mesh object.
1467 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1470 sum of areas of all 2D elements
1473 if isinstance(obj, Mesh): obj = obj.mesh
1474 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1475 aMeasurements = self.CreateMeasurements()
1476 value = aMeasurements.Area(obj)
1477 aMeasurements.UnRegister()
1480 def GetVolume(self, obj):
1482 Get sum of volumes of all 3D elements in the mesh object.
1485 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1488 sum of volumes of all 3D elements
1491 if isinstance(obj, Mesh): obj = obj.mesh
1492 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1493 aMeasurements = self.CreateMeasurements()
1494 value = aMeasurements.Volume(obj)
1495 aMeasurements.UnRegister()
1498 def GetGravityCenter(self, obj):
1500 Get gravity center of all nodes of a mesh object.
1503 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1506 Three components of the gravity center (x,y,z)
1509 :meth:`Mesh.BaryCenter`
1511 if isinstance(obj, Mesh): obj = obj.mesh
1512 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1513 aMeasurements = self.CreateMeasurements()
1514 pointStruct = aMeasurements.GravityCenter(obj)
1515 aMeasurements.UnRegister()
1516 return pointStruct.x, pointStruct.y, pointStruct.z
1518 def GetAngle(self, p1, p2, p3 ):
1520 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1523 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1529 if isinstance( p1, list ): p1 = PointStruct(*p1)
1530 if isinstance( p2, list ): p2 = PointStruct(*p2)
1531 if isinstance( p3, list ): p3 = PointStruct(*p3)
1533 aMeasurements = self.CreateMeasurements()
1534 angle = aMeasurements.Angle(p1,p2,p3)
1535 aMeasurements.UnRegister()
1540 pass # end of class smeshBuilder
1543 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1544 """Registering the new proxy for SMESH.SMESH_Gen"""
1547 def New( instance=None, instanceGeom=None):
1549 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1550 interface to create or load meshes.
1555 salome.salome_init()
1556 from salome.smesh import smeshBuilder
1557 smesh = smeshBuilder.New()
1560 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1561 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1563 :class:`smeshBuilder` instance
1568 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1570 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1575 smeshInst = smeshBuilder()
1576 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1577 smeshInst.init_smesh(instanceGeom)
1581 # Public class: Mesh
1582 # ==================
1585 class Mesh(metaclass = MeshMeta):
1587 This class allows defining and managing a mesh.
1588 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1589 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1590 new nodes and elements and by changing the existing entities), to get information
1591 about a mesh and to export a mesh in different formats.
1598 def __init__(self, smeshpyD, geompyD, obj=0, name=0, parallel=False):
1603 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1604 sets the GUI name of this mesh to *name*.
1607 smeshpyD: an instance of smeshBuilder class
1608 geompyD: an instance of geomBuilder class
1609 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1610 name: Study name of the mesh
1613 self.smeshpyD = smeshpyD
1614 self.geompyD = geompyD
1619 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1622 # publish geom of mesh (issue 0021122)
1623 if not self.geom.GetStudyEntry():
1627 geo_name = name + " shape"
1629 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1630 geompyD.addToStudy( self.geom, geo_name )
1631 if parallel and isinstance(self, ParallelMesh):
1632 self.SetMesh( self.smeshpyD.CreateParallelMesh(self.geom) )
1634 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1636 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1639 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1641 self.smeshpyD.SetName(self.mesh, name)
1643 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1646 self.geom = self.mesh.GetShapeToMesh()
1648 self.editor = self.mesh.GetMeshEditor()
1649 self.functors = [None] * SMESH.FT_Undefined._v
1651 # set self to algoCreator's
1652 for attrName in dir(self):
1653 attr = getattr( self, attrName )
1654 if isinstance( attr, algoCreator ):
1655 setattr( self, attrName, attr.copy( self ))
1662 Destructor. Clean-up resources
1665 #self.mesh.UnRegister()
1669 def SetMesh(self, theMesh):
1671 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1674 theMesh: a :class:`SMESH.SMESH_Mesh` object
1676 # do not call Register() as this prevents mesh servant deletion at closing study
1677 #if self.mesh: self.mesh.UnRegister()
1680 #self.mesh.Register()
1681 self.geom = self.mesh.GetShapeToMesh()
1685 if salome.sg.hasDesktop():
1686 so = salome.ObjectToSObject( self.geom )
1687 comp = so.GetFatherComponent()
1688 if comp.ComponentDataType() == "SHAPERSTUDY":
1689 import shaperBuilder
1690 self.geompyD = shaperBuilder.New()
1693 if not self.geompyD:
1694 self.geompyD = self.geom.GetGen()
1699 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1702 a :class:`SMESH.SMESH_Mesh` object
1707 def GetEngine(self):
1709 Return a smeshBuilder instance created this mesh
1711 return self.smeshpyD
1713 def GetGeomEngine(self):
1715 Return a geomBuilder instance
1721 Get the name of the mesh
1724 the name of the mesh as a string
1727 name = GetName(self.GetMesh())
1730 def SetName(self, name):
1732 Set a name to the mesh
1735 name: a new name of the mesh
1738 self.smeshpyD.SetName(self.GetMesh(), name)
1740 def GetSubMesh(self, geom, name):
1742 Get a sub-mesh object associated to a *geom* geometrical object.
1745 geom: a geometrical object (shape)
1746 name: a name for the sub-mesh in the Object Browser
1749 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1750 which lies on the given shape
1753 A sub-mesh is implicitly created when a sub-shape is specified at
1754 creating an algorithm, for example::
1756 algo1D = mesh.Segment(geom=Edge_1)
1758 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1759 The created sub-mesh can be retrieved from the algorithm::
1761 submesh = algo1D.GetSubMesh()
1764 AssureGeomPublished( self, geom, name )
1765 submesh = self.mesh.GetSubMesh( geom, name )
1770 Return the shape associated to the mesh
1778 def SetShape(self, geom):
1780 Associate the given shape to the mesh (entails the recreation of the mesh)
1783 geom: the shape to be meshed (GEOM_Object)
1786 self.mesh = self.smeshpyD.CreateMesh(geom)
1788 def HasShapeToMesh(self):
1790 Return ``True`` if this mesh is based on geometry
1792 return self.mesh.HasShapeToMesh()
1796 Load mesh from the study after opening the study
1800 def IsReadyToCompute(self, theSubObject):
1802 Return true if the hypotheses are defined well
1805 theSubObject: a sub-shape of a mesh shape
1811 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1813 def GetAlgoState(self, theSubObject):
1815 Return errors of hypotheses definition.
1816 The list of errors is empty if everything is OK.
1819 theSubObject: a sub-shape of a mesh shape
1825 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1827 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1829 Return a geometrical object on which the given element was built.
1830 The returned geometrical object, if not nil, is either found in the
1831 study or published by this method with the given name
1834 theElementID: the id of the mesh element
1835 theGeomName: the user-defined name of the geometrical object
1838 GEOM.GEOM_Object instance
1841 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1843 def MeshDimension(self):
1845 Return the mesh dimension depending on the dimension of the underlying shape
1846 or, if the mesh is not based on any shape, basing on deimension of elements
1849 mesh dimension as an integer value [0,3]
1852 if self.mesh.HasShapeToMesh():
1853 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1854 if len( shells ) > 0 :
1856 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1858 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1863 if self.NbVolumes() > 0: return 3
1864 if self.NbFaces() > 0: return 2
1865 if self.NbEdges() > 0: return 1
1868 def Evaluate(self, geom=0):
1870 Evaluate size of prospective mesh on a shape
1873 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1874 To know predicted number of e.g. edges, inquire it this way::
1876 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1879 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1881 geom = self.mesh.GetShapeToMesh()
1884 return self.smeshpyD.Evaluate(self.mesh, geom)
1886 def Compute(self, geom=0, discardModifs=False, refresh=False):
1888 Compute the mesh and return the status of the computation
1891 geom: geomtrical shape on which mesh data should be computed
1892 discardModifs: if True and the mesh has been edited since
1893 a last total re-compute and that may prevent successful partial re-compute,
1894 then the mesh is cleaned before Compute()
1895 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1901 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1902 geom = self.mesh.GetShapeToMesh()
1905 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1907 ok = self.smeshpyD.Compute(self.mesh, geom)
1908 except SALOME.SALOME_Exception as ex:
1909 print("Mesh computation failed, exception caught:")
1910 print(" ", ex.details.text)
1913 print("Mesh computation failed, exception caught:")
1914 traceback.print_exc()
1918 # Treat compute errors
1919 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1921 for err in computeErrors:
1922 if self.mesh.HasShapeToMesh():
1923 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1925 stdErrors = ["OK", #COMPERR_OK
1926 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1927 "std::exception", #COMPERR_STD_EXCEPTION
1928 "OCC exception", #COMPERR_OCC_EXCEPTION
1929 "..", #COMPERR_SLM_EXCEPTION
1930 "Unknown exception", #COMPERR_EXCEPTION
1931 "Memory allocation problem", #COMPERR_MEMORY_PB
1932 "Algorithm failed", #COMPERR_ALGO_FAILED
1933 "Unexpected geometry", #COMPERR_BAD_SHAPE
1934 "Warning", #COMPERR_WARNING
1935 "Computation cancelled",#COMPERR_CANCELED
1936 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1938 if err.code < len(stdErrors): errText = stdErrors[err.code]
1940 errText = "code %s" % -err.code
1941 if errText: errText += ". "
1942 errText += err.comment
1943 if allReasons: allReasons += "\n"
1945 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1947 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1951 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1953 if err.isGlobalAlgo:
1961 reason = '%s %sD algorithm is missing' % (glob, dim)
1962 elif err.state == HYP_MISSING:
1963 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1964 % (glob, dim, name, dim))
1965 elif err.state == HYP_NOTCONFORM:
1966 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1967 elif err.state == HYP_BAD_PARAMETER:
1968 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1969 % ( glob, dim, name ))
1970 elif err.state == HYP_BAD_GEOMETRY:
1971 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1972 'geometry' % ( glob, dim, name ))
1973 elif err.state == HYP_HIDDEN_ALGO:
1974 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1975 'algorithm of upper dimension generating %sD mesh'
1976 % ( glob, dim, name, glob, dim ))
1978 reason = ("For unknown reason. "
1979 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1981 if allReasons: allReasons += "\n"
1982 allReasons += "- " + reason
1984 if not ok or allReasons != "":
1985 msg = '"' + GetName(self.mesh) + '"'
1986 if ok: msg += " has been computed with warnings"
1987 else: msg += " has not been computed"
1988 if allReasons != "": msg += ":"
1994 if salome.sg.hasDesktop():
1995 if not isinstance( refresh, list): # not a call from subMesh.Compute()
1996 if refresh: salome.sg.updateObjBrowser()
2000 def GetComputeErrors(self, shape=0 ):
2002 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2006 shape = self.mesh.GetShapeToMesh()
2007 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2009 def GetSubShapeName(self, subShapeID ):
2011 Return a name of a sub-shape by its ID.
2012 Possible variants (for *subShapeID* == 3):
2014 - **"Face_12"** - published sub-shape
2015 - **FACE #3** - not published sub-shape
2016 - **sub-shape #3** - invalid sub-shape ID
2017 - **#3** - error in this function
2020 subShapeID: a unique ID of a sub-shape
2023 a string describing the sub-shape
2027 if not self.mesh.HasShapeToMesh():
2031 mainIOR = salome.orb.object_to_string( self.GetShape() )
2033 mainSO = s.FindObjectIOR(mainIOR)
2036 shapeText = '"%s"' % mainSO.GetName()
2037 subIt = s.NewChildIterator(mainSO)
2039 subSO = subIt.Value()
2041 obj = subSO.GetObject()
2042 if not obj: continue
2043 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2046 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2049 if ids == subShapeID:
2050 shapeText = '"%s"' % subSO.GetName()
2053 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2055 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2057 shapeText = 'sub-shape #%s' % (subShapeID)
2059 shapeText = "#%s" % (subShapeID)
2062 def GetFailedShapes(self, publish=False):
2064 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2065 error of an algorithm
2068 publish: if *True*, the returned groups will be published in the study
2071 a list of GEOM groups each named after a failed algorithm
2076 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2077 for err in computeErrors:
2078 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2079 if not shape: continue
2080 if err.algoName in algo2shapes:
2081 algo2shapes[ err.algoName ].append( shape )
2083 algo2shapes[ err.algoName ] = [ shape ]
2087 for algoName, shapes in list(algo2shapes.items()):
2089 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2090 otherTypeShapes = []
2092 group = self.geompyD.CreateGroup( self.geom, groupType )
2093 for shape in shapes:
2094 if shape.GetShapeType() == shapes[0].GetShapeType():
2095 sameTypeShapes.append( shape )
2097 otherTypeShapes.append( shape )
2098 self.geompyD.UnionList( group, sameTypeShapes )
2100 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2102 group.SetName( algoName )
2103 groups.append( group )
2104 shapes = otherTypeShapes
2107 for group in groups:
2108 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2111 def GetMeshOrder(self):
2113 Return sub-mesh objects list in meshing order
2116 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2119 return self.mesh.GetMeshOrder()
2121 def SetMeshOrder(self, submeshes):
2123 Set priority of sub-meshes. It works in two ways:
2125 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2126 *several dimensions*, it sets the order in which the sub-meshes are computed.
2127 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2128 when looking for meshing parameters to apply to a sub-shape. To impose the
2129 order in which sub-meshes with uni-dimensional algorithms are computed,
2130 call **submesh.Compute()** in a desired order.
2133 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2135 Warning: the method is for setting the order for all sub-meshes at once:
2136 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2139 return self.mesh.SetMeshOrder(submeshes)
2141 def Clear(self, refresh=False):
2143 Remove all nodes and elements generated on geometry. Imported elements remain.
2146 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2150 if ( salome.sg.hasDesktop() ):
2151 if refresh: salome.sg.updateObjBrowser()
2153 def ClearSubMesh(self, geomId, refresh=False):
2155 Remove all nodes and elements of indicated shape
2158 geomId: the ID of a sub-shape to remove elements on
2159 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2162 self.mesh.ClearSubMesh(geomId)
2163 if salome.sg.hasDesktop():
2164 if refresh: salome.sg.updateObjBrowser()
2166 def AutomaticTetrahedralization(self, fineness=0):
2168 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2171 fineness: [0.0,1.0] defines mesh fineness
2177 dim = self.MeshDimension()
2179 self.RemoveGlobalHypotheses()
2180 self.Segment().AutomaticLength(fineness)
2182 self.Triangle().LengthFromEdges()
2187 return self.Compute()
2189 def AutomaticHexahedralization(self, fineness=0):
2191 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2194 fineness: [0.0, 1.0] defines mesh fineness
2200 dim = self.MeshDimension()
2201 # assign the hypotheses
2202 self.RemoveGlobalHypotheses()
2203 self.Segment().AutomaticLength(fineness)
2210 return self.Compute()
2212 def AddHypothesis(self, hyp, geom=0):
2217 hyp: a hypothesis to assign
2218 geom: a subhape of mesh geometry
2221 :class:`SMESH.Hypothesis_Status`
2224 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2225 hyp, geom = geom, hyp
2226 if isinstance( hyp, Mesh_Algorithm ):
2227 hyp = hyp.GetAlgorithm()
2232 geom = self.mesh.GetShapeToMesh()
2235 if self.mesh.HasShapeToMesh():
2236 hyp_type = hyp.GetName()
2237 lib_name = hyp.GetLibName()
2238 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2239 # if checkAll and geom:
2240 # checkAll = geom.GetType() == 37
2242 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2244 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2245 status = self.mesh.AddHypothesis(geom, hyp)
2247 status = HYP_BAD_GEOMETRY, ""
2248 hyp_name = GetName( hyp )
2251 geom_name = geom.GetName()
2252 isAlgo = hyp._narrow( SMESH_Algo )
2253 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2256 def IsUsedHypothesis(self, hyp, geom):
2258 Return True if an algorithm or hypothesis is assigned to a given shape
2261 hyp: an algorithm or hypothesis to check
2262 geom: a subhape of mesh geometry
2268 if not hyp: # or not geom
2270 if isinstance( hyp, Mesh_Algorithm ):
2271 hyp = hyp.GetAlgorithm()
2273 hyps = self.GetHypothesisList(geom)
2275 if h.GetId() == hyp.GetId():
2279 def RemoveHypothesis(self, hyp, geom=0):
2281 Unassign a hypothesis
2284 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2285 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2288 :class:`SMESH.Hypothesis_Status`
2293 if isinstance( hyp, Mesh_Algorithm ):
2294 hyp = hyp.GetAlgorithm()
2300 if self.IsUsedHypothesis( hyp, shape ):
2301 return self.mesh.RemoveHypothesis( shape, hyp )
2302 hypName = GetName( hyp )
2303 geoName = GetName( shape )
2304 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2307 def GetHypothesisList(self, geom):
2309 Get the list of hypotheses added on a geometry
2312 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2315 the sequence of :class:`SMESH.SMESH_Hypothesis`
2318 return self.mesh.GetHypothesisList( geom )
2320 def RemoveGlobalHypotheses(self):
2322 Remove all global hypotheses
2325 current_hyps = self.mesh.GetHypothesisList( self.geom )
2326 for hyp in current_hyps:
2327 self.mesh.RemoveHypothesis( self.geom, hyp )
2331 def ExportMEDCoupling(self, *args, **kwargs):
2333 Export the mesh in a memory representation.
2336 auto_groups (boolean): parameter for creating/not creating
2337 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2338 the typical use is auto_groups=False.
2339 overwrite (boolean): parameter for overwriting/not overwriting the file
2340 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2341 to export instead of the mesh
2342 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2344 - 1D if all mesh nodes lie on OX coordinate axis, or
2345 - 2D if all mesh nodes lie on XOY coordinate plane, or
2346 - 3D in the rest cases.
2348 If *autoDimension* is *False*, the space dimension is always 3.
2349 fields: list of GEOM fields defined on the shape to mesh.
2350 geomAssocFields: each character of this string means a need to export a
2351 corresponding field; correspondence between fields and characters
2354 - 'v' stands for "_vertices_" field;
2355 - 'e' stands for "_edges_" field;
2356 - 'f' stands for "_faces_" field;
2357 - 's' stands for "_solids_" field.
2359 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2360 close to zero within a given tolerance, the coordinate is set to zero.
2361 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2362 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2364 auto_groups = args[0] if len(args) > 0 else False
2365 meshPart = args[1] if len(args) > 1 else None
2366 autoDimension = args[2] if len(args) > 2 else True
2367 fields = args[3] if len(args) > 3 else []
2368 geomAssocFields = args[4] if len(args) > 4 else ''
2369 z_tolerance = args[5] if len(args) > 5 else -1.
2370 saveNumbers = args[6] if len(args) > 6 else True
2371 # process keywords arguments
2372 auto_groups = kwargs.get("auto_groups", auto_groups)
2373 meshPart = kwargs.get("meshPart", meshPart)
2374 autoDimension = kwargs.get("autoDimension", autoDimension)
2375 fields = kwargs.get("fields", fields)
2376 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2377 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2378 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2380 # invoke engine's function
2381 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2382 unRegister = genObjUnRegister()
2383 if isinstance( meshPart, list ):
2384 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2385 unRegister.set( meshPart )
2387 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2388 self.mesh.SetParameters(Parameters)
2390 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2391 fields, geomAssocFields, z_tolerance,
2394 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2395 return medcoupling.MEDFileData.New(dab)
2397 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2399 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2400 return medcoupling.MEDFileMesh.New(dab)
2402 def ExportMED(self, *args, **kwargs):
2404 Export the mesh in a file in MED format
2405 allowing to overwrite the file if it exists or add the exported data to its contents
2408 fileName: is the file name
2409 auto_groups (boolean): parameter for creating/not creating
2410 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2411 the typical use is auto_groups=False.
2412 version (int): define the version (xy, where version is x.y.z) of MED file format.
2413 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2414 The rules of compatibility to write a mesh in an older version than
2415 the current version depend on the current version. For instance,
2416 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2417 or 3.2.1 or 3.3.1 formats.
2418 If the version is equal to -1, the version is not changed (default).
2419 overwrite (boolean): parameter for overwriting/not overwriting the file
2420 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2421 to export instead of the mesh
2422 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2424 - 1D if all mesh nodes lie on OX coordinate axis, or
2425 - 2D if all mesh nodes lie on XOY coordinate plane, or
2426 - 3D in the rest cases.
2428 If *autoDimension* is *False*, the space dimension is always 3.
2429 fields: list of GEOM fields defined on the shape to mesh.
2430 geomAssocFields: each character of this string means a need to export a
2431 corresponding field; correspondence between fields and characters
2434 - 'v' stands for "_vertices_" field;
2435 - 'e' stands for "_edges_" field;
2436 - 'f' stands for "_faces_" field;
2437 - 's' stands for "_solids_" field.
2439 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2440 close to zero within a given tolerance, the coordinate is set to zero.
2441 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2442 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2444 # process positional arguments
2445 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2447 auto_groups = args[1] if len(args) > 1 else False
2448 version = args[2] if len(args) > 2 else -1
2449 overwrite = args[3] if len(args) > 3 else True
2450 meshPart = args[4] if len(args) > 4 else None
2451 autoDimension = args[5] if len(args) > 5 else True
2452 fields = args[6] if len(args) > 6 else []
2453 geomAssocFields = args[7] if len(args) > 7 else ''
2454 z_tolerance = args[8] if len(args) > 8 else -1.
2455 saveNumbers = args[9] if len(args) > 9 else True
2456 # process keywords arguments
2457 auto_groups = kwargs.get("auto_groups", auto_groups)
2458 version = kwargs.get("version", version)
2459 version = kwargs.get("minor", version)
2460 overwrite = kwargs.get("overwrite", overwrite)
2461 meshPart = kwargs.get("meshPart", meshPart)
2462 autoDimension = kwargs.get("autoDimension", autoDimension)
2463 fields = kwargs.get("fields", fields)
2464 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2465 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2466 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2468 if isinstance( meshPart, Mesh):
2469 meshPart = meshPart.GetMesh()
2471 # invoke engine's function
2472 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2473 unRegister = genObjUnRegister()
2474 if isinstance( meshPart, list ):
2475 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2476 unRegister.set( meshPart )
2478 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2479 self.mesh.SetParameters(Parameters)
2481 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2482 version, overwrite, autoDimension,
2483 fields, geomAssocFields, z_tolerance, saveNumbers )
2485 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2487 def ExportDAT(self, f, meshPart=None, renumber=True):
2489 Export the mesh in a file in DAT format
2493 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2494 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2497 if meshPart or not renumber:
2498 unRegister = genObjUnRegister()
2499 if isinstance( meshPart, list ):
2500 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2501 unRegister.set( meshPart )
2502 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2504 self.mesh.ExportDAT( f, renumber )
2506 def ExportUNV(self, f, meshPart=None, renumber=True):
2508 Export the mesh in a file in UNV format
2512 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2513 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2516 if meshPart or not renumber:
2517 unRegister = genObjUnRegister()
2518 if isinstance( meshPart, list ):
2519 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2520 unRegister.set( meshPart )
2521 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2523 self.mesh.ExportUNV( f, renumber )
2525 def ExportSTL(self, f, ascii=1, meshPart=None):
2527 Export the mesh in a file in STL format
2531 ascii: defines the file encoding
2532 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2536 unRegister = genObjUnRegister()
2537 if isinstance( meshPart, list ):
2538 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2539 unRegister.set( meshPart )
2540 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2542 self.mesh.ExportSTL(f, ascii)
2544 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2546 Export the mesh in a file in CGNS format
2550 overwrite: boolean parameter for overwriting/not overwriting the file
2551 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2552 groupElemsByType: if True all elements of same entity type are exported at ones,
2553 else elements are exported in order of their IDs which can cause creation
2554 of multiple cgns sections
2557 unRegister = genObjUnRegister()
2558 if isinstance( meshPart, list ):
2559 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2560 unRegister.set( meshPart )
2561 if isinstance( meshPart, Mesh ):
2562 meshPart = meshPart.mesh
2564 meshPart = self.mesh
2565 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2567 def ExportGMF(self, f, meshPart=None):
2569 Export the mesh in a file in GMF format.
2570 GMF files must have .mesh extension for the ASCII format and .meshb for
2571 the bynary format. Other extensions are not allowed.
2575 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2578 unRegister = genObjUnRegister()
2579 if isinstance( meshPart, list ):
2580 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2581 unRegister.set( meshPart )
2582 if isinstance( meshPart, Mesh ):
2583 meshPart = meshPart.mesh
2585 meshPart = self.mesh
2586 self.mesh.ExportGMF(meshPart, f, True)
2588 def ExportToMED(self, *args, **kwargs):
2590 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2591 Export the mesh in a file in MED format
2592 allowing to overwrite the file if it exists or add the exported data to its contents
2595 fileName: the file name
2596 opt (boolean): parameter for creating/not creating
2597 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2598 overwrite: boolean parameter for overwriting/not overwriting the file
2599 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2601 - 1D if all mesh nodes lie on OX coordinate axis, or
2602 - 2D if all mesh nodes lie on XOY coordinate plane, or
2603 - 3D in the rest cases.
2605 If **autoDimension** is *False*, the space dimension is always 3.
2608 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2609 # process positional arguments
2610 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2612 auto_groups = args[1] if len(args) > 1 else False
2613 overwrite = args[2] if len(args) > 2 else True
2614 autoDimension = args[3] if len(args) > 3 else True
2615 # process keywords arguments
2616 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2617 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2618 overwrite = kwargs.get("overwrite", overwrite)
2619 autoDimension = kwargs.get("autoDimension", autoDimension)
2621 # invoke engine's function
2622 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2624 def ExportToMEDX(self, *args, **kwargs):
2626 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2627 Export the mesh in a file in MED format
2630 fileName: the file name
2631 opt (boolean): parameter for creating/not creating
2632 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2633 overwrite: boolean parameter for overwriting/not overwriting the file
2634 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2636 - 1D if all mesh nodes lie on OX coordinate axis, or
2637 - 2D if all mesh nodes lie on XOY coordinate plane, or
2638 - 3D in the rest cases.
2640 If **autoDimension** is *False*, the space dimension is always 3.
2643 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2644 # process positional arguments
2645 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2647 auto_groups = args[1] if len(args) > 1 else False
2648 overwrite = args[2] if len(args) > 2 else True
2649 autoDimension = args[3] if len(args) > 3 else True
2650 # process keywords arguments
2651 auto_groups = kwargs.get("auto_groups", auto_groups)
2652 overwrite = kwargs.get("overwrite", overwrite)
2653 autoDimension = kwargs.get("autoDimension", autoDimension)
2655 # invoke engine's function
2656 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2660 def Append(self, meshes, uniteIdenticalGroups = True,
2661 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2663 Append given meshes into this mesh.
2664 All groups of input meshes will be created in this mesh.
2667 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2668 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2669 mergeNodesAndElements: if True, equal nodes and elements are merged
2670 mergeTolerance: tolerance for merging nodes
2671 allGroups: forces creation of groups corresponding to every input mesh
2673 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2674 mergeNodesAndElements, mergeTolerance, allGroups,
2675 meshToAppendTo = self.GetMesh() )
2677 # Operations with groups:
2678 # ----------------------
2679 def CreateEmptyGroup(self, elementType, name):
2681 Create an empty standalone mesh group
2684 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2685 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2686 name: the name of the mesh group
2689 :class:`SMESH.SMESH_Group`
2692 return self.mesh.CreateGroup(elementType, name)
2694 def Group(self, grp, name=""):
2696 Create a mesh group based on the geometric object *grp*
2697 and give it a *name*.
2698 If *name* is not defined the name of the geometric group is used
2701 Works like :meth:`GroupOnGeom`.
2704 grp: a geometric group, a vertex, an edge, a face or a solid
2705 name: the name of the mesh group
2708 :class:`SMESH.SMESH_GroupOnGeom`
2711 return self.GroupOnGeom(grp, name)
2713 def GroupOnGeom(self, grp, name="", typ=None):
2715 Create a mesh group based on the geometrical object *grp*
2716 and give it a *name*.
2717 if *name* is not defined the name of the geometric group is used
2720 grp: a geometrical group, a vertex, an edge, a face or a solid
2721 name: the name of the mesh group
2722 typ: the type of elements in the group; either of
2723 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2724 automatically detected by the type of the geometry
2727 :class:`SMESH.SMESH_GroupOnGeom`
2730 AssureGeomPublished( self, grp, name )
2732 name = grp.GetName()
2734 typ = self._groupTypeFromShape( grp )
2735 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2737 def _groupTypeFromShape( self, shape ):
2739 Pivate method to get a type of group on geometry
2741 tgeo = str(shape.GetShapeType())
2742 if tgeo == "VERTEX":
2744 elif tgeo == "EDGE" or tgeo == "WIRE":
2746 elif tgeo == "FACE" or tgeo == "SHELL":
2748 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2750 elif tgeo == "COMPOUND":
2752 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2754 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2755 # simplification of access in geomBuilder: omniORB.registerObjref
2756 from SHAPERSTUDY_utils import getEngine
2759 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2761 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2762 return self._groupTypeFromShape( sub[0] )
2764 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2767 def GroupOnFilter(self, typ, name, filter):
2769 Create a mesh group with given *name* based on the *filter*.
2770 It is a special type of group dynamically updating it's contents during
2774 typ: the type of elements in the group; either of
2775 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2776 name: the name of the mesh group
2777 filter (SMESH.Filter): the filter defining group contents
2780 :class:`SMESH.SMESH_GroupOnFilter`
2783 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2785 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2787 Create a mesh group by the given ids of elements
2790 groupName: the name of the mesh group
2791 elementType: the type of elements in the group; either of
2792 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2793 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2796 :class:`SMESH.SMESH_Group`
2799 group = self.mesh.CreateGroup(elementType, groupName)
2800 if isinstance( elemIDs, Mesh ):
2801 elemIDs = elemIDs.GetMesh()
2802 if hasattr( elemIDs, "GetIDs" ):
2803 if hasattr( elemIDs, "SetMesh" ):
2804 elemIDs.SetMesh( self.GetMesh() )
2805 group.AddFrom( elemIDs )
2813 CritType=FT_Undefined,
2816 UnaryOp=FT_Undefined,
2819 Create a mesh group by the given conditions
2822 groupName: the name of the mesh group
2823 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2824 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2825 Note that the items starting from FT_LessThan are not suitable for CritType.
2826 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2827 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2828 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2829 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2830 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2833 :class:`SMESH.SMESH_GroupOnFilter`
2836 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2837 group = self.MakeGroupByCriterion(groupName, aCriterion)
2840 def MakeGroupByCriterion(self, groupName, Criterion):
2842 Create a mesh group by the given criterion
2845 groupName: the name of the mesh group
2846 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2849 :class:`SMESH.SMESH_GroupOnFilter`
2852 :meth:`smeshBuilder.GetCriterion`
2855 return self.MakeGroupByCriteria( groupName, [Criterion] )
2857 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2859 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2862 groupName: the name of the mesh group
2863 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2864 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2867 :class:`SMESH.SMESH_GroupOnFilter`
2870 :meth:`smeshBuilder.GetCriterion`
2873 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2874 group = self.MakeGroupByFilter(groupName, aFilter)
2877 def MakeGroupByFilter(self, groupName, theFilter):
2879 Create a mesh group by the given filter
2882 groupName (string): the name of the mesh group
2883 theFilter (SMESH.Filter): the filter
2886 :class:`SMESH.SMESH_GroupOnFilter`
2889 :meth:`smeshBuilder.GetFilter`
2892 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2893 #theFilter.SetMesh( self.mesh )
2894 #group.AddFrom( theFilter )
2895 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2898 def RemoveGroup(self, group):
2903 group (SMESH.SMESH_GroupBase): group to remove
2906 self.mesh.RemoveGroup(group)
2908 def RemoveGroupWithContents(self, group):
2910 Remove a group with its contents
2913 group (SMESH.SMESH_GroupBase): group to remove
2916 This operation can create gaps in numeration of nodes or elements.
2917 Call :meth:`RenumberElements` to remove the gaps.
2920 self.mesh.RemoveGroupWithContents(group)
2922 def GetGroups(self, elemType = SMESH.ALL):
2924 Get the list of groups existing in the mesh in the order of creation
2925 (starting from the oldest one)
2928 elemType (SMESH.ElementType): type of elements the groups contain;
2929 by default groups of elements of all types are returned
2932 a list of :class:`SMESH.SMESH_GroupBase`
2935 groups = self.mesh.GetGroups()
2936 if elemType == SMESH.ALL:
2940 if g.GetType() == elemType:
2941 typedGroups.append( g )
2948 Get the number of groups existing in the mesh
2951 the quantity of groups as an integer value
2954 return self.mesh.NbGroups()
2956 def GetGroupNames(self):
2958 Get the list of names of groups existing in the mesh
2964 groups = self.GetGroups()
2966 for group in groups:
2967 names.append(group.GetName())
2970 def GetGroupByName(self, name, elemType = None):
2972 Find groups by name and type
2975 name (string): name of the group of interest
2976 elemType (SMESH.ElementType): type of elements the groups contain;
2977 by default one group of any type is returned;
2978 if elemType == SMESH.ALL then all groups of any type are returned
2981 a list of :class:`SMESH.SMESH_GroupBase`
2985 for group in self.GetGroups():
2986 if group.GetName() == name:
2987 if elemType is None:
2989 if ( elemType == SMESH.ALL or
2990 group.GetType() == elemType ):
2991 groups.append( group )
2994 def UnionGroups(self, group1, group2, name):
2996 Produce a union of two groups.
2997 A new group is created. All mesh elements that are
2998 present in the initial groups are added to the new one
3001 group1 (SMESH.SMESH_GroupBase): a group
3002 group2 (SMESH.SMESH_GroupBase): another group
3005 instance of :class:`SMESH.SMESH_Group`
3008 return self.mesh.UnionGroups(group1, group2, name)
3010 def UnionListOfGroups(self, groups, name):
3012 Produce a union list of groups.
3013 New group is created. All mesh elements that are present in
3014 initial groups are added to the new one
3017 groups: list of :class:`SMESH.SMESH_GroupBase`
3020 instance of :class:`SMESH.SMESH_Group`
3022 return self.mesh.UnionListOfGroups(groups, name)
3024 def IntersectGroups(self, group1, group2, name):
3026 Prodice an intersection of two groups.
3027 A new group is created. All mesh elements that are common
3028 for the two initial groups are added to the new one.
3031 group1 (SMESH.SMESH_GroupBase): a group
3032 group2 (SMESH.SMESH_GroupBase): another group
3035 instance of :class:`SMESH.SMESH_Group`
3038 return self.mesh.IntersectGroups(group1, group2, name)
3040 def IntersectListOfGroups(self, groups, name):
3042 Produce an intersection of groups.
3043 New group is created. All mesh elements that are present in all
3044 initial groups simultaneously are added to the new one
3047 groups: a list of :class:`SMESH.SMESH_GroupBase`
3050 instance of :class:`SMESH.SMESH_Group`
3052 return self.mesh.IntersectListOfGroups(groups, name)
3054 def CutGroups(self, main_group, tool_group, name):
3056 Produce a cut of two groups.
3057 A new group is created. All mesh elements that are present in
3058 the main group but are not present in the tool group are added to the new one
3061 main_group (SMESH.SMESH_GroupBase): a group to cut from
3062 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3065 an instance of :class:`SMESH.SMESH_Group`
3068 return self.mesh.CutGroups(main_group, tool_group, name)
3070 def CutListOfGroups(self, main_groups, tool_groups, name):
3072 Produce a cut of groups.
3073 A new group is created. All mesh elements that are present in main groups
3074 but do not present in tool groups are added to the new one
3077 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3078 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3081 an instance of :class:`SMESH.SMESH_Group`
3084 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3086 def CreateDimGroup(self, groups, elemType, name,
3087 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3089 Create a standalone group of entities basing on nodes of other groups.
3092 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3093 elemType: a type of elements to include to the new group; either of
3094 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3095 name: a name of the new group.
3096 nbCommonNodes: a criterion of inclusion of an element to the new group
3097 basing on number of element nodes common with reference *groups*.
3098 Meaning of possible values are:
3100 - SMESH.ALL_NODES - include if all nodes are common,
3101 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3102 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3103 - SMEHS.MAJORITY - include if half of nodes or more are common.
3104 underlyingOnly: if *True* (default), an element is included to the
3105 new group provided that it is based on nodes of an element of *groups*;
3106 in this case the reference *groups* are supposed to be of higher dimension
3107 than *elemType*, which can be useful for example to get all faces lying on
3108 volumes of the reference *groups*.
3111 an instance of :class:`SMESH.SMESH_Group`
3114 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3116 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3118 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3120 Distribute all faces of the mesh among groups using sharp edges and optionally
3121 existing 1D elements as group boundaries.
3124 sharpAngle: edge is considered sharp if an angle between normals of
3125 adjacent faces is more than \a sharpAngle in degrees.
3126 createEdges (boolean): to create 1D elements for detected sharp edges.
3127 useExistingEdges (boolean): to use existing edges as group boundaries
3129 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3131 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3132 self.mesh.SetParameters(Parameters)
3133 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3135 def ConvertToStandalone(self, group):
3137 Convert group on geom into standalone group
3140 return self.mesh.ConvertToStandalone(group)
3142 # Get some info about mesh:
3143 # ------------------------
3145 def GetLog(self, clearAfterGet):
3147 Return the log of nodes and elements added or removed
3148 since the previous clear of the log.
3151 clearAfterGet: log is emptied after Get (safe if concurrents access)
3154 list of SMESH.log_block structures { commandType, number, coords, indexes }
3157 return self.mesh.GetLog(clearAfterGet)
3161 Clear the log of nodes and elements added or removed since the previous
3162 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3165 self.mesh.ClearLog()
3167 def SetAutoColor(self, theAutoColor):
3169 Toggle auto color mode on the object.
3170 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3173 theAutoColor (boolean): the flag which toggles auto color mode.
3176 self.mesh.SetAutoColor(theAutoColor)
3178 def GetAutoColor(self):
3180 Get flag of object auto color mode.
3186 return self.mesh.GetAutoColor()
3193 integer value, which is the internal Id of the mesh
3196 return self.mesh.GetId()
3198 def HasDuplicatedGroupNamesMED(self):
3200 Check the group names for duplications.
3201 Consider the maximum group name length stored in MED file.
3207 return self.mesh.HasDuplicatedGroupNamesMED()
3209 def GetMeshEditor(self):
3211 Obtain the mesh editor tool
3214 an instance of :class:`SMESH.SMESH_MeshEditor`
3219 def GetIDSource(self, ids, elemType = SMESH.ALL):
3221 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3222 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3226 elemType: type of elements; this parameter is used to distinguish
3227 IDs of nodes from IDs of elements; by default ids are treated as
3228 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3231 an instance of :class:`SMESH.SMESH_IDSource`
3234 call UnRegister() for the returned object as soon as it is no more useful::
3236 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3237 mesh.DoSomething( idSrc )
3241 if isinstance( ids, int ):
3243 return self.editor.MakeIDSource(ids, elemType)
3246 # Get information about mesh contents:
3247 # ------------------------------------
3249 def GetMeshInfo(self, obj = None):
3251 Get the mesh statistic.
3254 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3257 if not obj: obj = self.mesh
3258 return self.smeshpyD.GetMeshInfo(obj)
3262 Return the number of nodes in the mesh
3268 return self.mesh.NbNodes()
3270 def NbElements(self):
3272 Return the number of elements in the mesh
3278 return self.mesh.NbElements()
3280 def Nb0DElements(self):
3282 Return the number of 0d elements in the mesh
3288 return self.mesh.Nb0DElements()
3292 Return the number of ball discrete elements in the mesh
3298 return self.mesh.NbBalls()
3302 Return the number of edges in the mesh
3308 return self.mesh.NbEdges()
3310 def NbEdgesOfOrder(self, elementOrder):
3312 Return the number of edges with the given order in the mesh
3315 elementOrder: the order of elements
3316 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322 return self.mesh.NbEdgesOfOrder(elementOrder)
3326 Return the number of faces in the mesh
3332 return self.mesh.NbFaces()
3334 def NbFacesOfOrder(self, elementOrder):
3336 Return the number of faces with the given order in the mesh
3339 elementOrder: the order of elements
3340 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346 return self.mesh.NbFacesOfOrder(elementOrder)
3348 def NbTriangles(self):
3350 Return the number of triangles in the mesh
3356 return self.mesh.NbTriangles()
3358 def NbTrianglesOfOrder(self, elementOrder):
3360 Return the number of triangles with the given order in the mesh
3363 elementOrder: is the order of elements
3364 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370 return self.mesh.NbTrianglesOfOrder(elementOrder)
3372 def NbBiQuadTriangles(self):
3374 Return the number of biquadratic triangles in the mesh
3380 return self.mesh.NbBiQuadTriangles()
3382 def NbQuadrangles(self):
3384 Return the number of quadrangles in the mesh
3390 return self.mesh.NbQuadrangles()
3392 def NbQuadranglesOfOrder(self, elementOrder):
3394 Return the number of quadrangles with the given order in the mesh
3397 elementOrder: the order of elements
3398 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3404 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3406 def NbBiQuadQuadrangles(self):
3408 Return the number of biquadratic quadrangles in the mesh
3414 return self.mesh.NbBiQuadQuadrangles()
3416 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3418 Return the number of polygons of given order in the mesh
3421 elementOrder: the order of elements
3422 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428 return self.mesh.NbPolygonsOfOrder(elementOrder)
3430 def NbVolumes(self):
3432 Return the number of volumes in the mesh
3438 return self.mesh.NbVolumes()
3441 def NbVolumesOfOrder(self, elementOrder):
3443 Return the number of volumes with the given order in the mesh
3446 elementOrder: the order of elements
3447 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3453 return self.mesh.NbVolumesOfOrder(elementOrder)
3457 Return the number of tetrahedrons in the mesh
3463 return self.mesh.NbTetras()
3465 def NbTetrasOfOrder(self, elementOrder):
3467 Return the number of tetrahedrons with the given order in the mesh
3470 elementOrder: the order of elements
3471 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3477 return self.mesh.NbTetrasOfOrder(elementOrder)
3481 Return the number of hexahedrons in the mesh
3487 return self.mesh.NbHexas()
3489 def NbHexasOfOrder(self, elementOrder):
3491 Return the number of hexahedrons with the given order in the mesh
3494 elementOrder: the order of elements
3495 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3501 return self.mesh.NbHexasOfOrder(elementOrder)
3503 def NbTriQuadraticHexas(self):
3505 Return the number of triquadratic hexahedrons in the mesh
3511 return self.mesh.NbTriQuadraticHexas()
3513 def NbPyramids(self):
3515 Return the number of pyramids in the mesh
3521 return self.mesh.NbPyramids()
3523 def NbPyramidsOfOrder(self, elementOrder):
3525 Return the number of pyramids with the given order in the mesh
3528 elementOrder: the order of elements
3529 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3535 return self.mesh.NbPyramidsOfOrder(elementOrder)
3539 Return the number of prisms in the mesh
3545 return self.mesh.NbPrisms()
3547 def NbPrismsOfOrder(self, elementOrder):
3549 Return the number of prisms with the given order in the mesh
3552 elementOrder: the order of elements
3553 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3559 return self.mesh.NbPrismsOfOrder(elementOrder)
3561 def NbHexagonalPrisms(self):
3563 Return the number of hexagonal prisms in the mesh
3569 return self.mesh.NbHexagonalPrisms()
3571 def NbPolyhedrons(self):
3573 Return the number of polyhedrons in the mesh
3579 return self.mesh.NbPolyhedrons()
3581 def NbSubMesh(self):
3583 Return the number of submeshes in the mesh
3589 return self.mesh.NbSubMesh()
3591 def GetElementsId(self):
3593 Return the list of all mesh elements IDs
3596 the list of integer values
3599 :meth:`GetElementsByType`
3602 return self.mesh.GetElementsId()
3604 def GetElementsByType(self, elementType):
3606 Return the list of IDs of mesh elements with the given type
3609 elementType (SMESH.ElementType): the required type of elements
3612 list of integer values
3615 return self.mesh.GetElementsByType(elementType)
3617 def GetNodesId(self):
3619 Return the list of mesh nodes IDs
3622 the list of integer values
3625 return self.mesh.GetNodesId()
3627 # Get the information about mesh elements:
3628 # ------------------------------------
3630 def GetElementType(self, id, iselem=True):
3632 Return the type of mesh element or node
3635 the value from :class:`SMESH.ElementType` enumeration.
3636 Return SMESH.ALL if element or node with the given ID does not exist
3639 return self.mesh.GetElementType(id, iselem)
3641 def GetElementGeomType(self, id):
3643 Return the geometric type of mesh element
3646 the value from :class:`SMESH.EntityType` enumeration.
3649 return self.mesh.GetElementGeomType(id)
3651 def GetElementShape(self, id):
3653 Return the shape type of mesh element
3656 the value from :class:`SMESH.GeometryType` enumeration.
3659 return self.mesh.GetElementShape(id)
3661 def GetSubMeshElementsId(self, Shape):
3663 Return the list of sub-mesh elements IDs
3666 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3667 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3670 list of integer values
3673 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3674 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3677 return self.mesh.GetSubMeshElementsId(ShapeID)
3679 def GetSubMeshNodesId(self, Shape, all):
3681 Return the list of sub-mesh nodes IDs
3684 Shape: a geom object (sub-shape).
3685 *Shape* must be the sub-shape of a :meth:`GetShape`
3686 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3689 list of integer values
3692 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3693 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3696 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3698 def GetSubMeshElementType(self, Shape):
3700 Return type of elements on given shape
3703 Shape: a geom object (sub-shape).
3704 *Shape* must be a sub-shape of a ShapeToMesh()
3707 :class:`SMESH.ElementType`
3710 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3711 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3714 return self.mesh.GetSubMeshElementType(ShapeID)
3718 Get the mesh description
3724 return self.mesh.Dump()
3727 # Get the information about nodes and elements of a mesh by its IDs:
3728 # -----------------------------------------------------------
3730 def GetNodeXYZ(self, id):
3732 Get XYZ coordinates of a node.
3733 If there is no node for the given ID - return an empty list
3736 list of float values
3739 return self.mesh.GetNodeXYZ(id)
3741 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3743 Return list of IDs of inverse elements for the given node.
3744 If there is no node for the given ID - return an empty list
3748 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3751 list of integer values
3754 return self.mesh.GetNodeInverseElements(id,elemType)
3756 def GetNodePosition(self,NodeID):
3758 Return the position of a node on the shape
3761 :class:`SMESH.NodePosition`
3764 return self.mesh.GetNodePosition(NodeID)
3766 def GetElementPosition(self,ElemID):
3768 Return the position of an element on the shape
3771 :class:`SMESH.ElementPosition`
3774 return self.mesh.GetElementPosition(ElemID)
3776 def GetShapeID(self, id):
3778 Return the ID of the shape, on which the given node was generated.
3781 an integer value > 0 or -1 if there is no node for the given
3782 ID or the node is not assigned to any geometry
3785 return self.mesh.GetShapeID(id)
3787 def GetShapeIDForElem(self,id):
3789 Return the ID of the shape, on which the given element was generated.
3792 an integer value > 0 or -1 if there is no element for the given
3793 ID or the element is not assigned to any geometry
3796 return self.mesh.GetShapeIDForElem(id)
3798 def GetElemNbNodes(self, id):
3800 Return the number of nodes of the given element
3803 an integer value > 0 or -1 if there is no element for the given ID
3806 return self.mesh.GetElemNbNodes(id)
3808 def GetElemNode(self, id, index):
3810 Return the node ID the given (zero based) index for the given element.
3812 * If there is no element for the given ID - return -1.
3813 * If there is no node for the given index - return -2.
3816 id (int): element ID
3817 index (int): node index within the element
3820 an integer value (ID)
3823 :meth:`GetElemNodes`
3826 return self.mesh.GetElemNode(id, index)
3828 def GetElemNodes(self, id):
3830 Return the IDs of nodes of the given element
3833 a list of integer values
3836 return self.mesh.GetElemNodes(id)
3838 def IsMediumNode(self, elementID, nodeID):
3840 Return true if the given node is the medium node in the given quadratic element
3843 return self.mesh.IsMediumNode(elementID, nodeID)
3845 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3847 Return true if the given node is the medium node in one of quadratic elements
3850 nodeID: ID of the node
3851 elementType: the type of elements to check a state of the node, either of
3852 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3855 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3857 def ElemNbEdges(self, id):
3859 Return the number of edges for the given element
3862 return self.mesh.ElemNbEdges(id)
3864 def ElemNbFaces(self, id):
3866 Return the number of faces for the given element
3869 return self.mesh.ElemNbFaces(id)
3871 def GetElemFaceNodes(self,elemId, faceIndex):
3873 Return nodes of given face (counted from zero) for given volumic element.
3876 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3878 def GetFaceNormal(self, faceId, normalized=False):
3880 Return three components of normal of given mesh face
3881 (or an empty array in KO case)
3884 return self.mesh.GetFaceNormal(faceId,normalized)
3886 def FindElementByNodes(self, nodes):
3888 Return an element based on all given nodes.
3891 return self.mesh.FindElementByNodes(nodes)
3893 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3895 Return elements including all given nodes.
3898 return self.mesh.GetElementsByNodes( nodes, elemType )
3900 def IsPoly(self, id):
3902 Return true if the given element is a polygon
3905 return self.mesh.IsPoly(id)
3907 def IsQuadratic(self, id):
3909 Return true if the given element is quadratic
3912 return self.mesh.IsQuadratic(id)
3914 def GetBallDiameter(self, id):
3916 Return diameter of a ball discrete element or zero in case of an invalid *id*
3919 return self.mesh.GetBallDiameter(id)
3921 def BaryCenter(self, id):
3923 Return XYZ coordinates of the barycenter of the given element.
3924 If there is no element for the given ID - return an empty list
3927 a list of three double values
3930 :meth:`smeshBuilder.GetGravityCenter`
3933 return self.mesh.BaryCenter(id)
3935 def GetIdsFromFilter(self, filter, meshParts=[] ):
3937 Pass mesh elements through the given filter and return IDs of fitting elements
3940 filter: :class:`SMESH.Filter`
3941 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3947 :meth:`SMESH.Filter.GetIDs`
3948 :meth:`SMESH.Filter.GetElementsIdFromParts`
3951 filter.SetMesh( self.mesh )
3954 if isinstance( meshParts, Mesh ):
3955 filter.SetMesh( meshParts.GetMesh() )
3956 return theFilter.GetIDs()
3957 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3958 meshParts = [ meshParts ]
3959 return filter.GetElementsIdFromParts( meshParts )
3961 return filter.GetIDs()
3963 # Get mesh measurements information:
3964 # ------------------------------------
3966 def GetFreeBorders(self):
3968 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3969 Return a list of special structures (borders).
3972 a list of :class:`SMESH.FreeEdges.Border`
3975 aFilterMgr = self.smeshpyD.CreateFilterManager()
3976 aPredicate = aFilterMgr.CreateFreeEdges()
3977 aPredicate.SetMesh(self.mesh)
3978 aBorders = aPredicate.GetBorders()
3979 aFilterMgr.UnRegister()
3982 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3984 Get minimum distance between two nodes, elements or distance to the origin
3987 id1: first node/element id
3988 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3989 isElem1: *True* if *id1* is element id, *False* if it is node id
3990 isElem2: *True* if *id2* is element id, *False* if it is node id
3993 minimum distance value
3995 :meth:`GetMinDistance`
3998 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3999 return aMeasure.value
4001 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4003 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4006 id1: first node/element id
4007 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4008 isElem1: *True* if *id1* is element id, *False* if it is node id
4009 isElem2: *True* if *id2* is element id, *False* if it is node id
4012 :class:`SMESH.Measure` structure
4018 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4020 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4023 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4025 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4030 aMeasurements = self.smeshpyD.CreateMeasurements()
4031 aMeasure = aMeasurements.MinDistance(id1, id2)
4032 genObjUnRegister([aMeasurements,id1, id2])
4035 def BoundingBox(self, objects=None, isElem=False):
4037 Get bounding box of the specified object(s)
4040 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4041 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4042 *False* specifies that *objects* are nodes
4045 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4048 :meth:`GetBoundingBox()`
4051 result = self.GetBoundingBox(objects, isElem)
4055 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4058 def GetBoundingBox(self, objects=None, isElem=False):
4060 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4063 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4064 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4065 False means that *objects* are nodes
4068 :class:`SMESH.Measure` structure
4071 :meth:`BoundingBox()`
4075 objects = [self.mesh]
4076 elif isinstance(objects, tuple):
4077 objects = list(objects)
4078 if not isinstance(objects, list):
4080 if len(objects) > 0 and isinstance(objects[0], int):
4083 unRegister = genObjUnRegister()
4085 if isinstance(o, Mesh):
4086 srclist.append(o.mesh)
4087 elif hasattr(o, "_narrow"):
4088 src = o._narrow(SMESH.SMESH_IDSource)
4089 if src: srclist.append(src)
4091 elif isinstance(o, list):
4093 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4095 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4096 unRegister.set( srclist[-1] )
4099 aMeasurements = self.smeshpyD.CreateMeasurements()
4100 unRegister.set( aMeasurements )
4101 aMeasure = aMeasurements.BoundingBox(srclist)
4104 # Mesh edition (SMESH_MeshEditor functionality):
4105 # ---------------------------------------------
4107 def RemoveElements(self, IDsOfElements):
4109 Remove the elements from the mesh by ids
4112 IDsOfElements: is a list of ids of elements to remove
4118 This operation can create gaps in numeration of elements.
4119 Call :meth:`RenumberElements` to remove the gaps.
4122 return self.editor.RemoveElements(IDsOfElements)
4124 def RemoveNodes(self, IDsOfNodes):
4126 Remove nodes from mesh by ids
4129 IDsOfNodes: is a list of ids of nodes to remove
4135 This operation can create gaps in numeration of nodes.
4136 Call :meth:`RenumberElements` to remove the gaps.
4139 return self.editor.RemoveNodes(IDsOfNodes)
4141 def RemoveNodeWithReconnection(self, nodeID ):
4143 Remove a node along with changing surrounding faces to cover a hole.
4146 nodeID: ID of node to remove
4149 return self.editor.RemoveNodeWithReconnection( nodeID )
4151 def RemoveOrphanNodes(self):
4153 Remove all orphan (free) nodes from mesh
4156 number of the removed nodes
4159 This operation can create gaps in numeration of nodes.
4160 Call :meth:`RenumberElements` to remove the gaps.
4163 return self.editor.RemoveOrphanNodes()
4165 def AddNode(self, x, y, z):
4167 Add a node to the mesh by coordinates
4173 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4174 if hasVars: self.mesh.SetParameters(Parameters)
4175 return self.editor.AddNode( x, y, z)
4177 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4179 Create a 0D element on a node with given number.
4182 IDOfNode: the ID of node for creation of the element.
4183 DuplicateElements: to add one more 0D element to a node or not
4186 ID of the new 0D element
4189 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4191 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4193 Create 0D elements on all nodes of the given elements except those
4194 nodes on which a 0D element already exists.
4197 theObject: an object on whose nodes 0D elements will be created.
4198 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4199 theGroupName: optional name of a group to add 0D elements created
4200 and/or found on nodes of *theObject*.
4201 DuplicateElements: to add one more 0D element to a node or not
4204 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4205 IDs of new and/or found 0D elements. IDs of 0D elements
4206 can be retrieved from the returned object by
4207 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4210 unRegister = genObjUnRegister()
4211 if isinstance( theObject, Mesh ):
4212 theObject = theObject.GetMesh()
4213 elif isinstance( theObject, list ):
4214 theObject = self.GetIDSource( theObject, SMESH.ALL )
4215 unRegister.set( theObject )
4216 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4218 def AddBall(self, IDOfNode, diameter):
4220 Create a ball element on a node with given ID.
4223 IDOfNode: the ID of node for creation of the element.
4224 diameter: the bal diameter.
4227 ID of the new ball element
4230 return self.editor.AddBall( IDOfNode, diameter )
4232 def AddEdge(self, IDsOfNodes):
4234 Create a linear or quadratic edge (this is determined
4235 by the number of given nodes).
4238 IDsOfNodes: list of node IDs for creation of the element.
4239 The order of nodes in this list should correspond to
4240 the :ref:`connectivity convention <connectivity_page>`.
4246 return self.editor.AddEdge(IDsOfNodes)
4248 def AddFace(self, IDsOfNodes):
4250 Create a linear or quadratic face (this is determined
4251 by the number of given nodes).
4254 IDsOfNodes: list of node IDs for creation of the element.
4255 The order of nodes in this list should correspond to
4256 the :ref:`connectivity convention <connectivity_page>`.
4262 return self.editor.AddFace(IDsOfNodes)
4264 def AddPolygonalFace(self, IdsOfNodes):
4266 Add a polygonal face defined by a list of node IDs
4269 IdsOfNodes: the list of node IDs for creation of the element.
4275 return self.editor.AddPolygonalFace(IdsOfNodes)
4277 def AddQuadPolygonalFace(self, IdsOfNodes):
4279 Add a quadratic polygonal face defined by a list of node IDs
4282 IdsOfNodes: the list of node IDs for creation of the element;
4283 corner nodes follow first.
4289 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4291 def AddVolume(self, IDsOfNodes):
4293 Create both simple and quadratic volume (this is determined
4294 by the number of given nodes).
4297 IDsOfNodes: list of node IDs for creation of the element.
4298 The order of nodes in this list should correspond to
4299 the :ref:`connectivity convention <connectivity_page>`.
4302 ID of the new volumic element
4305 return self.editor.AddVolume(IDsOfNodes)
4307 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4309 Create a volume of many faces, giving nodes for each face.
4312 IdsOfNodes: list of node IDs for volume creation, face by face.
4313 Quantities: list of integer values, Quantities[i]
4314 gives the quantity of nodes in face number i.
4317 ID of the new volumic element
4320 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4322 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4324 Create a volume of many faces, giving the IDs of the existing faces.
4327 The created volume will refer only to the nodes
4328 of the given faces, not to the faces themselves.
4331 IdsOfFaces: the list of face IDs for volume creation.
4334 ID of the new volumic element
4337 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4340 def SetNodeOnVertex(self, NodeID, Vertex):
4342 Bind a node to a vertex
4346 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4349 True if succeed else raises an exception
4352 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4353 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4357 self.editor.SetNodeOnVertex(NodeID, VertexID)
4358 except SALOME.SALOME_Exception as inst:
4359 raise ValueError(inst.details.text)
4363 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4365 Store the node position on an edge
4369 Edge: an edge (GEOM.GEOM_Object) or edge ID
4370 paramOnEdge: a parameter on the edge where the node is located
4373 True if succeed else raises an exception
4376 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4377 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4381 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4382 except SALOME.SALOME_Exception as inst:
4383 raise ValueError(inst.details.text)
4386 def SetNodeOnFace(self, NodeID, Face, u, v):
4388 Store node position on a face
4392 Face: a face (GEOM.GEOM_Object) or face ID
4393 u: U parameter on the face where the node is located
4394 v: V parameter on the face where the node is located
4397 True if succeed else raises an exception
4400 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4401 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4405 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4406 except SALOME.SALOME_Exception as inst:
4407 raise ValueError(inst.details.text)
4410 def SetNodeInVolume(self, NodeID, Solid):
4412 Bind a node to a solid
4416 Solid: a solid (GEOM.GEOM_Object) or solid ID
4419 True if succeed else raises an exception
4422 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4423 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4427 self.editor.SetNodeInVolume(NodeID, SolidID)
4428 except SALOME.SALOME_Exception as inst:
4429 raise ValueError(inst.details.text)
4432 def SetMeshElementOnShape(self, ElementID, Shape):
4434 Bind an element to a shape
4437 ElementID: an element ID
4438 Shape: a shape (GEOM.GEOM_Object) or shape ID
4441 True if succeed else raises an exception
4444 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4445 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4449 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4450 except SALOME.SALOME_Exception as inst:
4451 raise ValueError(inst.details.text)
4455 def MoveNode(self, NodeID, x, y, z):
4457 Move the node with the given id
4460 NodeID: the id of the node
4461 x: a new X coordinate
4462 y: a new Y coordinate
4463 z: a new Z coordinate
4466 True if succeed else False
4469 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4470 if hasVars: self.mesh.SetParameters(Parameters)
4471 return self.editor.MoveNode(NodeID, x, y, z)
4473 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4475 Find the node closest to a point and moves it to a point location
4478 x: the X coordinate of a point
4479 y: the Y coordinate of a point
4480 z: the Z coordinate of a point
4481 NodeID: if specified (>0), the node with this ID is moved,
4482 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4485 the ID of a moved node
4488 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4489 if hasVars: self.mesh.SetParameters(Parameters)
4490 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4492 def FindNodeClosestTo(self, x, y, z):
4494 Find the node closest to a point
4497 x: the X coordinate of a point
4498 y: the Y coordinate of a point
4499 z: the Z coordinate of a point
4505 return self.editor.FindNodeClosestTo(x, y, z)
4507 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4509 Find the elements where a point lays IN or ON
4512 x,y,z (float): coordinates of the point
4513 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4514 means elements of any type excluding nodes, discrete and 0D elements.
4515 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4518 list of IDs of found elements
4521 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4523 return self.editor.FindElementsByPoint(x, y, z, elementType)
4525 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4527 Project a point to a mesh object.
4528 Return ID of an element of given type where the given point is projected
4529 and coordinates of the projection point.
4530 In the case if nothing found, return -1 and []
4532 if isinstance( meshObject, Mesh ):
4533 meshObject = meshObject.GetMesh()
4535 meshObject = self.GetMesh()
4536 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4538 def GetPointState(self, x, y, z):
4540 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4541 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4542 UNKNOWN state means that either mesh is wrong or the analysis fails.
4545 return self.editor.GetPointState(x, y, z)
4547 def IsManifold(self):
4549 Check if a 2D mesh is manifold
4552 return self.editor.IsManifold()
4554 def IsCoherentOrientation2D(self):
4556 Check if orientation of 2D elements is coherent
4559 return self.editor.IsCoherentOrientation2D()
4561 def Get1DBranches( self, edges, startNode = 0 ):
4563 Partition given 1D elements into groups of contiguous edges.
4564 A node where number of meeting edges != 2 is a group end.
4565 An optional startNode is used to orient groups it belongs to.
4568 A list of edge groups and a list of corresponding node groups,
4569 where the group is a list of IDs of edges or nodes, like follows
4570 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4571 If a group is closed, the first and last nodes of the group are same.
4573 if isinstance( edges, Mesh ):
4574 edges = edges.GetMesh()
4575 unRegister = genObjUnRegister()
4576 if isinstance( edges, list ):
4577 edges = self.GetIDSource( edges, SMESH.EDGE )
4578 unRegister.set( edges )
4579 return self.editor.Get1DBranches( edges, startNode )
4581 def FindSharpEdges( self, angle, addExisting=False ):
4583 Return sharp edges of faces and non-manifold ones.
4584 Optionally add existing edges.
4587 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4588 addExisting: to return existing edges (1D elements) as well
4591 list of FaceEdge structures
4593 angle = ParseParameters( angle )[0]
4594 return self.editor.FindSharpEdges( angle, addExisting )
4596 def MeshToPassThroughAPoint(self, x, y, z):
4598 Find the node closest to a point and moves it to a point location
4601 x: the X coordinate of a point
4602 y: the Y coordinate of a point
4603 z: the Z coordinate of a point
4606 the ID of a moved node
4609 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4611 def InverseDiag(self, NodeID1, NodeID2):
4613 Replace two neighbour triangles sharing Node1-Node2 link
4614 with the triangles built on the same 4 nodes but having other common link.
4617 NodeID1: the ID of the first node
4618 NodeID2: the ID of the second node
4621 False if proper faces were not found
4623 return self.editor.InverseDiag(NodeID1, NodeID2)
4625 def DeleteDiag(self, NodeID1, NodeID2):
4627 Replace two neighbour triangles sharing *Node1-Node2* link
4628 with a quadrangle built on the same 4 nodes.
4631 NodeID1: ID of the first node
4632 NodeID2: ID of the second node
4635 False if proper faces were not found
4638 This operation can create gaps in numeration of elements.
4639 Call :meth:`RenumberElements` to remove the gaps.
4642 return self.editor.DeleteDiag(NodeID1, NodeID2)
4644 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4646 Replace each triangle bound by Node1-Node2 segment with
4647 two triangles by connecting a node made on the link with a node
4648 opposite to the link.
4651 Node1: ID of the first node
4652 Node2: ID of the second node
4653 position: location [0,1] of the new node on the segment
4655 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4657 def AddNodeOnFace(self, face, x, y, z):
4659 Split a face into triangles by adding a new node onto the face
4660 and connecting the new node with face nodes
4663 face: ID of the face
4664 x,y,z: coordinates of the new node
4666 return self.editor.AddNodeOnFace(face, x, y, z)
4668 def Reorient(self, IDsOfElements=None):
4670 Reorient elements by ids
4673 IDsOfElements: if undefined reorients all mesh elements
4676 True if succeed else False
4679 if IDsOfElements == None:
4680 IDsOfElements = self.GetElementsId()
4681 return self.editor.Reorient(IDsOfElements)
4683 def ReorientObject(self, theObject):
4685 Reorient all elements of the object
4688 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4691 True if succeed else False
4694 if ( isinstance( theObject, Mesh )):
4695 theObject = theObject.GetMesh()
4696 return self.editor.ReorientObject(theObject)
4698 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4700 Reorient faces contained in *the2DObject*.
4703 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4704 theDirection: a desired direction of normal of *theFace*.
4705 It can be either a GEOM vector or a list of coordinates [x,y,z].
4706 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4707 compared with theDirection. It can be either ID of face or a point
4708 by which the face will be found. The point can be given as either
4709 a GEOM vertex or a list of point coordinates.
4712 number of reoriented faces
4715 unRegister = genObjUnRegister()
4717 if isinstance( the2DObject, Mesh ):
4718 the2DObject = the2DObject.GetMesh()
4719 if isinstance( the2DObject, list ):
4720 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4721 unRegister.set( the2DObject )
4722 # check theDirection
4723 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4724 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4725 if isinstance( theDirection, list ):
4726 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4727 # prepare theFace and thePoint
4728 theFace = theFaceOrPoint
4729 thePoint = PointStruct(0,0,0)
4730 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4731 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4733 if isinstance( theFaceOrPoint, list ):
4734 thePoint = PointStruct( *theFaceOrPoint )
4736 if isinstance( theFaceOrPoint, PointStruct ):
4737 thePoint = theFaceOrPoint
4739 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4741 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4743 Reorient faces contained in a list of *objectFaces*
4744 equally to faces contained in a list of *referenceFaces*.
4747 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4748 referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference.
4751 number of reoriented faces.
4753 if not isinstance( objectFaces, list ):
4754 objectFaces = [ objectFaces ]
4755 for i,obj2D in enumerate( objectFaces ):
4756 if isinstance( obj2D, Mesh ):
4757 objectFaces[i] = obj2D.GetMesh()
4758 if not isinstance( referenceFaces, list ):
4759 referenceFaces = [ referenceFaces ]
4761 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4764 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4766 Reorient faces according to adjacent volumes.
4769 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4770 either IDs of faces or face groups.
4771 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4772 theOutsideNormal: to orient faces to have their normals
4773 pointing either *outside* or *inside* the adjacent volumes.
4776 number of reoriented faces.
4779 unRegister = genObjUnRegister()
4781 if not isinstance( the2DObject, list ):
4782 the2DObject = [ the2DObject ]
4783 elif the2DObject and isinstance( the2DObject[0], int ):
4784 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4785 unRegister.set( the2DObject )
4786 the2DObject = [ the2DObject ]
4787 for i,obj2D in enumerate( the2DObject ):
4788 if isinstance( obj2D, Mesh ):
4789 the2DObject[i] = obj2D.GetMesh()
4790 if isinstance( obj2D, list ):
4791 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4792 unRegister.set( the2DObject[i] )
4794 if isinstance( the3DObject, Mesh ):
4795 the3DObject = the3DObject.GetMesh()
4796 if isinstance( the3DObject, list ):
4797 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4798 unRegister.set( the3DObject )
4799 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4801 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4803 Fuse the neighbouring triangles into quadrangles.
4806 IDsOfElements: The triangles to be fused.
4807 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4808 applied to possible quadrangles to choose a neighbour to fuse with.
4809 Note that not all items of :class:`SMESH.FunctorType` corresponds
4810 to numerical functors.
4811 MaxAngle: is the maximum angle between element normals at which the fusion
4812 is still performed; theMaxAngle is measured in radians.
4813 Also it could be a name of variable which defines angle in degrees.
4816 True in case of success, False otherwise.
4819 This operation can create gaps in numeration of elements.
4820 Call :meth:`RenumberElements` to remove the gaps.
4823 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4824 self.mesh.SetParameters(Parameters)
4825 if not IDsOfElements:
4826 IDsOfElements = self.GetElementsId()
4827 Functor = self.smeshpyD.GetFunctor(theCriterion)
4828 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4830 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4832 Fuse the neighbouring triangles of the object into quadrangles
4835 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4836 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4837 applied to possible quadrangles to choose a neighbour to fuse with.
4838 Note that not all items of :class:`SMESH.FunctorType` corresponds
4839 to numerical functors.
4840 MaxAngle: a max angle between element normals at which the fusion
4841 is still performed; theMaxAngle is measured in radians.
4844 True in case of success, False otherwise.
4847 This operation can create gaps in numeration of elements.
4848 Call :meth:`RenumberElements` to remove the gaps.
4851 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4852 self.mesh.SetParameters(Parameters)
4853 if isinstance( theObject, Mesh ):
4854 theObject = theObject.GetMesh()
4855 Functor = self.smeshpyD.GetFunctor(theCriterion)
4856 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4858 def QuadToTri (self, IDsOfElements, theCriterion = None):
4860 Split quadrangles into triangles.
4863 IDsOfElements: the faces to be splitted.
4864 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4865 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4866 value, then quadrangles will be split by the smallest diagonal.
4867 Note that not all items of :class:`SMESH.FunctorType` corresponds
4868 to numerical functors.
4871 True in case of success, False otherwise.
4874 This operation can create gaps in numeration of elements.
4875 Call :meth:`RenumberElements` to remove the gaps.
4877 if IDsOfElements == []:
4878 IDsOfElements = self.GetElementsId()
4879 if theCriterion is None:
4880 theCriterion = FT_MaxElementLength2D
4881 Functor = self.smeshpyD.GetFunctor(theCriterion)
4882 return self.editor.QuadToTri(IDsOfElements, Functor)
4884 def QuadToTriObject (self, theObject, theCriterion = None):
4886 Split quadrangles into triangles.
4889 theObject: the object from which the list of elements is taken,
4890 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4891 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4892 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4893 value, then quadrangles will be split by the smallest diagonal.
4894 Note that not all items of :class:`SMESH.FunctorType` corresponds
4895 to numerical functors.
4898 True in case of success, False otherwise.
4901 This operation can create gaps in numeration of elements.
4902 Call :meth:`RenumberElements` to remove the gaps.
4904 if ( isinstance( theObject, Mesh )):
4905 theObject = theObject.GetMesh()
4906 if theCriterion is None:
4907 theCriterion = FT_MaxElementLength2D
4908 Functor = self.smeshpyD.GetFunctor(theCriterion)
4909 return self.editor.QuadToTriObject(theObject, Functor)
4911 def QuadTo4Tri (self, theElements=[]):
4913 Split each of given quadrangles into 4 triangles. A node is added at the center of
4917 theElements: the faces to be splitted. This can be either
4918 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4919 or a list of face IDs. By default all quadrangles are split
4922 This operation can create gaps in numeration of elements.
4923 Call :meth:`RenumberElements` to remove the gaps.
4925 unRegister = genObjUnRegister()
4926 if isinstance( theElements, Mesh ):
4927 theElements = theElements.mesh
4928 elif not theElements:
4929 theElements = self.mesh
4930 elif isinstance( theElements, list ):
4931 theElements = self.GetIDSource( theElements, SMESH.FACE )
4932 unRegister.set( theElements )
4933 return self.editor.QuadTo4Tri( theElements )
4935 def SplitQuad (self, IDsOfElements, Diag13):
4937 Split quadrangles into triangles.
4940 IDsOfElements: the faces to be splitted
4941 Diag13 (boolean): is used to choose a diagonal for splitting.
4944 True in case of success, False otherwise.
4947 This operation can create gaps in numeration of elements.
4948 Call :meth:`RenumberElements` to remove the gaps.
4950 if IDsOfElements == []:
4951 IDsOfElements = self.GetElementsId()
4952 return self.editor.SplitQuad(IDsOfElements, Diag13)
4954 def SplitQuadObject (self, theObject, Diag13):
4956 Split quadrangles into triangles.
4959 theObject: the object from which the list of elements is taken,
4960 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4961 Diag13 (boolean): is used to choose a diagonal for splitting.
4964 True in case of success, False otherwise.
4967 This operation can create gaps in numeration of elements.
4968 Call :meth:`RenumberElements` to remove the gaps.
4970 if ( isinstance( theObject, Mesh )):
4971 theObject = theObject.GetMesh()
4972 return self.editor.SplitQuadObject(theObject, Diag13)
4974 def BestSplit (self, IDOfQuad, theCriterion):
4976 Find a better splitting of the given quadrangle.
4979 IDOfQuad: the ID of the quadrangle to be splitted.
4980 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4981 choose a diagonal for splitting.
4982 Note that not all items of :class:`SMESH.FunctorType` corresponds
4983 to numerical functors.
4986 * 1 if 1-3 diagonal is better,
4987 * 2 if 2-4 diagonal is better,
4988 * 0 if error occurs.
4991 This operation can create gaps in numeration of elements.
4992 Call :meth:`RenumberElements` to remove the gaps.
4994 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4996 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4998 Split volumic elements into tetrahedrons
5001 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5002 method: flags passing splitting method:
5003 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5004 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5007 This operation can create gaps in numeration of elements.
5008 Call :meth:`RenumberElements` to remove the gaps.
5010 unRegister = genObjUnRegister()
5011 if isinstance( elems, Mesh ):
5012 elems = elems.GetMesh()
5013 if ( isinstance( elems, list )):
5014 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5015 unRegister.set( elems )
5016 self.editor.SplitVolumesIntoTetra(elems, method)
5019 def SplitBiQuadraticIntoLinear(self, elems=None):
5021 Split bi-quadratic elements into linear ones without creation of additional nodes:
5023 - bi-quadratic triangle will be split into 3 linear quadrangles;
5024 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5025 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5027 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5028 will be split in order to keep the mesh conformal.
5031 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5032 if None (default), all bi-quadratic elements will be split
5035 This operation can create gaps in numeration of elements.
5036 Call :meth:`RenumberElements` to remove the gaps.
5038 unRegister = genObjUnRegister()
5039 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5040 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5041 unRegister.set( elems )
5043 elems = [ self.GetMesh() ]
5044 if isinstance( elems, Mesh ):
5045 elems = [ elems.GetMesh() ]
5046 if not isinstance( elems, list ):
5048 self.editor.SplitBiQuadraticIntoLinear( elems )
5050 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5051 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5053 Split hexahedra into prisms
5056 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5057 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5058 gives a normal vector defining facets to split into triangles.
5059 *startHexPoint* can be either a triple of coordinates or a vertex.
5060 facetNormal: a normal to a facet to split into triangles of a
5061 hexahedron found by *startHexPoint*.
5062 *facetNormal* can be either a triple of coordinates or an edge.
5063 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5064 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5065 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5066 to *startHexPoint* are split, else *startHexPoint*
5067 is used to find the facet to split in all domains present in *elems*.
5070 This operation can create gaps in numeration of elements.
5071 Call :meth:`RenumberElements` to remove the gaps.
5074 unRegister = genObjUnRegister()
5075 if isinstance( elems, Mesh ):
5076 elems = elems.GetMesh()
5077 if ( isinstance( elems, list )):
5078 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5079 unRegister.set( elems )
5082 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5083 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5084 elif isinstance( startHexPoint, list ):
5085 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5088 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5089 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5090 elif isinstance( facetNormal, list ):
5091 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5094 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5096 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5098 def SplitQuadsNearTriangularFacets(self):
5100 Split quadrangle faces near triangular facets of volumes
5103 This operation can create gaps in numeration of elements.
5104 Call :meth:`RenumberElements` to remove the gaps.
5106 faces_array = self.GetElementsByType(SMESH.FACE)
5107 for face_id in faces_array:
5108 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5109 quad_nodes = self.mesh.GetElemNodes(face_id)
5110 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5111 isVolumeFound = False
5112 for node1_elem in node1_elems:
5113 if not isVolumeFound:
5114 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5115 nb_nodes = self.GetElemNbNodes(node1_elem)
5116 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5117 volume_elem = node1_elem
5118 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5119 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5120 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5121 isVolumeFound = True
5122 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5123 self.SplitQuad([face_id], False) # diagonal 2-4
5124 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5125 isVolumeFound = True
5126 self.SplitQuad([face_id], True) # diagonal 1-3
5127 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5128 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5129 isVolumeFound = True
5130 self.SplitQuad([face_id], True) # diagonal 1-3
5132 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5134 Split hexahedrons into tetrahedrons.
5136 This operation uses :doc:`pattern_mapping` functionality for splitting.
5139 theObject: the object from which the list of hexahedrons is taken;
5140 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5141 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5142 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5143 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5144 key-point will be mapped into *theNode001*-th node of each volume.
5145 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5148 True in case of success, False otherwise.
5151 This operation can create gaps in numeration of elements.
5152 Call :meth:`RenumberElements` to remove the gaps.
5160 # (0,0,1) 4.---------.7 * |
5167 # (0,0,0) 0.---------.3
5168 pattern_tetra = "!!! Nb of points: \n 8 \n\
5178 !!! Indices of points of 6 tetras: \n\
5186 pattern = self.smeshpyD.GetPattern()
5187 isDone = pattern.LoadFromFile(pattern_tetra)
5189 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5192 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5193 isDone = pattern.MakeMesh(self.mesh, False, False)
5194 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5196 # split quafrangle faces near triangular facets of volumes
5197 self.SplitQuadsNearTriangularFacets()
5201 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5203 Split hexahedrons into prisms.
5205 Uses the :doc:`pattern_mapping` functionality for splitting.
5208 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5209 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5210 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5211 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5212 will be mapped into the *theNode001* -th node of each volume.
5213 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5216 True in case of success, False otherwise.
5219 This operation can create gaps in numeration of elements.
5220 Call :meth:`RenumberElements` to remove the gaps.
5222 # Pattern: 5.---------.6
5227 # (0,0,1) 4.---------.7 |
5234 # (0,0,0) 0.---------.3
5235 pattern_prism = "!!! Nb of points: \n 8 \n\
5245 !!! Indices of points of 2 prisms: \n\
5249 pattern = self.smeshpyD.GetPattern()
5250 isDone = pattern.LoadFromFile(pattern_prism)
5252 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5255 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5256 isDone = pattern.MakeMesh(self.mesh, False, False)
5257 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5259 # Split quafrangle faces near triangular facets of volumes
5260 self.SplitQuadsNearTriangularFacets()
5264 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5265 MaxNbOfIterations, MaxAspectRatio, Method):
5270 IDsOfElements: the list if ids of elements to smooth
5271 IDsOfFixedNodes: the list of ids of fixed nodes.
5272 Note that nodes built on edges and boundary nodes are always fixed.
5273 MaxNbOfIterations: the maximum number of iterations
5274 MaxAspectRatio: varies in range [1.0, inf]
5275 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5276 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5279 True in case of success, False otherwise.
5282 if IDsOfElements == []:
5283 IDsOfElements = self.GetElementsId()
5284 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5285 self.mesh.SetParameters(Parameters)
5286 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5287 MaxNbOfIterations, MaxAspectRatio, Method)
5289 def SmoothObject(self, theObject, IDsOfFixedNodes,
5290 MaxNbOfIterations, MaxAspectRatio, Method):
5292 Smooth elements which belong to the given object
5295 theObject: the object to smooth
5296 IDsOfFixedNodes: the list of ids of fixed nodes.
5297 Note that nodes built on edges and boundary nodes are always fixed.
5298 MaxNbOfIterations: the maximum number of iterations
5299 MaxAspectRatio: varies in range [1.0, inf]
5300 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5301 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5304 True in case of success, False otherwise.
5307 if ( isinstance( theObject, Mesh )):
5308 theObject = theObject.GetMesh()
5309 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5310 MaxNbOfIterations, MaxAspectRatio, Method)
5312 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5313 MaxNbOfIterations, MaxAspectRatio, Method):
5315 Parametrically smooth the given elements
5318 IDsOfElements: the list if ids of elements to smooth
5319 IDsOfFixedNodes: the list of ids of fixed nodes.
5320 Note that nodes built on edges and boundary nodes are always fixed.
5321 MaxNbOfIterations: the maximum number of iterations
5322 MaxAspectRatio: varies in range [1.0, inf]
5323 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5324 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5327 True in case of success, False otherwise.
5330 if IDsOfElements == []:
5331 IDsOfElements = self.GetElementsId()
5332 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5333 self.mesh.SetParameters(Parameters)
5334 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5335 MaxNbOfIterations, MaxAspectRatio, Method)
5337 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5338 MaxNbOfIterations, MaxAspectRatio, Method):
5340 Parametrically smooth the elements which belong to the given object
5343 theObject: the object to smooth
5344 IDsOfFixedNodes: the list of ids of fixed nodes.
5345 Note that nodes built on edges and boundary nodes are always fixed.
5346 MaxNbOfIterations: the maximum number of iterations
5347 MaxAspectRatio: varies in range [1.0, inf]
5348 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5349 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5352 True in case of success, False otherwise.
5355 if ( isinstance( theObject, Mesh )):
5356 theObject = theObject.GetMesh()
5357 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5358 MaxNbOfIterations, MaxAspectRatio, Method)
5360 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5362 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5363 them with quadratic with the same id.
5366 theForce3d: method of new node creation:
5368 * False - the medium node lies at the geometrical entity from which the mesh element is built
5369 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5370 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5371 theToBiQuad: If True, converts the mesh to bi-quadratic
5374 :class:`SMESH.ComputeError` which can hold a warning
5377 If *theSubMesh* is provided, the mesh can become non-conformal
5380 This operation can create gaps in numeration of nodes or elements.
5381 Call :meth:`RenumberElements` to remove the gaps.
5384 if isinstance( theSubMesh, Mesh ):
5385 theSubMesh = theSubMesh.mesh
5387 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5390 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5392 self.editor.ConvertToQuadratic(theForce3d)
5393 error = self.editor.GetLastError()
5394 if error and error.comment:
5395 print(error.comment)
5398 def ConvertFromQuadratic(self, theSubMesh=None):
5400 Convert the mesh from quadratic to ordinary,
5401 deletes old quadratic elements,
5402 replacing them with ordinary mesh elements with the same id.
5405 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5408 If *theSubMesh* is provided, the mesh can become non-conformal
5411 This operation can create gaps in numeration of nodes or elements.
5412 Call :meth:`RenumberElements` to remove the gaps.
5416 self.editor.ConvertFromQuadraticObject(theSubMesh)
5418 return self.editor.ConvertFromQuadratic()
5420 def Make2DMeshFrom3D(self):
5422 Create 2D mesh as skin on boundary faces of a 3D mesh
5425 True if operation has been completed successfully, False otherwise
5428 return self.editor.Make2DMeshFrom3D()
5430 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5431 toCopyElements=False, toCopyExistingBondary=False):
5433 Create missing boundary elements
5436 elements: elements whose boundary is to be checked:
5437 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5438 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5439 dimension: defines type of boundary elements to create, either of
5440 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5441 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5442 groupName: a name of group to store created boundary elements in,
5443 "" means not to create the group
5444 meshName: a name of new mesh to store created boundary elements in,
5445 "" means not to create the new mesh
5446 toCopyElements: if True, the checked elements will be copied into
5447 the new mesh else only boundary elements will be copied into the new mesh
5448 toCopyExistingBondary: if True, not only new but also pre-existing
5449 boundary elements will be copied into the new mesh
5452 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5455 unRegister = genObjUnRegister()
5456 if isinstance( elements, Mesh ):
5457 elements = elements.GetMesh()
5458 if ( isinstance( elements, list )):
5459 elemType = SMESH.ALL
5460 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5461 elements = self.editor.MakeIDSource(elements, elemType)
5462 unRegister.set( elements )
5463 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5464 toCopyElements,toCopyExistingBondary)
5465 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5468 def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
5470 Create boundary elements around the whole mesh or groups of elements
5473 groupName: a name of group to store all boundary elements in,
5474 "" means not to create the group
5475 meshName: a name of a new mesh, which is a copy of the initial
5476 mesh + created boundary elements; "" means not to create the new mesh
5477 toCopyAll: if True, the whole initial mesh will be copied into
5478 the new mesh else only boundary elements will be copied into the new mesh
5479 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5482 tuple( long, mesh, group )
5483 - long - number of added boundary elements
5484 - mesh - the :class:`Mesh` where elements were added to
5485 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5487 dimension=SMESH.BND_2DFROM3D
5488 toCreateAllElements = True # create all boundary elements in the mesh
5489 nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
5490 toCopyAll,toCreateAllElements,groups)
5491 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5492 return nb, mesh, group
5494 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5495 toCopyAll=False, groups=[]):
5497 Create missing boundary elements around either the whole mesh or
5501 dimension: defines type of boundary elements to create, either of
5502 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5503 groupName: a name of group to store all boundary elements in,
5504 "" means not to create the group
5505 meshName: a name of a new mesh, which is a copy of the initial
5506 mesh + created boundary elements; "" means not to create the new mesh
5507 toCopyAll: if True, the whole initial mesh will be copied into
5508 the new mesh else only boundary elements will be copied into the new mesh
5509 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5512 tuple( long, mesh, group )
5513 - long - number of added boundary elements
5514 - mesh - the :class:`Mesh` where elements were added to
5515 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5517 toCreateAllElements = False # create only elements in the boundary of the solid
5518 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5519 toCopyAll,toCreateAllElements,groups)
5520 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5521 return nb, mesh, group
5523 def RenumberNodes(self):
5525 Renumber mesh nodes to remove unused node IDs
5527 self.editor.RenumberNodes()
5529 def RenumberElements(self):
5531 Renumber mesh elements to remove unused element IDs
5533 self.editor.RenumberElements()
5535 def _getIdSourceList(self, arg, idType, unRegister):
5537 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5539 if arg and isinstance( arg, list ):
5540 if isinstance( arg[0], int ):
5541 arg = self.GetIDSource( arg, idType )
5542 unRegister.set( arg )
5543 elif isinstance( arg[0], Mesh ):
5544 arg[0] = arg[0].GetMesh()
5545 elif isinstance( arg, Mesh ):
5547 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5551 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5552 MakeGroups=False, TotalAngle=False):
5554 Generate new elements by rotation of the given elements and nodes around the axis
5557 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5558 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5559 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5560 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5561 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5562 which defines angle in degrees
5563 NbOfSteps: the number of steps
5564 Tolerance: tolerance
5565 MakeGroups: forces the generation of new groups from existing ones
5566 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5567 of all steps, else - size of each step
5570 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5573 unRegister = genObjUnRegister()
5574 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5575 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5576 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5578 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5579 Axis = self.smeshpyD.GetAxisStruct( Axis )
5580 if isinstance( Axis, list ):
5581 Axis = SMESH.AxisStruct( *Axis )
5583 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5584 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5585 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5586 self.mesh.SetParameters(Parameters)
5587 if TotalAngle and NbOfSteps:
5588 AngleInRadians /= NbOfSteps
5589 return self.editor.RotationSweepObjects( nodes, edges, faces,
5590 Axis, AngleInRadians,
5591 NbOfSteps, Tolerance, MakeGroups)
5593 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5594 MakeGroups=False, TotalAngle=False):
5596 Generate new elements by rotation of the elements around the axis
5599 IDsOfElements: the list of ids of elements to sweep
5600 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5601 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5602 NbOfSteps: the number of steps
5603 Tolerance: tolerance
5604 MakeGroups: forces the generation of new groups from existing ones
5605 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5606 of all steps, else - size of each step
5609 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5612 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5613 AngleInRadians, NbOfSteps, Tolerance,
5614 MakeGroups, TotalAngle)
5616 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5617 MakeGroups=False, TotalAngle=False):
5619 Generate new elements by rotation of the elements of object around the axis
5620 theObject object which elements should be sweeped.
5621 It can be a mesh, a sub mesh or a group.
5624 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5625 AngleInRadians: the angle of Rotation
5626 NbOfSteps: number of steps
5627 Tolerance: tolerance
5628 MakeGroups: forces the generation of new groups from existing ones
5629 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5630 of all steps, else - size of each step
5633 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5636 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5637 AngleInRadians, NbOfSteps, Tolerance,
5638 MakeGroups, TotalAngle )
5640 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5641 MakeGroups=False, TotalAngle=False):
5643 Generate new elements by rotation of the elements of object around the axis
5644 theObject object which elements should be sweeped.
5645 It can be a mesh, a sub mesh or a group.
5648 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5649 AngleInRadians: the angle of Rotation
5650 NbOfSteps: number of steps
5651 Tolerance: tolerance
5652 MakeGroups: forces the generation of new groups from existing ones
5653 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5654 of all steps, else - size of each step
5657 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5658 empty list otherwise
5661 return self.RotationSweepObjects([],theObject,[], Axis,
5662 AngleInRadians, NbOfSteps, Tolerance,
5663 MakeGroups, TotalAngle)
5665 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5666 MakeGroups=False, TotalAngle=False):
5668 Generate new elements by rotation of the elements of object around the axis
5669 theObject object which elements should be sweeped.
5670 It can be a mesh, a sub mesh or a group.
5673 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5674 AngleInRadians: the angle of Rotation
5675 NbOfSteps: number of steps
5676 Tolerance: tolerance
5677 MakeGroups: forces the generation of new groups from existing ones
5678 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5679 of all steps, else - size of each step
5682 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5685 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5686 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5688 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5689 scaleFactors=[], linearVariation=False, basePoint=[],
5690 angles=[], anglesVariation=False):
5692 Generate new elements by extrusion of the given elements and nodes
5695 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5696 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5697 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5698 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5699 the direction and value of extrusion for one step (the total extrusion
5700 length will be NbOfSteps * ||StepVector||)
5701 NbOfSteps: the number of steps
5702 MakeGroups: forces the generation of new groups from existing ones
5703 scaleFactors: optional scale factors to apply during extrusion
5704 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5705 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5706 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5707 nodes and elements being extruded is used as the scaling center.
5710 - a list of tree components of the point or
5713 angles: list of angles in radians. Nodes at each extrusion step are rotated
5714 around *basePoint*, additionally to previous steps.
5715 anglesVariation: forces the computation of rotation angles as linear
5716 variation of the given *angles* along path steps
5718 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5720 Example: :ref:`tui_extrusion`
5722 unRegister = genObjUnRegister()
5723 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5724 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5725 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5727 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5728 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5729 if isinstance( StepVector, list ):
5730 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5732 if isinstance( basePoint, int):
5733 xyz = self.GetNodeXYZ( basePoint )
5735 raise RuntimeError("Invalid node ID: %s" % basePoint)
5737 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5738 basePoint = self.geompyD.PointCoordinates( basePoint )
5740 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5741 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5742 angles,angleParameters,hasVars = ParseAngles(angles)
5743 Parameters = StepVector.PS.parameters + var_separator + \
5744 Parameters + var_separator + \
5745 scaleParameters + var_separator + angleParameters
5746 self.mesh.SetParameters(Parameters)
5748 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5749 StepVector, NbOfSteps, MakeGroups,
5750 scaleFactors, linearVariation, basePoint,
5751 angles, anglesVariation )
5754 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5756 Generate new elements by extrusion of the elements with given ids
5759 IDsOfElements: the list of ids of elements or nodes for extrusion
5760 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5761 the direction and value of extrusion for one step (the total extrusion
5762 length will be NbOfSteps * ||StepVector||)
5763 NbOfSteps: the number of steps
5764 MakeGroups: forces the generation of new groups from existing ones
5765 IsNodes: is True if elements with given ids are nodes
5768 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5770 Example: :ref:`tui_extrusion`
5773 if IsNodes: n = IDsOfElements
5774 else : e,f, = IDsOfElements,IDsOfElements
5775 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5777 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5778 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5780 Generate new elements by extrusion along the normal to a discretized surface or wire
5783 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5784 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5785 StepSize: length of one extrusion step (the total extrusion
5786 length will be *NbOfSteps* *StepSize*).
5787 NbOfSteps: number of extrusion steps.
5788 ByAverageNormal: if True each node is translated by *StepSize*
5789 along the average of the normal vectors to the faces sharing the node;
5790 else each node is translated along the same average normal till
5791 intersection with the plane got by translation of the face sharing
5792 the node along its own normal by *StepSize*.
5793 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5794 for every node of *Elements*.
5795 MakeGroups: forces generation of new groups from existing ones.
5796 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5797 is not yet implemented. This parameter is used if *Elements* contains
5798 both faces and edges, i.e. *Elements* is a Mesh.
5801 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5802 empty list otherwise.
5803 Example: :ref:`tui_extrusion`
5806 unRegister = genObjUnRegister()
5807 if isinstance( Elements, Mesh ):
5808 Elements = [ Elements.GetMesh() ]
5809 if isinstance( Elements, list ):
5811 raise RuntimeError("Elements empty!")
5812 if isinstance( Elements[0], Mesh ):
5813 Elements = [ Elements[0].GetMesh() ]
5814 if isinstance( Elements[0], int ):
5815 Elements = self.GetIDSource( Elements, SMESH.ALL )
5816 unRegister.set( Elements )
5817 if not isinstance( Elements, list ):
5818 Elements = [ Elements ]
5819 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5820 self.mesh.SetParameters(Parameters)
5821 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5822 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5824 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5826 Generate new elements by extrusion of the elements or nodes which belong to the object
5829 theObject: the object whose elements or nodes should be processed.
5830 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5831 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5832 the direction and value of extrusion for one step (the total extrusion
5833 length will be NbOfSteps * ||StepVector||)
5834 NbOfSteps: the number of steps
5835 MakeGroups: forces the generation of new groups from existing ones
5836 IsNodes: is True if elements to extrude are nodes
5839 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5840 Example: :ref:`tui_extrusion`
5844 if IsNodes: n = theObject
5845 else : e,f, = theObject,theObject
5846 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5848 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5850 Generate new elements by extrusion of edges which belong to the object
5853 theObject: object whose 1D elements should be processed.
5854 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5855 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5856 the direction and value of extrusion for one step (the total extrusion
5857 length will be NbOfSteps * ||StepVector||)
5858 NbOfSteps: the number of steps
5859 MakeGroups: to generate new groups from existing ones
5862 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5863 Example: :ref:`tui_extrusion`
5866 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5868 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5870 Generate new elements by extrusion of faces which belong to the object
5873 theObject: object whose 2D elements should be processed.
5874 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5875 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5876 the direction and value of extrusion for one step (the total extrusion
5877 length will be NbOfSteps * ||StepVector||)
5878 NbOfSteps: the number of steps
5879 MakeGroups: forces the generation of new groups from existing ones
5882 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5883 Example: :ref:`tui_extrusion`
5886 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5888 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5889 ExtrFlags, SewTolerance, MakeGroups=False):
5891 Generate new elements by extrusion of the elements with given ids
5894 IDsOfElements: is ids of elements
5895 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5896 the direction and value of extrusion for one step (the total extrusion
5897 length will be NbOfSteps * ||StepVector||)
5898 NbOfSteps: the number of steps
5899 ExtrFlags: sets flags for extrusion
5900 SewTolerance: uses for comparing locations of nodes if flag
5901 EXTRUSION_FLAG_SEW is set
5902 MakeGroups: forces the generation of new groups from existing ones
5905 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5908 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5909 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5910 if isinstance( StepVector, list ):
5911 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5912 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5913 ExtrFlags, SewTolerance, MakeGroups)
5915 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5916 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5917 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5918 ScaleFactors=[], ScalesVariation=False):
5920 Generate new elements by extrusion of the given elements and nodes along the path.
5921 The path of extrusion must be a meshed edge.
5924 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5925 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5926 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5927 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5928 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
5929 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5930 HasAngles: not used obsolete
5931 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5932 around *basePoint*, additionally to previous steps.
5933 LinearVariation: forces the computation of rotation angles as linear
5934 variation of the given Angles along path steps
5935 HasRefPoint: allows using the reference point
5936 RefPoint: optional scaling and rotation center (mass center of the extruded
5937 elements by default). The User can specify any point as the Reference Point.
5938 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5939 MakeGroups: forces the generation of new groups from existing ones
5940 ScaleFactors: optional scale factors to apply during extrusion
5941 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5942 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5945 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5946 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5947 Example: :ref:`tui_extrusion_along_path`
5950 unRegister = genObjUnRegister()
5951 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5952 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5953 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5955 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5956 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5957 if isinstance( RefPoint, list ):
5958 if not RefPoint: RefPoint = [0,0,0]
5959 RefPoint = SMESH.PointStruct( *RefPoint )
5960 if isinstance( PathObject, Mesh ):
5961 PathObject = PathObject.GetMesh()
5962 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5963 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5964 Parameters = AnglesParameters + var_separator + \
5965 RefPoint.parameters + var_separator + ScalesParameters
5966 self.mesh.SetParameters(Parameters)
5967 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5968 PathObject, PathShape, NodeStart,
5969 HasAngles, Angles, LinearVariation,
5970 HasRefPoint, RefPoint, MakeGroups,
5971 ScaleFactors, ScalesVariation)
5973 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5974 HasAngles=False, Angles=[], LinearVariation=False,
5975 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5976 ElemType=SMESH.FACE):
5978 Generate new elements by extrusion of the given elements.
5979 The path of extrusion must be a meshed edge.
5982 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5983 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5984 NodeStart: the start node from Path. Defines the direction of extrusion
5985 HasAngles: not used obsolete
5986 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5987 around *basePoint*, additionally to previous steps.
5988 LinearVariation: forces the computation of rotation angles as linear
5989 variation of the given Angles along path steps
5990 HasRefPoint: allows using the reference point
5991 RefPoint: the reference point around which the elements are rotated (the mass
5992 center of the elements by default).
5993 The User can specify any point as the Reference Point.
5994 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5995 MakeGroups: forces the generation of new groups from existing ones
5996 ElemType: type of elements for extrusion (if param Base is a mesh)
5999 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6000 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6001 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6003 Example: :ref:`tui_extrusion_along_path`
6007 if ElemType == SMESH.NODE: n = Base
6008 if ElemType == SMESH.EDGE: e = Base
6009 if ElemType == SMESH.FACE: f = Base
6010 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
6011 HasAngles, Angles, LinearVariation,
6012 HasRefPoint, RefPoint, MakeGroups)
6013 if MakeGroups: return gr,er
6016 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
6017 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6018 MakeGroups=False, LinearVariation=False):
6020 Generate new elements by extrusion of the given elements.
6021 The path of extrusion must be a meshed edge.
6024 IDsOfElements: ids of elements
6025 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6026 PathShape: shape (edge) defines the sub-mesh for the path
6027 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6028 HasAngles: not used obsolete
6029 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6030 around *basePoint*, additionally to previous steps.
6031 HasRefPoint: allows using the reference point
6032 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6033 The User can specify any point as the Reference Point.
6034 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6035 MakeGroups: forces the generation of new groups from existing ones
6036 LinearVariation: forces the computation of rotation angles as linear
6037 variation of the given Angles along path steps
6040 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6041 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6042 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6043 Example: :ref:`tui_extrusion_along_path`
6046 if not IDsOfElements:
6047 IDsOfElements = [ self.GetMesh() ]
6048 n,e,f = [],IDsOfElements,IDsOfElements
6049 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6050 NodeStart, HasAngles, Angles,
6052 HasRefPoint, RefPoint, MakeGroups)
6053 if MakeGroups: return gr,er
6056 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6057 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6058 MakeGroups=False, LinearVariation=False):
6060 Generate new elements by extrusion of the elements which belong to the object.
6061 The path of extrusion must be a meshed edge.
6064 theObject: the object whose elements should be processed.
6065 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6066 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6067 PathShape: shape (edge) defines the sub-mesh for the path
6068 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6069 HasAngles: not used obsolete
6070 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6071 around *basePoint*, additionally to previous steps.
6072 HasRefPoint: allows using the reference point
6073 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6074 The User can specify any point as the Reference Point.
6075 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6076 MakeGroups: forces the generation of new groups from existing ones
6077 LinearVariation: forces the computation of rotation angles as linear
6078 variation of the given Angles along path steps
6081 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6082 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6083 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6084 Example: :ref:`tui_extrusion_along_path`
6087 n,e,f = [],theObject,theObject
6088 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6089 HasAngles, Angles, LinearVariation,
6090 HasRefPoint, RefPoint, MakeGroups)
6091 if MakeGroups: return gr,er
6094 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6095 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6096 MakeGroups=False, LinearVariation=False):
6098 Generate new elements by extrusion of mesh segments which belong to the object.
6099 The path of extrusion must be a meshed edge.
6102 theObject: the object whose 1D elements should be processed.
6103 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6104 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6105 PathShape: shape (edge) defines the sub-mesh for the path
6106 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6107 HasAngles: not used obsolete
6108 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6109 around *basePoint*, additionally to previous steps.
6110 HasRefPoint: allows using the reference point
6111 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6112 The User can specify any point as the Reference Point.
6113 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6114 MakeGroups: forces the generation of new groups from existing ones
6115 LinearVariation: forces the computation of rotation angles as linear
6116 variation of the given Angles along path steps
6119 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6120 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6121 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6122 Example: :ref:`tui_extrusion_along_path`
6125 n,e,f = [],theObject,[]
6126 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6127 HasAngles, Angles, LinearVariation,
6128 HasRefPoint, RefPoint, MakeGroups)
6129 if MakeGroups: return gr,er
6132 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6133 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6134 MakeGroups=False, LinearVariation=False):
6136 Generate new elements by extrusion of faces which belong to the object.
6137 The path of extrusion must be a meshed edge.
6140 theObject: the object whose 2D elements should be processed.
6141 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6142 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6143 PathShape: shape (edge) defines the sub-mesh for the path
6144 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6145 HasAngles: not used obsolete
6146 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6147 around *basePoint*, additionally to previous steps.
6148 HasRefPoint: allows using the reference point
6149 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6150 The User can specify any point as the Reference Point.
6151 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6152 MakeGroups: forces the generation of new groups from existing ones
6153 LinearVariation: forces the computation of rotation angles as linear
6154 variation of the given Angles along path steps
6157 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6158 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6159 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6160 Example: :ref:`tui_extrusion_along_path`
6163 n,e,f = [],[],theObject
6164 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6165 HasAngles, Angles, LinearVariation,
6166 HasRefPoint, RefPoint, MakeGroups)
6167 if MakeGroups: return gr,er
6170 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6172 Create a symmetrical copy of mesh elements
6175 IDsOfElements: list of elements ids
6176 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6177 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6178 If the *Mirror* is a geom object this parameter is unnecessary
6179 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6180 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6183 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6186 if IDsOfElements == []:
6187 IDsOfElements = self.GetElementsId()
6188 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6189 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6190 theMirrorType = Mirror._mirrorType
6192 self.mesh.SetParameters(Mirror.parameters)
6193 if Copy and MakeGroups:
6194 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6195 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6198 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6200 Create a new mesh by a symmetrical copy of mesh elements
6203 IDsOfElements: the list of elements ids
6204 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6205 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6206 If the *Mirror* is a geom object this parameter is unnecessary
6207 MakeGroups: to generate new groups from existing ones
6208 NewMeshName: a name of the new mesh to create
6211 instance of class :class:`Mesh`
6214 if IDsOfElements == []:
6215 IDsOfElements = self.GetElementsId()
6216 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6217 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6218 theMirrorType = Mirror._mirrorType
6220 self.mesh.SetParameters(Mirror.parameters)
6221 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6222 MakeGroups, NewMeshName)
6223 return Mesh(self.smeshpyD,self.geompyD,mesh)
6225 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6227 Create a symmetrical copy of the object
6230 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6231 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6232 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6233 If the *Mirror* is a geom object this parameter is unnecessary
6234 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6235 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6238 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6241 if ( isinstance( theObject, Mesh )):
6242 theObject = theObject.GetMesh()
6243 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6244 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6245 theMirrorType = Mirror._mirrorType
6247 self.mesh.SetParameters(Mirror.parameters)
6248 if Copy and MakeGroups:
6249 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6250 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6253 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6255 Create a new mesh by a symmetrical copy of the object
6258 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6259 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6260 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6261 If the *Mirror* is a geom object this parameter is unnecessary
6262 MakeGroups: forces the generation of new groups from existing ones
6263 NewMeshName: the name of the new mesh to create
6266 instance of class :class:`Mesh`
6269 if ( isinstance( theObject, Mesh )):
6270 theObject = theObject.GetMesh()
6271 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6272 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6273 theMirrorType = Mirror._mirrorType
6275 self.mesh.SetParameters(Mirror.parameters)
6276 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6277 MakeGroups, NewMeshName)
6278 return Mesh( self.smeshpyD,self.geompyD,mesh )
6280 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6282 Translate the elements
6285 IDsOfElements: list of elements ids
6286 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6287 Copy: allows copying the translated elements
6288 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6291 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6294 if IDsOfElements == []:
6295 IDsOfElements = self.GetElementsId()
6296 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6297 Vector = self.smeshpyD.GetDirStruct(Vector)
6298 if isinstance( Vector, list ):
6299 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6300 self.mesh.SetParameters(Vector.PS.parameters)
6301 if Copy and MakeGroups:
6302 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6303 self.editor.Translate(IDsOfElements, Vector, Copy)
6306 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6308 Create a new mesh of translated elements
6311 IDsOfElements: list of elements ids
6312 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6313 MakeGroups: forces the generation of new groups from existing ones
6314 NewMeshName: the name of the newly created mesh
6317 instance of class :class:`Mesh`
6320 if IDsOfElements == []:
6321 IDsOfElements = self.GetElementsId()
6322 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6323 Vector = self.smeshpyD.GetDirStruct(Vector)
6324 if isinstance( Vector, list ):
6325 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6326 self.mesh.SetParameters(Vector.PS.parameters)
6327 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6328 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6330 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6332 Translate the object
6335 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6336 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6337 Copy: allows copying the translated elements
6338 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6341 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6344 if ( isinstance( theObject, Mesh )):
6345 theObject = theObject.GetMesh()
6346 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6347 Vector = self.smeshpyD.GetDirStruct(Vector)
6348 if isinstance( Vector, list ):
6349 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6350 self.mesh.SetParameters(Vector.PS.parameters)
6351 if Copy and MakeGroups:
6352 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6353 self.editor.TranslateObject(theObject, Vector, Copy)
6356 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6358 Create a new mesh from the translated object
6361 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6362 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6363 MakeGroups: forces the generation of new groups from existing ones
6364 NewMeshName: the name of the newly created mesh
6367 instance of class :class:`Mesh`
6370 if isinstance( theObject, Mesh ):
6371 theObject = theObject.GetMesh()
6372 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6373 Vector = self.smeshpyD.GetDirStruct(Vector)
6374 if isinstance( Vector, list ):
6375 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6376 self.mesh.SetParameters(Vector.PS.parameters)
6377 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6378 return Mesh( self.smeshpyD, self.geompyD, mesh )
6382 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6387 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6388 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6389 theScaleFact: list of 1-3 scale factors for axises
6390 Copy: allows copying the translated elements
6391 MakeGroups: forces the generation of new groups from existing
6395 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6396 empty list otherwise
6398 unRegister = genObjUnRegister()
6399 if ( isinstance( theObject, Mesh )):
6400 theObject = theObject.GetMesh()
6401 if ( isinstance( theObject, list )):
6402 theObject = self.GetIDSource(theObject, SMESH.ALL)
6403 unRegister.set( theObject )
6404 if ( isinstance( thePoint, list )):
6405 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6406 if ( isinstance( theScaleFact, float )):
6407 theScaleFact = [theScaleFact]
6408 if ( isinstance( theScaleFact, int )):
6409 theScaleFact = [ float(theScaleFact)]
6411 self.mesh.SetParameters(thePoint.parameters)
6413 if Copy and MakeGroups:
6414 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6415 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6418 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6420 Create a new mesh from the translated object
6423 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6424 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6425 theScaleFact: list of 1-3 scale factors for axises
6426 MakeGroups: forces the generation of new groups from existing ones
6427 NewMeshName: the name of the newly created mesh
6430 instance of class :class:`Mesh`
6432 unRegister = genObjUnRegister()
6433 if (isinstance(theObject, Mesh)):
6434 theObject = theObject.GetMesh()
6435 if ( isinstance( theObject, list )):
6436 theObject = self.GetIDSource(theObject,SMESH.ALL)
6437 unRegister.set( theObject )
6438 if ( isinstance( thePoint, list )):
6439 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6440 if ( isinstance( theScaleFact, float )):
6441 theScaleFact = [theScaleFact]
6442 if ( isinstance( theScaleFact, int )):
6443 theScaleFact = [ float(theScaleFact)]
6445 self.mesh.SetParameters(thePoint.parameters)
6446 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6447 MakeGroups, NewMeshName)
6448 return Mesh( self.smeshpyD, self.geompyD, mesh )
6452 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6457 IDsOfElements: list of elements ids
6458 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6459 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6460 Copy: allows copying the rotated elements
6461 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6464 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6468 if IDsOfElements == []:
6469 IDsOfElements = self.GetElementsId()
6470 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6471 Axis = self.smeshpyD.GetAxisStruct(Axis)
6472 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6473 Parameters = Axis.parameters + var_separator + Parameters
6474 self.mesh.SetParameters(Parameters)
6475 if Copy and MakeGroups:
6476 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6477 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6480 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6482 Create a new mesh of rotated elements
6485 IDsOfElements: list of element ids
6486 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6487 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6488 MakeGroups: forces the generation of new groups from existing ones
6489 NewMeshName: the name of the newly created mesh
6492 instance of class :class:`Mesh`
6495 if IDsOfElements == []:
6496 IDsOfElements = self.GetElementsId()
6497 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6498 Axis = self.smeshpyD.GetAxisStruct(Axis)
6499 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6500 Parameters = Axis.parameters + var_separator + Parameters
6501 self.mesh.SetParameters(Parameters)
6502 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6503 MakeGroups, NewMeshName)
6504 return Mesh( self.smeshpyD, self.geompyD, mesh )
6506 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6511 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6512 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6513 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6514 Copy: allows copying the rotated elements
6515 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6518 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6521 if (isinstance(theObject, Mesh)):
6522 theObject = theObject.GetMesh()
6523 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6524 Axis = self.smeshpyD.GetAxisStruct(Axis)
6525 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6526 Parameters = Axis.parameters + ":" + Parameters
6527 self.mesh.SetParameters(Parameters)
6528 if Copy and MakeGroups:
6529 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6530 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6533 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6535 Create a new mesh from the rotated object
6538 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6539 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6540 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6541 MakeGroups: forces the generation of new groups from existing ones
6542 NewMeshName: the name of the newly created mesh
6545 instance of class :class:`Mesh`
6548 if (isinstance( theObject, Mesh )):
6549 theObject = theObject.GetMesh()
6550 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6551 Axis = self.smeshpyD.GetAxisStruct(Axis)
6552 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6553 Parameters = Axis.parameters + ":" + Parameters
6554 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6555 MakeGroups, NewMeshName)
6556 self.mesh.SetParameters(Parameters)
6557 return Mesh( self.smeshpyD, self.geompyD, mesh )
6559 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6561 Create an offset mesh from the given 2D object
6564 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6565 theValue (float): signed offset size
6566 MakeGroups (boolean): forces the generation of new groups from existing ones
6567 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6568 False means to remove original elements.
6569 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6572 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6575 if isinstance( theObject, Mesh ):
6576 theObject = theObject.GetMesh()
6577 theValue,Parameters,hasVars = ParseParameters(Value)
6578 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6579 self.mesh.SetParameters(Parameters)
6581 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6584 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6586 Find groups of adjacent nodes within Tolerance.
6589 Tolerance (float): the value of tolerance
6590 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6591 corner and medium nodes in separate groups thus preventing
6592 their further merge.
6595 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6598 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6600 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6601 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6603 Find groups of adjacent nodes within Tolerance.
6606 Tolerance: the value of tolerance
6607 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6608 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6609 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6610 corner and medium nodes in separate groups thus preventing
6611 their further merge.
6614 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6617 unRegister = genObjUnRegister()
6618 if not isinstance( SubMeshOrGroup, list ):
6619 SubMeshOrGroup = [ SubMeshOrGroup ]
6620 for i,obj in enumerate( SubMeshOrGroup ):
6621 if isinstance( obj, Mesh ):
6622 SubMeshOrGroup = [ obj.GetMesh() ]
6624 if isinstance( obj, int ):
6625 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6626 unRegister.set( SubMeshOrGroup )
6629 if not isinstance( exceptNodes, list ):
6630 exceptNodes = [ exceptNodes ]
6631 if exceptNodes and isinstance( exceptNodes[0], int ):
6632 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6633 unRegister.set( exceptNodes )
6635 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6636 exceptNodes, SeparateCornerAndMediumNodes)
6638 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6643 GroupsOfNodes: a list of groups of nodes IDs for merging.
6644 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6645 in all elements and mesh groups by nodes 1 and 25 correspondingly
6646 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6647 If *NodesToKeep* does not include a node to keep for some group to merge,
6648 then the first node in the group is kept.
6649 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6653 This operation can create gaps in numeration of nodes or elements.
6654 Call :meth:`RenumberElements` to remove the gaps.
6656 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6658 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6660 Find the elements built on the same nodes.
6663 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6664 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6668 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6671 unRegister = genObjUnRegister()
6672 if MeshOrSubMeshOrGroup is None:
6673 MeshOrSubMeshOrGroup = [ self.mesh ]
6674 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6675 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6676 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6677 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6678 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6679 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6680 unRegister.set( MeshOrSubMeshOrGroup )
6681 for item in MeshOrSubMeshOrGroup:
6682 if isinstance( item, Mesh ):
6683 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6685 if not isinstance( exceptElements, list ):
6686 exceptElements = [ exceptElements ]
6687 if exceptElements and isinstance( exceptElements[0], int ):
6688 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6689 unRegister.set( exceptElements )
6691 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6693 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6695 Merge elements in each given group.
6698 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6699 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6700 replaced in all mesh groups by elements 1 and 25)
6701 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6702 If *ElementsToKeep* does not include an element to keep for some group to merge,
6703 then the first element in the group is kept.
6706 This operation can create gaps in numeration of elements.
6707 Call :meth:`RenumberElements` to remove the gaps.
6710 unRegister = genObjUnRegister()
6712 if not isinstance( ElementsToKeep, list ):
6713 ElementsToKeep = [ ElementsToKeep ]
6714 if isinstance( ElementsToKeep[0], int ):
6715 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6716 unRegister.set( ElementsToKeep )
6718 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6720 def MergeEqualElements(self):
6722 Leave one element and remove all other elements built on the same nodes.
6725 This operation can create gaps in numeration of elements.
6726 Call :meth:`RenumberElements` to remove the gaps.
6729 self.editor.MergeEqualElements()
6731 def FindFreeBorders(self, ClosedOnly=True):
6733 Returns all or only closed free borders
6736 list of SMESH.FreeBorder's
6739 return self.editor.FindFreeBorders( ClosedOnly )
6741 def FillHole(self, holeNodes, groupName=""):
6743 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6746 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6747 must describe all sequential nodes of the hole border. The first and the last
6748 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6749 groupName (string): name of a group to add new faces
6751 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6755 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6756 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6757 if not isinstance( holeNodes, SMESH.FreeBorder ):
6758 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6759 return self.editor.FillHole( holeNodes, groupName )
6761 def FindCoincidentFreeBorders (self, tolerance=0.):
6763 Return groups of FreeBorder's coincident within the given tolerance.
6766 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6767 size of elements adjacent to free borders being compared is used.
6770 SMESH.CoincidentFreeBorders structure
6773 return self.editor.FindCoincidentFreeBorders( tolerance )
6775 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6777 Sew FreeBorder's of each group
6780 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6781 where each enclosed list contains node IDs of a group of coincident free
6782 borders such that each consequent triple of IDs within a group describes
6783 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6784 last node of a border.
6785 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6786 groups of coincident free borders, each group including two borders.
6787 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6788 polygons if a node of opposite border falls on a face edge, else such
6789 faces are split into several ones.
6790 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6791 polyhedra if a node of opposite border falls on a volume edge, else such
6792 volumes, if any, remain intact and the mesh becomes non-conformal.
6795 a number of successfully sewed groups
6798 This operation can create gaps in numeration of nodes or elements.
6799 Call :meth:`RenumberElements` to remove the gaps.
6802 if freeBorders and isinstance( freeBorders, list ):
6803 # construct SMESH.CoincidentFreeBorders
6804 if isinstance( freeBorders[0], int ):
6805 freeBorders = [freeBorders]
6807 coincidentGroups = []
6808 for nodeList in freeBorders:
6809 if not nodeList or len( nodeList ) % 3:
6810 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6813 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6814 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6815 nodeList = nodeList[3:]
6817 coincidentGroups.append( group )
6819 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6821 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6823 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6824 FirstNodeID2, SecondNodeID2, LastNodeID2,
6825 CreatePolygons, CreatePolyedrs):
6830 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6833 This operation can create gaps in numeration of nodes or elements.
6834 Call :meth:`RenumberElements` to remove the gaps.
6837 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6838 FirstNodeID2, SecondNodeID2, LastNodeID2,
6839 CreatePolygons, CreatePolyedrs)
6841 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6842 FirstNodeID2, SecondNodeID2):
6844 Sew conform free borders
6847 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6850 This operation can create gaps in numeration of elements.
6851 Call :meth:`RenumberElements` to remove the gaps.
6854 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6855 FirstNodeID2, SecondNodeID2)
6857 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6858 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6863 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6866 This operation can create gaps in numeration of elements.
6867 Call :meth:`RenumberElements` to remove the gaps.
6870 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6871 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6873 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6874 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6875 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6877 Sew two sides of a mesh. The nodes belonging to Side1 are
6878 merged with the nodes of elements of Side2.
6879 The number of elements in theSide1 and in theSide2 must be
6880 equal and they should have similar nodal connectivity.
6881 The nodes to merge should belong to side borders and
6882 the first node should be linked to the second.
6885 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6888 This operation can create gaps in numeration of nodes.
6889 Call :meth:`RenumberElements` to remove the gaps.
6892 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6893 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6894 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6896 def ChangeElemNodes(self, ide, newIDs):
6898 Set new nodes for the given element. Number of nodes should be kept.
6905 False if the number of nodes does not correspond to the type of element
6908 return self.editor.ChangeElemNodes(ide, newIDs)
6910 def GetLastCreatedNodes(self):
6912 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6913 created, this method return the list of their IDs.
6914 If new nodes were not created - return empty list
6917 the list of integer values (can be empty)
6920 return self.editor.GetLastCreatedNodes()
6922 def GetLastCreatedElems(self):
6924 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6925 created this method return the list of their IDs.
6926 If new elements were not created - return empty list
6929 the list of integer values (can be empty)
6932 return self.editor.GetLastCreatedElems()
6934 def ClearLastCreated(self):
6936 Forget what nodes and elements were created by the last mesh edition operation
6939 self.editor.ClearLastCreated()
6941 def DoubleElements(self, theElements, theGroupName=""):
6943 Create duplicates of given elements, i.e. create new elements based on the
6944 same nodes as the given ones.
6947 theElements: container of elements to duplicate. It can be a
6948 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6949 or a list of element IDs. If *theElements* is
6950 a :class:`Mesh`, elements of highest dimension are duplicated
6951 theGroupName: a name of group to contain the generated elements.
6952 If a group with such a name already exists, the new elements
6953 are added to the existing group, else a new group is created.
6954 If *theGroupName* is empty, new elements are not added
6958 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6959 None if *theGroupName* == "".
6962 unRegister = genObjUnRegister()
6963 if isinstance( theElements, Mesh ):
6964 theElements = theElements.mesh
6965 elif isinstance( theElements, list ):
6966 theElements = self.GetIDSource( theElements, SMESH.ALL )
6967 unRegister.set( theElements )
6968 return self.editor.DoubleElements(theElements, theGroupName)
6970 def DoubleNodes(self, theNodes, theModifiedElems):
6972 Create a hole in a mesh by doubling the nodes of some particular elements
6975 theNodes: IDs of nodes to be doubled
6976 theModifiedElems: IDs of elements to be updated by the new (doubled)
6977 nodes. If list of element identifiers is empty then nodes are doubled but
6978 they not assigned to elements
6981 True if operation has been completed successfully, False otherwise
6984 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6986 def DoubleNode(self, theNodeId, theModifiedElems):
6988 Create a hole in a mesh by doubling the nodes of some particular elements.
6989 This method provided for convenience works as :meth:`DoubleNodes`.
6992 theNodeId: IDs of node to double
6993 theModifiedElems: IDs of elements to update
6996 True if operation has been completed successfully, False otherwise
6999 return self.editor.DoubleNode(theNodeId, theModifiedElems)
7001 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
7003 Create a hole in a mesh by doubling the nodes of some particular elements.
7004 This method provided for convenience works as :meth:`DoubleNodes`.
7007 theNodes: group of nodes to double.
7008 theModifiedElems: group of elements to update.
7009 theMakeGroup: forces the generation of a group containing new nodes.
7012 True or a created group if operation has been completed successfully,
7013 False or None otherwise
7017 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
7018 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7020 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7022 Create a hole in a mesh by doubling the nodes of some particular elements.
7023 This method provided for convenience works as :meth:`DoubleNodes`.
7026 theNodes: list of groups of nodes to double.
7027 theModifiedElems: list of groups of elements to update.
7028 theMakeGroup: forces the generation of a group containing new nodes.
7031 True if operation has been completed successfully, False otherwise
7035 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7036 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7038 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7040 Create a hole in a mesh by doubling the nodes of some particular elements
7043 theElems: the list of elements (edges or faces) to replicate.
7044 The nodes for duplication could be found from these elements
7045 theNodesNot: list of nodes NOT to replicate
7046 theAffectedElems: the list of elements (cells and edges) to which the
7047 replicated nodes should be associated to
7050 True if operation has been completed successfully, False otherwise
7053 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7055 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7057 Create a hole in a mesh by doubling the nodes of some particular elements
7060 theElems: the list of elements (edges or faces) to replicate.
7061 The nodes for duplication could be found from these elements
7062 theNodesNot: list of nodes NOT to replicate
7063 theShape: shape to detect affected elements (element which geometric center
7064 located on or inside shape).
7065 The replicated nodes should be associated to affected elements.
7068 True if operation has been completed successfully, False otherwise
7071 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7073 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7074 theMakeGroup=False, theMakeNodeGroup=False):
7076 Create a hole in a mesh by doubling the nodes of some particular elements.
7077 This method provided for convenience works as :meth:`DoubleNodes`.
7080 theElems: group of of elements (edges or faces) to replicate.
7081 theNodesNot: group of nodes NOT to replicate.
7082 theAffectedElems: group of elements to which the replicated nodes
7083 should be associated to.
7084 theMakeGroup: forces the generation of a group containing new elements.
7085 theMakeNodeGroup: forces the generation of a group containing new nodes.
7088 True or created groups (one or two) if operation has been completed successfully,
7089 False or None otherwise
7092 if theMakeGroup or theMakeNodeGroup:
7093 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7095 theMakeGroup, theMakeNodeGroup)
7096 if theMakeGroup and theMakeNodeGroup:
7099 return twoGroups[ int(theMakeNodeGroup) ]
7100 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7102 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7104 Create a hole in a mesh by doubling the nodes of some particular elements.
7105 This method provided for convenience works as :meth:`DoubleNodes`.
7108 theElems: group of of elements (edges or faces) to replicate
7109 theNodesNot: group of nodes not to replicate
7110 theShape: shape to detect affected elements (element which geometric center
7111 located on or inside shape).
7112 The replicated nodes should be associated to affected elements
7115 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7117 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7118 theMakeGroup=False, theMakeNodeGroup=False):
7120 Create a hole in a mesh by doubling the nodes of some particular elements.
7121 This method provided for convenience works as :meth:`DoubleNodes`.
7124 theElems: list of groups of elements (edges or faces) to replicate
7125 theNodesNot: list of groups of nodes NOT to replicate
7126 theAffectedElems: group of elements to which the replicated nodes
7127 should be associated to
7128 theMakeGroup: forces generation of a group containing new elements.
7129 theMakeNodeGroup: forces generation of a group containing new nodes
7132 True or created groups (one or two) if operation has been completed successfully,
7133 False or None otherwise
7136 if theMakeGroup or theMakeNodeGroup:
7137 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7139 theMakeGroup, theMakeNodeGroup)
7140 if theMakeGroup and theMakeNodeGroup:
7143 return twoGroups[ int(theMakeNodeGroup) ]
7144 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7146 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7148 Create a hole in a mesh by doubling the nodes of some particular elements.
7149 This method provided for convenience works as :meth:`DoubleNodes`.
7152 theElems: list of groups of elements (edges or faces) to replicate
7153 theNodesNot: list of groups of nodes NOT to replicate
7154 theShape: shape to detect affected elements (element which geometric center
7155 located on or inside shape).
7156 The replicated nodes should be associated to affected elements
7159 True if operation has been completed successfully, False otherwise
7162 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7164 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7166 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7167 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7170 theElems: list of groups of nodes or elements (edges or faces) to replicate
7171 theNodesNot: list of groups of nodes NOT to replicate
7172 theShape: shape to detect affected elements (element which geometric center
7173 located on or inside shape).
7174 The replicated nodes should be associated to affected elements
7177 groups of affected elements in order: volumes, faces, edges
7180 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7182 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7185 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7186 The list of groups must describe a partition of the mesh volumes.
7187 The nodes of the internal faces at the boundaries of the groups are doubled.
7188 In option, the internal faces are replaced by flat elements.
7189 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7192 theDomains: list of groups of volumes
7193 createJointElems: if True, create the elements
7194 onAllBoundaries: if True, the nodes and elements are also created on
7195 the boundary between *theDomains* and the rest mesh
7198 True if operation has been completed successfully, False otherwise
7201 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7203 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7205 Double nodes on some external faces and create flat elements.
7206 Flat elements are mainly used by some types of mechanic calculations.
7208 Each group of the list must be constituted of faces.
7209 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7212 theGroupsOfFaces: list of groups of faces
7215 True if operation has been completed successfully, False otherwise
7218 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7220 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7222 Identify all the elements around a geom shape, get the faces delimiting the hole
7224 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7226 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7228 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7229 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7230 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7231 If there are several paths connecting a pair of points, the shortest path is
7232 selected by the module. Position of the cutting plane is defined by the two
7233 points and an optional vector lying on the plane specified by a PolySegment.
7234 By default the vector is defined by Mesh module as following. A middle point
7235 of the two given points is computed. The middle point is projected to the mesh.
7236 The vector goes from the middle point to the projection point. In case of planar
7237 mesh, the vector is normal to the mesh.
7239 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7242 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7243 groupName: optional name of a group where created mesh segments will be added.
7246 editor = self.editor
7248 editor = self.mesh.GetMeshEditPreviewer()
7249 segmentsRes = editor.MakePolyLine( segments, groupName )
7250 for i, seg in enumerate( segmentsRes ):
7251 segments[i].vector = seg.vector
7253 return editor.GetPreviewData()
7256 def MakeSlot(self, segmentGroup, width ):
7258 Create a slot of given width around given 1D elements lying on a triangle mesh.
7259 The slot is constructed by cutting faces by cylindrical surfaces made
7260 around each segment. Segments are expected to be created by MakePolyLine().
7263 FaceEdge's located at the slot boundary
7265 return self.editor.MakeSlot( segmentGroup, width )
7267 def GetFunctor(self, funcType ):
7269 Return a cached numerical functor by its type.
7272 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7273 Note that not all items correspond to numerical functors.
7276 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7279 fn = self.functors[ funcType._v ]
7281 fn = self.smeshpyD.GetFunctor(funcType)
7282 fn.SetMesh(self.mesh)
7283 self.functors[ funcType._v ] = fn
7286 def FunctorValue(self, funcType, elemId, isElem=True):
7288 Return value of a functor for a given element
7291 funcType: an item of :class:`SMESH.FunctorType` enum.
7292 elemId: element or node ID
7293 isElem: *elemId* is ID of element or node
7296 the functor value or zero in case of invalid arguments
7299 fn = self.GetFunctor( funcType )
7300 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7301 val = fn.GetValue(elemId)
7306 def GetLength(self, elemId=None):
7308 Get length of given 1D elements or of all 1D mesh elements
7311 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.
7314 Sum of lengths of given elements
7319 length = self.smeshpyD.GetLength(self)
7320 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7321 length = self.smeshpyD.GetLength(elemId)
7324 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7326 length += self.smeshpyD.GetLength(obj)
7327 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7328 unRegister = genObjUnRegister()
7329 obj = self.GetIDSource( elemId )
7330 unRegister.set( obj )
7331 length = self.smeshpyD.GetLength( obj )
7333 length = self.FunctorValue(SMESH.FT_Length, elemId)
7336 def GetArea(self, elemId=None):
7338 Get area of given 2D elements or of all 2D mesh elements
7341 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.
7344 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7349 area = self.smeshpyD.GetArea(self)
7350 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7351 area = self.smeshpyD.GetArea(elemId)
7354 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7356 area += self.smeshpyD.GetArea(obj)
7357 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7358 unRegister = genObjUnRegister()
7359 obj = self.GetIDSource( elemId )
7360 unRegister.set( obj )
7361 area = self.smeshpyD.GetArea( obj )
7363 area = self.FunctorValue(SMESH.FT_Area, elemId)
7366 def GetVolume(self, elemId=None):
7368 Get volume of given 3D elements or of all 3D mesh elements
7371 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.
7374 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7379 volume= self.smeshpyD.GetVolume(self)
7380 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7381 volume= self.smeshpyD.GetVolume(elemId)
7384 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7386 volume+= self.smeshpyD.GetVolume(obj)
7387 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7388 unRegister = genObjUnRegister()
7389 obj = self.GetIDSource( elemId )
7390 unRegister.set( obj )
7391 volume= self.smeshpyD.GetVolume( obj )
7393 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7396 def GetAngle(self, node1, node2, node3 ):
7398 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7401 node1,node2,node3: IDs of the three nodes
7404 Angle in radians [0,PI]. -1 if failure case.
7406 p1 = self.GetNodeXYZ( node1 )
7407 p2 = self.GetNodeXYZ( node2 )
7408 p3 = self.GetNodeXYZ( node3 )
7409 if p1 and p2 and p3:
7410 return self.smeshpyD.GetAngle( p1,p2,p3 )
7414 def GetMaxElementLength(self, elemId):
7416 Get maximum element length.
7419 elemId: mesh element ID
7422 element's maximum length value
7425 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7426 ftype = SMESH.FT_MaxElementLength3D
7428 ftype = SMESH.FT_MaxElementLength2D
7429 return self.FunctorValue(ftype, elemId)
7431 def GetAspectRatio(self, elemId):
7433 Get aspect ratio of 2D or 3D element.
7436 elemId: mesh element ID
7439 element's aspect ratio value
7442 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7443 ftype = SMESH.FT_AspectRatio3D
7445 ftype = SMESH.FT_AspectRatio
7446 return self.FunctorValue(ftype, elemId)
7448 def GetWarping(self, elemId):
7450 Get warping angle of 2D element.
7453 elemId: mesh element ID
7456 element's warping angle value
7459 return self.FunctorValue(SMESH.FT_Warping, elemId)
7461 def GetMinimumAngle(self, elemId):
7463 Get minimum angle of 2D element.
7466 elemId: mesh element ID
7469 element's minimum angle value
7472 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7474 def GetTaper(self, elemId):
7476 Get taper of 2D element.
7479 elemId: mesh element ID
7482 element's taper value
7485 return self.FunctorValue(SMESH.FT_Taper, elemId)
7487 def GetSkew(self, elemId):
7489 Get skew of 2D element.
7492 elemId: mesh element ID
7495 element's skew value
7498 return self.FunctorValue(SMESH.FT_Skew, elemId)
7500 def GetScaledJacobian(self, elemId):
7502 Get the scaled jacobian of 3D element id
7505 elemId: mesh element ID
7511 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7513 def GetMinMax(self, funType, meshPart=None):
7515 Return minimal and maximal value of a given functor.
7518 funType (SMESH.FunctorType): a functor type.
7519 Note that not all items of :class:`SMESH.FunctorType` corresponds
7520 to numerical functors.
7521 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7527 unRegister = genObjUnRegister()
7528 if isinstance( meshPart, list ):
7529 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7530 unRegister.set( meshPart )
7531 if isinstance( meshPart, Mesh ):
7532 meshPart = meshPart.mesh
7533 fun = self.GetFunctor( funType )
7536 if hasattr( meshPart, "SetMesh" ):
7537 meshPart.SetMesh( self.mesh ) # set mesh to filter
7538 hist = fun.GetLocalHistogram( 1, False, meshPart )
7540 hist = fun.GetHistogram( 1, False )
7542 return hist[0].min, hist[0].max
7545 pass # end of Mesh class
7548 def _copy_netgen_param(dim, local_param, global_param):
7550 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7553 #TODO: Try to identify why we need to substract 1
7554 local_param.NumberOfSegments(int(global_param.GetNbSegPerEdge())-1)
7556 local_param.SetMaxSize(global_param.GetMaxSize())
7557 local_param.SetMinSize(global_param.GetMinSize())
7558 local_param.SetOptimize(global_param.GetOptimize())
7559 local_param.SetFineness(global_param.GetFineness())
7560 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7561 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7562 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7563 local_param.SetChordalError(global_param.GetChordalError())
7564 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7565 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7566 local_param.SetUseDelauney(global_param.GetUseDelauney())
7567 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7568 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7569 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7570 local_param.SetNbThreads(global_param.GetNbThreads())
7572 local_param.SetMaxSize(global_param.GetMaxSize())
7573 local_param.SetMinSize(global_param.GetMinSize())
7574 local_param.SetOptimize(global_param.GetOptimize())
7575 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7576 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7577 local_param.SetFineness(global_param.GetFineness())
7578 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7579 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7580 local_param.SetGrowthRate(global_param.GetGrowthRate())
7581 local_param.SetNbThreads(global_param.GetNbThreads())
7583 def _split_geom(geompyD, geom):
7585 Splitting geometry into n solids and a 2D/1D compound
7588 geompyD: geomBuilder instance
7589 geom: geometrical object for meshing
7592 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7593 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7598 for solid in object_solids:
7600 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7601 solids.append(solid)
7602 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7608 for isolid, solid in enumerate(solids):
7609 solid_faces = geompyD.ExtractShapes(solid, geompyD.ShapeType["FACE"],
7611 for face in solid_faces:
7614 geompyD.addToStudyInFather(solid, face,
7615 'Face_{}'.format(iface))
7617 # Creating submesh for edges 1D/2D part
7619 all_faces = geompyD.MakeCompound(faces)
7620 geompyD.addToStudy(all_faces, 'Compound_1')
7621 all_faces = geompyD.MakeGlueEdges(all_faces, 1e-07)
7622 all_faces = geompyD.MakeGlueFaces(all_faces, 1e-07)
7623 geompyD.addToStudy(all_faces, 'global2D')
7625 return all_faces, solids
7627 class ParallelismSettings:
7629 Defines the parameters for the parallelism of ParallelMesh
7631 def __init__(self, mesh):
7636 mesh: Instance of ParallelMesh
7638 if not(isinstance(mesh, ParallelMesh)):
7639 raise ValueError("mesh should be a ParallelMesh")
7643 def SetNbThreads(self, nbThreads):
7645 Set the number of threads for multithreading
7648 raise ValueError("Number of threads must be stricly greater than 1")
7650 self._mesh.mesh.SetNbThreads(nbThreads)
7652 def GetNbThreads(self):
7654 Get Number of threads
7656 return self._mesh.mesh.GetNbThreads()
7658 class ParallelMesh(Mesh):
7660 Surcharge on Mesh for parallel computation of a mesh
7662 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7664 Create a parallel mesh.
7667 smeshpyD: instance of smeshBuilder
7668 geompyD: instance of geomBuilder
7669 geom: geometrical object for meshing
7670 split_geom: If true will divide geometry on solids and 1D/2D
7671 coumpound and create the associated submeshes
7672 name: the name for the new mesh.
7675 an instance of class :class:`ParallelMesh`.
7678 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7679 raise ValueError("geom argument must be a geometry")
7681 # Splitting geometry into one geom containing 1D and 2D elements and a
7682 # list of 3D elements
7683 super(ParallelMesh, self).__init__(smeshpyD, geompyD, geom, name, parallel=True)
7686 self._all_faces, self._solids = _split_geom(geompyD, geom)
7688 self.UseExistingSegments()
7689 self.UseExistingFaces()
7691 self._algo2d = self.Triangle(geom=self._all_faces, algo="NETGEN_2D")
7694 for solid_id, solid in enumerate(self._solids):
7695 name = "Solid_{}".format(solid_id)
7696 self.UseExistingSegments(geom=solid)
7697 self.UseExistingFaces(geom=solid)
7698 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7699 self._algo3d.append(algo3d)
7701 self._param = ParallelismSettings(self)
7704 def GetParallelismSettings(self):
7706 Return class to set parameters for the parallelism
7710 def AddGlobalHypothesis(self, hyp):
7712 Split hypothesis to apply it to all the submeshes:
7714 - each of the 3D solids
7717 hyp: a hypothesis to assign
7720 if not isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7721 raise ValueError("param must come from NETGENPlugin")
7723 param2d = self._algo2d.Parameters()
7724 _copy_netgen_param(2, param2d, hyp)
7726 for algo3d in self._algo3d:
7728 param3d = algo3d.Parameters()
7729 _copy_netgen_param(3, param3d, hyp)
7732 pass # End of ParallelMesh
7735 class meshProxy(SMESH._objref_SMESH_Mesh):
7737 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7738 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7740 def __init__(self,*args):
7741 SMESH._objref_SMESH_Mesh.__init__(self,*args)
7742 def __deepcopy__(self, memo=None):
7743 new = self.__class__(self)
7745 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7746 if len( args ) == 3:
7747 args += SMESH.ALL_NODES, True
7748 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7749 def ExportToMEDX(self, *args): # function removed
7750 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7751 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7752 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7753 def ExportToMED(self, *args): # function removed
7754 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7755 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7757 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7759 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7760 def ExportPartToMED(self, *args): # 'version' parameter removed
7761 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7762 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7763 def ExportMED(self, *args): # signature of method changed
7764 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7766 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
7768 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7769 def ExportUNV(self, *args): # renumber arg added
7770 if len( args ) == 1:
7772 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7773 def ExportDAT(self, *args): # renumber arg added
7774 if len( args ) == 1:
7776 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7778 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7781 class submeshProxy(SMESH._objref_SMESH_subMesh):
7784 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7786 def __init__(self,*args):
7787 SMESH._objref_SMESH_subMesh.__init__(self,*args)
7789 def __deepcopy__(self, memo=None):
7790 new = self.__class__(self)
7793 def Compute(self,refresh=False):
7795 Compute the sub-mesh and return the status of the computation
7798 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7803 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7804 :meth:`smeshBuilder.Mesh.GetSubMesh`.
7808 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7810 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7812 if salome.sg.hasDesktop():
7813 if refresh: salome.sg.updateObjBrowser()
7818 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7821 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7823 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7824 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7827 def __init__(self,*args):
7828 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7830 def __getattr__(self, name ): # method called if an attribute not found
7831 if not self.mesh: # look for name() method in Mesh class
7832 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7833 if hasattr( self.mesh, name ):
7834 return getattr( self.mesh, name )
7835 if name == "ExtrusionAlongPathObjX":
7836 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7837 print("meshEditor: attribute '%s' NOT FOUND" % name)
7839 def __deepcopy__(self, memo=None):
7840 new = self.__class__(self)
7842 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7843 if len( args ) == 1: args += False,
7844 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7845 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7846 if len( args ) == 2: args += False,
7847 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7848 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7849 if len( args ) == 1:
7850 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7851 NodesToKeep = args[1]
7852 AvoidMakingHoles = args[2] if len( args ) == 3 else False
7853 unRegister = genObjUnRegister()
7855 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7856 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7857 if not isinstance( NodesToKeep, list ):
7858 NodesToKeep = [ NodesToKeep ]
7859 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7861 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7863 class Pattern(SMESH._objref_SMESH_Pattern):
7865 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7866 variables in some methods
7869 def LoadFromFile(self, patternTextOrFile ):
7870 text = patternTextOrFile
7871 if os.path.exists( text ):
7872 text = open( patternTextOrFile ).read()
7874 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7876 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7877 decrFun = lambda i: i-1
7878 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7879 theMesh.SetParameters(Parameters)
7880 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7882 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7883 decrFun = lambda i: i-1
7884 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7885 theMesh.SetParameters(Parameters)
7886 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7888 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7889 if isinstance( mesh, Mesh ):
7890 mesh = mesh.GetMesh()
7891 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7893 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7895 Registering the new proxy for Pattern
7900 Private class used to bind methods creating algorithms to the class Mesh
7903 def __init__(self, method):
7905 self.defaultAlgoType = ""
7906 self.algoTypeToClass = {}
7907 self.method = method
7909 def add(self, algoClass):
7911 Store a python class of algorithm
7913 if inspect.isclass(algoClass) and \
7914 hasattr( algoClass, "algoType"):
7915 self.algoTypeToClass[ algoClass.algoType ] = algoClass
7916 if not self.defaultAlgoType and \
7917 hasattr( algoClass, "isDefault") and algoClass.isDefault:
7918 self.defaultAlgoType = algoClass.algoType
7919 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7921 def copy(self, mesh):
7923 Create a copy of self and assign mesh to the copy
7926 other = algoCreator( self.method )
7927 other.defaultAlgoType = self.defaultAlgoType
7928 other.algoTypeToClass = self.algoTypeToClass
7932 def __call__(self,algo="",geom=0,*args):
7934 Create an instance of algorithm
7938 if isinstance( algo, str ):
7940 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7941 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7946 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7948 elif not algoType and isinstance( geom, str ):
7953 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7955 elif isinstance( arg, str ) and not algoType:
7958 import traceback, sys
7959 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
7960 sys.stderr.write( msg + '\n' )
7961 tb = traceback.extract_stack(None,2)
7962 traceback.print_list( [tb[0]] )
7964 algoType = self.defaultAlgoType
7965 if not algoType and self.algoTypeToClass:
7966 algoType = sorted( self.algoTypeToClass.keys() )[0]
7967 if algoType in self.algoTypeToClass:
7968 #print("Create algo",algoType)
7969 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7970 raise RuntimeError( "No class found for algo type %s" % algoType)
7973 class hypMethodWrapper:
7975 Private class used to substitute and store variable parameters of hypotheses.
7978 def __init__(self, hyp, method):
7980 self.method = method
7981 #print("REBIND:", method.__name__)
7984 def __call__(self,*args):
7986 call a method of hypothesis with calling SetVarParameter() before
7990 return self.method( self.hyp, *args ) # hypothesis method with no args
7992 #print("MethWrapper.__call__", self.method.__name__, args)
7994 parsed = ParseParameters(*args) # replace variables with their values
7995 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7996 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7997 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7998 # maybe there is a replaced string arg which is not variable
7999 result = self.method( self.hyp, *args )
8000 except ValueError as detail: # raised by ParseParameters()
8002 result = self.method( self.hyp, *args )
8003 except omniORB.CORBA.BAD_PARAM:
8004 raise ValueError(detail) # wrong variable name
8009 class genObjUnRegister:
8011 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
8014 def __init__(self, genObj=None):
8015 self.genObjList = []
8019 def set(self, genObj):
8020 "Store one or a list of of SALOME.GenericObj'es"
8021 if isinstance( genObj, list ):
8022 self.genObjList.extend( genObj )
8024 self.genObjList.append( genObj )
8028 for genObj in self.genObjList:
8029 if genObj and hasattr( genObj, "UnRegister" ):
8032 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8034 Bind methods creating mesher plug-ins to the Mesh class
8037 # print("pluginName: ", pluginName)
8038 pluginBuilderName = pluginName + "Builder"
8040 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8041 except Exception as e:
8042 from salome_utils import verbose
8043 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8045 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8046 plugin = eval( pluginBuilderName )
8047 # print(" plugin:" , str(plugin))
8049 # add methods creating algorithms to Mesh
8050 for k in dir( plugin ):
8051 if k[0] == '_': continue
8052 algo = getattr( plugin, k )
8053 #print(" algo:", str(algo))
8054 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8055 #print(" meshMethod:" , str(algo.meshMethod))
8056 if not hasattr( Mesh, algo.meshMethod ):
8057 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8059 _mmethod = getattr( Mesh, algo.meshMethod )
8060 if hasattr( _mmethod, "add" ):