1 # Copyright (C) 2007-2024 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_Warping3D:
1207 functor = aFilterMgr.CreateWarping3D()
1208 elif theCriterion == FT_MinimumAngle:
1209 functor = aFilterMgr.CreateMinimumAngle()
1210 elif theCriterion == FT_Taper:
1211 functor = aFilterMgr.CreateTaper()
1212 elif theCriterion == FT_Skew:
1213 functor = aFilterMgr.CreateSkew()
1214 elif theCriterion == FT_Area:
1215 functor = aFilterMgr.CreateArea()
1216 elif theCriterion == FT_Volume3D:
1217 functor = aFilterMgr.CreateVolume3D()
1218 elif theCriterion == FT_MaxElementLength2D:
1219 functor = aFilterMgr.CreateMaxElementLength2D()
1220 elif theCriterion == FT_MaxElementLength3D:
1221 functor = aFilterMgr.CreateMaxElementLength3D()
1222 elif theCriterion == FT_MultiConnection:
1223 functor = aFilterMgr.CreateMultiConnection()
1224 elif theCriterion == FT_MultiConnection2D:
1225 functor = aFilterMgr.CreateMultiConnection2D()
1226 elif theCriterion == FT_Length:
1227 functor = aFilterMgr.CreateLength()
1228 elif theCriterion == FT_Length2D:
1229 functor = aFilterMgr.CreateLength2D()
1230 elif theCriterion == FT_Length3D:
1231 functor = aFilterMgr.CreateLength3D()
1232 elif theCriterion == FT_Deflection2D:
1233 functor = aFilterMgr.CreateDeflection2D()
1234 elif theCriterion == FT_NodeConnectivityNumber:
1235 functor = aFilterMgr.CreateNodeConnectivityNumber()
1236 elif theCriterion == FT_BallDiameter:
1237 functor = aFilterMgr.CreateBallDiameter()
1238 elif theCriterion == FT_ScaledJacobian:
1239 functor = aFilterMgr.CreateScaledJacobian()
1241 print("Error: given parameter is not numerical functor type.")
1242 aFilterMgr.UnRegister()
1245 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1250 theHType (string): mesh hypothesis type
1251 theLibName (string): mesh plug-in library name
1254 created hypothesis instance
1256 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1258 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1261 # wrap hypothesis methods
1262 for meth_name in dir( hyp.__class__ ):
1263 if not meth_name.startswith("Get") and \
1264 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1265 method = getattr ( hyp.__class__, meth_name )
1266 if callable(method):
1267 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1271 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1273 Create hypothesis initialized according to parameters
1276 hypType (string): hypothesis type
1277 libName (string): plug-in library name
1278 mesh: optional mesh by which a hypotheses can initialize self
1279 shape: optional geometry by size of which a hypotheses can initialize self
1280 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1283 created hypothesis instance
1285 if isinstance( mesh, Mesh ):
1286 mesh = mesh.GetMesh()
1287 if isinstance( initParams, (bool,int)):
1288 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1289 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1290 mesh, shape, initParams )
1292 def GetMeshInfo(self, obj):
1294 Get the mesh statistic.
1297 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1300 if isinstance( obj, Mesh ):
1303 if hasattr(obj, "GetMeshInfo"):
1304 values = obj.GetMeshInfo()
1305 for i in range(SMESH.Entity_Last._v):
1306 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1310 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1312 Get minimum distance between two objects
1314 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1315 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1318 src1 (SMESH.SMESH_IDSource): first source object
1319 src2 (SMESH.SMESH_IDSource): second source object
1320 id1 (int): node/element id from the first source
1321 id2 (int): node/element id from the second (or first) source
1322 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1323 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1326 minimum distance value
1329 :meth:`GetMinDistance`
1332 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1336 result = result.value
1339 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1341 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1343 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1344 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1347 src1 (SMESH.SMESH_IDSource): first source object
1348 src2 (SMESH.SMESH_IDSource): second source object
1349 id1 (int): node/element id from the first source
1350 id2 (int): node/element id from the second (or first) source
1351 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1352 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1355 :class:`SMESH.Measure` structure or None if input data is invalid
1360 if isinstance(src1, Mesh): src1 = src1.mesh
1361 if isinstance(src2, Mesh): src2 = src2.mesh
1362 if src2 is None and id2 != 0: src2 = src1
1363 if not hasattr(src1, "_narrow"): return None
1364 src1 = src1._narrow(SMESH.SMESH_IDSource)
1365 if not src1: return None
1366 unRegister = genObjUnRegister()
1369 e = m.GetMeshEditor()
1371 src1 = e.MakeIDSource([id1], SMESH.FACE)
1373 src1 = e.MakeIDSource([id1], SMESH.NODE)
1374 unRegister.set( src1 )
1376 if hasattr(src2, "_narrow"):
1377 src2 = src2._narrow(SMESH.SMESH_IDSource)
1378 if src2 and id2 != 0:
1380 e = m.GetMeshEditor()
1382 src2 = e.MakeIDSource([id2], SMESH.FACE)
1384 src2 = e.MakeIDSource([id2], SMESH.NODE)
1385 unRegister.set( src2 )
1388 aMeasurements = self.CreateMeasurements()
1389 unRegister.set( aMeasurements )
1390 result = aMeasurements.MinDistance(src1, src2)
1393 def BoundingBox(self, objects):
1395 Get bounding box of the specified object(s)
1398 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1401 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1404 :meth:`GetBoundingBox`
1407 result = self.GetBoundingBox(objects)
1411 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1414 def GetBoundingBox(self, objects):
1416 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1419 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1422 :class:`SMESH.Measure` structure
1428 if isinstance(objects, tuple):
1429 objects = list(objects)
1430 if not isinstance(objects, list):
1434 if isinstance(o, Mesh):
1435 srclist.append(o.mesh)
1436 elif hasattr(o, "_narrow"):
1437 src = o._narrow(SMESH.SMESH_IDSource)
1438 if src: srclist.append(src)
1441 aMeasurements = self.CreateMeasurements()
1442 result = aMeasurements.BoundingBox(srclist)
1443 aMeasurements.UnRegister()
1446 def GetLength(self, obj):
1448 Get sum of lengths of all 1D elements in the mesh object.
1451 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1454 sum of lengths of all 1D elements
1457 if isinstance(obj, Mesh): obj = obj.mesh
1458 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1459 aMeasurements = self.CreateMeasurements()
1460 value = aMeasurements.Length(obj)
1461 aMeasurements.UnRegister()
1464 def GetArea(self, obj):
1466 Get sum of areas of all 2D elements in the mesh object.
1469 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1472 sum of areas of all 2D elements
1475 if isinstance(obj, Mesh): obj = obj.mesh
1476 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1477 aMeasurements = self.CreateMeasurements()
1478 value = aMeasurements.Area(obj)
1479 aMeasurements.UnRegister()
1482 def GetVolume(self, obj):
1484 Get sum of volumes of all 3D elements in the mesh object.
1487 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1490 sum of volumes of all 3D elements
1493 if isinstance(obj, Mesh): obj = obj.mesh
1494 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1495 aMeasurements = self.CreateMeasurements()
1496 value = aMeasurements.Volume(obj)
1497 aMeasurements.UnRegister()
1500 def GetGravityCenter(self, obj):
1502 Get gravity center of all nodes of a mesh object.
1505 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1508 Three components of the gravity center (x,y,z)
1511 :meth:`Mesh.BaryCenter`
1513 if isinstance(obj, Mesh): obj = obj.mesh
1514 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1515 aMeasurements = self.CreateMeasurements()
1516 pointStruct = aMeasurements.GravityCenter(obj)
1517 aMeasurements.UnRegister()
1518 return pointStruct.x, pointStruct.y, pointStruct.z
1520 def GetAngle(self, p1, p2, p3 ):
1522 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1525 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1531 if isinstance( p1, list ): p1 = PointStruct(*p1)
1532 if isinstance( p2, list ): p2 = PointStruct(*p2)
1533 if isinstance( p3, list ): p3 = PointStruct(*p3)
1535 aMeasurements = self.CreateMeasurements()
1536 angle = aMeasurements.Angle(p1,p2,p3)
1537 aMeasurements.UnRegister()
1542 pass # end of class smeshBuilder
1545 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1546 """Registering the new proxy for SMESH.SMESH_Gen"""
1549 def New( instance=None, instanceGeom=None):
1551 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1552 interface to create or load meshes.
1557 salome.salome_init()
1558 from salome.smesh import smeshBuilder
1559 smesh = smeshBuilder.New()
1562 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1563 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1565 :class:`smeshBuilder` instance
1570 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1572 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1577 smeshInst = smeshBuilder()
1578 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1579 smeshInst.init_smesh(instanceGeom)
1583 # Public class: Mesh
1584 # ==================
1587 class Mesh(metaclass = MeshMeta):
1589 This class allows defining and managing a mesh.
1590 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1591 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1592 new nodes and elements and by changing the existing entities), to get information
1593 about a mesh and to export a mesh in different formats.
1600 def __init__(self, smeshpyD, geompyD, obj=0, name=0, parallel=False):
1605 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1606 sets the GUI name of this mesh to *name*.
1609 smeshpyD: an instance of smeshBuilder class
1610 geompyD: an instance of geomBuilder class
1611 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1612 name: Study name of the mesh
1615 self.smeshpyD = smeshpyD
1616 self.geompyD = geompyD
1621 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1624 # publish geom of mesh (issue 0021122)
1625 if not self.geom.GetStudyEntry():
1629 geo_name = name + " shape"
1631 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1632 geompyD.addToStudy( self.geom, geo_name )
1633 if parallel and isinstance(self, ParallelMesh):
1634 mymesh = self.smeshpyD.CreateParallelMesh(self.geom)
1635 mymesh2 = mymesh._narrow(SMESH._objref_SMESH_Mesh)
1636 self.SetMesh( mymesh )
1638 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1640 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1643 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1645 self.smeshpyD.SetName(self.mesh, name)
1647 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1650 self.geom = self.mesh.GetShapeToMesh()
1652 self.editor = self.mesh.GetMeshEditor()
1653 self.functors = [None] * SMESH.FT_Undefined._v
1655 # set self to algoCreator's
1656 for attrName in dir(self):
1657 attr = getattr( self, attrName )
1658 if isinstance( attr, algoCreator ):
1659 setattr( self, attrName, attr.copy( self ))
1666 Destructor. Clean-up resources
1669 #self.mesh.UnRegister()
1673 def SetMesh(self, theMesh):
1675 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1678 theMesh: a :class:`SMESH.SMESH_Mesh` object
1680 # do not call Register() as this prevents mesh servant deletion at closing study
1681 #if self.mesh: self.mesh.UnRegister()
1684 #self.mesh.Register()
1685 self.geom = self.mesh.GetShapeToMesh()
1689 if salome.sg.hasDesktop():
1690 so = salome.ObjectToSObject( self.geom )
1691 comp = so.GetFatherComponent()
1692 if comp.ComponentDataType() == "SHAPERSTUDY":
1693 import shaperBuilder
1694 self.geompyD = shaperBuilder.New()
1697 if not self.geompyD:
1698 self.geompyD = self.geom.GetGen()
1703 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1706 a :class:`SMESH.SMESH_Mesh` object
1711 def GetEngine(self):
1713 Return a smeshBuilder instance created this mesh
1715 return self.smeshpyD
1717 def GetGeomEngine(self):
1719 Return a geomBuilder instance
1725 Get the name of the mesh
1728 the name of the mesh as a string
1731 name = GetName(self.GetMesh())
1734 def SetName(self, name):
1736 Set a name to the mesh
1739 name: a new name of the mesh
1742 self.smeshpyD.SetName(self.GetMesh(), name)
1744 def GetSubMesh(self, geom, name):
1746 Get a sub-mesh object associated to a *geom* geometrical object.
1749 geom: a geometrical object (shape)
1750 name: a name for the sub-mesh in the Object Browser
1753 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1754 which lies on the given shape
1757 A sub-mesh is implicitly created when a sub-shape is specified at
1758 creating an algorithm, for example::
1760 algo1D = mesh.Segment(geom=Edge_1)
1762 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1763 The created sub-mesh can be retrieved from the algorithm::
1765 submesh = algo1D.GetSubMesh()
1768 AssureGeomPublished( self, geom, name )
1769 submesh = self.mesh.GetSubMesh( geom, name )
1774 Return the shape associated to the mesh
1782 def SetShape(self, geom):
1784 Associate the given shape to the mesh (entails the recreation of the mesh)
1787 geom: the shape to be meshed (GEOM_Object)
1790 self.mesh = self.smeshpyD.CreateMesh(geom)
1792 def HasShapeToMesh(self):
1794 Return ``True`` if this mesh is based on geometry
1796 return self.mesh.HasShapeToMesh()
1800 Load mesh from the study after opening the study
1804 def IsReadyToCompute(self, theSubObject):
1806 Return true if the hypotheses are defined well
1809 theSubObject: a sub-shape of a mesh shape
1815 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1817 def GetAlgoState(self, theSubObject):
1819 Return errors of hypotheses definition.
1820 The list of errors is empty if everything is OK.
1823 theSubObject: a sub-shape of a mesh shape
1829 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1831 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1833 Return a geometrical object on which the given element was built.
1834 The returned geometrical object, if not nil, is either found in the
1835 study or published by this method with the given name
1838 theElementID: the id of the mesh element
1839 theGeomName: the user-defined name of the geometrical object
1842 GEOM.GEOM_Object instance
1845 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1847 def MeshDimension(self):
1849 Return the mesh dimension depending on the dimension of the underlying shape
1850 or, if the mesh is not based on any shape, basing on deimension of elements
1853 mesh dimension as an integer value [0,3]
1856 if self.mesh.HasShapeToMesh():
1857 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1858 if len( shells ) > 0 :
1860 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1862 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1867 if self.NbVolumes() > 0: return 3
1868 if self.NbFaces() > 0: return 2
1869 if self.NbEdges() > 0: return 1
1872 def Evaluate(self, geom=0):
1874 Evaluate size of prospective mesh on a shape
1877 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1878 To know predicted number of e.g. edges, inquire it this way::
1880 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1883 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1885 geom = self.mesh.GetShapeToMesh()
1888 return self.smeshpyD.Evaluate(self.mesh, geom)
1890 def Compute(self, geom=0, discardModifs=False, refresh=False):
1892 Compute the mesh and return the status of the computation
1895 geom: geomtrical shape on which mesh data should be computed
1896 discardModifs: if True and the mesh has been edited since
1897 a last total re-compute and that may prevent successful partial re-compute,
1898 then the mesh is cleaned before Compute()
1899 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1905 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1906 geom = self.mesh.GetShapeToMesh()
1909 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1911 ok = self.smeshpyD.Compute(self.mesh, geom)
1912 except SALOME.SALOME_Exception as ex:
1913 print("Mesh computation failed, exception caught:")
1914 print(" ", ex.details.text)
1917 print("Mesh computation failed, exception caught:")
1918 traceback.print_exc()
1922 # Treat compute errors
1923 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1925 for err in computeErrors:
1926 if self.mesh.HasShapeToMesh():
1927 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1929 stdErrors = ["OK", #COMPERR_OK
1930 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1931 "std::exception", #COMPERR_STD_EXCEPTION
1932 "OCC exception", #COMPERR_OCC_EXCEPTION
1933 "..", #COMPERR_SLM_EXCEPTION
1934 "Unknown exception", #COMPERR_EXCEPTION
1935 "Memory allocation problem", #COMPERR_MEMORY_PB
1936 "Algorithm failed", #COMPERR_ALGO_FAILED
1937 "Unexpected geometry", #COMPERR_BAD_SHAPE
1938 "Warning", #COMPERR_WARNING
1939 "Computation cancelled",#COMPERR_CANCELED
1940 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1942 if err.code < len(stdErrors): errText = stdErrors[err.code]
1944 errText = "code %s" % -err.code
1945 if errText: errText += ". "
1946 errText += err.comment
1947 if allReasons: allReasons += "\n"
1949 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1951 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1955 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1957 if err.isGlobalAlgo:
1965 reason = '%s %sD algorithm is missing' % (glob, dim)
1966 elif err.state == HYP_MISSING:
1967 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1968 % (glob, dim, name, dim))
1969 elif err.state == HYP_NOTCONFORM:
1970 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1971 elif err.state == HYP_BAD_PARAMETER:
1972 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1973 % ( glob, dim, name ))
1974 elif err.state == HYP_BAD_GEOMETRY:
1975 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1976 'geometry' % ( glob, dim, name ))
1977 elif err.state == HYP_HIDDEN_ALGO:
1978 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1979 'algorithm of upper dimension generating %sD mesh'
1980 % ( glob, dim, name, glob, dim ))
1982 reason = ("For unknown reason. "
1983 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1985 if allReasons: allReasons += "\n"
1986 allReasons += "- " + reason
1988 if not ok or allReasons != "":
1989 msg = '"' + GetName(self.mesh) + '"'
1990 if ok: msg += " has been computed with warnings"
1991 else: msg += " has not been computed"
1992 if allReasons != "": msg += ":"
1998 if salome.sg.hasDesktop():
1999 if not isinstance( refresh, list): # not a call from subMesh.Compute()
2000 if refresh: salome.sg.updateObjBrowser()
2004 def GetComputeErrors(self, shape=0 ):
2006 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2010 shape = self.mesh.GetShapeToMesh()
2011 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2013 def GetSubShapeName(self, subShapeID ):
2015 Return a name of a sub-shape by its ID.
2016 Possible variants (for *subShapeID* == 3):
2018 - **"Face_12"** - published sub-shape
2019 - **FACE #3** - not published sub-shape
2020 - **sub-shape #3** - invalid sub-shape ID
2021 - **#3** - error in this function
2024 subShapeID: a unique ID of a sub-shape
2027 a string describing the sub-shape
2031 if not self.mesh.HasShapeToMesh():
2035 mainIOR = salome.orb.object_to_string( self.GetShape() )
2037 mainSO = s.FindObjectIOR(mainIOR)
2040 shapeText = '"%s"' % mainSO.GetName()
2041 subIt = s.NewChildIterator(mainSO)
2043 subSO = subIt.Value()
2045 obj = subSO.GetObject()
2046 if not obj: continue
2047 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2050 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2053 if ids == subShapeID:
2054 shapeText = '"%s"' % subSO.GetName()
2057 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2059 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2061 shapeText = 'sub-shape #%s' % (subShapeID)
2063 shapeText = "#%s" % (subShapeID)
2066 def GetFailedShapes(self, publish=False):
2068 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2069 error of an algorithm
2072 publish: if *True*, the returned groups will be published in the study
2075 a list of GEOM groups each named after a failed algorithm
2080 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2081 for err in computeErrors:
2082 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2083 if not shape: continue
2084 if err.algoName in algo2shapes:
2085 algo2shapes[ err.algoName ].append( shape )
2087 algo2shapes[ err.algoName ] = [ shape ]
2091 for algoName, shapes in list(algo2shapes.items()):
2093 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2094 otherTypeShapes = []
2096 group = self.geompyD.CreateGroup( self.geom, groupType )
2097 for shape in shapes:
2098 if shape.GetShapeType() == shapes[0].GetShapeType():
2099 sameTypeShapes.append( shape )
2101 otherTypeShapes.append( shape )
2102 self.geompyD.UnionList( group, sameTypeShapes )
2104 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2106 group.SetName( algoName )
2107 groups.append( group )
2108 shapes = otherTypeShapes
2111 for group in groups:
2112 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2115 def GetMeshOrder(self):
2117 Return sub-mesh objects list in meshing order
2120 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2123 return self.mesh.GetMeshOrder()
2125 def SetMeshOrder(self, submeshes):
2127 Set priority of sub-meshes. It works in two ways:
2129 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2130 *several dimensions*, it sets the order in which the sub-meshes are computed.
2131 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2132 when looking for meshing parameters to apply to a sub-shape. To impose the
2133 order in which sub-meshes with uni-dimensional algorithms are computed,
2134 call **submesh.Compute()** in a desired order.
2137 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2139 Warning: the method is for setting the order for all sub-meshes at once:
2140 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2143 return self.mesh.SetMeshOrder(submeshes)
2145 def Clear(self, refresh=False):
2147 Remove all nodes and elements generated on geometry. Imported elements remain.
2150 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2154 if ( salome.sg.hasDesktop() ):
2155 if refresh: salome.sg.updateObjBrowser()
2157 def ClearSubMesh(self, geomId, refresh=False):
2159 Remove all nodes and elements of indicated shape
2162 geomId: the ID of a sub-shape to remove elements on
2163 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2166 self.mesh.ClearSubMesh(geomId)
2167 if salome.sg.hasDesktop():
2168 if refresh: salome.sg.updateObjBrowser()
2170 def AutomaticTetrahedralization(self, fineness=0):
2172 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2175 fineness: [0.0,1.0] defines mesh fineness
2181 dim = self.MeshDimension()
2183 self.RemoveGlobalHypotheses()
2184 self.Segment().AutomaticLength(fineness)
2186 self.Triangle().LengthFromEdges()
2191 return self.Compute()
2193 def AutomaticHexahedralization(self, fineness=0):
2195 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2198 fineness: [0.0, 1.0] defines mesh fineness
2204 dim = self.MeshDimension()
2205 # assign the hypotheses
2206 self.RemoveGlobalHypotheses()
2207 self.Segment().AutomaticLength(fineness)
2214 return self.Compute()
2216 def AddHypothesis(self, hyp, geom=0):
2221 hyp: a hypothesis to assign
2222 geom: a subhape of mesh geometry
2225 :class:`SMESH.Hypothesis_Status`
2228 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2229 hyp, geom = geom, hyp
2230 if isinstance( hyp, Mesh_Algorithm ):
2231 hyp = hyp.GetAlgorithm()
2236 geom = self.mesh.GetShapeToMesh()
2239 if self.mesh.HasShapeToMesh():
2240 hyp_type = hyp.GetName()
2241 lib_name = hyp.GetLibName()
2242 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2243 # if checkAll and geom:
2244 # checkAll = geom.GetType() == 37
2246 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2248 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2249 status = self.mesh.AddHypothesis(geom, hyp)
2251 status = HYP_BAD_GEOMETRY, ""
2252 hyp_name = GetName( hyp )
2255 geom_name = geom.GetName()
2256 isAlgo = hyp._narrow( SMESH_Algo )
2257 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2260 def IsUsedHypothesis(self, hyp, geom):
2262 Return True if an algorithm or hypothesis is assigned to a given shape
2265 hyp: an algorithm or hypothesis to check
2266 geom: a subhape of mesh geometry
2272 if not hyp: # or not geom
2274 if isinstance( hyp, Mesh_Algorithm ):
2275 hyp = hyp.GetAlgorithm()
2277 hyps = self.GetHypothesisList(geom)
2279 if h.GetId() == hyp.GetId():
2283 def RemoveHypothesis(self, hyp, geom=0):
2285 Unassign a hypothesis
2288 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2289 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2292 :class:`SMESH.Hypothesis_Status`
2297 if isinstance( hyp, Mesh_Algorithm ):
2298 hyp = hyp.GetAlgorithm()
2304 if self.IsUsedHypothesis( hyp, shape ):
2305 return self.mesh.RemoveHypothesis( shape, hyp )
2306 hypName = GetName( hyp )
2307 geoName = GetName( shape )
2308 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2311 def GetHypothesisList(self, geom):
2313 Get the list of hypotheses added on a geometry
2316 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2319 the sequence of :class:`SMESH.SMESH_Hypothesis`
2322 return self.mesh.GetHypothesisList( geom )
2324 def RemoveGlobalHypotheses(self):
2326 Remove all global hypotheses
2329 current_hyps = self.mesh.GetHypothesisList( self.geom )
2330 for hyp in current_hyps:
2331 self.mesh.RemoveHypothesis( self.geom, hyp )
2335 def ExportMEDCoupling(self, *args, **kwargs):
2337 Export the mesh in a memory representation.
2340 auto_groups (boolean): parameter for creating/not creating
2341 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2342 the typical use is auto_groups=False.
2343 overwrite (boolean): parameter for overwriting/not overwriting the file
2344 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2345 to export instead of the mesh
2346 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2348 - 1D if all mesh nodes lie on OX coordinate axis, or
2349 - 2D if all mesh nodes lie on XOY coordinate plane, or
2350 - 3D in the rest cases.
2352 If *autoDimension* is *False*, the space dimension is always 3.
2353 fields: list of GEOM fields defined on the shape to mesh.
2354 geomAssocFields: each character of this string means a need to export a
2355 corresponding field; correspondence between fields and characters
2358 - 'v' stands for "_vertices_" field;
2359 - 'e' stands for "_edges_" field;
2360 - 'f' stands for "_faces_" field;
2361 - 's' stands for "_solids_" field.
2363 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2364 close to zero within a given tolerance, the coordinate is set to zero.
2365 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2366 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2368 auto_groups = args[0] if len(args) > 0 else False
2369 meshPart = args[1] if len(args) > 1 else None
2370 autoDimension = args[2] if len(args) > 2 else True
2371 fields = args[3] if len(args) > 3 else []
2372 geomAssocFields = args[4] if len(args) > 4 else ''
2373 z_tolerance = args[5] if len(args) > 5 else -1.
2374 saveNumbers = args[6] if len(args) > 6 else True
2375 # process keywords arguments
2376 auto_groups = kwargs.get("auto_groups", auto_groups)
2377 meshPart = kwargs.get("meshPart", meshPart)
2378 autoDimension = kwargs.get("autoDimension", autoDimension)
2379 fields = kwargs.get("fields", fields)
2380 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2381 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2382 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2384 # invoke engine's function
2385 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2386 unRegister = genObjUnRegister()
2387 if isinstance( meshPart, list ):
2388 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2389 unRegister.set( meshPart )
2391 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2392 self.mesh.SetParameters(Parameters)
2394 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2395 fields, geomAssocFields, z_tolerance,
2398 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2399 return medcoupling.MEDFileData.New(dab)
2401 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2403 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2404 return medcoupling.MEDFileMesh.New(dab)
2406 def ExportMED(self, *args, **kwargs):
2408 Export the mesh in a file in MED format
2409 allowing to overwrite the file if it exists or add the exported data to its contents
2412 fileName: is the file name
2413 auto_groups (boolean): parameter for creating/not creating
2414 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2415 the typical use is auto_groups=False.
2416 version (int): define the version (xy, where version is x.y.z) of MED file format.
2417 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2418 The rules of compatibility to write a mesh in an older version than
2419 the current version depend on the current version. For instance,
2420 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2421 or 3.2.1 or 3.3.1 formats.
2422 If the version is equal to -1, the version is not changed (default).
2423 overwrite (boolean): parameter for overwriting/not overwriting the file
2424 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2425 to export instead of the mesh
2426 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2428 - 1D if all mesh nodes lie on OX coordinate axis, or
2429 - 2D if all mesh nodes lie on XOY coordinate plane, or
2430 - 3D in the rest cases.
2432 If *autoDimension* is *False*, the space dimension is always 3.
2433 fields: list of GEOM fields defined on the shape to mesh.
2434 geomAssocFields: each character of this string means a need to export a
2435 corresponding field; correspondence between fields and characters
2438 - 'v' stands for "_vertices_" field;
2439 - 'e' stands for "_edges_" field;
2440 - 'f' stands for "_faces_" field;
2441 - 's' stands for "_solids_" field.
2443 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2444 close to zero within a given tolerance, the coordinate is set to zero.
2445 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2446 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2448 # process positional arguments
2449 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2451 auto_groups = args[1] if len(args) > 1 else False
2452 version = args[2] if len(args) > 2 else -1
2453 overwrite = args[3] if len(args) > 3 else True
2454 meshPart = args[4] if len(args) > 4 else None
2455 autoDimension = args[5] if len(args) > 5 else True
2456 fields = args[6] if len(args) > 6 else []
2457 geomAssocFields = args[7] if len(args) > 7 else ''
2458 z_tolerance = args[8] if len(args) > 8 else -1.
2459 saveNumbers = args[9] if len(args) > 9 else True
2460 # process keywords arguments
2461 auto_groups = kwargs.get("auto_groups", auto_groups)
2462 version = kwargs.get("version", version)
2463 version = kwargs.get("minor", version)
2464 overwrite = kwargs.get("overwrite", overwrite)
2465 meshPart = kwargs.get("meshPart", meshPart)
2466 autoDimension = kwargs.get("autoDimension", autoDimension)
2467 fields = kwargs.get("fields", fields)
2468 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2469 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2470 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2472 if isinstance( meshPart, Mesh):
2473 meshPart = meshPart.GetMesh()
2475 # invoke engine's function
2476 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2477 unRegister = genObjUnRegister()
2478 if isinstance( meshPart, list ):
2479 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2480 unRegister.set( meshPart )
2482 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2483 self.mesh.SetParameters(Parameters)
2485 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2486 version, overwrite, autoDimension,
2487 fields, geomAssocFields, z_tolerance, saveNumbers )
2489 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2491 def ExportDAT(self, f, meshPart=None, renumber=True):
2493 Export the mesh in a file in DAT format
2497 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2498 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2501 if meshPart or not renumber:
2502 unRegister = genObjUnRegister()
2503 if isinstance( meshPart, list ):
2504 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2505 unRegister.set( meshPart )
2506 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2508 self.mesh.ExportDAT( f, renumber )
2510 def ExportUNV(self, f, meshPart=None, renumber=True):
2512 Export the mesh in a file in UNV format
2516 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2517 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2520 if meshPart or not renumber:
2521 unRegister = genObjUnRegister()
2522 if isinstance( meshPart, list ):
2523 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2524 unRegister.set( meshPart )
2525 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2527 self.mesh.ExportUNV( f, renumber )
2529 def ExportSTL(self, f, ascii=1, meshPart=None):
2531 Export the mesh in a file in STL format
2535 ascii: defines the file encoding
2536 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2540 unRegister = genObjUnRegister()
2541 if isinstance( meshPart, list ):
2542 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2543 unRegister.set( meshPart )
2544 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2546 self.mesh.ExportSTL(f, ascii)
2548 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2550 Export the mesh in a file in CGNS format
2554 overwrite: boolean parameter for overwriting/not overwriting the file
2555 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2556 groupElemsByType: if True all elements of same entity type are exported at ones,
2557 else elements are exported in order of their IDs which can cause creation
2558 of multiple cgns sections
2561 unRegister = genObjUnRegister()
2562 if isinstance( meshPart, list ):
2563 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2564 unRegister.set( meshPart )
2565 if isinstance( meshPart, Mesh ):
2566 meshPart = meshPart.mesh
2568 meshPart = self.mesh
2569 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2571 def ExportGMF(self, f, meshPart=None):
2573 Export the mesh in a file in GMF format.
2574 GMF files must have .mesh extension for the ASCII format and .meshb for
2575 the bynary format. Other extensions are not allowed.
2579 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2582 unRegister = genObjUnRegister()
2583 if isinstance( meshPart, list ):
2584 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2585 unRegister.set( meshPart )
2586 if isinstance( meshPart, Mesh ):
2587 meshPart = meshPart.mesh
2589 meshPart = self.mesh
2590 self.mesh.ExportGMF(meshPart, f, True)
2592 def ExportToMED(self, *args, **kwargs):
2594 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2595 Export the mesh in a file in MED format
2596 allowing to overwrite the file if it exists or add the exported data to its contents
2599 fileName: the file name
2600 opt (boolean): parameter for creating/not creating
2601 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2602 overwrite: boolean parameter for overwriting/not overwriting the file
2603 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2605 - 1D if all mesh nodes lie on OX coordinate axis, or
2606 - 2D if all mesh nodes lie on XOY coordinate plane, or
2607 - 3D in the rest cases.
2609 If **autoDimension** is *False*, the space dimension is always 3.
2612 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2613 # process positional arguments
2614 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2616 auto_groups = args[1] if len(args) > 1 else False
2617 overwrite = args[2] if len(args) > 2 else True
2618 autoDimension = args[3] if len(args) > 3 else True
2619 # process keywords arguments
2620 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2621 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2622 overwrite = kwargs.get("overwrite", overwrite)
2623 autoDimension = kwargs.get("autoDimension", autoDimension)
2625 # invoke engine's function
2626 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2628 def ExportToMEDX(self, *args, **kwargs):
2630 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2631 Export the mesh in a file in MED format
2634 fileName: the file name
2635 opt (boolean): parameter for creating/not creating
2636 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2637 overwrite: boolean parameter for overwriting/not overwriting the file
2638 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2640 - 1D if all mesh nodes lie on OX coordinate axis, or
2641 - 2D if all mesh nodes lie on XOY coordinate plane, or
2642 - 3D in the rest cases.
2644 If **autoDimension** is *False*, the space dimension is always 3.
2647 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2648 # process positional arguments
2649 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2651 auto_groups = args[1] if len(args) > 1 else False
2652 overwrite = args[2] if len(args) > 2 else True
2653 autoDimension = args[3] if len(args) > 3 else True
2654 # process keywords arguments
2655 auto_groups = kwargs.get("auto_groups", auto_groups)
2656 overwrite = kwargs.get("overwrite", overwrite)
2657 autoDimension = kwargs.get("autoDimension", autoDimension)
2659 # invoke engine's function
2660 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2664 def Append(self, meshes, uniteIdenticalGroups = True,
2665 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2667 Append given meshes into this mesh.
2668 All groups of input meshes will be created in this mesh.
2671 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2672 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2673 mergeNodesAndElements: if True, equal nodes and elements are merged
2674 mergeTolerance: tolerance for merging nodes
2675 allGroups: forces creation of groups corresponding to every input mesh
2677 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2678 mergeNodesAndElements, mergeTolerance, allGroups,
2679 meshToAppendTo = self.GetMesh() )
2681 # Operations with groups:
2682 # ----------------------
2683 def CreateEmptyGroup(self, elementType, name):
2685 Create an empty standalone mesh group
2688 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2689 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2690 name: the name of the mesh group
2693 :class:`SMESH.SMESH_Group`
2696 return self.mesh.CreateGroup(elementType, name)
2698 def Group(self, grp, name=""):
2700 Create a mesh group based on the geometric object *grp*
2701 and give it a *name*.
2702 If *name* is not defined the name of the geometric group is used
2705 Works like :meth:`GroupOnGeom`.
2708 grp: a geometric group, a vertex, an edge, a face or a solid
2709 name: the name of the mesh group
2712 :class:`SMESH.SMESH_GroupOnGeom`
2715 return self.GroupOnGeom(grp, name)
2717 def GroupOnGeom(self, grp, name="", typ=None):
2719 Create a mesh group based on the geometrical object *grp*
2720 and give it a *name*.
2721 if *name* is not defined the name of the geometric group is used
2724 grp: a geometrical group, a vertex, an edge, a face or a solid
2725 name: the name of the mesh group
2726 typ: the type of elements in the group; either of
2727 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2728 automatically detected by the type of the geometry
2731 :class:`SMESH.SMESH_GroupOnGeom`
2734 AssureGeomPublished( self, grp, name )
2736 name = grp.GetName()
2738 typ = self._groupTypeFromShape( grp )
2739 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2741 def _groupTypeFromShape( self, shape ):
2743 Pivate method to get a type of group on geometry
2745 tgeo = str(shape.GetShapeType())
2746 if tgeo == "VERTEX":
2748 elif tgeo == "EDGE" or tgeo == "WIRE":
2750 elif tgeo == "FACE" or tgeo == "SHELL":
2752 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2754 elif tgeo == "COMPOUND":
2756 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2758 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2759 # simplification of access in geomBuilder: omniORB.registerObjref
2760 from SHAPERSTUDY_utils import getEngine
2763 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2765 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2766 return self._groupTypeFromShape( sub[0] )
2768 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2771 def GroupOnFilter(self, typ, name, filter):
2773 Create a mesh group with given *name* based on the *filter*.
2774 It is a special type of group dynamically updating it's contents during
2778 typ: the type of elements in the group; either of
2779 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2780 name: the name of the mesh group
2781 filter (SMESH.Filter): the filter defining group contents
2784 :class:`SMESH.SMESH_GroupOnFilter`
2787 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2789 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2791 Create a mesh group by the given ids of elements
2794 groupName: the name of the mesh group
2795 elementType: the type of elements in the group; either of
2796 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2797 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2800 :class:`SMESH.SMESH_Group`
2803 group = self.mesh.CreateGroup(elementType, groupName)
2804 if isinstance( elemIDs, Mesh ):
2805 elemIDs = elemIDs.GetMesh()
2806 if hasattr( elemIDs, "GetIDs" ):
2807 if hasattr( elemIDs, "SetMesh" ):
2808 elemIDs.SetMesh( self.GetMesh() )
2809 group.AddFrom( elemIDs )
2817 CritType=FT_Undefined,
2820 UnaryOp=FT_Undefined,
2823 Create a mesh group by the given conditions
2826 groupName: the name of the mesh group
2827 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2828 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2829 Note that the items starting from FT_LessThan are not suitable for CritType.
2830 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2831 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2832 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2833 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2834 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2837 :class:`SMESH.SMESH_GroupOnFilter`
2840 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2841 group = self.MakeGroupByCriterion(groupName, aCriterion)
2844 def MakeGroupByCriterion(self, groupName, Criterion):
2846 Create a mesh group by the given criterion
2849 groupName: the name of the mesh group
2850 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2853 :class:`SMESH.SMESH_GroupOnFilter`
2856 :meth:`smeshBuilder.GetCriterion`
2859 return self.MakeGroupByCriteria( groupName, [Criterion] )
2861 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2863 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2866 groupName: the name of the mesh group
2867 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2868 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2871 :class:`SMESH.SMESH_GroupOnFilter`
2874 :meth:`smeshBuilder.GetCriterion`
2877 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2878 group = self.MakeGroupByFilter(groupName, aFilter)
2881 def MakeGroupByFilter(self, groupName, theFilter):
2883 Create a mesh group by the given filter
2886 groupName (string): the name of the mesh group
2887 theFilter (SMESH.Filter): the filter
2890 :class:`SMESH.SMESH_GroupOnFilter`
2893 :meth:`smeshBuilder.GetFilter`
2896 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2897 #theFilter.SetMesh( self.mesh )
2898 #group.AddFrom( theFilter )
2899 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2902 def RemoveGroup(self, group):
2907 group (SMESH.SMESH_GroupBase): group to remove
2910 self.mesh.RemoveGroup(group)
2912 def RemoveGroupWithContents(self, group):
2914 Remove a group with its contents
2917 group (SMESH.SMESH_GroupBase): group to remove
2920 This operation can create gaps in numeration of nodes or elements.
2921 Call :meth:`RenumberElements` to remove the gaps.
2924 self.mesh.RemoveGroupWithContents(group)
2926 def GetGroups(self, elemType = SMESH.ALL):
2928 Get the list of groups existing in the mesh in the order of creation
2929 (starting from the oldest one)
2932 elemType (SMESH.ElementType): type of elements the groups contain;
2933 by default groups of elements of all types are returned
2936 a list of :class:`SMESH.SMESH_GroupBase`
2939 groups = self.mesh.GetGroups()
2940 if elemType == SMESH.ALL:
2944 if g.GetType() == elemType:
2945 typedGroups.append( g )
2952 Get the number of groups existing in the mesh
2955 the quantity of groups as an integer value
2958 return self.mesh.NbGroups()
2960 def GetGroupNames(self):
2962 Get the list of names of groups existing in the mesh
2968 groups = self.GetGroups()
2970 for group in groups:
2971 names.append(group.GetName())
2974 def GetGroupByName(self, name, elemType = None):
2976 Find groups by name and type
2979 name (string): name of the group of interest
2980 elemType (SMESH.ElementType): type of elements the groups contain;
2981 by default one group of any type is returned;
2982 if elemType == SMESH.ALL then all groups of any type are returned
2985 a list of :class:`SMESH.SMESH_GroupBase`
2989 for group in self.GetGroups():
2990 if group.GetName() == name:
2991 if elemType is None:
2993 if ( elemType == SMESH.ALL or
2994 group.GetType() == elemType ):
2995 groups.append( group )
2998 def UnionGroups(self, group1, group2, name):
3000 Produce a union of two groups.
3001 A new group is created. All mesh elements that are
3002 present in the initial groups are added to the new one
3005 group1 (SMESH.SMESH_GroupBase): a group
3006 group2 (SMESH.SMESH_GroupBase): another group
3009 instance of :class:`SMESH.SMESH_Group`
3012 return self.mesh.UnionGroups(group1, group2, name)
3014 def UnionListOfGroups(self, groups, name):
3016 Produce a union list of groups.
3017 New group is created. All mesh elements that are present in
3018 initial groups are added to the new one
3021 groups: list of :class:`SMESH.SMESH_GroupBase`
3024 instance of :class:`SMESH.SMESH_Group`
3026 return self.mesh.UnionListOfGroups(groups, name)
3028 def IntersectGroups(self, group1, group2, name):
3030 Prodice an intersection of two groups.
3031 A new group is created. All mesh elements that are common
3032 for the two initial groups are added to the new one.
3035 group1 (SMESH.SMESH_GroupBase): a group
3036 group2 (SMESH.SMESH_GroupBase): another group
3039 instance of :class:`SMESH.SMESH_Group`
3042 return self.mesh.IntersectGroups(group1, group2, name)
3044 def IntersectListOfGroups(self, groups, name):
3046 Produce an intersection of groups.
3047 New group is created. All mesh elements that are present in all
3048 initial groups simultaneously are added to the new one
3051 groups: a list of :class:`SMESH.SMESH_GroupBase`
3054 instance of :class:`SMESH.SMESH_Group`
3056 return self.mesh.IntersectListOfGroups(groups, name)
3058 def CutGroups(self, main_group, tool_group, name):
3060 Produce a cut of two groups.
3061 A new group is created. All mesh elements that are present in
3062 the main group but are not present in the tool group are added to the new one
3065 main_group (SMESH.SMESH_GroupBase): a group to cut from
3066 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3069 an instance of :class:`SMESH.SMESH_Group`
3072 return self.mesh.CutGroups(main_group, tool_group, name)
3074 def CutListOfGroups(self, main_groups, tool_groups, name):
3076 Produce a cut of groups.
3077 A new group is created. All mesh elements that are present in main groups
3078 but do not present in tool groups are added to the new one
3081 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3082 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3085 an instance of :class:`SMESH.SMESH_Group`
3088 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3090 def CreateDimGroup(self, groups, elemType, name,
3091 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3093 Create a standalone group of entities basing on nodes of other groups.
3096 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3097 elemType: a type of elements to include to the new group; either of
3098 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3099 name: a name of the new group.
3100 nbCommonNodes: a criterion of inclusion of an element to the new group
3101 basing on number of element nodes common with reference *groups*.
3102 Meaning of possible values are:
3104 - SMESH.ALL_NODES - include if all nodes are common,
3105 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3106 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3107 - SMEHS.MAJORITY - include if half of nodes or more are common.
3108 underlyingOnly: if *True* (default), an element is included to the
3109 new group provided that it is based on nodes of an element of *groups*;
3110 in this case the reference *groups* are supposed to be of higher dimension
3111 than *elemType*, which can be useful for example to get all faces lying on
3112 volumes of the reference *groups*.
3115 an instance of :class:`SMESH.SMESH_Group`
3118 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3120 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3122 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3124 Distribute all faces of the mesh among groups using sharp edges and optionally
3125 existing 1D elements as group boundaries.
3128 sharpAngle: edge is considered sharp if an angle between normals of
3129 adjacent faces is more than \a sharpAngle in degrees.
3130 createEdges (boolean): to create 1D elements for detected sharp edges.
3131 useExistingEdges (boolean): to use existing edges as group boundaries
3133 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3135 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3136 self.mesh.SetParameters(Parameters)
3137 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3139 def ConvertToStandalone(self, group):
3141 Convert group on geom into standalone group
3144 return self.mesh.ConvertToStandalone(group)
3146 # Get some info about mesh:
3147 # ------------------------
3149 def GetLog(self, clearAfterGet):
3151 Return the log of nodes and elements added or removed
3152 since the previous clear of the log.
3155 clearAfterGet: log is emptied after Get (safe if concurrents access)
3158 list of SMESH.log_block structures { commandType, number, coords, indexes }
3161 return self.mesh.GetLog(clearAfterGet)
3165 Clear the log of nodes and elements added or removed since the previous
3166 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3169 self.mesh.ClearLog()
3171 def SetAutoColor(self, theAutoColor):
3173 Toggle auto color mode on the object.
3174 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3177 theAutoColor (boolean): the flag which toggles auto color mode.
3180 self.mesh.SetAutoColor(theAutoColor)
3182 def GetAutoColor(self):
3184 Get flag of object auto color mode.
3190 return self.mesh.GetAutoColor()
3197 integer value, which is the internal Id of the mesh
3200 return self.mesh.GetId()
3202 def HasDuplicatedGroupNamesMED(self):
3204 Check the group names for duplications.
3205 Consider the maximum group name length stored in MED file.
3211 return self.mesh.HasDuplicatedGroupNamesMED()
3213 def GetMeshEditor(self):
3215 Obtain the mesh editor tool
3218 an instance of :class:`SMESH.SMESH_MeshEditor`
3223 def GetIDSource(self, ids, elemType = SMESH.ALL):
3225 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3226 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3230 elemType: type of elements; this parameter is used to distinguish
3231 IDs of nodes from IDs of elements; by default ids are treated as
3232 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3235 an instance of :class:`SMESH.SMESH_IDSource`
3238 call UnRegister() for the returned object as soon as it is no more useful::
3240 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3241 mesh.DoSomething( idSrc )
3245 if isinstance( ids, int ):
3247 return self.editor.MakeIDSource(ids, elemType)
3250 # Get information about mesh contents:
3251 # ------------------------------------
3253 def GetMeshInfo(self, obj = None):
3255 Get the mesh statistic.
3258 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3261 if not obj: obj = self.mesh
3262 return self.smeshpyD.GetMeshInfo(obj)
3266 Return the number of nodes in the mesh
3272 return self.mesh.NbNodes()
3274 def NbElements(self):
3276 Return the number of elements in the mesh
3282 return self.mesh.NbElements()
3284 def Nb0DElements(self):
3286 Return the number of 0d elements in the mesh
3292 return self.mesh.Nb0DElements()
3296 Return the number of ball discrete elements in the mesh
3302 return self.mesh.NbBalls()
3306 Return the number of edges in the mesh
3312 return self.mesh.NbEdges()
3314 def NbEdgesOfOrder(self, elementOrder):
3316 Return the number of edges with the given order in the mesh
3319 elementOrder: the order of elements
3320 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3326 return self.mesh.NbEdgesOfOrder(elementOrder)
3330 Return the number of faces in the mesh
3336 return self.mesh.NbFaces()
3338 def NbFacesOfOrder(self, elementOrder):
3340 Return the number of faces with the given order in the mesh
3343 elementOrder: the order of elements
3344 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3350 return self.mesh.NbFacesOfOrder(elementOrder)
3352 def NbTriangles(self):
3354 Return the number of triangles in the mesh
3360 return self.mesh.NbTriangles()
3362 def NbTrianglesOfOrder(self, elementOrder):
3364 Return the number of triangles with the given order in the mesh
3367 elementOrder: is the order of elements
3368 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3374 return self.mesh.NbTrianglesOfOrder(elementOrder)
3376 def NbBiQuadTriangles(self):
3378 Return the number of biquadratic triangles in the mesh
3384 return self.mesh.NbBiQuadTriangles()
3386 def NbQuadrangles(self):
3388 Return the number of quadrangles in the mesh
3394 return self.mesh.NbQuadrangles()
3396 def NbQuadranglesOfOrder(self, elementOrder):
3398 Return the number of quadrangles with the given order in the mesh
3401 elementOrder: the order of elements
3402 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3408 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3410 def NbBiQuadQuadrangles(self):
3412 Return the number of biquadratic quadrangles in the mesh
3418 return self.mesh.NbBiQuadQuadrangles()
3420 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3422 Return the number of polygons of given order in the mesh
3425 elementOrder: the order of elements
3426 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3432 return self.mesh.NbPolygonsOfOrder(elementOrder)
3434 def NbVolumes(self):
3436 Return the number of volumes in the mesh
3442 return self.mesh.NbVolumes()
3445 def NbVolumesOfOrder(self, elementOrder):
3447 Return the number of volumes with the given order in the mesh
3450 elementOrder: the order of elements
3451 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3457 return self.mesh.NbVolumesOfOrder(elementOrder)
3461 Return the number of tetrahedrons in the mesh
3467 return self.mesh.NbTetras()
3469 def NbTetrasOfOrder(self, elementOrder):
3471 Return the number of tetrahedrons with the given order in the mesh
3474 elementOrder: the order of elements
3475 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3481 return self.mesh.NbTetrasOfOrder(elementOrder)
3485 Return the number of hexahedrons in the mesh
3491 return self.mesh.NbHexas()
3493 def NbHexasOfOrder(self, elementOrder):
3495 Return the number of hexahedrons with the given order in the mesh
3498 elementOrder: the order of elements
3499 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3505 return self.mesh.NbHexasOfOrder(elementOrder)
3507 def NbTriQuadraticHexas(self):
3509 Return the number of triquadratic hexahedrons in the mesh
3515 return self.mesh.NbTriQuadraticHexas()
3517 def NbPyramids(self):
3519 Return the number of pyramids in the mesh
3525 return self.mesh.NbPyramids()
3527 def NbPyramidsOfOrder(self, elementOrder):
3529 Return the number of pyramids with the given order in the mesh
3532 elementOrder: the order of elements
3533 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3539 return self.mesh.NbPyramidsOfOrder(elementOrder)
3543 Return the number of prisms in the mesh
3549 return self.mesh.NbPrisms()
3551 def NbPrismsOfOrder(self, elementOrder):
3553 Return the number of prisms with the given order in the mesh
3556 elementOrder: the order of elements
3557 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3563 return self.mesh.NbPrismsOfOrder(elementOrder)
3565 def NbHexagonalPrisms(self):
3567 Return the number of hexagonal prisms in the mesh
3573 return self.mesh.NbHexagonalPrisms()
3575 def NbPolyhedrons(self):
3577 Return the number of polyhedrons in the mesh
3583 return self.mesh.NbPolyhedrons()
3585 def NbSubMesh(self):
3587 Return the number of submeshes in the mesh
3593 return self.mesh.NbSubMesh()
3595 def GetElementsId(self):
3597 Return the list of all mesh elements IDs
3600 the list of integer values
3603 :meth:`GetElementsByType`
3606 return self.mesh.GetElementsId()
3608 def GetElementsByType(self, elementType):
3610 Return the list of IDs of mesh elements with the given type
3613 elementType (SMESH.ElementType): the required type of elements
3616 list of integer values
3619 return self.mesh.GetElementsByType(elementType)
3621 def GetNodesId(self):
3623 Return the list of mesh nodes IDs
3626 the list of integer values
3629 return self.mesh.GetNodesId()
3631 # Get the information about mesh elements:
3632 # ------------------------------------
3634 def GetElementType(self, id, iselem=True):
3636 Return the type of mesh element or node
3639 the value from :class:`SMESH.ElementType` enumeration.
3640 Return SMESH.ALL if element or node with the given ID does not exist
3643 return self.mesh.GetElementType(id, iselem)
3645 def GetElementGeomType(self, id):
3647 Return the geometric type of mesh element
3650 the value from :class:`SMESH.EntityType` enumeration.
3653 return self.mesh.GetElementGeomType(id)
3655 def GetElementShape(self, id):
3657 Return the shape type of mesh element
3660 the value from :class:`SMESH.GeometryType` enumeration.
3663 return self.mesh.GetElementShape(id)
3665 def GetSubMeshElementsId(self, Shape):
3667 Return the list of sub-mesh elements IDs
3670 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3671 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3674 list of integer values
3677 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3678 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3681 return self.mesh.GetSubMeshElementsId(ShapeID)
3683 def GetSubMeshNodesId(self, Shape, all):
3685 Return the list of sub-mesh nodes IDs
3688 Shape: a geom object (sub-shape).
3689 *Shape* must be the sub-shape of a :meth:`GetShape`
3690 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3693 list of integer values
3696 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3697 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3700 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3702 def GetSubMeshElementType(self, Shape):
3704 Return type of elements on given shape
3707 Shape: a geom object (sub-shape).
3708 *Shape* must be a sub-shape of a ShapeToMesh()
3711 :class:`SMESH.ElementType`
3714 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3715 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3718 return self.mesh.GetSubMeshElementType(ShapeID)
3722 Get the mesh description
3728 return self.mesh.Dump()
3731 # Get the information about nodes and elements of a mesh by its IDs:
3732 # -----------------------------------------------------------
3734 def GetNodeXYZ(self, id):
3736 Get XYZ coordinates of a node.
3737 If there is no node for the given ID - return an empty list
3740 list of float values
3743 return self.mesh.GetNodeXYZ(id)
3745 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3747 Return list of IDs of inverse elements for the given node.
3748 If there is no node for the given ID - return an empty list
3752 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3755 list of integer values
3758 return self.mesh.GetNodeInverseElements(id,elemType)
3760 def GetNodePosition(self,NodeID):
3762 Return the position of a node on the shape
3765 :class:`SMESH.NodePosition`
3768 return self.mesh.GetNodePosition(NodeID)
3770 def GetElementPosition(self,ElemID):
3772 Return the position of an element on the shape
3775 :class:`SMESH.ElementPosition`
3778 return self.mesh.GetElementPosition(ElemID)
3780 def GetShapeID(self, id):
3782 Return the ID of the shape, on which the given node was generated.
3785 an integer value > 0 or -1 if there is no node for the given
3786 ID or the node is not assigned to any geometry
3789 return self.mesh.GetShapeID(id)
3791 def GetShapeIDForElem(self,id):
3793 Return the ID of the shape, on which the given element was generated.
3796 an integer value > 0 or -1 if there is no element for the given
3797 ID or the element is not assigned to any geometry
3800 return self.mesh.GetShapeIDForElem(id)
3802 def GetElemNbNodes(self, id):
3804 Return the number of nodes of the given element
3807 an integer value > 0 or -1 if there is no element for the given ID
3810 return self.mesh.GetElemNbNodes(id)
3812 def GetElemNode(self, id, index):
3814 Return the node ID the given (zero based) index for the given element.
3816 * If there is no element for the given ID - return -1.
3817 * If there is no node for the given index - return -2.
3820 id (int): element ID
3821 index (int): node index within the element
3824 an integer value (ID)
3827 :meth:`GetElemNodes`
3830 return self.mesh.GetElemNode(id, index)
3832 def GetElemNodes(self, id):
3834 Return the IDs of nodes of the given element
3837 a list of integer values
3840 return self.mesh.GetElemNodes(id)
3842 def IsMediumNode(self, elementID, nodeID):
3844 Return true if the given node is the medium node in the given quadratic element
3847 return self.mesh.IsMediumNode(elementID, nodeID)
3849 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3851 Return true if the given node is the medium node in one of quadratic elements
3854 nodeID: ID of the node
3855 elementType: the type of elements to check a state of the node, either of
3856 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3859 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3861 def ElemNbEdges(self, id):
3863 Return the number of edges for the given element
3866 return self.mesh.ElemNbEdges(id)
3868 def ElemNbFaces(self, id):
3870 Return the number of faces for the given element
3873 return self.mesh.ElemNbFaces(id)
3875 def GetElemFaceNodes(self,elemId, faceIndex):
3877 Return nodes of given face (counted from zero) for given volumic element.
3880 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3882 def GetFaceNormal(self, faceId, normalized=False):
3884 Return three components of normal of given mesh face
3885 (or an empty array in KO case)
3888 return self.mesh.GetFaceNormal(faceId,normalized)
3890 def FindElementByNodes(self, nodes):
3892 Return an element based on all given nodes.
3895 return self.mesh.FindElementByNodes(nodes)
3897 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3899 Return elements including all given nodes.
3902 return self.mesh.GetElementsByNodes( nodes, elemType )
3904 def IsPoly(self, id):
3906 Return true if the given element is a polygon
3909 return self.mesh.IsPoly(id)
3911 def IsQuadratic(self, id):
3913 Return true if the given element is quadratic
3916 return self.mesh.IsQuadratic(id)
3918 def GetBallDiameter(self, id):
3920 Return diameter of a ball discrete element or zero in case of an invalid *id*
3923 return self.mesh.GetBallDiameter(id)
3925 def BaryCenter(self, id):
3927 Return XYZ coordinates of the barycenter of the given element.
3928 If there is no element for the given ID - return an empty list
3931 a list of three double values
3934 :meth:`smeshBuilder.GetGravityCenter`
3937 return self.mesh.BaryCenter(id)
3939 def GetIdsFromFilter(self, filter, meshParts=[] ):
3941 Pass mesh elements through the given filter and return IDs of fitting elements
3944 filter: :class:`SMESH.Filter`
3945 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3951 :meth:`SMESH.Filter.GetIDs`
3952 :meth:`SMESH.Filter.GetElementsIdFromParts`
3955 filter.SetMesh( self.mesh )
3958 if isinstance( meshParts, Mesh ):
3959 filter.SetMesh( meshParts.GetMesh() )
3960 return theFilter.GetIDs()
3961 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3962 meshParts = [ meshParts ]
3963 return filter.GetElementsIdFromParts( meshParts )
3965 return filter.GetIDs()
3967 # Get mesh measurements information:
3968 # ------------------------------------
3970 def GetFreeBorders(self):
3972 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3973 Return a list of special structures (borders).
3976 a list of :class:`SMESH.FreeEdges.Border`
3979 aFilterMgr = self.smeshpyD.CreateFilterManager()
3980 aPredicate = aFilterMgr.CreateFreeEdges()
3981 aPredicate.SetMesh(self.mesh)
3982 aBorders = aPredicate.GetBorders()
3983 aFilterMgr.UnRegister()
3986 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3988 Get minimum distance between two nodes, elements or distance to the origin
3991 id1: first node/element id
3992 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3993 isElem1: *True* if *id1* is element id, *False* if it is node id
3994 isElem2: *True* if *id2* is element id, *False* if it is node id
3997 minimum distance value
3999 :meth:`GetMinDistance`
4002 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4003 return aMeasure.value
4005 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4007 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4010 id1: first node/element id
4011 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4012 isElem1: *True* if *id1* is element id, *False* if it is node id
4013 isElem2: *True* if *id2* is element id, *False* if it is node id
4016 :class:`SMESH.Measure` structure
4022 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4024 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4027 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4029 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4034 aMeasurements = self.smeshpyD.CreateMeasurements()
4035 aMeasure = aMeasurements.MinDistance(id1, id2)
4036 genObjUnRegister([aMeasurements,id1, id2])
4039 def BoundingBox(self, objects=None, isElem=False):
4041 Get bounding box of the specified object(s)
4044 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4045 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4046 *False* specifies that *objects* are nodes
4049 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4052 :meth:`GetBoundingBox()`
4055 result = self.GetBoundingBox(objects, isElem)
4059 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4062 def GetBoundingBox(self, objects=None, isElem=False):
4064 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4067 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4068 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4069 False means that *objects* are nodes
4072 :class:`SMESH.Measure` structure
4075 :meth:`BoundingBox()`
4079 objects = [self.mesh]
4080 elif isinstance(objects, tuple):
4081 objects = list(objects)
4082 if not isinstance(objects, list):
4084 if len(objects) > 0 and isinstance(objects[0], int):
4087 unRegister = genObjUnRegister()
4089 if isinstance(o, Mesh):
4090 srclist.append(o.mesh)
4091 elif hasattr(o, "_narrow"):
4092 src = o._narrow(SMESH.SMESH_IDSource)
4093 if src: srclist.append(src)
4095 elif isinstance(o, list):
4097 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4099 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4100 unRegister.set( srclist[-1] )
4103 aMeasurements = self.smeshpyD.CreateMeasurements()
4104 unRegister.set( aMeasurements )
4105 aMeasure = aMeasurements.BoundingBox(srclist)
4108 # Mesh edition (SMESH_MeshEditor functionality):
4109 # ---------------------------------------------
4111 def RemoveElements(self, IDsOfElements):
4113 Remove the elements from the mesh by ids
4116 IDsOfElements: is a list of ids of elements to remove
4122 This operation can create gaps in numeration of elements.
4123 Call :meth:`RenumberElements` to remove the gaps.
4126 return self.editor.RemoveElements(IDsOfElements)
4128 def RemoveNodes(self, IDsOfNodes):
4130 Remove nodes from mesh by ids
4133 IDsOfNodes: is a list of ids of nodes to remove
4139 This operation can create gaps in numeration of nodes.
4140 Call :meth:`RenumberElements` to remove the gaps.
4143 return self.editor.RemoveNodes(IDsOfNodes)
4145 def RemoveNodeWithReconnection(self, nodeID ):
4147 Remove a node along with changing surrounding faces to cover a hole.
4150 nodeID: ID of node to remove
4153 return self.editor.RemoveNodeWithReconnection( nodeID )
4155 def RemoveOrphanNodes(self):
4157 Remove all orphan (free) nodes from mesh
4160 number of the removed nodes
4163 This operation can create gaps in numeration of nodes.
4164 Call :meth:`RenumberElements` to remove the gaps.
4167 return self.editor.RemoveOrphanNodes()
4169 def AddNode(self, x, y, z):
4171 Add a node to the mesh by coordinates
4177 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4178 if hasVars: self.mesh.SetParameters(Parameters)
4179 return self.editor.AddNode( x, y, z)
4181 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4183 Create a 0D element on a node with given number.
4186 IDOfNode: the ID of node for creation of the element.
4187 DuplicateElements: to add one more 0D element to a node or not
4190 ID of the new 0D element
4193 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4195 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4197 Create 0D elements on all nodes of the given elements except those
4198 nodes on which a 0D element already exists.
4201 theObject: an object on whose nodes 0D elements will be created.
4202 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4203 theGroupName: optional name of a group to add 0D elements created
4204 and/or found on nodes of *theObject*.
4205 DuplicateElements: to add one more 0D element to a node or not
4208 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4209 IDs of new and/or found 0D elements. IDs of 0D elements
4210 can be retrieved from the returned object by
4211 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4214 unRegister = genObjUnRegister()
4215 if isinstance( theObject, Mesh ):
4216 theObject = theObject.GetMesh()
4217 elif isinstance( theObject, list ):
4218 theObject = self.GetIDSource( theObject, SMESH.ALL )
4219 unRegister.set( theObject )
4220 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4222 def AddBall(self, IDOfNode, diameter):
4224 Create a ball element on a node with given ID.
4227 IDOfNode: the ID of node for creation of the element.
4228 diameter: the bal diameter.
4231 ID of the new ball element
4234 return self.editor.AddBall( IDOfNode, diameter )
4236 def AddEdge(self, IDsOfNodes):
4238 Create a linear or quadratic edge (this is determined
4239 by the number of given nodes).
4242 IDsOfNodes: list of node IDs for creation of the element.
4243 The order of nodes in this list should correspond to
4244 the :ref:`connectivity convention <connectivity_page>`.
4250 return self.editor.AddEdge(IDsOfNodes)
4252 def AddFace(self, IDsOfNodes):
4254 Create a linear or quadratic face (this is determined
4255 by the number of given nodes).
4258 IDsOfNodes: list of node IDs for creation of the element.
4259 The order of nodes in this list should correspond to
4260 the :ref:`connectivity convention <connectivity_page>`.
4266 return self.editor.AddFace(IDsOfNodes)
4268 def AddPolygonalFace(self, IdsOfNodes):
4270 Add a polygonal face defined by a list of node IDs
4273 IdsOfNodes: the list of node IDs for creation of the element.
4279 return self.editor.AddPolygonalFace(IdsOfNodes)
4281 def AddQuadPolygonalFace(self, IdsOfNodes):
4283 Add a quadratic polygonal face defined by a list of node IDs
4286 IdsOfNodes: the list of node IDs for creation of the element;
4287 corner nodes follow first.
4293 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4295 def AddVolume(self, IDsOfNodes):
4297 Create both simple and quadratic volume (this is determined
4298 by the number of given nodes).
4301 IDsOfNodes: list of node IDs for creation of the element.
4302 The order of nodes in this list should correspond to
4303 the :ref:`connectivity convention <connectivity_page>`.
4306 ID of the new volumic element
4309 return self.editor.AddVolume(IDsOfNodes)
4311 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4313 Create a volume of many faces, giving nodes for each face.
4316 IdsOfNodes: list of node IDs for volume creation, face by face.
4317 Quantities: list of integer values, Quantities[i]
4318 gives the quantity of nodes in face number i.
4321 ID of the new volumic element
4324 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4326 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4328 Create a volume of many faces, giving the IDs of the existing faces.
4331 The created volume will refer only to the nodes
4332 of the given faces, not to the faces themselves.
4335 IdsOfFaces: the list of face IDs for volume creation.
4338 ID of the new volumic element
4341 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4344 def SetNodeOnVertex(self, NodeID, Vertex):
4346 Bind a node to a vertex
4350 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4353 True if succeed else raises an exception
4356 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4357 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4361 self.editor.SetNodeOnVertex(NodeID, VertexID)
4362 except SALOME.SALOME_Exception as inst:
4363 raise ValueError(inst.details.text)
4367 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4369 Store the node position on an edge
4373 Edge: an edge (GEOM.GEOM_Object) or edge ID
4374 paramOnEdge: a parameter on the edge where the node is located
4377 True if succeed else raises an exception
4380 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4381 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4385 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4386 except SALOME.SALOME_Exception as inst:
4387 raise ValueError(inst.details.text)
4390 def SetNodeOnFace(self, NodeID, Face, u, v):
4392 Store node position on a face
4396 Face: a face (GEOM.GEOM_Object) or face ID
4397 u: U parameter on the face where the node is located
4398 v: V parameter on the face where the node is located
4401 True if succeed else raises an exception
4404 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4405 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4409 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4410 except SALOME.SALOME_Exception as inst:
4411 raise ValueError(inst.details.text)
4414 def SetNodeInVolume(self, NodeID, Solid):
4416 Bind a node to a solid
4420 Solid: a solid (GEOM.GEOM_Object) or solid ID
4423 True if succeed else raises an exception
4426 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4427 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4431 self.editor.SetNodeInVolume(NodeID, SolidID)
4432 except SALOME.SALOME_Exception as inst:
4433 raise ValueError(inst.details.text)
4436 def SetMeshElementOnShape(self, ElementID, Shape):
4438 Bind an element to a shape
4441 ElementID: an element ID
4442 Shape: a shape (GEOM.GEOM_Object) or shape ID
4445 True if succeed else raises an exception
4448 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4449 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4453 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4454 except SALOME.SALOME_Exception as inst:
4455 raise ValueError(inst.details.text)
4459 def MoveNode(self, NodeID, x, y, z):
4461 Move the node with the given id
4464 NodeID: the id of the node
4465 x: a new X coordinate
4466 y: a new Y coordinate
4467 z: a new Z coordinate
4470 True if succeed else False
4473 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4474 if hasVars: self.mesh.SetParameters(Parameters)
4475 return self.editor.MoveNode(NodeID, x, y, z)
4477 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4479 Find the node closest to a point and moves it to a point location
4482 x: the X coordinate of a point
4483 y: the Y coordinate of a point
4484 z: the Z coordinate of a point
4485 NodeID: if specified (>0), the node with this ID is moved,
4486 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4489 the ID of a moved node
4492 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4493 if hasVars: self.mesh.SetParameters(Parameters)
4494 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4496 def FindNodeClosestTo(self, x, y, z):
4498 Find the node closest to a point
4501 x: the X coordinate of a point
4502 y: the Y coordinate of a point
4503 z: the Z coordinate of a point
4509 return self.editor.FindNodeClosestTo(x, y, z)
4511 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4513 Find the elements where a point lays IN or ON
4516 x,y,z (float): coordinates of the point
4517 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4518 means elements of any type excluding nodes, discrete and 0D elements.
4519 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4522 list of IDs of found elements
4525 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4527 return self.editor.FindElementsByPoint(x, y, z, elementType)
4529 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4531 Project a point to a mesh object.
4532 Return ID of an element of given type where the given point is projected
4533 and coordinates of the projection point.
4534 In the case if nothing found, return -1 and []
4536 if isinstance( meshObject, Mesh ):
4537 meshObject = meshObject.GetMesh()
4539 meshObject = self.GetMesh()
4540 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4542 def GetPointState(self, x, y, z):
4544 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4545 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4546 UNKNOWN state means that either mesh is wrong or the analysis fails.
4549 return self.editor.GetPointState(x, y, z)
4551 def IsManifold(self):
4553 Check if a 2D mesh is manifold
4556 return self.editor.IsManifold()
4558 def IsCoherentOrientation2D(self):
4560 Check if orientation of 2D elements is coherent
4563 return self.editor.IsCoherentOrientation2D()
4565 def Get1DBranches( self, edges, startNode = 0 ):
4567 Partition given 1D elements into groups of contiguous edges.
4568 A node where number of meeting edges != 2 is a group end.
4569 An optional startNode is used to orient groups it belongs to.
4572 A list of edge groups and a list of corresponding node groups,
4573 where the group is a list of IDs of edges or nodes, like follows
4574 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4575 If a group is closed, the first and last nodes of the group are same.
4577 if isinstance( edges, Mesh ):
4578 edges = edges.GetMesh()
4579 unRegister = genObjUnRegister()
4580 if isinstance( edges, list ):
4581 edges = self.GetIDSource( edges, SMESH.EDGE )
4582 unRegister.set( edges )
4583 return self.editor.Get1DBranches( edges, startNode )
4585 def FindSharpEdges( self, angle, addExisting=False ):
4587 Return sharp edges of faces and non-manifold ones.
4588 Optionally add existing edges.
4591 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4592 addExisting: to return existing edges (1D elements) as well
4595 list of FaceEdge structures
4597 angle = ParseParameters( angle )[0]
4598 return self.editor.FindSharpEdges( angle, addExisting )
4600 def MeshToPassThroughAPoint(self, x, y, z):
4602 Find the node closest to a point and moves it to a point location
4605 x: the X coordinate of a point
4606 y: the Y coordinate of a point
4607 z: the Z coordinate of a point
4610 the ID of a moved node
4613 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4615 def InverseDiag(self, NodeID1, NodeID2):
4617 Replace two neighbour triangles sharing Node1-Node2 link
4618 with the triangles built on the same 4 nodes but having other common link.
4621 NodeID1: the ID of the first node
4622 NodeID2: the ID of the second node
4625 False if proper faces were not found
4627 return self.editor.InverseDiag(NodeID1, NodeID2)
4629 def DeleteDiag(self, NodeID1, NodeID2):
4631 Replace two neighbour triangles sharing *Node1-Node2* link
4632 with a quadrangle built on the same 4 nodes.
4635 NodeID1: ID of the first node
4636 NodeID2: ID of the second node
4639 False if proper faces were not found
4642 This operation can create gaps in numeration of elements.
4643 Call :meth:`RenumberElements` to remove the gaps.
4646 return self.editor.DeleteDiag(NodeID1, NodeID2)
4648 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4650 Replace each triangle bound by Node1-Node2 segment with
4651 two triangles by connecting a node made on the link with a node
4652 opposite to the link.
4655 Node1: ID of the first node
4656 Node2: ID of the second node
4657 position: location [0,1] of the new node on the segment
4659 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4661 def AddNodeOnFace(self, face, x, y, z):
4663 Split a face into triangles by adding a new node onto the face
4664 and connecting the new node with face nodes
4667 face: ID of the face
4668 x,y,z: coordinates of the new node
4670 return self.editor.AddNodeOnFace(face, x, y, z)
4672 def Reorient(self, IDsOfElements=None):
4674 Reorient elements by ids
4677 IDsOfElements: if undefined reorients all mesh elements
4680 True if succeed else False
4683 if IDsOfElements == None:
4684 IDsOfElements = self.GetElementsId()
4685 return self.editor.Reorient(IDsOfElements)
4687 def ReorientObject(self, theObject):
4689 Reorient all elements of the object
4692 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4695 True if succeed else False
4698 if ( isinstance( theObject, Mesh )):
4699 theObject = theObject.GetMesh()
4700 return self.editor.ReorientObject(theObject)
4702 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4704 Reorient faces contained in *the2DObject*.
4707 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4708 theDirection: a desired direction of normal of *theFace*.
4709 It can be either a GEOM vector or a list of coordinates [x,y,z].
4710 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4711 compared with theDirection. It can be either ID of face or a point
4712 by which the face will be found. The point can be given as either
4713 a GEOM vertex or a list of point coordinates.
4716 number of reoriented faces
4719 unRegister = genObjUnRegister()
4721 if isinstance( the2DObject, Mesh ):
4722 the2DObject = the2DObject.GetMesh()
4723 if isinstance( the2DObject, list ):
4724 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4725 unRegister.set( the2DObject )
4726 # check theDirection
4727 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4728 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4729 if isinstance( theDirection, list ):
4730 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4731 # prepare theFace and thePoint
4732 theFace = theFaceOrPoint
4733 thePoint = PointStruct(0,0,0)
4734 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4735 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4737 if isinstance( theFaceOrPoint, list ):
4738 thePoint = PointStruct( *theFaceOrPoint )
4740 if isinstance( theFaceOrPoint, PointStruct ):
4741 thePoint = theFaceOrPoint
4743 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4745 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4747 Reorient faces contained in a list of *objectFaces*
4748 equally to faces contained in a list of *referenceFaces*.
4751 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4752 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.
4755 number of reoriented faces.
4757 if not isinstance( objectFaces, list ):
4758 objectFaces = [ objectFaces ]
4759 for i,obj2D in enumerate( objectFaces ):
4760 if isinstance( obj2D, Mesh ):
4761 objectFaces[i] = obj2D.GetMesh()
4762 if not isinstance( referenceFaces, list ):
4763 referenceFaces = [ referenceFaces ]
4765 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4768 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4770 Reorient faces according to adjacent volumes.
4773 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4774 either IDs of faces or face groups.
4775 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4776 theOutsideNormal: to orient faces to have their normals
4777 pointing either *outside* or *inside* the adjacent volumes.
4780 number of reoriented faces.
4783 unRegister = genObjUnRegister()
4785 if not isinstance( the2DObject, list ):
4786 the2DObject = [ the2DObject ]
4787 elif the2DObject and isinstance( the2DObject[0], int ):
4788 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4789 unRegister.set( the2DObject )
4790 the2DObject = [ the2DObject ]
4791 for i,obj2D in enumerate( the2DObject ):
4792 if isinstance( obj2D, Mesh ):
4793 the2DObject[i] = obj2D.GetMesh()
4794 if isinstance( obj2D, list ):
4795 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4796 unRegister.set( the2DObject[i] )
4798 if isinstance( the3DObject, Mesh ):
4799 the3DObject = the3DObject.GetMesh()
4800 if isinstance( the3DObject, list ):
4801 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4802 unRegister.set( the3DObject )
4803 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4805 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4807 Fuse the neighbouring triangles into quadrangles.
4810 IDsOfElements: The triangles to be fused.
4811 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4812 applied to possible quadrangles to choose a neighbour to fuse with.
4813 Note that not all items of :class:`SMESH.FunctorType` corresponds
4814 to numerical functors.
4815 MaxAngle: is the maximum angle between element normals at which the fusion
4816 is still performed; theMaxAngle is measured in radians.
4817 Also it could be a name of variable which defines angle in degrees.
4820 True in case of success, False otherwise.
4823 This operation can create gaps in numeration of elements.
4824 Call :meth:`RenumberElements` to remove the gaps.
4827 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4828 self.mesh.SetParameters(Parameters)
4829 if not IDsOfElements:
4830 IDsOfElements = self.GetElementsId()
4831 Functor = self.smeshpyD.GetFunctor(theCriterion)
4832 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4834 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4836 Fuse the neighbouring triangles of the object into quadrangles
4839 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4840 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4841 applied to possible quadrangles to choose a neighbour to fuse with.
4842 Note that not all items of :class:`SMESH.FunctorType` corresponds
4843 to numerical functors.
4844 MaxAngle: a max angle between element normals at which the fusion
4845 is still performed; theMaxAngle is measured in radians.
4848 True in case of success, False otherwise.
4851 This operation can create gaps in numeration of elements.
4852 Call :meth:`RenumberElements` to remove the gaps.
4855 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4856 self.mesh.SetParameters(Parameters)
4857 if isinstance( theObject, Mesh ):
4858 theObject = theObject.GetMesh()
4859 Functor = self.smeshpyD.GetFunctor(theCriterion)
4860 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4862 def QuadToTri (self, IDsOfElements, theCriterion = None):
4864 Split quadrangles into triangles.
4867 IDsOfElements: the faces to be splitted.
4868 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4869 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4870 value, then quadrangles will be split by the smallest diagonal.
4871 Note that not all items of :class:`SMESH.FunctorType` corresponds
4872 to numerical functors.
4875 True in case of success, False otherwise.
4878 This operation can create gaps in numeration of elements.
4879 Call :meth:`RenumberElements` to remove the gaps.
4881 if IDsOfElements == []:
4882 IDsOfElements = self.GetElementsId()
4883 if theCriterion is None:
4884 theCriterion = FT_MaxElementLength2D
4885 Functor = self.smeshpyD.GetFunctor(theCriterion)
4886 return self.editor.QuadToTri(IDsOfElements, Functor)
4888 def QuadToTriObject (self, theObject, theCriterion = None):
4890 Split quadrangles into triangles.
4893 theObject: the object from which the list of elements is taken,
4894 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4895 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4896 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4897 value, then quadrangles will be split by the smallest diagonal.
4898 Note that not all items of :class:`SMESH.FunctorType` corresponds
4899 to numerical functors.
4902 True in case of success, False otherwise.
4905 This operation can create gaps in numeration of elements.
4906 Call :meth:`RenumberElements` to remove the gaps.
4908 if ( isinstance( theObject, Mesh )):
4909 theObject = theObject.GetMesh()
4910 if theCriterion is None:
4911 theCriterion = FT_MaxElementLength2D
4912 Functor = self.smeshpyD.GetFunctor(theCriterion)
4913 return self.editor.QuadToTriObject(theObject, Functor)
4915 def QuadTo4Tri (self, theElements=[]):
4917 Split each of given quadrangles into 4 triangles. A node is added at the center of
4921 theElements: the faces to be splitted. This can be either
4922 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4923 or a list of face IDs. By default all quadrangles are split
4926 This operation can create gaps in numeration of elements.
4927 Call :meth:`RenumberElements` to remove the gaps.
4929 unRegister = genObjUnRegister()
4930 if isinstance( theElements, Mesh ):
4931 theElements = theElements.mesh
4932 elif not theElements:
4933 theElements = self.mesh
4934 elif isinstance( theElements, list ):
4935 theElements = self.GetIDSource( theElements, SMESH.FACE )
4936 unRegister.set( theElements )
4937 return self.editor.QuadTo4Tri( theElements )
4939 def SplitQuad (self, IDsOfElements, Diag13):
4941 Split quadrangles into triangles.
4944 IDsOfElements: the faces to be splitted
4945 Diag13 (boolean): is used to choose a diagonal for splitting.
4948 True in case of success, False otherwise.
4951 This operation can create gaps in numeration of elements.
4952 Call :meth:`RenumberElements` to remove the gaps.
4954 if IDsOfElements == []:
4955 IDsOfElements = self.GetElementsId()
4956 return self.editor.SplitQuad(IDsOfElements, Diag13)
4958 def SplitQuadObject (self, theObject, Diag13):
4960 Split quadrangles into triangles.
4963 theObject: the object from which the list of elements is taken,
4964 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4965 Diag13 (boolean): is used to choose a diagonal for splitting.
4968 True in case of success, False otherwise.
4971 This operation can create gaps in numeration of elements.
4972 Call :meth:`RenumberElements` to remove the gaps.
4974 if ( isinstance( theObject, Mesh )):
4975 theObject = theObject.GetMesh()
4976 return self.editor.SplitQuadObject(theObject, Diag13)
4978 def BestSplit (self, IDOfQuad, theCriterion):
4980 Find a better splitting of the given quadrangle.
4983 IDOfQuad: the ID of the quadrangle to be splitted.
4984 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4985 choose a diagonal for splitting.
4986 Note that not all items of :class:`SMESH.FunctorType` corresponds
4987 to numerical functors.
4990 * 1 if 1-3 diagonal is better,
4991 * 2 if 2-4 diagonal is better,
4992 * 0 if error occurs.
4995 This operation can create gaps in numeration of elements.
4996 Call :meth:`RenumberElements` to remove the gaps.
4998 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5000 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5002 Split volumic elements into tetrahedrons
5005 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5006 method: flags passing splitting method:
5007 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5008 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5011 This operation can create gaps in numeration of elements.
5012 Call :meth:`RenumberElements` to remove the gaps.
5014 unRegister = genObjUnRegister()
5015 if isinstance( elems, Mesh ):
5016 elems = elems.GetMesh()
5017 if ( isinstance( elems, list )):
5018 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5019 unRegister.set( elems )
5020 self.editor.SplitVolumesIntoTetra(elems, method)
5023 def SplitBiQuadraticIntoLinear(self, elems=None):
5025 Split bi-quadratic elements into linear ones without creation of additional nodes:
5027 - bi-quadratic triangle will be split into 3 linear quadrangles;
5028 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5029 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5031 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5032 will be split in order to keep the mesh conformal.
5035 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5036 if None (default), all bi-quadratic elements will be split
5039 This operation can create gaps in numeration of elements.
5040 Call :meth:`RenumberElements` to remove the gaps.
5042 unRegister = genObjUnRegister()
5043 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5044 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5045 unRegister.set( elems )
5047 elems = [ self.GetMesh() ]
5048 if isinstance( elems, Mesh ):
5049 elems = [ elems.GetMesh() ]
5050 if not isinstance( elems, list ):
5052 self.editor.SplitBiQuadraticIntoLinear( elems )
5054 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5055 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5057 Split hexahedra into prisms
5060 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5061 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5062 gives a normal vector defining facets to split into triangles.
5063 *startHexPoint* can be either a triple of coordinates or a vertex.
5064 facetNormal: a normal to a facet to split into triangles of a
5065 hexahedron found by *startHexPoint*.
5066 *facetNormal* can be either a triple of coordinates or an edge.
5067 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5068 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5069 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5070 to *startHexPoint* are split, else *startHexPoint*
5071 is used to find the facet to split in all domains present in *elems*.
5074 This operation can create gaps in numeration of elements.
5075 Call :meth:`RenumberElements` to remove the gaps.
5078 unRegister = genObjUnRegister()
5079 if isinstance( elems, Mesh ):
5080 elems = elems.GetMesh()
5081 if ( isinstance( elems, list )):
5082 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5083 unRegister.set( elems )
5086 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5087 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5088 elif isinstance( startHexPoint, list ):
5089 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5092 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5093 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5094 elif isinstance( facetNormal, list ):
5095 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5098 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5100 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5102 def SplitQuadsNearTriangularFacets(self):
5104 Split quadrangle faces near triangular facets of volumes
5107 This operation can create gaps in numeration of elements.
5108 Call :meth:`RenumberElements` to remove the gaps.
5110 faces_array = self.GetElementsByType(SMESH.FACE)
5111 for face_id in faces_array:
5112 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5113 quad_nodes = self.mesh.GetElemNodes(face_id)
5114 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5115 isVolumeFound = False
5116 for node1_elem in node1_elems:
5117 if not isVolumeFound:
5118 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5119 nb_nodes = self.GetElemNbNodes(node1_elem)
5120 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5121 volume_elem = node1_elem
5122 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5123 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5124 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5125 isVolumeFound = True
5126 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5127 self.SplitQuad([face_id], False) # diagonal 2-4
5128 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5129 isVolumeFound = True
5130 self.SplitQuad([face_id], True) # diagonal 1-3
5131 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5132 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5133 isVolumeFound = True
5134 self.SplitQuad([face_id], True) # diagonal 1-3
5136 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5138 Split hexahedrons into tetrahedrons.
5140 This operation uses :doc:`pattern_mapping` functionality for splitting.
5143 theObject: the object from which the list of hexahedrons is taken;
5144 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5145 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5146 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5147 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5148 key-point will be mapped into *theNode001*-th node of each volume.
5149 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5152 True in case of success, False otherwise.
5155 This operation can create gaps in numeration of elements.
5156 Call :meth:`RenumberElements` to remove the gaps.
5164 # (0,0,1) 4.---------.7 * |
5171 # (0,0,0) 0.---------.3
5172 pattern_tetra = "!!! Nb of points: \n 8 \n\
5182 !!! Indices of points of 6 tetras: \n\
5190 pattern = self.smeshpyD.GetPattern()
5191 isDone = pattern.LoadFromFile(pattern_tetra)
5193 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5196 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5197 isDone = pattern.MakeMesh(self.mesh, False, False)
5198 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5200 # split quafrangle faces near triangular facets of volumes
5201 self.SplitQuadsNearTriangularFacets()
5205 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5207 Split hexahedrons into prisms.
5209 Uses the :doc:`pattern_mapping` functionality for splitting.
5212 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5213 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5214 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5215 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5216 will be mapped into the *theNode001* -th node of each volume.
5217 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5220 True in case of success, False otherwise.
5223 This operation can create gaps in numeration of elements.
5224 Call :meth:`RenumberElements` to remove the gaps.
5226 # Pattern: 5.---------.6
5231 # (0,0,1) 4.---------.7 |
5238 # (0,0,0) 0.---------.3
5239 pattern_prism = "!!! Nb of points: \n 8 \n\
5249 !!! Indices of points of 2 prisms: \n\
5253 pattern = self.smeshpyD.GetPattern()
5254 isDone = pattern.LoadFromFile(pattern_prism)
5256 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5259 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5260 isDone = pattern.MakeMesh(self.mesh, False, False)
5261 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5263 # Split quafrangle faces near triangular facets of volumes
5264 self.SplitQuadsNearTriangularFacets()
5268 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5269 MaxNbOfIterations, MaxAspectRatio, Method):
5274 IDsOfElements: the list if ids of elements to smooth
5275 IDsOfFixedNodes: the list of ids of fixed nodes.
5276 Note that nodes built on edges and boundary nodes are always fixed.
5277 MaxNbOfIterations: the maximum number of iterations
5278 MaxAspectRatio: varies in range [1.0, inf]
5279 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5280 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5283 True in case of success, False otherwise.
5286 if IDsOfElements == []:
5287 IDsOfElements = self.GetElementsId()
5288 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5289 self.mesh.SetParameters(Parameters)
5290 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5291 MaxNbOfIterations, MaxAspectRatio, Method)
5293 def SmoothObject(self, theObject, IDsOfFixedNodes,
5294 MaxNbOfIterations, MaxAspectRatio, Method):
5296 Smooth elements which belong to the given object
5299 theObject: the object to smooth
5300 IDsOfFixedNodes: the list of ids of fixed nodes.
5301 Note that nodes built on edges and boundary nodes are always fixed.
5302 MaxNbOfIterations: the maximum number of iterations
5303 MaxAspectRatio: varies in range [1.0, inf]
5304 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5305 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5308 True in case of success, False otherwise.
5311 if ( isinstance( theObject, Mesh )):
5312 theObject = theObject.GetMesh()
5313 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5314 MaxNbOfIterations, MaxAspectRatio, Method)
5316 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5317 MaxNbOfIterations, MaxAspectRatio, Method):
5319 Parametrically smooth the given elements
5322 IDsOfElements: the list if ids of elements to smooth
5323 IDsOfFixedNodes: the list of ids of fixed nodes.
5324 Note that nodes built on edges and boundary nodes are always fixed.
5325 MaxNbOfIterations: the maximum number of iterations
5326 MaxAspectRatio: varies in range [1.0, inf]
5327 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5328 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5331 True in case of success, False otherwise.
5334 if IDsOfElements == []:
5335 IDsOfElements = self.GetElementsId()
5336 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5337 self.mesh.SetParameters(Parameters)
5338 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5339 MaxNbOfIterations, MaxAspectRatio, Method)
5341 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5342 MaxNbOfIterations, MaxAspectRatio, Method):
5344 Parametrically smooth the elements which belong to the given object
5347 theObject: the object to smooth
5348 IDsOfFixedNodes: the list of ids of fixed nodes.
5349 Note that nodes built on edges and boundary nodes are always fixed.
5350 MaxNbOfIterations: the maximum number of iterations
5351 MaxAspectRatio: varies in range [1.0, inf]
5352 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5353 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5356 True in case of success, False otherwise.
5359 if ( isinstance( theObject, Mesh )):
5360 theObject = theObject.GetMesh()
5361 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5362 MaxNbOfIterations, MaxAspectRatio, Method)
5364 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5366 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5367 them with quadratic with the same id.
5370 theForce3d: method of new node creation:
5372 * False - the medium node lies at the geometrical entity from which the mesh element is built
5373 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5374 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5375 theToBiQuad: If True, converts the mesh to bi-quadratic
5378 :class:`SMESH.ComputeError` which can hold a warning
5381 If *theSubMesh* is provided, the mesh can become non-conformal
5384 This operation can create gaps in numeration of nodes or elements.
5385 Call :meth:`RenumberElements` to remove the gaps.
5388 if isinstance( theSubMesh, Mesh ):
5389 theSubMesh = theSubMesh.mesh
5391 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5394 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5396 self.editor.ConvertToQuadratic(theForce3d)
5397 error = self.editor.GetLastError()
5398 if error and error.comment:
5399 print(error.comment)
5402 def ConvertFromQuadratic(self, theSubMesh=None):
5404 Convert the mesh from quadratic to ordinary,
5405 deletes old quadratic elements,
5406 replacing them with ordinary mesh elements with the same id.
5409 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5412 If *theSubMesh* is provided, the mesh can become non-conformal
5415 This operation can create gaps in numeration of nodes or elements.
5416 Call :meth:`RenumberElements` to remove the gaps.
5420 self.editor.ConvertFromQuadraticObject(theSubMesh)
5422 return self.editor.ConvertFromQuadratic()
5424 def Make2DMeshFrom3D(self):
5426 Create 2D mesh as skin on boundary faces of a 3D mesh
5429 True if operation has been completed successfully, False otherwise
5432 return self.editor.Make2DMeshFrom3D()
5434 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5435 toCopyElements=False, toCopyExistingBondary=False):
5437 Create missing boundary elements
5440 elements: elements whose boundary is to be checked:
5441 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5442 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5443 dimension: defines type of boundary elements to create, either of
5444 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5445 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5446 groupName: a name of group to store created boundary elements in,
5447 "" means not to create the group
5448 meshName: a name of new mesh to store created boundary elements in,
5449 "" means not to create the new mesh
5450 toCopyElements: if True, the checked elements will be copied into
5451 the new mesh else only boundary elements will be copied into the new mesh
5452 toCopyExistingBondary: if True, not only new but also pre-existing
5453 boundary elements will be copied into the new mesh
5456 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5459 unRegister = genObjUnRegister()
5460 if isinstance( elements, Mesh ):
5461 elements = elements.GetMesh()
5462 if ( isinstance( elements, list )):
5463 elemType = SMESH.ALL
5464 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5465 elements = self.editor.MakeIDSource(elements, elemType)
5466 unRegister.set( elements )
5467 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5468 toCopyElements,toCopyExistingBondary)
5469 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5472 def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
5474 Create boundary elements around the whole mesh or groups of elements
5477 groupName: a name of group to store all boundary elements in,
5478 "" means not to create the group
5479 meshName: a name of a new mesh, which is a copy of the initial
5480 mesh + created boundary elements; "" means not to create the new mesh
5481 toCopyAll: if True, the whole initial mesh will be copied into
5482 the new mesh else only boundary elements will be copied into the new mesh
5483 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5486 tuple( long, mesh, group )
5487 - long - number of added boundary elements
5488 - mesh - the :class:`Mesh` where elements were added to
5489 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5491 dimension=SMESH.BND_2DFROM3D
5492 toCreateAllElements = True # create all boundary elements in the mesh
5493 nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
5494 toCopyAll,toCreateAllElements,groups)
5495 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5496 return nb, mesh, group
5498 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5499 toCopyAll=False, groups=[]):
5501 Create missing boundary elements around either the whole mesh or
5505 dimension: defines type of boundary elements to create, either of
5506 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5507 groupName: a name of group to store all boundary elements in,
5508 "" means not to create the group
5509 meshName: a name of a new mesh, which is a copy of the initial
5510 mesh + created boundary elements; "" means not to create the new mesh
5511 toCopyAll: if True, the whole initial mesh will be copied into
5512 the new mesh else only boundary elements will be copied into the new mesh
5513 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5516 tuple( long, mesh, group )
5517 - long - number of added boundary elements
5518 - mesh - the :class:`Mesh` where elements were added to
5519 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5521 toCreateAllElements = False # create only elements in the boundary of the solid
5522 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5523 toCopyAll,toCreateAllElements,groups)
5524 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5525 return nb, mesh, group
5527 def RenumberNodes(self):
5529 Renumber mesh nodes to remove unused node IDs
5531 self.editor.RenumberNodes()
5533 def RenumberElements(self):
5535 Renumber mesh elements to remove unused element IDs
5537 self.editor.RenumberElements()
5539 def _getIdSourceList(self, arg, idType, unRegister):
5541 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5543 if arg and isinstance( arg, list ):
5544 if isinstance( arg[0], int ):
5545 arg = self.GetIDSource( arg, idType )
5546 unRegister.set( arg )
5547 elif isinstance( arg[0], Mesh ):
5548 arg[0] = arg[0].GetMesh()
5549 elif isinstance( arg, Mesh ):
5551 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5555 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5556 MakeGroups=False, TotalAngle=False):
5558 Generate new elements by rotation of the given elements and nodes around the axis
5561 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5562 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5563 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5564 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5565 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5566 which defines angle in degrees
5567 NbOfSteps: the number of steps
5568 Tolerance: tolerance
5569 MakeGroups: forces the generation of new groups from existing ones
5570 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5571 of all steps, else - size of each step
5574 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5577 unRegister = genObjUnRegister()
5578 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5579 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5580 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5582 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5583 Axis = self.smeshpyD.GetAxisStruct( Axis )
5584 if isinstance( Axis, list ):
5585 Axis = SMESH.AxisStruct( *Axis )
5587 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5588 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5589 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5590 self.mesh.SetParameters(Parameters)
5591 if TotalAngle and NbOfSteps:
5592 AngleInRadians /= NbOfSteps
5593 return self.editor.RotationSweepObjects( nodes, edges, faces,
5594 Axis, AngleInRadians,
5595 NbOfSteps, Tolerance, MakeGroups)
5597 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5598 MakeGroups=False, TotalAngle=False):
5600 Generate new elements by rotation of the elements around the axis
5603 IDsOfElements: the list of ids of elements to sweep
5604 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5605 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5606 NbOfSteps: the number of steps
5607 Tolerance: tolerance
5608 MakeGroups: forces the generation of new groups from existing ones
5609 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5610 of all steps, else - size of each step
5613 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5616 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5617 AngleInRadians, NbOfSteps, Tolerance,
5618 MakeGroups, TotalAngle)
5620 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5621 MakeGroups=False, TotalAngle=False):
5623 Generate new elements by rotation of the elements of object around the axis
5624 theObject object which elements should be sweeped.
5625 It can be a mesh, a sub mesh or a group.
5628 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5629 AngleInRadians: the angle of Rotation
5630 NbOfSteps: number of steps
5631 Tolerance: tolerance
5632 MakeGroups: forces the generation of new groups from existing ones
5633 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5634 of all steps, else - size of each step
5637 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5640 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5641 AngleInRadians, NbOfSteps, Tolerance,
5642 MakeGroups, TotalAngle )
5644 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5645 MakeGroups=False, TotalAngle=False):
5647 Generate new elements by rotation of the elements of object around the axis
5648 theObject object which elements should be sweeped.
5649 It can be a mesh, a sub mesh or a group.
5652 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5653 AngleInRadians: the angle of Rotation
5654 NbOfSteps: number of steps
5655 Tolerance: tolerance
5656 MakeGroups: forces the generation of new groups from existing ones
5657 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5658 of all steps, else - size of each step
5661 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5662 empty list otherwise
5665 return self.RotationSweepObjects([],theObject,[], Axis,
5666 AngleInRadians, NbOfSteps, Tolerance,
5667 MakeGroups, TotalAngle)
5669 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5670 MakeGroups=False, TotalAngle=False):
5672 Generate new elements by rotation of the elements of object around the axis
5673 theObject object which elements should be sweeped.
5674 It can be a mesh, a sub mesh or a group.
5677 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5678 AngleInRadians: the angle of Rotation
5679 NbOfSteps: number of steps
5680 Tolerance: tolerance
5681 MakeGroups: forces the generation of new groups from existing ones
5682 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5683 of all steps, else - size of each step
5686 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5689 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5690 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5692 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5693 scaleFactors=[], linearVariation=False, basePoint=[],
5694 angles=[], anglesVariation=False):
5696 Generate new elements by extrusion of the given elements and nodes
5699 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5700 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5701 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5702 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5703 the direction and value of extrusion for one step (the total extrusion
5704 length will be NbOfSteps * ||StepVector||)
5705 NbOfSteps: the number of steps
5706 MakeGroups: forces the generation of new groups from existing ones
5707 scaleFactors: optional scale factors to apply during extrusion
5708 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5709 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5710 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5711 nodes and elements being extruded is used as the scaling center.
5714 - a list of tree components of the point or
5717 angles: list of angles in radians. Nodes at each extrusion step are rotated
5718 around *basePoint*, additionally to previous steps.
5719 anglesVariation: forces the computation of rotation angles as linear
5720 variation of the given *angles* along path steps
5722 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5724 Example: :ref:`tui_extrusion`
5726 unRegister = genObjUnRegister()
5727 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5728 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5729 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5731 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5732 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5733 if isinstance( StepVector, list ):
5734 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5736 if isinstance( basePoint, int):
5737 xyz = self.GetNodeXYZ( basePoint )
5739 raise RuntimeError("Invalid node ID: %s" % basePoint)
5741 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5742 basePoint = self.geompyD.PointCoordinates( basePoint )
5744 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5745 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5746 angles,angleParameters,hasVars = ParseAngles(angles)
5747 Parameters = StepVector.PS.parameters + var_separator + \
5748 Parameters + var_separator + \
5749 scaleParameters + var_separator + angleParameters
5750 self.mesh.SetParameters(Parameters)
5752 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5753 StepVector, NbOfSteps, MakeGroups,
5754 scaleFactors, linearVariation, basePoint,
5755 angles, anglesVariation )
5758 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5760 Generate new elements by extrusion of the elements with given ids
5763 IDsOfElements: the list of ids of elements or nodes for extrusion
5764 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5765 the direction and value of extrusion for one step (the total extrusion
5766 length will be NbOfSteps * ||StepVector||)
5767 NbOfSteps: the number of steps
5768 MakeGroups: forces the generation of new groups from existing ones
5769 IsNodes: is True if elements with given ids are nodes
5772 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5774 Example: :ref:`tui_extrusion`
5777 if IsNodes: n = IDsOfElements
5778 else : e,f, = IDsOfElements,IDsOfElements
5779 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5781 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5782 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5784 Generate new elements by extrusion along the normal to a discretized surface or wire
5787 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5788 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5789 StepSize: length of one extrusion step (the total extrusion
5790 length will be *NbOfSteps* *StepSize*).
5791 NbOfSteps: number of extrusion steps.
5792 ByAverageNormal: if True each node is translated by *StepSize*
5793 along the average of the normal vectors to the faces sharing the node;
5794 else each node is translated along the same average normal till
5795 intersection with the plane got by translation of the face sharing
5796 the node along its own normal by *StepSize*.
5797 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5798 for every node of *Elements*.
5799 MakeGroups: forces generation of new groups from existing ones.
5800 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5801 is not yet implemented. This parameter is used if *Elements* contains
5802 both faces and edges, i.e. *Elements* is a Mesh.
5805 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5806 empty list otherwise.
5807 Example: :ref:`tui_extrusion`
5810 unRegister = genObjUnRegister()
5811 if isinstance( Elements, Mesh ):
5812 Elements = [ Elements.GetMesh() ]
5813 if isinstance( Elements, list ):
5815 raise RuntimeError("Elements empty!")
5816 if isinstance( Elements[0], Mesh ):
5817 Elements = [ Elements[0].GetMesh() ]
5818 if isinstance( Elements[0], int ):
5819 Elements = self.GetIDSource( Elements, SMESH.ALL )
5820 unRegister.set( Elements )
5821 if not isinstance( Elements, list ):
5822 Elements = [ Elements ]
5823 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5824 self.mesh.SetParameters(Parameters)
5825 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5826 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5828 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5830 Generate new elements by extrusion of the elements or nodes which belong to the object
5833 theObject: the object whose elements or nodes should be processed.
5834 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5835 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5836 the direction and value of extrusion for one step (the total extrusion
5837 length will be NbOfSteps * ||StepVector||)
5838 NbOfSteps: the number of steps
5839 MakeGroups: forces the generation of new groups from existing ones
5840 IsNodes: is True if elements to extrude are nodes
5843 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5844 Example: :ref:`tui_extrusion`
5848 if IsNodes: n = theObject
5849 else : e,f, = theObject,theObject
5850 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5852 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5854 Generate new elements by extrusion of edges which belong to the object
5857 theObject: object whose 1D elements should be processed.
5858 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5859 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5860 the direction and value of extrusion for one step (the total extrusion
5861 length will be NbOfSteps * ||StepVector||)
5862 NbOfSteps: the number of steps
5863 MakeGroups: to generate new groups from existing ones
5866 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5867 Example: :ref:`tui_extrusion`
5870 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5872 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5874 Generate new elements by extrusion of faces which belong to the object
5877 theObject: object whose 2D elements should be processed.
5878 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5879 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5880 the direction and value of extrusion for one step (the total extrusion
5881 length will be NbOfSteps * ||StepVector||)
5882 NbOfSteps: the number of steps
5883 MakeGroups: forces the generation of new groups from existing ones
5886 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5887 Example: :ref:`tui_extrusion`
5890 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5892 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5893 ExtrFlags, SewTolerance, MakeGroups=False):
5895 Generate new elements by extrusion of the elements with given ids
5898 IDsOfElements: is ids of elements
5899 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5900 the direction and value of extrusion for one step (the total extrusion
5901 length will be NbOfSteps * ||StepVector||)
5902 NbOfSteps: the number of steps
5903 ExtrFlags: sets flags for extrusion
5904 SewTolerance: uses for comparing locations of nodes if flag
5905 EXTRUSION_FLAG_SEW is set
5906 MakeGroups: forces the generation of new groups from existing ones
5909 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5912 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5913 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5914 if isinstance( StepVector, list ):
5915 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5916 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5917 ExtrFlags, SewTolerance, MakeGroups)
5919 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5920 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5921 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5922 ScaleFactors=[], ScalesVariation=False):
5924 Generate new elements by extrusion of the given elements and nodes along the path.
5925 The path of extrusion must be a meshed edge.
5928 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5929 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5930 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5931 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5932 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
5933 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5934 HasAngles: not used obsolete
5935 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5936 around *basePoint*, additionally to previous steps.
5937 LinearVariation: forces the computation of rotation angles as linear
5938 variation of the given Angles along path steps
5939 HasRefPoint: allows using the reference point
5940 RefPoint: optional scaling and rotation center (mass center of the extruded
5941 elements by default). The User can specify any point as the Reference Point.
5942 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5943 MakeGroups: forces the generation of new groups from existing ones
5944 ScaleFactors: optional scale factors to apply during extrusion
5945 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5946 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5949 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5950 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5951 Example: :ref:`tui_extrusion_along_path`
5954 unRegister = genObjUnRegister()
5955 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5956 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5957 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5959 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5960 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5961 if isinstance( RefPoint, list ):
5962 if not RefPoint: RefPoint = [0,0,0]
5963 RefPoint = SMESH.PointStruct( *RefPoint )
5964 if isinstance( PathObject, Mesh ):
5965 PathObject = PathObject.GetMesh()
5966 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5967 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5968 Parameters = AnglesParameters + var_separator + \
5969 RefPoint.parameters + var_separator + ScalesParameters
5970 self.mesh.SetParameters(Parameters)
5971 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5972 PathObject, PathShape, NodeStart,
5973 HasAngles, Angles, LinearVariation,
5974 HasRefPoint, RefPoint, MakeGroups,
5975 ScaleFactors, ScalesVariation)
5977 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5978 HasAngles=False, Angles=[], LinearVariation=False,
5979 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5980 ElemType=SMESH.FACE):
5982 Generate new elements by extrusion of the given elements.
5983 The path of extrusion must be a meshed edge.
5986 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5987 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5988 NodeStart: the start node from Path. Defines the direction of extrusion
5989 HasAngles: not used obsolete
5990 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5991 around *basePoint*, additionally to previous steps.
5992 LinearVariation: forces the computation of rotation angles as linear
5993 variation of the given Angles along path steps
5994 HasRefPoint: allows using the reference point
5995 RefPoint: the reference point around which the elements are rotated (the mass
5996 center of the elements by default).
5997 The User can specify any point as the Reference Point.
5998 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5999 MakeGroups: forces the generation of new groups from existing ones
6000 ElemType: type of elements for extrusion (if param Base is a mesh)
6003 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6004 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6005 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6007 Example: :ref:`tui_extrusion_along_path`
6011 if ElemType == SMESH.NODE: n = Base
6012 if ElemType == SMESH.EDGE: e = Base
6013 if ElemType == SMESH.FACE: f = Base
6014 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
6015 HasAngles, Angles, LinearVariation,
6016 HasRefPoint, RefPoint, MakeGroups)
6017 if MakeGroups: return gr,er
6020 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
6021 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6022 MakeGroups=False, LinearVariation=False):
6024 Generate new elements by extrusion of the given elements.
6025 The path of extrusion must be a meshed edge.
6028 IDsOfElements: ids of elements
6029 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6030 PathShape: shape (edge) defines the sub-mesh for the path
6031 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6032 HasAngles: not used obsolete
6033 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6034 around *basePoint*, additionally to previous steps.
6035 HasRefPoint: allows using the reference point
6036 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6037 The User can specify any point as the Reference Point.
6038 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6039 MakeGroups: forces the generation of new groups from existing ones
6040 LinearVariation: forces the computation of rotation angles as linear
6041 variation of the given Angles along path steps
6044 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6045 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6046 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6047 Example: :ref:`tui_extrusion_along_path`
6050 if not IDsOfElements:
6051 IDsOfElements = [ self.GetMesh() ]
6052 n,e,f = [],IDsOfElements,IDsOfElements
6053 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6054 NodeStart, HasAngles, Angles,
6056 HasRefPoint, RefPoint, MakeGroups)
6057 if MakeGroups: return gr,er
6060 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6061 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6062 MakeGroups=False, LinearVariation=False):
6064 Generate new elements by extrusion of the elements which belong to the object.
6065 The path of extrusion must be a meshed edge.
6068 theObject: the object whose elements should be processed.
6069 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6070 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6071 PathShape: shape (edge) defines the sub-mesh for the path
6072 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6073 HasAngles: not used obsolete
6074 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6075 around *basePoint*, additionally to previous steps.
6076 HasRefPoint: allows using the reference point
6077 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6078 The User can specify any point as the Reference Point.
6079 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6080 MakeGroups: forces the generation of new groups from existing ones
6081 LinearVariation: forces the computation of rotation angles as linear
6082 variation of the given Angles along path steps
6085 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6086 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6087 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6088 Example: :ref:`tui_extrusion_along_path`
6091 n,e,f = [],theObject,theObject
6092 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6093 HasAngles, Angles, LinearVariation,
6094 HasRefPoint, RefPoint, MakeGroups)
6095 if MakeGroups: return gr,er
6098 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6099 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6100 MakeGroups=False, LinearVariation=False):
6102 Generate new elements by extrusion of mesh segments which belong to the object.
6103 The path of extrusion must be a meshed edge.
6106 theObject: the object whose 1D elements should be processed.
6107 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6108 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6109 PathShape: shape (edge) defines the sub-mesh for the path
6110 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6111 HasAngles: not used obsolete
6112 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6113 around *basePoint*, additionally to previous steps.
6114 HasRefPoint: allows using the reference point
6115 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6116 The User can specify any point as the Reference Point.
6117 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6118 MakeGroups: forces the generation of new groups from existing ones
6119 LinearVariation: forces the computation of rotation angles as linear
6120 variation of the given Angles along path steps
6123 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6124 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6125 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6126 Example: :ref:`tui_extrusion_along_path`
6129 n,e,f = [],theObject,[]
6130 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6131 HasAngles, Angles, LinearVariation,
6132 HasRefPoint, RefPoint, MakeGroups)
6133 if MakeGroups: return gr,er
6136 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6137 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6138 MakeGroups=False, LinearVariation=False):
6140 Generate new elements by extrusion of faces which belong to the object.
6141 The path of extrusion must be a meshed edge.
6144 theObject: the object whose 2D elements should be processed.
6145 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6146 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6147 PathShape: shape (edge) defines the sub-mesh for the path
6148 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6149 HasAngles: not used obsolete
6150 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6151 around *basePoint*, additionally to previous steps.
6152 HasRefPoint: allows using the reference point
6153 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6154 The User can specify any point as the Reference Point.
6155 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6156 MakeGroups: forces the generation of new groups from existing ones
6157 LinearVariation: forces the computation of rotation angles as linear
6158 variation of the given Angles along path steps
6161 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6162 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6163 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6164 Example: :ref:`tui_extrusion_along_path`
6167 n,e,f = [],[],theObject
6168 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6169 HasAngles, Angles, LinearVariation,
6170 HasRefPoint, RefPoint, MakeGroups)
6171 if MakeGroups: return gr,er
6174 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6176 Create a symmetrical copy of mesh elements
6179 IDsOfElements: list of elements ids
6180 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6181 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6182 If the *Mirror* is a geom object this parameter is unnecessary
6183 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6184 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6187 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6190 if IDsOfElements == []:
6191 IDsOfElements = self.GetElementsId()
6192 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6193 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6194 theMirrorType = Mirror._mirrorType
6196 self.mesh.SetParameters(Mirror.parameters)
6197 if Copy and MakeGroups:
6198 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6199 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6202 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6204 Create a new mesh by a symmetrical copy of mesh elements
6207 IDsOfElements: the list of elements ids
6208 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6209 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6210 If the *Mirror* is a geom object this parameter is unnecessary
6211 MakeGroups: to generate new groups from existing ones
6212 NewMeshName: a name of the new mesh to create
6215 instance of class :class:`Mesh`
6218 if IDsOfElements == []:
6219 IDsOfElements = self.GetElementsId()
6220 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6221 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6222 theMirrorType = Mirror._mirrorType
6224 self.mesh.SetParameters(Mirror.parameters)
6225 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6226 MakeGroups, NewMeshName)
6227 return Mesh(self.smeshpyD,self.geompyD,mesh)
6229 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6231 Create a symmetrical copy of the object
6234 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6235 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6236 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6237 If the *Mirror* is a geom object this parameter is unnecessary
6238 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6239 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6242 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6245 if ( isinstance( theObject, Mesh )):
6246 theObject = theObject.GetMesh()
6247 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6248 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6249 theMirrorType = Mirror._mirrorType
6251 self.mesh.SetParameters(Mirror.parameters)
6252 if Copy and MakeGroups:
6253 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6254 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6257 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6259 Create a new mesh by a symmetrical copy of the object
6262 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6263 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6264 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6265 If the *Mirror* is a geom object this parameter is unnecessary
6266 MakeGroups: forces the generation of new groups from existing ones
6267 NewMeshName: the name of the new mesh to create
6270 instance of class :class:`Mesh`
6273 if ( isinstance( theObject, Mesh )):
6274 theObject = theObject.GetMesh()
6275 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6276 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6277 theMirrorType = Mirror._mirrorType
6279 self.mesh.SetParameters(Mirror.parameters)
6280 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6281 MakeGroups, NewMeshName)
6282 return Mesh( self.smeshpyD,self.geompyD,mesh )
6284 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6286 Translate the elements
6289 IDsOfElements: list of elements ids
6290 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6291 Copy: allows copying the translated elements
6292 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6295 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6298 if IDsOfElements == []:
6299 IDsOfElements = self.GetElementsId()
6300 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6301 Vector = self.smeshpyD.GetDirStruct(Vector)
6302 if isinstance( Vector, list ):
6303 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6304 self.mesh.SetParameters(Vector.PS.parameters)
6305 if Copy and MakeGroups:
6306 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6307 self.editor.Translate(IDsOfElements, Vector, Copy)
6310 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6312 Create a new mesh of translated elements
6315 IDsOfElements: list of elements ids
6316 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6317 MakeGroups: forces the generation of new groups from existing ones
6318 NewMeshName: the name of the newly created mesh
6321 instance of class :class:`Mesh`
6324 if IDsOfElements == []:
6325 IDsOfElements = self.GetElementsId()
6326 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6327 Vector = self.smeshpyD.GetDirStruct(Vector)
6328 if isinstance( Vector, list ):
6329 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6330 self.mesh.SetParameters(Vector.PS.parameters)
6331 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6332 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6334 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6336 Translate the object
6339 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6340 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6341 Copy: allows copying the translated elements
6342 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6345 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6348 if ( isinstance( theObject, Mesh )):
6349 theObject = theObject.GetMesh()
6350 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6351 Vector = self.smeshpyD.GetDirStruct(Vector)
6352 if isinstance( Vector, list ):
6353 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6354 self.mesh.SetParameters(Vector.PS.parameters)
6355 if Copy and MakeGroups:
6356 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6357 self.editor.TranslateObject(theObject, Vector, Copy)
6360 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6362 Create a new mesh from the translated object
6365 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6366 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6367 MakeGroups: forces the generation of new groups from existing ones
6368 NewMeshName: the name of the newly created mesh
6371 instance of class :class:`Mesh`
6374 if isinstance( theObject, Mesh ):
6375 theObject = theObject.GetMesh()
6376 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6377 Vector = self.smeshpyD.GetDirStruct(Vector)
6378 if isinstance( Vector, list ):
6379 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6380 self.mesh.SetParameters(Vector.PS.parameters)
6381 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6382 return Mesh( self.smeshpyD, self.geompyD, mesh )
6386 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6391 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6392 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6393 theScaleFact: list of 1-3 scale factors for axises
6394 Copy: allows copying the translated elements
6395 MakeGroups: forces the generation of new groups from existing
6399 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6400 empty list otherwise
6402 unRegister = genObjUnRegister()
6403 if ( isinstance( theObject, Mesh )):
6404 theObject = theObject.GetMesh()
6405 if ( isinstance( theObject, list )):
6406 theObject = self.GetIDSource(theObject, SMESH.ALL)
6407 unRegister.set( theObject )
6408 if ( isinstance( thePoint, list )):
6409 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6410 if ( isinstance( theScaleFact, float )):
6411 theScaleFact = [theScaleFact]
6412 if ( isinstance( theScaleFact, int )):
6413 theScaleFact = [ float(theScaleFact)]
6415 self.mesh.SetParameters(thePoint.parameters)
6417 if Copy and MakeGroups:
6418 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6419 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6422 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6424 Create a new mesh from the translated object
6427 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6428 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6429 theScaleFact: list of 1-3 scale factors for axises
6430 MakeGroups: forces the generation of new groups from existing ones
6431 NewMeshName: the name of the newly created mesh
6434 instance of class :class:`Mesh`
6436 unRegister = genObjUnRegister()
6437 if (isinstance(theObject, Mesh)):
6438 theObject = theObject.GetMesh()
6439 if ( isinstance( theObject, list )):
6440 theObject = self.GetIDSource(theObject,SMESH.ALL)
6441 unRegister.set( theObject )
6442 if ( isinstance( thePoint, list )):
6443 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6444 if ( isinstance( theScaleFact, float )):
6445 theScaleFact = [theScaleFact]
6446 if ( isinstance( theScaleFact, int )):
6447 theScaleFact = [ float(theScaleFact)]
6449 self.mesh.SetParameters(thePoint.parameters)
6450 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6451 MakeGroups, NewMeshName)
6452 return Mesh( self.smeshpyD, self.geompyD, mesh )
6456 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6461 IDsOfElements: list of elements ids
6462 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6463 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6464 Copy: allows copying the rotated elements
6465 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6468 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6472 if IDsOfElements == []:
6473 IDsOfElements = self.GetElementsId()
6474 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6475 Axis = self.smeshpyD.GetAxisStruct(Axis)
6476 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6477 Parameters = Axis.parameters + var_separator + Parameters
6478 self.mesh.SetParameters(Parameters)
6479 if Copy and MakeGroups:
6480 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6481 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6484 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6486 Create a new mesh of rotated elements
6489 IDsOfElements: list of element ids
6490 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6491 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6492 MakeGroups: forces the generation of new groups from existing ones
6493 NewMeshName: the name of the newly created mesh
6496 instance of class :class:`Mesh`
6499 if IDsOfElements == []:
6500 IDsOfElements = self.GetElementsId()
6501 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6502 Axis = self.smeshpyD.GetAxisStruct(Axis)
6503 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6504 Parameters = Axis.parameters + var_separator + Parameters
6505 self.mesh.SetParameters(Parameters)
6506 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6507 MakeGroups, NewMeshName)
6508 return Mesh( self.smeshpyD, self.geompyD, mesh )
6510 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6515 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6516 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6517 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6518 Copy: allows copying the rotated elements
6519 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6522 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6525 if (isinstance(theObject, Mesh)):
6526 theObject = theObject.GetMesh()
6527 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6528 Axis = self.smeshpyD.GetAxisStruct(Axis)
6529 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6530 Parameters = Axis.parameters + ":" + Parameters
6531 self.mesh.SetParameters(Parameters)
6532 if Copy and MakeGroups:
6533 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6534 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6537 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6539 Create a new mesh from the rotated object
6542 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6543 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6544 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6545 MakeGroups: forces the generation of new groups from existing ones
6546 NewMeshName: the name of the newly created mesh
6549 instance of class :class:`Mesh`
6552 if (isinstance( theObject, Mesh )):
6553 theObject = theObject.GetMesh()
6554 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6555 Axis = self.smeshpyD.GetAxisStruct(Axis)
6556 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6557 Parameters = Axis.parameters + ":" + Parameters
6558 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6559 MakeGroups, NewMeshName)
6560 self.mesh.SetParameters(Parameters)
6561 return Mesh( self.smeshpyD, self.geompyD, mesh )
6563 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6565 Create an offset mesh from the given 2D object
6568 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6569 theValue (float): signed offset size
6570 MakeGroups (boolean): forces the generation of new groups from existing ones
6571 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6572 False means to remove original elements.
6573 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6576 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6579 if isinstance( theObject, Mesh ):
6580 theObject = theObject.GetMesh()
6581 theValue,Parameters,hasVars = ParseParameters(Value)
6582 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6583 self.mesh.SetParameters(Parameters)
6585 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6588 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6590 Find groups of adjacent nodes within Tolerance.
6593 Tolerance (float): the value of tolerance
6594 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6595 corner and medium nodes in separate groups thus preventing
6596 their further merge.
6599 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6602 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6604 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6605 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6607 Find groups of adjacent nodes within Tolerance.
6610 Tolerance: the value of tolerance
6611 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6612 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6613 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6614 corner and medium nodes in separate groups thus preventing
6615 their further merge.
6618 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6621 unRegister = genObjUnRegister()
6622 if not isinstance( SubMeshOrGroup, list ):
6623 SubMeshOrGroup = [ SubMeshOrGroup ]
6624 for i,obj in enumerate( SubMeshOrGroup ):
6625 if isinstance( obj, Mesh ):
6626 SubMeshOrGroup = [ obj.GetMesh() ]
6628 if isinstance( obj, int ):
6629 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6630 unRegister.set( SubMeshOrGroup )
6633 if not isinstance( exceptNodes, list ):
6634 exceptNodes = [ exceptNodes ]
6635 if exceptNodes and isinstance( exceptNodes[0], int ):
6636 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6637 unRegister.set( exceptNodes )
6639 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6640 exceptNodes, SeparateCornerAndMediumNodes)
6642 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6647 GroupsOfNodes: a list of groups of nodes IDs for merging.
6648 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6649 in all elements and mesh groups by nodes 1 and 25 correspondingly
6650 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6651 If *NodesToKeep* does not include a node to keep for some group to merge,
6652 then the first node in the group is kept.
6653 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6657 This operation can create gaps in numeration of nodes or elements.
6658 Call :meth:`RenumberElements` to remove the gaps.
6660 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6662 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6664 Find the elements built on the same nodes.
6667 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6668 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6672 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6675 unRegister = genObjUnRegister()
6676 if MeshOrSubMeshOrGroup is None:
6677 MeshOrSubMeshOrGroup = [ self.mesh ]
6678 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6679 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6680 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6681 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6682 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6683 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6684 unRegister.set( MeshOrSubMeshOrGroup )
6685 for item in MeshOrSubMeshOrGroup:
6686 if isinstance( item, Mesh ):
6687 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6689 if not isinstance( exceptElements, list ):
6690 exceptElements = [ exceptElements ]
6691 if exceptElements and isinstance( exceptElements[0], int ):
6692 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6693 unRegister.set( exceptElements )
6695 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6697 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6699 Merge elements in each given group.
6702 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6703 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6704 replaced in all mesh groups by elements 1 and 25)
6705 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6706 If *ElementsToKeep* does not include an element to keep for some group to merge,
6707 then the first element in the group is kept.
6710 This operation can create gaps in numeration of elements.
6711 Call :meth:`RenumberElements` to remove the gaps.
6714 unRegister = genObjUnRegister()
6716 if not isinstance( ElementsToKeep, list ):
6717 ElementsToKeep = [ ElementsToKeep ]
6718 if isinstance( ElementsToKeep[0], int ):
6719 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6720 unRegister.set( ElementsToKeep )
6722 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6724 def MergeEqualElements(self):
6726 Leave one element and remove all other elements built on the same nodes.
6729 This operation can create gaps in numeration of elements.
6730 Call :meth:`RenumberElements` to remove the gaps.
6733 self.editor.MergeEqualElements()
6735 def FindFreeBorders(self, ClosedOnly=True):
6737 Returns all or only closed free borders
6740 list of SMESH.FreeBorder's
6743 return self.editor.FindFreeBorders( ClosedOnly )
6745 def FillHole(self, holeNodes, groupName=""):
6747 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6750 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6751 must describe all sequential nodes of the hole border. The first and the last
6752 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6753 groupName (string): name of a group to add new faces
6755 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6759 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6760 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6761 if not isinstance( holeNodes, SMESH.FreeBorder ):
6762 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6763 return self.editor.FillHole( holeNodes, groupName )
6765 def FindCoincidentFreeBorders (self, tolerance=0.):
6767 Return groups of FreeBorder's coincident within the given tolerance.
6770 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6771 size of elements adjacent to free borders being compared is used.
6774 SMESH.CoincidentFreeBorders structure
6777 return self.editor.FindCoincidentFreeBorders( tolerance )
6779 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6781 Sew FreeBorder's of each group
6784 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6785 where each enclosed list contains node IDs of a group of coincident free
6786 borders such that each consequent triple of IDs within a group describes
6787 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6788 last node of a border.
6789 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6790 groups of coincident free borders, each group including two borders.
6791 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6792 polygons if a node of opposite border falls on a face edge, else such
6793 faces are split into several ones.
6794 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6795 polyhedra if a node of opposite border falls on a volume edge, else such
6796 volumes, if any, remain intact and the mesh becomes non-conformal.
6799 a number of successfully sewed groups
6802 This operation can create gaps in numeration of nodes or elements.
6803 Call :meth:`RenumberElements` to remove the gaps.
6806 if freeBorders and isinstance( freeBorders, list ):
6807 # construct SMESH.CoincidentFreeBorders
6808 if isinstance( freeBorders[0], int ):
6809 freeBorders = [freeBorders]
6811 coincidentGroups = []
6812 for nodeList in freeBorders:
6813 if not nodeList or len( nodeList ) % 3:
6814 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6817 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6818 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6819 nodeList = nodeList[3:]
6821 coincidentGroups.append( group )
6823 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6825 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6827 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6828 FirstNodeID2, SecondNodeID2, LastNodeID2,
6829 CreatePolygons, CreatePolyedrs):
6834 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6837 This operation can create gaps in numeration of nodes or elements.
6838 Call :meth:`RenumberElements` to remove the gaps.
6841 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6842 FirstNodeID2, SecondNodeID2, LastNodeID2,
6843 CreatePolygons, CreatePolyedrs)
6845 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6846 FirstNodeID2, SecondNodeID2):
6848 Sew conform free borders
6851 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6854 This operation can create gaps in numeration of elements.
6855 Call :meth:`RenumberElements` to remove the gaps.
6858 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6859 FirstNodeID2, SecondNodeID2)
6861 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6862 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6867 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6870 This operation can create gaps in numeration of elements.
6871 Call :meth:`RenumberElements` to remove the gaps.
6874 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6875 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6877 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6878 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6879 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6881 Sew two sides of a mesh. The nodes belonging to Side1 are
6882 merged with the nodes of elements of Side2.
6883 The number of elements in theSide1 and in theSide2 must be
6884 equal and they should have similar nodal connectivity.
6885 The nodes to merge should belong to side borders and
6886 the first node should be linked to the second.
6889 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6892 This operation can create gaps in numeration of nodes.
6893 Call :meth:`RenumberElements` to remove the gaps.
6896 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6897 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6898 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6900 def ChangeElemNodes(self, ide, newIDs):
6902 Set new nodes for the given element. Number of nodes should be kept.
6909 False if the number of nodes does not correspond to the type of element
6912 return self.editor.ChangeElemNodes(ide, newIDs)
6914 def GetLastCreatedNodes(self):
6916 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6917 created, this method return the list of their IDs.
6918 If new nodes were not created - return empty list
6921 the list of integer values (can be empty)
6924 return self.editor.GetLastCreatedNodes()
6926 def GetLastCreatedElems(self):
6928 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6929 created this method return the list of their IDs.
6930 If new elements were not created - return empty list
6933 the list of integer values (can be empty)
6936 return self.editor.GetLastCreatedElems()
6938 def ClearLastCreated(self):
6940 Forget what nodes and elements were created by the last mesh edition operation
6943 self.editor.ClearLastCreated()
6945 def DoubleElements(self, theElements, theGroupName=""):
6947 Create duplicates of given elements, i.e. create new elements based on the
6948 same nodes as the given ones.
6951 theElements: container of elements to duplicate. It can be a
6952 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6953 or a list of element IDs. If *theElements* is
6954 a :class:`Mesh`, elements of highest dimension are duplicated
6955 theGroupName: a name of group to contain the generated elements.
6956 If a group with such a name already exists, the new elements
6957 are added to the existing group, else a new group is created.
6958 If *theGroupName* is empty, new elements are not added
6962 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6963 None if *theGroupName* == "".
6966 unRegister = genObjUnRegister()
6967 if isinstance( theElements, Mesh ):
6968 theElements = theElements.mesh
6969 elif isinstance( theElements, list ):
6970 theElements = self.GetIDSource( theElements, SMESH.ALL )
6971 unRegister.set( theElements )
6972 return self.editor.DoubleElements(theElements, theGroupName)
6974 def DoubleNodes(self, theNodes, theModifiedElems):
6976 Create a hole in a mesh by doubling the nodes of some particular elements
6979 theNodes: IDs of nodes to be doubled
6980 theModifiedElems: IDs of elements to be updated by the new (doubled)
6981 nodes. If list of element identifiers is empty then nodes are doubled but
6982 they not assigned to elements
6985 True if operation has been completed successfully, False otherwise
6988 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6990 def DoubleNode(self, theNodeId, theModifiedElems):
6992 Create a hole in a mesh by doubling the nodes of some particular elements.
6993 This method provided for convenience works as :meth:`DoubleNodes`.
6996 theNodeId: IDs of node to double
6997 theModifiedElems: IDs of elements to update
7000 True if operation has been completed successfully, False otherwise
7003 return self.editor.DoubleNode(theNodeId, theModifiedElems)
7005 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
7007 Create a hole in a mesh by doubling the nodes of some particular elements.
7008 This method provided for convenience works as :meth:`DoubleNodes`.
7011 theNodes: group of nodes to double.
7012 theModifiedElems: group of elements to update.
7013 theMakeGroup: forces the generation of a group containing new nodes.
7016 True or a created group if operation has been completed successfully,
7017 False or None otherwise
7021 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
7022 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7024 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7026 Create a hole in a mesh by doubling the nodes of some particular elements.
7027 This method provided for convenience works as :meth:`DoubleNodes`.
7030 theNodes: list of groups of nodes to double.
7031 theModifiedElems: list of groups of elements to update.
7032 theMakeGroup: forces the generation of a group containing new nodes.
7035 True if operation has been completed successfully, False otherwise
7039 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7040 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7042 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7044 Create a hole in a mesh by doubling the nodes of some particular elements
7047 theElems: the list of elements (edges or faces) to replicate.
7048 The nodes for duplication could be found from these elements
7049 theNodesNot: list of nodes NOT to replicate
7050 theAffectedElems: the list of elements (cells and edges) to which the
7051 replicated nodes should be associated to
7054 True if operation has been completed successfully, False otherwise
7057 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7059 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7061 Create a hole in a mesh by doubling the nodes of some particular elements
7064 theElems: the list of elements (edges or faces) to replicate.
7065 The nodes for duplication could be found from these elements
7066 theNodesNot: list of nodes NOT to replicate
7067 theShape: shape to detect affected elements (element which geometric center
7068 located on or inside shape).
7069 The replicated nodes should be associated to affected elements.
7072 True if operation has been completed successfully, False otherwise
7075 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7077 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7078 theMakeGroup=False, theMakeNodeGroup=False):
7080 Create a hole in a mesh by doubling the nodes of some particular elements.
7081 This method provided for convenience works as :meth:`DoubleNodes`.
7084 theElems: group of of elements (edges or faces) to replicate.
7085 theNodesNot: group of nodes NOT to replicate.
7086 theAffectedElems: group of elements to which the replicated nodes
7087 should be associated to.
7088 theMakeGroup: forces the generation of a group containing new elements.
7089 theMakeNodeGroup: forces the generation of a group containing new nodes.
7092 True or created groups (one or two) if operation has been completed successfully,
7093 False or None otherwise
7096 if theMakeGroup or theMakeNodeGroup:
7097 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7099 theMakeGroup, theMakeNodeGroup)
7100 if theMakeGroup and theMakeNodeGroup:
7103 return twoGroups[ int(theMakeNodeGroup) ]
7104 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7106 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7108 Create a hole in a mesh by doubling the nodes of some particular elements.
7109 This method provided for convenience works as :meth:`DoubleNodes`.
7112 theElems: group of of elements (edges or faces) to replicate
7113 theNodesNot: group of nodes not to replicate
7114 theShape: shape to detect affected elements (element which geometric center
7115 located on or inside shape).
7116 The replicated nodes should be associated to affected elements
7119 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7121 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7122 theMakeGroup=False, theMakeNodeGroup=False):
7124 Create a hole in a mesh by doubling the nodes of some particular elements.
7125 This method provided for convenience works as :meth:`DoubleNodes`.
7128 theElems: list of groups of elements (edges or faces) to replicate
7129 theNodesNot: list of groups of nodes NOT to replicate
7130 theAffectedElems: group of elements to which the replicated nodes
7131 should be associated to
7132 theMakeGroup: forces generation of a group containing new elements.
7133 theMakeNodeGroup: forces generation of a group containing new nodes
7136 True or created groups (one or two) if operation has been completed successfully,
7137 False or None otherwise
7140 if theMakeGroup or theMakeNodeGroup:
7141 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7143 theMakeGroup, theMakeNodeGroup)
7144 if theMakeGroup and theMakeNodeGroup:
7147 return twoGroups[ int(theMakeNodeGroup) ]
7148 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7150 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7152 Create a hole in a mesh by doubling the nodes of some particular elements.
7153 This method provided for convenience works as :meth:`DoubleNodes`.
7156 theElems: list of groups of elements (edges or faces) to replicate
7157 theNodesNot: list of groups of nodes NOT to replicate
7158 theShape: shape to detect affected elements (element which geometric center
7159 located on or inside shape).
7160 The replicated nodes should be associated to affected elements
7163 True if operation has been completed successfully, False otherwise
7166 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7168 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7170 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7171 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7174 theElems: list of groups of nodes or elements (edges or faces) to replicate
7175 theNodesNot: list of groups of nodes NOT to replicate
7176 theShape: shape to detect affected elements (element which geometric center
7177 located on or inside shape).
7178 The replicated nodes should be associated to affected elements
7181 groups of affected elements in order: volumes, faces, edges
7184 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7186 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7189 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7190 The list of groups must describe a partition of the mesh volumes.
7191 The nodes of the internal faces at the boundaries of the groups are doubled.
7192 In option, the internal faces are replaced by flat elements.
7193 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7196 theDomains: list of groups of volumes
7197 createJointElems: if True, create the elements
7198 onAllBoundaries: if True, the nodes and elements are also created on
7199 the boundary between *theDomains* and the rest mesh
7202 True if operation has been completed successfully, False otherwise
7205 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7207 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7209 Double nodes on some external faces and create flat elements.
7210 Flat elements are mainly used by some types of mechanic calculations.
7212 Each group of the list must be constituted of faces.
7213 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7216 theGroupsOfFaces: list of groups of faces
7219 True if operation has been completed successfully, False otherwise
7222 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7224 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7226 Identify all the elements around a geom shape, get the faces delimiting the hole
7228 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7230 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7232 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7233 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7234 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7235 If there are several paths connecting a pair of points, the shortest path is
7236 selected by the module. Position of the cutting plane is defined by the two
7237 points and an optional vector lying on the plane specified by a PolySegment.
7238 By default the vector is defined by Mesh module as following. A middle point
7239 of the two given points is computed. The middle point is projected to the mesh.
7240 The vector goes from the middle point to the projection point. In case of planar
7241 mesh, the vector is normal to the mesh.
7243 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7246 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7247 groupName: optional name of a group where created mesh segments will be added.
7250 editor = self.editor
7252 editor = self.mesh.GetMeshEditPreviewer()
7253 segmentsRes = editor.MakePolyLine( segments, groupName )
7254 for i, seg in enumerate( segmentsRes ):
7255 segments[i].vector = seg.vector
7257 return editor.GetPreviewData()
7260 def MakeSlot(self, segmentGroup, width ):
7262 Create a slot of given width around given 1D elements lying on a triangle mesh.
7263 The slot is constructed by cutting faces by cylindrical surfaces made
7264 around each segment. Segments are expected to be created by MakePolyLine().
7267 FaceEdge's located at the slot boundary
7269 return self.editor.MakeSlot( segmentGroup, width )
7271 def GetFunctor(self, funcType ):
7273 Return a cached numerical functor by its type.
7276 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7277 Note that not all items correspond to numerical functors.
7280 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7283 fn = self.functors[ funcType._v ]
7285 fn = self.smeshpyD.GetFunctor(funcType)
7286 fn.SetMesh(self.mesh)
7287 self.functors[ funcType._v ] = fn
7290 def FunctorValue(self, funcType, elemId, isElem=True):
7292 Return value of a functor for a given element
7295 funcType: an item of :class:`SMESH.FunctorType` enum.
7296 elemId: element or node ID
7297 isElem: *elemId* is ID of element or node
7300 the functor value or zero in case of invalid arguments
7303 fn = self.GetFunctor( funcType )
7304 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7305 val = fn.GetValue(elemId)
7310 def GetLength(self, elemId=None):
7312 Get length of given 1D elements or of all 1D mesh elements
7315 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.
7318 Sum of lengths of given elements
7323 length = self.smeshpyD.GetLength(self)
7324 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7325 length = self.smeshpyD.GetLength(elemId)
7328 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7330 length += self.smeshpyD.GetLength(obj)
7331 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7332 unRegister = genObjUnRegister()
7333 obj = self.GetIDSource( elemId )
7334 unRegister.set( obj )
7335 length = self.smeshpyD.GetLength( obj )
7337 length = self.FunctorValue(SMESH.FT_Length, elemId)
7340 def GetArea(self, elemId=None):
7342 Get area of given 2D elements or of all 2D mesh elements
7345 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.
7348 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7353 area = self.smeshpyD.GetArea(self)
7354 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7355 area = self.smeshpyD.GetArea(elemId)
7358 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7360 area += self.smeshpyD.GetArea(obj)
7361 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7362 unRegister = genObjUnRegister()
7363 obj = self.GetIDSource( elemId )
7364 unRegister.set( obj )
7365 area = self.smeshpyD.GetArea( obj )
7367 area = self.FunctorValue(SMESH.FT_Area, elemId)
7370 def GetVolume(self, elemId=None):
7372 Get volume of given 3D elements or of all 3D mesh elements
7375 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.
7378 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7383 volume= self.smeshpyD.GetVolume(self)
7384 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7385 volume= self.smeshpyD.GetVolume(elemId)
7388 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7390 volume+= self.smeshpyD.GetVolume(obj)
7391 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7392 unRegister = genObjUnRegister()
7393 obj = self.GetIDSource( elemId )
7394 unRegister.set( obj )
7395 volume= self.smeshpyD.GetVolume( obj )
7397 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7400 def GetAngle(self, node1, node2, node3 ):
7402 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7405 node1,node2,node3: IDs of the three nodes
7408 Angle in radians [0,PI]. -1 if failure case.
7410 p1 = self.GetNodeXYZ( node1 )
7411 p2 = self.GetNodeXYZ( node2 )
7412 p3 = self.GetNodeXYZ( node3 )
7413 if p1 and p2 and p3:
7414 return self.smeshpyD.GetAngle( p1,p2,p3 )
7418 def GetMaxElementLength(self, elemId):
7420 Get maximum element length.
7423 elemId: mesh element ID
7426 element's maximum length value
7429 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7430 ftype = SMESH.FT_MaxElementLength3D
7432 ftype = SMESH.FT_MaxElementLength2D
7433 return self.FunctorValue(ftype, elemId)
7435 def GetAspectRatio(self, elemId):
7437 Get aspect ratio of 2D or 3D element.
7440 elemId: mesh element ID
7443 element's aspect ratio value
7446 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7447 ftype = SMESH.FT_AspectRatio3D
7449 ftype = SMESH.FT_AspectRatio
7450 return self.FunctorValue(ftype, elemId)
7452 def GetWarping(self, elemId):
7454 Get warping angle of 2D element.
7457 elemId: mesh element ID
7460 element's warping angle value
7463 return self.FunctorValue(SMESH.FT_Warping, elemId)
7465 def GetWarping3D(self, elemId):
7467 Get warping angle of faces element of 3D elements.
7470 elemId: mesh element ID
7473 element's warping angle value
7476 return self.FunctorValue(SMESH.FT_Warping3D, elemId)
7478 def GetMinimumAngle(self, elemId):
7480 Get minimum angle of 2D element.
7483 elemId: mesh element ID
7486 element's minimum angle value
7489 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7491 def GetTaper(self, elemId):
7493 Get taper of 2D element.
7496 elemId: mesh element ID
7499 element's taper value
7502 return self.FunctorValue(SMESH.FT_Taper, elemId)
7504 def GetSkew(self, elemId):
7506 Get skew of 2D element.
7509 elemId: mesh element ID
7512 element's skew value
7515 return self.FunctorValue(SMESH.FT_Skew, elemId)
7517 def GetScaledJacobian(self, elemId):
7519 Get the scaled jacobian of 3D element id
7522 elemId: mesh element ID
7528 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7530 def GetMinMax(self, funType, meshPart=None):
7532 Return minimal and maximal value of a given functor.
7535 funType (SMESH.FunctorType): a functor type.
7536 Note that not all items of :class:`SMESH.FunctorType` corresponds
7537 to numerical functors.
7538 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7544 unRegister = genObjUnRegister()
7545 if isinstance( meshPart, list ):
7546 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7547 unRegister.set( meshPart )
7548 if isinstance( meshPart, Mesh ):
7549 meshPart = meshPart.mesh
7550 fun = self.GetFunctor( funType )
7553 if hasattr( meshPart, "SetMesh" ):
7554 meshPart.SetMesh( self.mesh ) # set mesh to filter
7555 hist = fun.GetLocalHistogram( 1, False, meshPart )
7557 hist = fun.GetHistogram( 1, False )
7559 return hist[0].min, hist[0].max
7562 pass # end of Mesh class
7564 def _copy_gmsh_param(dim, local_param, global_param):
7566 local_param.SetMaxSize(global_param.GetMaxSize())
7567 local_param.SetMinSize(global_param.GetMinSize())
7568 local_param.Set3DAlgo(global_param.Get3DAlgo())
7569 local_param.SetRecombineAll(global_param.GetRecombineAll())
7570 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7571 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7572 local_param.SetRemeshPara(global_param.GetRemeshPara())
7573 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7574 local_param.SetSizeFactor(global_param.GetSizeFactor())
7575 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7576 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7577 local_param.SetSecondOrder(global_param.GetSecondOrder())
7578 local_param.SetIs2d(global_param.GetIs2d())
7580 local_param.SetMaxSize(global_param.GetMaxSize())
7581 local_param.SetMinSize(global_param.GetMinSize())
7582 local_param.Set2DAlgo(global_param.Get2DAlgo())
7583 local_param.SetRecomb2DAlgo(global_param.GetRecomb2DAlgo())
7584 local_param.SetRecombineAll(global_param.GetRecombineAll())
7585 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7586 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7587 local_param.SetRemeshPara(global_param.GetRemeshPara())
7588 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7589 local_param.SetSizeFactor(global_param.GetSizeFactor())
7590 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7591 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7592 local_param.SetSecondOrder(global_param.GetSecondOrder())
7593 local_param.SetIs2d(global_param.GetIs2d())
7595 def _copy_netgen_param(dim, local_param, global_param):
7597 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7600 #TODO: More global conversion ? or let user define it
7601 local_param.NumberOfSegments(int(global_param.GetMaxSize()))
7603 local_param.SetMaxSize(global_param.GetMaxSize())
7604 local_param.SetMinSize(global_param.GetMinSize())
7605 local_param.SetOptimize(global_param.GetOptimize())
7606 local_param.SetFineness(global_param.GetFineness())
7607 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7608 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7609 #TODO: Why the 0.9 to have same results
7610 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7611 local_param.SetChordalError(global_param.GetChordalError())
7612 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7613 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7614 local_param.SetUseDelauney(global_param.GetUseDelauney())
7615 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7616 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7617 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7618 local_param.SetNbThreads(global_param.GetNbThreads())
7620 local_param.SetMaxSize(global_param.GetMaxSize())
7621 local_param.SetMinSize(global_param.GetMinSize())
7622 local_param.SetOptimize(global_param.GetOptimize())
7623 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7624 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7625 local_param.SetFineness(global_param.GetFineness())
7626 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7627 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7628 local_param.SetGrowthRate(global_param.GetGrowthRate())
7629 local_param.SetNbThreads(global_param.GetNbThreads())
7632 def _shaperstudy2geom(geompyD, shaper_obj):
7634 Convertion of shaper object to geom object
7637 geompyD: geomBuilder instance
7638 shaper_obj: Shaper study object
7645 #Writing shaperstudy object into a brep file
7646 fid, tmp_file = tempfile.mkstemp(suffix='.brep')
7647 with open(fid, 'wb') as f:
7648 f.write(shaper_obj.GetShapeStream())
7649 # Reimporting brep file into geom
7650 real_geom = geompyD.ImportBREP(tmp_file)
7656 def _split_geom(geompyD, geom):
7658 Splitting geometry into n solids and a 2D/1D compound
7661 geompyD: geomBuilder instance
7662 geom: geometrical object for meshing
7665 compound containing all the 1D,2D elements
7669 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7670 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7675 for solid in object_solids:
7677 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7678 solids.append(solid)
7679 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7685 solid_faces = geompyD.ExtractShapes(geom, geompyD.ShapeType["FACE"],
7687 for face in solid_faces:
7690 geompyD.addToStudyInFather(geom, face,
7691 'Face_{}'.format(iface))
7693 return faces, solids
7696 MULTITHREAD, MULTINODE = range(2)
7697 class ParallelismSettings:
7699 Defines the parameters for the parallelism of ParallelMesh
7701 def __init__(self, mesh):
7706 mesh: Instance of ParallelMesh
7708 if not(isinstance(mesh, ParallelMesh)):
7709 raise ValueError("mesh should be a ParallelMesh")
7714 class MTParallelismSettings(ParallelismSettings):
7716 Defines the parameters for the parallelism of ParallelMesh using MultiThreading
7718 def __init__(self, mesh):
7719 ParallelismSettings.__init__(self, mesh)
7721 # Multithreading methods
7722 def SetNbThreads(self, nbThreads):
7723 """ Set the number of threads for multithread """
7725 raise ValueError("Number of threads must be stricly greater than 1")
7727 self._mesh.mesh.SetNbThreads(nbThreads)
7729 def GetNbThreads(self):
7730 """ Get Number of threads """
7731 return self._mesh.mesh.GetNbThreads()
7734 """ str conversion """
7735 string = "\nParameter for MultiThreading parallelism:\n"
7736 string += "NbThreads: {}\n".format(self.GetNbThreads())
7741 class MNParallelismSettings(ParallelismSettings):
7743 Defines the parameters for the parallelism of ParallelMesh using MultiNodal
7745 def __init__(self, mesh):
7746 ParallelismSettings.__init__(self, mesh)
7748 def GetResource(self):
7749 """ Get the resource on which to run """
7750 return self._mesh.mesh.GetResource()
7752 def SetResource(self, resource):
7753 """ Set the resource on which to run """
7754 self._mesh.mesh.SetResource(resource)
7756 def SetNbProc(self, nbProc):
7757 """ Set the number of Processor for multinode """
7759 raise ValueError("Number of Proc must be stricly greater than 1")
7760 self._mesh.mesh.SetNbProc(nbProc)
7762 def GetNbProc(self):
7763 """ Get Number of Processor """
7764 return self._mesh.mesh.GetNbProc()
7766 def SetNbProcPerNode(self, nbProcPerNode):
7767 """ Set the number of Processor Per Node for multinode """
7768 if nbProcPerNode < 1:
7769 raise ValueError("Number of Processor Per Node must be stricly greater than 1")
7771 self._mesh.mesh.SetNbProcPerNode(nbProcPerNode)
7773 def GetNbProcPerNode(self):
7774 """ Get Number of Processor Per Node """
7775 return self._mesh.mesh.GetNbProcPerNode()
7777 def SetNbNode(self, nbNode):
7778 """ Set the number of Node for multinode """
7780 raise ValueError("Number of Node must be stricly greater than 1")
7781 self._mesh.mesh.SetNbNode(nbNode)
7783 def GetNbNode(self):
7784 """ Get Number of Node """
7785 return self._mesh.mesh.GetNbNode()
7787 def SetWcKey(self, wcKey):
7788 """ Set the number of Node for multinode """
7789 self._mesh.mesh.SetWcKey(wcKey)
7792 """ Get Number of Node """
7793 return self._mesh.mesh.GetWcKey()
7795 def SetWalltime(self, walltime):
7796 """ Set the number of Node for multinode """
7797 self._mesh.mesh.SetWalltime(walltime)
7799 def GetWalltime(self):
7800 """ Get Number of Node """
7801 return self._mesh.mesh.GetWalltime()
7804 """ str conversion """
7805 string = "\nParameter for MultiNode parallelism:\n"
7806 string += "Reource: {}\n".format(self.GetResource())
7807 string += "NbProc: {}\n".format(self.GetNbProc())
7808 string += "NbProcPerNode: {}\n".format(self.GetNbProcPerNode())
7809 string += "NbNode: {}\n".format(self.GetNbNode())
7810 string += "WcKey: {}\n".format(self.GetWcKey())
7811 string += "Walltime: {}\n".format(self.GetWalltime())
7816 class ParallelMesh(Mesh):
7818 Surcharge on Mesh for parallel computation of a mesh
7820 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7822 Create a parallel mesh.
7825 smeshpyD: instance of smeshBuilder
7826 geompyD: instance of geomBuilder
7827 geom: geometrical object for meshing
7828 split_geom: If true will divide geometry on solids and 1D/2D
7829 coumpound and create the associated submeshes
7830 name: the name for the new mesh.
7833 an instance of class :class:`ParallelMesh`.
7836 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7837 raise ValueError("geom argument must be a geometry")
7841 shaper_object = SHAPERSTUDY.SHAPERSTUDY_ORB._objref_SHAPER_Object
7847 # If we have a shaper object converting it into geom (temporary solution)
7848 if isinstance(geom, shaper_object):
7849 self._geom_obj = _shaperstudy2geom(geompyD, geom)
7850 elif isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7851 self._geom_obj = geom
7855 msg = "\nShaper was not compiled"
7856 raise Exception("Could not handle geom format {}.{} ".format(type(geom), msg))
7858 # Splitting geometry into one geom containing 1D and 2D elements and a
7859 # list of 3D elements
7860 super(ParallelMesh, self).__init__(smeshpyD, geompyD, self._geom_obj, name, parallel=True)
7863 self._faces, self._solids = _split_geom(geompyD, self._geom_obj)
7867 def _build_submeshes(self, mesher2D, mesher3D):
7869 Contruct the submeshes for a parallel use of smesh
7872 mesher2D: name of 2D mesher for 2D parallel compute (NETGEN)
7873 mesher3D: name of 3D mesher for 3D parallel compute (NETGEN or
7877 # Building global 2D mesher
7879 if mesher3D == "NETGEN":
7880 algo2D = "NETGEN_2D"
7881 elif mesher3D == "GMSH":
7884 raise ValueError("mesher3D should be either NETGEN or GMSH")
7886 self._algo2d = self.Triangle(geom=self._geom_obj, algo=algo2D)
7890 #Means that we want to mesh face of solids in parallel and not
7893 #For the moment use AutomaticLength based on finesse
7894 # TODO: replace by input hypothesis
7895 self._algo1d = self.Segment(geom=self._geom_obj)
7897 for face_id, face in enumerate(self._faces):
7898 name = "face_{}".format(face_id)
7899 algo2d = self.Triangle(geom=face, algo="NETGEN_2D_Remote")
7900 self._algo2d.append(algo2d)
7904 for solid_id, solid in enumerate(self._solids):
7905 name = "Solid_{}".format(solid_id)
7906 if ( mesher3D == "NETGEN" ):
7907 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7908 self._algo3d.append(algo3d)
7909 elif ( mesher3D == "GMSH" ):
7910 algo3d = self.Tetrahedron(geom=solid, algo="GMSH_3D_Remote")
7911 self._algo3d.append(algo3d)
7913 def GetNbSolids(self):
7915 Return the number of 3D solids
7917 return len(self._solids)
7919 def GetNbFaces(self):
7921 Return the number of 2D faces
7923 return len(self._faces)
7925 def GetParallelismMethod(self):
7926 """ Get the parallelims method """
7927 return self.mesh.GetParallelismMethod()
7929 def SetParallelismMethod(self, method):
7930 """ Set the parallelims method """
7931 if method not in [MULTITHREAD , MULTINODE]:
7932 raise ValueError("Parallelism method can only be 0:MultiThread or 1:MultiNode")
7934 self.mesh.SetParallelismMethod(method)
7936 if method == MULTITHREAD:
7937 self._param = MTParallelismSettings(self)
7939 self._param = MNParallelismSettings(self)
7941 def GetParallelismSettings(self):
7943 Return class to set parameters for the parallelism
7945 if self._param is None:
7946 raise Exception("You need to set Parallelism method first (SetParallelismMethod)")
7949 def AddGlobalHypothesis(self, hyp):
7951 Split hypothesis to apply it to all the submeshes:
7953 - each of the 3D solids
7956 hyp: a hypothesis to assign
7959 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7960 copy_param = _copy_netgen_param
7962 elif isinstance(hyp, GMSHPlugin._objref_GMSHPlugin_Hypothesis):
7963 copy_param = _copy_gmsh_param
7966 raise ValueError("param must come from NETGENPlugin or GMSHPlugin")
7968 self.mesh.SetParallelismDimension(3)
7969 self._build_submeshes(None, mesher3D)
7971 param2d = self._algo2d.Parameters()
7972 copy_param(2, param2d, hyp)
7974 for algo3d in self._algo3d:
7975 param3d = algo3d.Parameters()
7976 copy_param(3, param3d, hyp)
7978 def Add2DGlobalHypothesis(self, hyp):
7980 Split hypothesis to apply it to all the submeshes:
7982 - each of the 2D faces
7985 hyp: a hypothesis to assign
7988 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7989 copy_param = _copy_netgen_param
7992 raise ValueError("param must come from NETGENPlugin")
7994 self.mesh.SetParallelismDimension(2)
7995 self._build_submeshes(mesher2D, None)
7997 param1d = self._algo1d
7998 copy_param(1, param1d, hyp)
8000 for algo2d in self._algo2d:
8001 param2d = algo2d.Parameters()
8002 copy_param(2, param2d, hyp)
8004 pass # End of ParallelMesh
8006 class meshProxy(SMESH._objref_SMESH_Mesh):
8008 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
8009 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
8011 def __init__(self,*args):
8012 SMESH._objref_SMESH_Mesh.__init__(self,*args)
8013 def __deepcopy__(self, memo=None):
8014 new = self.__class__(self)
8016 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
8017 if len( args ) == 3:
8018 args += SMESH.ALL_NODES, True
8019 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
8020 def ExportToMEDX(self, *args): # function removed
8021 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
8022 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8023 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
8024 def ExportToMED(self, *args): # function removed
8025 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
8026 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8028 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8030 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8031 def ExportPartToMED(self, *args): # 'version' parameter removed
8032 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8033 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
8034 def ExportMED(self, *args): # signature of method changed
8035 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8037 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8039 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8040 def ExportUNV(self, *args): # renumber arg added
8041 if len( args ) == 1:
8043 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
8044 def ExportDAT(self, *args): # renumber arg added
8045 if len( args ) == 1:
8047 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
8049 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
8052 class parallelMeshProxy(SMESH._objref_SMESH_ParallelMesh):
8053 def __init__(self,*args):
8054 SMESH._objref_SMESH_ParallelMesh.__init__(self,*args)
8055 def __deepcopy__(self, memo=None):
8056 new = self.__class__(self)
8058 omniORB.registerObjref(SMESH._objref_SMESH_ParallelMesh._NP_RepositoryId, parallelMeshProxy)
8062 class submeshProxy(SMESH._objref_SMESH_subMesh):
8065 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
8067 def __init__(self,*args):
8068 SMESH._objref_SMESH_subMesh.__init__(self,*args)
8070 def __deepcopy__(self, memo=None):
8071 new = self.__class__(self)
8074 def Compute(self,refresh=False):
8076 Compute the sub-mesh and return the status of the computation
8079 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
8084 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
8085 :meth:`smeshBuilder.Mesh.GetSubMesh`.
8089 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
8091 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
8093 if salome.sg.hasDesktop():
8094 if refresh: salome.sg.updateObjBrowser()
8099 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
8102 class meshEditor(SMESH._objref_SMESH_MeshEditor):
8104 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
8105 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
8108 def __init__(self,*args):
8109 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
8111 def __getattr__(self, name ): # method called if an attribute not found
8112 if not self.mesh: # look for name() method in Mesh class
8113 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
8114 if hasattr( self.mesh, name ):
8115 return getattr( self.mesh, name )
8116 if name == "ExtrusionAlongPathObjX":
8117 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
8118 print("meshEditor: attribute '%s' NOT FOUND" % name)
8120 def __deepcopy__(self, memo=None):
8121 new = self.__class__(self)
8123 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
8124 if len( args ) == 1: args += False,
8125 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
8126 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
8127 if len( args ) == 2: args += False,
8128 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
8129 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
8130 if len( args ) == 1:
8131 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
8132 NodesToKeep = args[1]
8133 AvoidMakingHoles = args[2] if len( args ) == 3 else False
8134 unRegister = genObjUnRegister()
8136 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
8137 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
8138 if not isinstance( NodesToKeep, list ):
8139 NodesToKeep = [ NodesToKeep ]
8140 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
8142 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
8144 class Pattern(SMESH._objref_SMESH_Pattern):
8146 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
8147 variables in some methods
8150 def LoadFromFile(self, patternTextOrFile ):
8151 text = patternTextOrFile
8152 if os.path.exists( text ):
8153 text = open( patternTextOrFile ).read()
8155 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
8157 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
8158 decrFun = lambda i: i-1
8159 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
8160 theMesh.SetParameters(Parameters)
8161 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
8163 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
8164 decrFun = lambda i: i-1
8165 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
8166 theMesh.SetParameters(Parameters)
8167 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
8169 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
8170 if isinstance( mesh, Mesh ):
8171 mesh = mesh.GetMesh()
8172 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
8174 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
8176 Registering the new proxy for Pattern
8181 Private class used to bind methods creating algorithms to the class Mesh
8184 def __init__(self, method):
8186 self.defaultAlgoType = ""
8187 self.algoTypeToClass = {}
8188 self.method = method
8190 def add(self, algoClass):
8192 Store a python class of algorithm
8194 if inspect.isclass(algoClass) and \
8195 hasattr( algoClass, "algoType"):
8196 self.algoTypeToClass[ algoClass.algoType ] = algoClass
8197 if not self.defaultAlgoType and \
8198 hasattr( algoClass, "isDefault") and algoClass.isDefault:
8199 self.defaultAlgoType = algoClass.algoType
8200 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
8202 def copy(self, mesh):
8204 Create a copy of self and assign mesh to the copy
8207 other = algoCreator( self.method )
8208 other.defaultAlgoType = self.defaultAlgoType
8209 other.algoTypeToClass = self.algoTypeToClass
8213 def __call__(self,algo="",geom=0,*args):
8215 Create an instance of algorithm
8219 if isinstance( algo, str ):
8221 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
8222 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
8227 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
8229 elif not algoType and isinstance( geom, str ):
8234 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
8236 elif isinstance( arg, str ) and not algoType:
8239 import traceback, sys
8240 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
8241 sys.stderr.write( msg + '\n' )
8242 tb = traceback.extract_stack(None,2)
8243 traceback.print_list( [tb[0]] )
8245 algoType = self.defaultAlgoType
8246 if not algoType and self.algoTypeToClass:
8247 algoType = sorted( self.algoTypeToClass.keys() )[0]
8248 if algoType in self.algoTypeToClass:
8249 #print("Create algo",algoType)
8250 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
8251 raise RuntimeError( "No class found for algo type %s" % algoType)
8254 class hypMethodWrapper:
8256 Private class used to substitute and store variable parameters of hypotheses.
8259 def __init__(self, hyp, method):
8261 self.method = method
8262 #print("REBIND:", method.__name__)
8265 def __call__(self,*args):
8267 call a method of hypothesis with calling SetVarParameter() before
8271 return self.method( self.hyp, *args ) # hypothesis method with no args
8273 #print("MethWrapper.__call__", self.method.__name__, args)
8275 parsed = ParseParameters(*args) # replace variables with their values
8276 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
8277 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
8278 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
8279 # maybe there is a replaced string arg which is not variable
8280 result = self.method( self.hyp, *args )
8281 except ValueError as detail: # raised by ParseParameters()
8283 result = self.method( self.hyp, *args )
8284 except omniORB.CORBA.BAD_PARAM:
8285 raise ValueError(detail) # wrong variable name
8290 class genObjUnRegister:
8292 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
8295 def __init__(self, genObj=None):
8296 self.genObjList = []
8300 def set(self, genObj):
8301 "Store one or a list of of SALOME.GenericObj'es"
8302 if isinstance( genObj, list ):
8303 self.genObjList.extend( genObj )
8305 self.genObjList.append( genObj )
8309 for genObj in self.genObjList:
8310 if genObj and hasattr( genObj, "UnRegister" ):
8313 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8315 Bind methods creating mesher plug-ins to the Mesh class
8318 # print("pluginName: ", pluginName)
8319 pluginBuilderName = pluginName + "Builder"
8321 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8322 except Exception as e:
8323 from salome_utils import verbose
8324 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8326 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8327 plugin = eval( pluginBuilderName )
8328 # print(" plugin:" , str(plugin))
8330 # add methods creating algorithms to Mesh
8331 for k in dir( plugin ):
8332 if k[0] == '_': continue
8333 algo = getattr( plugin, k )
8334 #print(" algo:", str(algo))
8335 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8336 #print(" meshMethod:" , str(algo.meshMethod))
8337 if not hasattr( Mesh, algo.meshMethod ):
8338 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8340 _mmethod = getattr( Mesh, algo.meshMethod )
8341 if hasattr( _mmethod, "add" ):