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 CheckCompute(self):
2006 Check if the mesh was properly compute
2008 if not self.mesh.IsComputedOK():
2009 raise Exception("Could not compute {}".format(self.GetName()))
2011 def GetComputeErrors(self, shape=0 ):
2013 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2017 shape = self.mesh.GetShapeToMesh()
2018 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2020 def GetSubShapeName(self, subShapeID ):
2022 Return a name of a sub-shape by its ID.
2023 Possible variants (for *subShapeID* == 3):
2025 - **"Face_12"** - published sub-shape
2026 - **FACE #3** - not published sub-shape
2027 - **sub-shape #3** - invalid sub-shape ID
2028 - **#3** - error in this function
2031 subShapeID: a unique ID of a sub-shape
2034 a string describing the sub-shape
2038 if not self.mesh.HasShapeToMesh():
2042 mainIOR = salome.orb.object_to_string( self.GetShape() )
2044 mainSO = s.FindObjectIOR(mainIOR)
2047 shapeText = '"%s"' % mainSO.GetName()
2048 subIt = s.NewChildIterator(mainSO)
2050 subSO = subIt.Value()
2052 obj = subSO.GetObject()
2053 if not obj: continue
2054 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2057 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2060 if ids == subShapeID:
2061 shapeText = '"%s"' % subSO.GetName()
2064 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2066 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2068 shapeText = 'sub-shape #%s' % (subShapeID)
2070 shapeText = "#%s" % (subShapeID)
2073 def GetFailedShapes(self, publish=False):
2075 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2076 error of an algorithm
2079 publish: if *True*, the returned groups will be published in the study
2082 a list of GEOM groups each named after a failed algorithm
2087 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2088 for err in computeErrors:
2089 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2090 if not shape: continue
2091 if err.algoName in algo2shapes:
2092 algo2shapes[ err.algoName ].append( shape )
2094 algo2shapes[ err.algoName ] = [ shape ]
2098 for algoName, shapes in list(algo2shapes.items()):
2100 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2101 otherTypeShapes = []
2103 group = self.geompyD.CreateGroup( self.geom, groupType )
2104 for shape in shapes:
2105 if shape.GetShapeType() == shapes[0].GetShapeType():
2106 sameTypeShapes.append( shape )
2108 otherTypeShapes.append( shape )
2109 self.geompyD.UnionList( group, sameTypeShapes )
2111 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2113 group.SetName( algoName )
2114 groups.append( group )
2115 shapes = otherTypeShapes
2118 for group in groups:
2119 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2122 def GetMeshOrder(self):
2124 Return sub-mesh objects list in meshing order
2127 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2130 return self.mesh.GetMeshOrder()
2132 def SetMeshOrder(self, submeshes):
2134 Set priority of sub-meshes. It works in two ways:
2136 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2137 *several dimensions*, it sets the order in which the sub-meshes are computed.
2138 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2139 when looking for meshing parameters to apply to a sub-shape. To impose the
2140 order in which sub-meshes with uni-dimensional algorithms are computed,
2141 call **submesh.Compute()** in a desired order.
2144 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2146 Warning: the method is for setting the order for all sub-meshes at once:
2147 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2150 return self.mesh.SetMeshOrder(submeshes)
2152 def Clear(self, refresh=False):
2154 Remove all nodes and elements generated on geometry. Imported elements remain.
2157 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2161 if ( salome.sg.hasDesktop() ):
2162 if refresh: salome.sg.updateObjBrowser()
2164 def ClearSubMesh(self, geomId, refresh=False):
2166 Remove all nodes and elements of indicated shape
2169 geomId: the ID of a sub-shape to remove elements on
2170 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2173 self.mesh.ClearSubMesh(geomId)
2174 if salome.sg.hasDesktop():
2175 if refresh: salome.sg.updateObjBrowser()
2177 def AutomaticTetrahedralization(self, fineness=0):
2179 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2182 fineness: [0.0,1.0] defines mesh fineness
2188 dim = self.MeshDimension()
2190 self.RemoveGlobalHypotheses()
2191 self.Segment().AutomaticLength(fineness)
2193 self.Triangle().LengthFromEdges()
2198 return self.Compute()
2200 def AutomaticHexahedralization(self, fineness=0):
2202 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2205 fineness: [0.0, 1.0] defines mesh fineness
2211 dim = self.MeshDimension()
2212 # assign the hypotheses
2213 self.RemoveGlobalHypotheses()
2214 self.Segment().AutomaticLength(fineness)
2221 return self.Compute()
2223 def AddHypothesis(self, hyp, geom=0):
2228 hyp: a hypothesis to assign
2229 geom: a subhape of mesh geometry
2232 :class:`SMESH.Hypothesis_Status`
2235 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2236 hyp, geom = geom, hyp
2237 if isinstance( hyp, Mesh_Algorithm ):
2238 hyp = hyp.GetAlgorithm()
2243 geom = self.mesh.GetShapeToMesh()
2246 if self.mesh.HasShapeToMesh():
2247 hyp_type = hyp.GetName()
2248 lib_name = hyp.GetLibName()
2249 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2250 # if checkAll and geom:
2251 # checkAll = geom.GetType() == 37
2253 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2255 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2256 status = self.mesh.AddHypothesis(geom, hyp)
2258 status = HYP_BAD_GEOMETRY, ""
2259 hyp_name = GetName( hyp )
2262 geom_name = geom.GetName()
2263 isAlgo = hyp._narrow( SMESH_Algo )
2264 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2267 def IsUsedHypothesis(self, hyp, geom):
2269 Return True if an algorithm or hypothesis is assigned to a given shape
2272 hyp: an algorithm or hypothesis to check
2273 geom: a subhape of mesh geometry
2279 if not hyp: # or not geom
2281 if isinstance( hyp, Mesh_Algorithm ):
2282 hyp = hyp.GetAlgorithm()
2284 hyps = self.GetHypothesisList(geom)
2286 if h.GetId() == hyp.GetId():
2290 def RemoveHypothesis(self, hyp, geom=0):
2292 Unassign a hypothesis
2295 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2296 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2299 :class:`SMESH.Hypothesis_Status`
2304 if isinstance( hyp, Mesh_Algorithm ):
2305 hyp = hyp.GetAlgorithm()
2311 if self.IsUsedHypothesis( hyp, shape ):
2312 return self.mesh.RemoveHypothesis( shape, hyp )
2313 hypName = GetName( hyp )
2314 geoName = GetName( shape )
2315 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2318 def GetHypothesisList(self, geom):
2320 Get the list of hypotheses added on a geometry
2323 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2326 the sequence of :class:`SMESH.SMESH_Hypothesis`
2329 return self.mesh.GetHypothesisList( geom )
2331 def RemoveGlobalHypotheses(self):
2333 Remove all global hypotheses
2336 current_hyps = self.mesh.GetHypothesisList( self.geom )
2337 for hyp in current_hyps:
2338 self.mesh.RemoveHypothesis( self.geom, hyp )
2342 def ExportMEDCoupling(self, *args, **kwargs):
2344 Export the mesh in a memory representation.
2347 auto_groups (boolean): parameter for creating/not creating
2348 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2349 the typical use is auto_groups=False.
2350 overwrite (boolean): parameter for overwriting/not overwriting the file
2351 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2352 to export instead of the mesh
2353 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2355 - 1D if all mesh nodes lie on OX coordinate axis, or
2356 - 2D if all mesh nodes lie on XOY coordinate plane, or
2357 - 3D in the rest cases.
2359 If *autoDimension* is *False*, the space dimension is always 3.
2360 fields: list of GEOM fields defined on the shape to mesh.
2361 geomAssocFields: each character of this string means a need to export a
2362 corresponding field; correspondence between fields and characters
2365 - 'v' stands for "_vertices_" field;
2366 - 'e' stands for "_edges_" field;
2367 - 'f' stands for "_faces_" field;
2368 - 's' stands for "_solids_" field.
2370 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2371 close to zero within a given tolerance, the coordinate is set to zero.
2372 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2373 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2375 auto_groups = args[0] if len(args) > 0 else False
2376 meshPart = args[1] if len(args) > 1 else None
2377 autoDimension = args[2] if len(args) > 2 else True
2378 fields = args[3] if len(args) > 3 else []
2379 geomAssocFields = args[4] if len(args) > 4 else ''
2380 z_tolerance = args[5] if len(args) > 5 else -1.
2381 saveNumbers = args[6] if len(args) > 6 else True
2382 # process keywords arguments
2383 auto_groups = kwargs.get("auto_groups", auto_groups)
2384 meshPart = kwargs.get("meshPart", meshPart)
2385 autoDimension = kwargs.get("autoDimension", autoDimension)
2386 fields = kwargs.get("fields", fields)
2387 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2388 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2389 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2391 # invoke engine's function
2392 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2393 unRegister = genObjUnRegister()
2394 if isinstance( meshPart, list ):
2395 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2396 unRegister.set( meshPart )
2398 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2399 self.mesh.SetParameters(Parameters)
2401 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2402 fields, geomAssocFields, z_tolerance,
2405 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2406 return medcoupling.MEDFileData.New(dab)
2408 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2410 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2411 return medcoupling.MEDFileMesh.New(dab)
2413 def ExportMED(self, *args, **kwargs):
2415 Export the mesh in a file in MED format
2416 allowing to overwrite the file if it exists or add the exported data to its contents
2419 fileName: is the file name
2420 auto_groups (boolean): parameter for creating/not creating
2421 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2422 the typical use is auto_groups=False.
2423 version (int): define the version (xy, where version is x.y.z) of MED file format.
2424 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2425 The rules of compatibility to write a mesh in an older version than
2426 the current version depend on the current version. For instance,
2427 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2428 or 3.2.1 or 3.3.1 formats.
2429 If the version is equal to -1, the version is not changed (default).
2430 overwrite (boolean): parameter for overwriting/not overwriting the file
2431 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2432 to export instead of the mesh
2433 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2435 - 1D if all mesh nodes lie on OX coordinate axis, or
2436 - 2D if all mesh nodes lie on XOY coordinate plane, or
2437 - 3D in the rest cases.
2439 If *autoDimension* is *False*, the space dimension is always 3.
2440 fields: list of GEOM fields defined on the shape to mesh.
2441 geomAssocFields: each character of this string means a need to export a
2442 corresponding field; correspondence between fields and characters
2445 - 'v' stands for "_vertices_" field;
2446 - 'e' stands for "_edges_" field;
2447 - 'f' stands for "_faces_" field;
2448 - 's' stands for "_solids_" field.
2450 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2451 close to zero within a given tolerance, the coordinate is set to zero.
2452 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2453 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2455 # process positional arguments
2456 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2458 auto_groups = args[1] if len(args) > 1 else False
2459 version = args[2] if len(args) > 2 else -1
2460 overwrite = args[3] if len(args) > 3 else True
2461 meshPart = args[4] if len(args) > 4 else None
2462 autoDimension = args[5] if len(args) > 5 else True
2463 fields = args[6] if len(args) > 6 else []
2464 geomAssocFields = args[7] if len(args) > 7 else ''
2465 z_tolerance = args[8] if len(args) > 8 else -1.
2466 saveNumbers = args[9] if len(args) > 9 else True
2467 # process keywords arguments
2468 auto_groups = kwargs.get("auto_groups", auto_groups)
2469 version = kwargs.get("version", version)
2470 version = kwargs.get("minor", version)
2471 overwrite = kwargs.get("overwrite", overwrite)
2472 meshPart = kwargs.get("meshPart", meshPart)
2473 autoDimension = kwargs.get("autoDimension", autoDimension)
2474 fields = kwargs.get("fields", fields)
2475 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2476 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2477 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2479 if isinstance( meshPart, Mesh):
2480 meshPart = meshPart.GetMesh()
2482 # invoke engine's function
2483 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2484 unRegister = genObjUnRegister()
2485 if isinstance( meshPart, list ):
2486 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2487 unRegister.set( meshPart )
2489 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2490 self.mesh.SetParameters(Parameters)
2492 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2493 version, overwrite, autoDimension,
2494 fields, geomAssocFields, z_tolerance, saveNumbers )
2496 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2498 def ExportDAT(self, f, meshPart=None, renumber=True):
2500 Export the mesh in a file in DAT format
2504 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2505 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2508 if meshPart or not renumber:
2509 unRegister = genObjUnRegister()
2510 if isinstance( meshPart, list ):
2511 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2512 unRegister.set( meshPart )
2513 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2515 self.mesh.ExportDAT( f, renumber )
2517 def ExportUNV(self, f, meshPart=None, renumber=True):
2519 Export the mesh in a file in UNV format
2523 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2524 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2527 if meshPart or not renumber:
2528 unRegister = genObjUnRegister()
2529 if isinstance( meshPart, list ):
2530 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2531 unRegister.set( meshPart )
2532 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2534 self.mesh.ExportUNV( f, renumber )
2536 def ExportSTL(self, f, ascii=1, meshPart=None):
2538 Export the mesh in a file in STL format
2542 ascii: defines the file encoding
2543 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2547 unRegister = genObjUnRegister()
2548 if isinstance( meshPart, list ):
2549 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2550 unRegister.set( meshPart )
2551 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2553 self.mesh.ExportSTL(f, ascii)
2555 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2557 Export the mesh in a file in CGNS format
2561 overwrite: boolean parameter for overwriting/not overwriting the file
2562 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2563 groupElemsByType: if True all elements of same entity type are exported at ones,
2564 else elements are exported in order of their IDs which can cause creation
2565 of multiple cgns sections
2568 unRegister = genObjUnRegister()
2569 if isinstance( meshPart, list ):
2570 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2571 unRegister.set( meshPart )
2572 if isinstance( meshPart, Mesh ):
2573 meshPart = meshPart.mesh
2575 meshPart = self.mesh
2576 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2578 def ExportGMF(self, f, meshPart=None):
2580 Export the mesh in a file in GMF format.
2581 GMF files must have .mesh extension for the ASCII format and .meshb for
2582 the bynary format. Other extensions are not allowed.
2586 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2589 unRegister = genObjUnRegister()
2590 if isinstance( meshPart, list ):
2591 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2592 unRegister.set( meshPart )
2593 if isinstance( meshPart, Mesh ):
2594 meshPart = meshPart.mesh
2596 meshPart = self.mesh
2597 self.mesh.ExportGMF(meshPart, f, True)
2599 def ExportToMED(self, *args, **kwargs):
2601 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2602 Export the mesh in a file in MED format
2603 allowing to overwrite the file if it exists or add the exported data to its contents
2606 fileName: the file name
2607 opt (boolean): parameter for creating/not creating
2608 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2609 overwrite: boolean parameter for overwriting/not overwriting the file
2610 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2612 - 1D if all mesh nodes lie on OX coordinate axis, or
2613 - 2D if all mesh nodes lie on XOY coordinate plane, or
2614 - 3D in the rest cases.
2616 If **autoDimension** is *False*, the space dimension is always 3.
2619 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2620 # process positional arguments
2621 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2623 auto_groups = args[1] if len(args) > 1 else False
2624 overwrite = args[2] if len(args) > 2 else True
2625 autoDimension = args[3] if len(args) > 3 else True
2626 # process keywords arguments
2627 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2628 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2629 overwrite = kwargs.get("overwrite", overwrite)
2630 autoDimension = kwargs.get("autoDimension", autoDimension)
2632 # invoke engine's function
2633 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2635 def ExportToMEDX(self, *args, **kwargs):
2637 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2638 Export the mesh in a file in MED format
2641 fileName: the file name
2642 opt (boolean): parameter for creating/not creating
2643 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2644 overwrite: boolean parameter for overwriting/not overwriting the file
2645 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2647 - 1D if all mesh nodes lie on OX coordinate axis, or
2648 - 2D if all mesh nodes lie on XOY coordinate plane, or
2649 - 3D in the rest cases.
2651 If **autoDimension** is *False*, the space dimension is always 3.
2654 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2655 # process positional arguments
2656 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2658 auto_groups = args[1] if len(args) > 1 else False
2659 overwrite = args[2] if len(args) > 2 else True
2660 autoDimension = args[3] if len(args) > 3 else True
2661 # process keywords arguments
2662 auto_groups = kwargs.get("auto_groups", auto_groups)
2663 overwrite = kwargs.get("overwrite", overwrite)
2664 autoDimension = kwargs.get("autoDimension", autoDimension)
2666 # invoke engine's function
2667 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2671 def Append(self, meshes, uniteIdenticalGroups = True,
2672 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2674 Append given meshes into this mesh.
2675 All groups of input meshes will be created in this mesh.
2678 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2679 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2680 mergeNodesAndElements: if True, equal nodes and elements are merged
2681 mergeTolerance: tolerance for merging nodes
2682 allGroups: forces creation of groups corresponding to every input mesh
2684 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2685 mergeNodesAndElements, mergeTolerance, allGroups,
2686 meshToAppendTo = self.GetMesh() )
2688 # Operations with groups:
2689 # ----------------------
2690 def CreateEmptyGroup(self, elementType, name):
2692 Create an empty standalone mesh group
2695 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2696 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2697 name: the name of the mesh group
2700 :class:`SMESH.SMESH_Group`
2703 return self.mesh.CreateGroup(elementType, name)
2705 def Group(self, grp, name=""):
2707 Create a mesh group based on the geometric object *grp*
2708 and give it a *name*.
2709 If *name* is not defined the name of the geometric group is used
2712 Works like :meth:`GroupOnGeom`.
2715 grp: a geometric group, a vertex, an edge, a face or a solid
2716 name: the name of the mesh group
2719 :class:`SMESH.SMESH_GroupOnGeom`
2722 return self.GroupOnGeom(grp, name)
2724 def GroupOnGeom(self, grp, name="", typ=None):
2726 Create a mesh group based on the geometrical object *grp*
2727 and give it a *name*.
2728 if *name* is not defined the name of the geometric group is used
2731 grp: a geometrical group, a vertex, an edge, a face or a solid
2732 name: the name of the mesh group
2733 typ: the type of elements in the group; either of
2734 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2735 automatically detected by the type of the geometry
2738 :class:`SMESH.SMESH_GroupOnGeom`
2741 AssureGeomPublished( self, grp, name )
2743 name = grp.GetName()
2745 typ = self._groupTypeFromShape( grp )
2746 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2748 def _groupTypeFromShape( self, shape ):
2750 Pivate method to get a type of group on geometry
2752 tgeo = str(shape.GetShapeType())
2753 if tgeo == "VERTEX":
2755 elif tgeo == "EDGE" or tgeo == "WIRE":
2757 elif tgeo == "FACE" or tgeo == "SHELL":
2759 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2761 elif tgeo == "COMPOUND":
2763 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2765 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2766 # simplification of access in geomBuilder: omniORB.registerObjref
2767 from SHAPERSTUDY_utils import getEngine
2770 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2772 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2773 return self._groupTypeFromShape( sub[0] )
2775 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2778 def GroupOnFilter(self, typ, name, filter):
2780 Create a mesh group with given *name* based on the *filter*.
2781 It is a special type of group dynamically updating it's contents during
2785 typ: the type of elements in the group; either of
2786 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2787 name: the name of the mesh group
2788 filter (SMESH.Filter): the filter defining group contents
2791 :class:`SMESH.SMESH_GroupOnFilter`
2794 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2796 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2798 Create a mesh group by the given ids of elements
2801 groupName: the name of the mesh group
2802 elementType: the type of elements in the group; either of
2803 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2804 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2807 :class:`SMESH.SMESH_Group`
2810 group = self.mesh.CreateGroup(elementType, groupName)
2811 if isinstance( elemIDs, Mesh ):
2812 elemIDs = elemIDs.GetMesh()
2813 if hasattr( elemIDs, "GetIDs" ):
2814 if hasattr( elemIDs, "SetMesh" ):
2815 elemIDs.SetMesh( self.GetMesh() )
2816 group.AddFrom( elemIDs )
2824 CritType=FT_Undefined,
2827 UnaryOp=FT_Undefined,
2830 Create a mesh group by the given conditions
2833 groupName: the name of the mesh group
2834 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2835 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2836 Note that the items starting from FT_LessThan are not suitable for CritType.
2837 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2838 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2839 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2840 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2841 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2844 :class:`SMESH.SMESH_GroupOnFilter`
2847 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2848 group = self.MakeGroupByCriterion(groupName, aCriterion)
2851 def MakeGroupByCriterion(self, groupName, Criterion):
2853 Create a mesh group by the given criterion
2856 groupName: the name of the mesh group
2857 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2860 :class:`SMESH.SMESH_GroupOnFilter`
2863 :meth:`smeshBuilder.GetCriterion`
2866 return self.MakeGroupByCriteria( groupName, [Criterion] )
2868 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2870 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2873 groupName: the name of the mesh group
2874 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2875 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2878 :class:`SMESH.SMESH_GroupOnFilter`
2881 :meth:`smeshBuilder.GetCriterion`
2884 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2885 group = self.MakeGroupByFilter(groupName, aFilter)
2888 def MakeGroupByFilter(self, groupName, theFilter):
2890 Create a mesh group by the given filter
2893 groupName (string): the name of the mesh group
2894 theFilter (SMESH.Filter): the filter
2897 :class:`SMESH.SMESH_GroupOnFilter`
2900 :meth:`smeshBuilder.GetFilter`
2903 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2904 #theFilter.SetMesh( self.mesh )
2905 #group.AddFrom( theFilter )
2906 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2909 def RemoveGroup(self, group):
2914 group (SMESH.SMESH_GroupBase): group to remove
2917 self.mesh.RemoveGroup(group)
2919 def RemoveGroupWithContents(self, group):
2921 Remove a group with its contents
2924 group (SMESH.SMESH_GroupBase): group to remove
2927 This operation can create gaps in numeration of nodes or elements.
2928 Call :meth:`RenumberElements` to remove the gaps.
2931 self.mesh.RemoveGroupWithContents(group)
2933 def GetGroups(self, elemType = SMESH.ALL):
2935 Get the list of groups existing in the mesh in the order of creation
2936 (starting from the oldest one)
2939 elemType (SMESH.ElementType): type of elements the groups contain;
2940 by default groups of elements of all types are returned
2943 a list of :class:`SMESH.SMESH_GroupBase`
2946 groups = self.mesh.GetGroups()
2947 if elemType == SMESH.ALL:
2951 if g.GetType() == elemType:
2952 typedGroups.append( g )
2959 Get the number of groups existing in the mesh
2962 the quantity of groups as an integer value
2965 return self.mesh.NbGroups()
2967 def GetGroupNames(self):
2969 Get the list of names of groups existing in the mesh
2975 groups = self.GetGroups()
2977 for group in groups:
2978 names.append(group.GetName())
2981 def GetGroupByName(self, name, elemType = None):
2983 Find groups by name and type
2986 name (string): name of the group of interest
2987 elemType (SMESH.ElementType): type of elements the groups contain;
2988 by default one group of any type is returned;
2989 if elemType == SMESH.ALL then all groups of any type are returned
2992 a list of :class:`SMESH.SMESH_GroupBase`
2996 for group in self.GetGroups():
2997 if group.GetName() == name:
2998 if elemType is None:
3000 if ( elemType == SMESH.ALL or
3001 group.GetType() == elemType ):
3002 groups.append( group )
3005 def UnionGroups(self, group1, group2, name):
3007 Produce a union of two groups.
3008 A new group is created. All mesh elements that are
3009 present in the initial groups are added to the new one
3012 group1 (SMESH.SMESH_GroupBase): a group
3013 group2 (SMESH.SMESH_GroupBase): another group
3016 instance of :class:`SMESH.SMESH_Group`
3019 return self.mesh.UnionGroups(group1, group2, name)
3021 def UnionListOfGroups(self, groups, name):
3023 Produce a union list of groups.
3024 New group is created. All mesh elements that are present in
3025 initial groups are added to the new one
3028 groups: list of :class:`SMESH.SMESH_GroupBase`
3031 instance of :class:`SMESH.SMESH_Group`
3033 return self.mesh.UnionListOfGroups(groups, name)
3035 def IntersectGroups(self, group1, group2, name):
3037 Prodice an intersection of two groups.
3038 A new group is created. All mesh elements that are common
3039 for the two initial groups are added to the new one.
3042 group1 (SMESH.SMESH_GroupBase): a group
3043 group2 (SMESH.SMESH_GroupBase): another group
3046 instance of :class:`SMESH.SMESH_Group`
3049 return self.mesh.IntersectGroups(group1, group2, name)
3051 def IntersectListOfGroups(self, groups, name):
3053 Produce an intersection of groups.
3054 New group is created. All mesh elements that are present in all
3055 initial groups simultaneously are added to the new one
3058 groups: a list of :class:`SMESH.SMESH_GroupBase`
3061 instance of :class:`SMESH.SMESH_Group`
3063 return self.mesh.IntersectListOfGroups(groups, name)
3065 def CutGroups(self, main_group, tool_group, name):
3067 Produce a cut of two groups.
3068 A new group is created. All mesh elements that are present in
3069 the main group but are not present in the tool group are added to the new one
3072 main_group (SMESH.SMESH_GroupBase): a group to cut from
3073 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3076 an instance of :class:`SMESH.SMESH_Group`
3079 return self.mesh.CutGroups(main_group, tool_group, name)
3081 def CutListOfGroups(self, main_groups, tool_groups, name):
3083 Produce a cut of groups.
3084 A new group is created. All mesh elements that are present in main groups
3085 but do not present in tool groups are added to the new one
3088 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3089 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3092 an instance of :class:`SMESH.SMESH_Group`
3095 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3097 def CreateDimGroup(self, groups, elemType, name,
3098 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3100 Create a standalone group of entities basing on nodes of other groups.
3103 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3104 elemType: a type of elements to include to the new group; either of
3105 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3106 name: a name of the new group.
3107 nbCommonNodes: a criterion of inclusion of an element to the new group
3108 basing on number of element nodes common with reference *groups*.
3109 Meaning of possible values are:
3111 - SMESH.ALL_NODES - include if all nodes are common,
3112 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3113 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3114 - SMEHS.MAJORITY - include if half of nodes or more are common.
3115 underlyingOnly: if *True* (default), an element is included to the
3116 new group provided that it is based on nodes of an element of *groups*;
3117 in this case the reference *groups* are supposed to be of higher dimension
3118 than *elemType*, which can be useful for example to get all faces lying on
3119 volumes of the reference *groups*.
3122 an instance of :class:`SMESH.SMESH_Group`
3125 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3127 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3129 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3131 Distribute all faces of the mesh among groups using sharp edges and optionally
3132 existing 1D elements as group boundaries.
3135 sharpAngle: edge is considered sharp if an angle between normals of
3136 adjacent faces is more than \a sharpAngle in degrees.
3137 createEdges (boolean): to create 1D elements for detected sharp edges.
3138 useExistingEdges (boolean): to use existing edges as group boundaries
3140 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3142 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3143 self.mesh.SetParameters(Parameters)
3144 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3146 def ConvertToStandalone(self, group):
3148 Convert group on geom into standalone group
3151 return self.mesh.ConvertToStandalone(group)
3153 # Get some info about mesh:
3154 # ------------------------
3156 def GetLog(self, clearAfterGet):
3158 Return the log of nodes and elements added or removed
3159 since the previous clear of the log.
3162 clearAfterGet: log is emptied after Get (safe if concurrents access)
3165 list of SMESH.log_block structures { commandType, number, coords, indexes }
3168 return self.mesh.GetLog(clearAfterGet)
3172 Clear the log of nodes and elements added or removed since the previous
3173 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3176 self.mesh.ClearLog()
3178 def SetAutoColor(self, theAutoColor):
3180 Toggle auto color mode on the object.
3181 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3184 theAutoColor (boolean): the flag which toggles auto color mode.
3187 self.mesh.SetAutoColor(theAutoColor)
3189 def GetAutoColor(self):
3191 Get flag of object auto color mode.
3197 return self.mesh.GetAutoColor()
3204 integer value, which is the internal Id of the mesh
3207 return self.mesh.GetId()
3209 def HasDuplicatedGroupNamesMED(self):
3211 Check the group names for duplications.
3212 Consider the maximum group name length stored in MED file.
3218 return self.mesh.HasDuplicatedGroupNamesMED()
3220 def GetMeshEditor(self):
3222 Obtain the mesh editor tool
3225 an instance of :class:`SMESH.SMESH_MeshEditor`
3230 def GetIDSource(self, ids, elemType = SMESH.ALL):
3232 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3233 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3237 elemType: type of elements; this parameter is used to distinguish
3238 IDs of nodes from IDs of elements; by default ids are treated as
3239 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3242 an instance of :class:`SMESH.SMESH_IDSource`
3245 call UnRegister() for the returned object as soon as it is no more useful::
3247 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3248 mesh.DoSomething( idSrc )
3252 if isinstance( ids, int ):
3254 return self.editor.MakeIDSource(ids, elemType)
3257 # Get information about mesh contents:
3258 # ------------------------------------
3260 def GetMeshInfo(self, obj = None):
3262 Get the mesh statistic.
3265 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3268 if not obj: obj = self.mesh
3269 return self.smeshpyD.GetMeshInfo(obj)
3273 Return the number of nodes in the mesh
3279 return self.mesh.NbNodes()
3281 def NbElements(self):
3283 Return the number of elements in the mesh
3289 return self.mesh.NbElements()
3291 def Nb0DElements(self):
3293 Return the number of 0d elements in the mesh
3299 return self.mesh.Nb0DElements()
3303 Return the number of ball discrete elements in the mesh
3309 return self.mesh.NbBalls()
3313 Return the number of edges in the mesh
3319 return self.mesh.NbEdges()
3321 def NbEdgesOfOrder(self, elementOrder):
3323 Return the number of edges with the given order in the mesh
3326 elementOrder: the order of elements
3327 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3333 return self.mesh.NbEdgesOfOrder(elementOrder)
3337 Return the number of faces in the mesh
3343 return self.mesh.NbFaces()
3345 def NbFacesOfOrder(self, elementOrder):
3347 Return the number of faces with the given order in the mesh
3350 elementOrder: the order of elements
3351 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3357 return self.mesh.NbFacesOfOrder(elementOrder)
3359 def NbTriangles(self):
3361 Return the number of triangles in the mesh
3367 return self.mesh.NbTriangles()
3369 def NbTrianglesOfOrder(self, elementOrder):
3371 Return the number of triangles with the given order in the mesh
3374 elementOrder: is the order of elements
3375 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3381 return self.mesh.NbTrianglesOfOrder(elementOrder)
3383 def NbBiQuadTriangles(self):
3385 Return the number of biquadratic triangles in the mesh
3391 return self.mesh.NbBiQuadTriangles()
3393 def NbQuadrangles(self):
3395 Return the number of quadrangles in the mesh
3401 return self.mesh.NbQuadrangles()
3403 def NbQuadranglesOfOrder(self, elementOrder):
3405 Return the number of quadrangles with the given order in the mesh
3408 elementOrder: the order of elements
3409 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3415 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3417 def NbBiQuadQuadrangles(self):
3419 Return the number of biquadratic quadrangles in the mesh
3425 return self.mesh.NbBiQuadQuadrangles()
3427 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3429 Return the number of polygons of given order in the mesh
3432 elementOrder: the order of elements
3433 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3439 return self.mesh.NbPolygonsOfOrder(elementOrder)
3441 def NbVolumes(self):
3443 Return the number of volumes in the mesh
3449 return self.mesh.NbVolumes()
3452 def NbVolumesOfOrder(self, elementOrder):
3454 Return the number of volumes with the given order in the mesh
3457 elementOrder: the order of elements
3458 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3464 return self.mesh.NbVolumesOfOrder(elementOrder)
3468 Return the number of tetrahedrons in the mesh
3474 return self.mesh.NbTetras()
3476 def NbTetrasOfOrder(self, elementOrder):
3478 Return the number of tetrahedrons with the given order in the mesh
3481 elementOrder: the order of elements
3482 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3488 return self.mesh.NbTetrasOfOrder(elementOrder)
3492 Return the number of hexahedrons in the mesh
3498 return self.mesh.NbHexas()
3500 def NbHexasOfOrder(self, elementOrder):
3502 Return the number of hexahedrons with the given order in the mesh
3505 elementOrder: the order of elements
3506 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3512 return self.mesh.NbHexasOfOrder(elementOrder)
3514 def NbTriQuadraticHexas(self):
3516 Return the number of triquadratic hexahedrons in the mesh
3522 return self.mesh.NbTriQuadraticHexas()
3524 def NbPyramids(self):
3526 Return the number of pyramids in the mesh
3532 return self.mesh.NbPyramids()
3534 def NbPyramidsOfOrder(self, elementOrder):
3536 Return the number of pyramids with the given order in the mesh
3539 elementOrder: the order of elements
3540 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3546 return self.mesh.NbPyramidsOfOrder(elementOrder)
3550 Return the number of prisms in the mesh
3556 return self.mesh.NbPrisms()
3558 def NbPrismsOfOrder(self, elementOrder):
3560 Return the number of prisms with the given order in the mesh
3563 elementOrder: the order of elements
3564 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3570 return self.mesh.NbPrismsOfOrder(elementOrder)
3572 def NbHexagonalPrisms(self):
3574 Return the number of hexagonal prisms in the mesh
3580 return self.mesh.NbHexagonalPrisms()
3582 def NbPolyhedrons(self):
3584 Return the number of polyhedrons in the mesh
3590 return self.mesh.NbPolyhedrons()
3592 def NbSubMesh(self):
3594 Return the number of submeshes in the mesh
3600 return self.mesh.NbSubMesh()
3602 def GetElementsId(self):
3604 Return the list of all mesh elements IDs
3607 the list of integer values
3610 :meth:`GetElementsByType`
3613 return self.mesh.GetElementsId()
3615 def GetElementsByType(self, elementType):
3617 Return the list of IDs of mesh elements with the given type
3620 elementType (SMESH.ElementType): the required type of elements
3623 list of integer values
3626 return self.mesh.GetElementsByType(elementType)
3628 def GetNodesId(self):
3630 Return the list of mesh nodes IDs
3633 the list of integer values
3636 return self.mesh.GetNodesId()
3638 # Get the information about mesh elements:
3639 # ------------------------------------
3641 def GetElementType(self, id, iselem=True):
3643 Return the type of mesh element or node
3646 the value from :class:`SMESH.ElementType` enumeration.
3647 Return SMESH.ALL if element or node with the given ID does not exist
3650 return self.mesh.GetElementType(id, iselem)
3652 def GetElementGeomType(self, id):
3654 Return the geometric type of mesh element
3657 the value from :class:`SMESH.EntityType` enumeration.
3660 return self.mesh.GetElementGeomType(id)
3662 def GetElementShape(self, id):
3664 Return the shape type of mesh element
3667 the value from :class:`SMESH.GeometryType` enumeration.
3670 return self.mesh.GetElementShape(id)
3672 def GetSubMeshElementsId(self, Shape):
3674 Return the list of sub-mesh elements IDs
3677 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3678 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3681 list of integer values
3684 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3685 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3688 return self.mesh.GetSubMeshElementsId(ShapeID)
3690 def GetSubMeshNodesId(self, Shape, all):
3692 Return the list of sub-mesh nodes IDs
3695 Shape: a geom object (sub-shape).
3696 *Shape* must be the sub-shape of a :meth:`GetShape`
3697 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3700 list of integer values
3703 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3704 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3707 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3709 def GetSubMeshElementType(self, Shape):
3711 Return type of elements on given shape
3714 Shape: a geom object (sub-shape).
3715 *Shape* must be a sub-shape of a ShapeToMesh()
3718 :class:`SMESH.ElementType`
3721 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3722 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3725 return self.mesh.GetSubMeshElementType(ShapeID)
3729 Get the mesh description
3735 return self.mesh.Dump()
3738 # Get the information about nodes and elements of a mesh by its IDs:
3739 # -----------------------------------------------------------
3741 def GetNodeXYZ(self, id):
3743 Get XYZ coordinates of a node.
3744 If there is no node for the given ID - return an empty list
3747 list of float values
3750 return self.mesh.GetNodeXYZ(id)
3752 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3754 Return list of IDs of inverse elements for the given node.
3755 If there is no node for the given ID - return an empty list
3759 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3762 list of integer values
3765 return self.mesh.GetNodeInverseElements(id,elemType)
3767 def GetNodePosition(self,NodeID):
3769 Return the position of a node on the shape
3772 :class:`SMESH.NodePosition`
3775 return self.mesh.GetNodePosition(NodeID)
3777 def GetElementPosition(self,ElemID):
3779 Return the position of an element on the shape
3782 :class:`SMESH.ElementPosition`
3785 return self.mesh.GetElementPosition(ElemID)
3787 def GetShapeID(self, id):
3789 Return the ID of the shape, on which the given node was generated.
3792 an integer value > 0 or -1 if there is no node for the given
3793 ID or the node is not assigned to any geometry
3796 return self.mesh.GetShapeID(id)
3798 def GetShapeIDForElem(self,id):
3800 Return the ID of the shape, on which the given element was generated.
3803 an integer value > 0 or -1 if there is no element for the given
3804 ID or the element is not assigned to any geometry
3807 return self.mesh.GetShapeIDForElem(id)
3809 def GetElemNbNodes(self, id):
3811 Return the number of nodes of the given element
3814 an integer value > 0 or -1 if there is no element for the given ID
3817 return self.mesh.GetElemNbNodes(id)
3819 def GetElemNode(self, id, index):
3821 Return the node ID the given (zero based) index for the given element.
3823 * If there is no element for the given ID - return -1.
3824 * If there is no node for the given index - return -2.
3827 id (int): element ID
3828 index (int): node index within the element
3831 an integer value (ID)
3834 :meth:`GetElemNodes`
3837 return self.mesh.GetElemNode(id, index)
3839 def GetElemNodes(self, id):
3841 Return the IDs of nodes of the given element
3844 a list of integer values
3847 return self.mesh.GetElemNodes(id)
3849 def IsMediumNode(self, elementID, nodeID):
3851 Return true if the given node is the medium node in the given quadratic element
3854 return self.mesh.IsMediumNode(elementID, nodeID)
3856 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3858 Return true if the given node is the medium node in one of quadratic elements
3861 nodeID: ID of the node
3862 elementType: the type of elements to check a state of the node, either of
3863 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3866 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3868 def ElemNbEdges(self, id):
3870 Return the number of edges for the given element
3873 return self.mesh.ElemNbEdges(id)
3875 def ElemNbFaces(self, id):
3877 Return the number of faces for the given element
3880 return self.mesh.ElemNbFaces(id)
3882 def GetElemFaceNodes(self,elemId, faceIndex):
3884 Return nodes of given face (counted from zero) for given volumic element.
3887 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3889 def GetFaceNormal(self, faceId, normalized=False):
3891 Return three components of normal of given mesh face
3892 (or an empty array in KO case)
3895 return self.mesh.GetFaceNormal(faceId,normalized)
3897 def FindElementByNodes(self, nodes):
3899 Return an element based on all given nodes.
3902 return self.mesh.FindElementByNodes(nodes)
3904 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3906 Return elements including all given nodes.
3909 return self.mesh.GetElementsByNodes( nodes, elemType )
3911 def IsPoly(self, id):
3913 Return true if the given element is a polygon
3916 return self.mesh.IsPoly(id)
3918 def IsQuadratic(self, id):
3920 Return true if the given element is quadratic
3923 return self.mesh.IsQuadratic(id)
3925 def GetBallDiameter(self, id):
3927 Return diameter of a ball discrete element or zero in case of an invalid *id*
3930 return self.mesh.GetBallDiameter(id)
3932 def BaryCenter(self, id):
3934 Return XYZ coordinates of the barycenter of the given element.
3935 If there is no element for the given ID - return an empty list
3938 a list of three double values
3941 :meth:`smeshBuilder.GetGravityCenter`
3944 return self.mesh.BaryCenter(id)
3946 def GetIdsFromFilter(self, filter, meshParts=[] ):
3948 Pass mesh elements through the given filter and return IDs of fitting elements
3951 filter: :class:`SMESH.Filter`
3952 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3958 :meth:`SMESH.Filter.GetIDs`
3959 :meth:`SMESH.Filter.GetElementsIdFromParts`
3962 filter.SetMesh( self.mesh )
3965 if isinstance( meshParts, Mesh ):
3966 filter.SetMesh( meshParts.GetMesh() )
3967 return theFilter.GetIDs()
3968 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3969 meshParts = [ meshParts ]
3970 return filter.GetElementsIdFromParts( meshParts )
3972 return filter.GetIDs()
3974 # Get mesh measurements information:
3975 # ------------------------------------
3977 def GetFreeBorders(self):
3979 Verify whether a 2D mesh element has free edges (edges connected to one face only).
3980 Return a list of special structures (borders).
3983 a list of :class:`SMESH.FreeEdges.Border`
3986 aFilterMgr = self.smeshpyD.CreateFilterManager()
3987 aPredicate = aFilterMgr.CreateFreeEdges()
3988 aPredicate.SetMesh(self.mesh)
3989 aBorders = aPredicate.GetBorders()
3990 aFilterMgr.UnRegister()
3993 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3995 Get minimum distance between two nodes, elements or distance to the origin
3998 id1: first node/element id
3999 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4000 isElem1: *True* if *id1* is element id, *False* if it is node id
4001 isElem2: *True* if *id2* is element id, *False* if it is node id
4004 minimum distance value
4006 :meth:`GetMinDistance`
4009 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4010 return aMeasure.value
4012 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4014 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4017 id1: first node/element id
4018 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4019 isElem1: *True* if *id1* is element id, *False* if it is node id
4020 isElem2: *True* if *id2* is element id, *False* if it is node id
4023 :class:`SMESH.Measure` structure
4029 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4031 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4034 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4036 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4041 aMeasurements = self.smeshpyD.CreateMeasurements()
4042 aMeasure = aMeasurements.MinDistance(id1, id2)
4043 genObjUnRegister([aMeasurements,id1, id2])
4046 def BoundingBox(self, objects=None, isElem=False):
4048 Get bounding box of the specified object(s)
4051 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4052 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4053 *False* specifies that *objects* are nodes
4056 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4059 :meth:`GetBoundingBox()`
4062 result = self.GetBoundingBox(objects, isElem)
4066 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4069 def GetBoundingBox(self, objects=None, isElem=False):
4071 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4074 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4075 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4076 False means that *objects* are nodes
4079 :class:`SMESH.Measure` structure
4082 :meth:`BoundingBox()`
4086 objects = [self.mesh]
4087 elif isinstance(objects, tuple):
4088 objects = list(objects)
4089 if not isinstance(objects, list):
4091 if len(objects) > 0 and isinstance(objects[0], int):
4094 unRegister = genObjUnRegister()
4096 if isinstance(o, Mesh):
4097 srclist.append(o.mesh)
4098 elif hasattr(o, "_narrow"):
4099 src = o._narrow(SMESH.SMESH_IDSource)
4100 if src: srclist.append(src)
4102 elif isinstance(o, list):
4104 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4106 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4107 unRegister.set( srclist[-1] )
4110 aMeasurements = self.smeshpyD.CreateMeasurements()
4111 unRegister.set( aMeasurements )
4112 aMeasure = aMeasurements.BoundingBox(srclist)
4115 # Mesh edition (SMESH_MeshEditor functionality):
4116 # ---------------------------------------------
4118 def RemoveElements(self, IDsOfElements):
4120 Remove the elements from the mesh by ids
4123 IDsOfElements: is a list of ids of elements to remove
4129 This operation can create gaps in numeration of elements.
4130 Call :meth:`RenumberElements` to remove the gaps.
4133 return self.editor.RemoveElements(IDsOfElements)
4135 def RemoveNodes(self, IDsOfNodes):
4137 Remove nodes from mesh by ids
4140 IDsOfNodes: is a list of ids of nodes to remove
4146 This operation can create gaps in numeration of nodes.
4147 Call :meth:`RenumberElements` to remove the gaps.
4150 return self.editor.RemoveNodes(IDsOfNodes)
4152 def RemoveNodeWithReconnection(self, nodeID ):
4154 Remove a node along with changing surrounding faces to cover a hole.
4157 nodeID: ID of node to remove
4160 return self.editor.RemoveNodeWithReconnection( nodeID )
4162 def RemoveOrphanNodes(self):
4164 Remove all orphan (free) nodes from mesh
4167 number of the removed nodes
4170 This operation can create gaps in numeration of nodes.
4171 Call :meth:`RenumberElements` to remove the gaps.
4174 return self.editor.RemoveOrphanNodes()
4176 def AddNode(self, x, y, z):
4178 Add a node to the mesh by coordinates
4184 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4185 if hasVars: self.mesh.SetParameters(Parameters)
4186 return self.editor.AddNode( x, y, z)
4188 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4190 Create a 0D element on a node with given number.
4193 IDOfNode: the ID of node for creation of the element.
4194 DuplicateElements: to add one more 0D element to a node or not
4197 ID of the new 0D element
4200 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4202 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4204 Create 0D elements on all nodes of the given elements except those
4205 nodes on which a 0D element already exists.
4208 theObject: an object on whose nodes 0D elements will be created.
4209 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4210 theGroupName: optional name of a group to add 0D elements created
4211 and/or found on nodes of *theObject*.
4212 DuplicateElements: to add one more 0D element to a node or not
4215 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4216 IDs of new and/or found 0D elements. IDs of 0D elements
4217 can be retrieved from the returned object by
4218 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4221 unRegister = genObjUnRegister()
4222 if isinstance( theObject, Mesh ):
4223 theObject = theObject.GetMesh()
4224 elif isinstance( theObject, list ):
4225 theObject = self.GetIDSource( theObject, SMESH.ALL )
4226 unRegister.set( theObject )
4227 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4229 def AddBall(self, IDOfNode, diameter):
4231 Create a ball element on a node with given ID.
4234 IDOfNode: the ID of node for creation of the element.
4235 diameter: the bal diameter.
4238 ID of the new ball element
4241 return self.editor.AddBall( IDOfNode, diameter )
4243 def AddEdge(self, IDsOfNodes):
4245 Create a linear or quadratic edge (this is determined
4246 by the number of given nodes).
4249 IDsOfNodes: list of node IDs for creation of the element.
4250 The order of nodes in this list should correspond to
4251 the :ref:`connectivity convention <connectivity_page>`.
4257 return self.editor.AddEdge(IDsOfNodes)
4259 def AddFace(self, IDsOfNodes):
4261 Create a linear or quadratic face (this is determined
4262 by the number of given nodes).
4265 IDsOfNodes: list of node IDs for creation of the element.
4266 The order of nodes in this list should correspond to
4267 the :ref:`connectivity convention <connectivity_page>`.
4273 return self.editor.AddFace(IDsOfNodes)
4275 def AddPolygonalFace(self, IdsOfNodes):
4277 Add a polygonal face defined by a list of node IDs
4280 IdsOfNodes: the list of node IDs for creation of the element.
4286 return self.editor.AddPolygonalFace(IdsOfNodes)
4288 def AddQuadPolygonalFace(self, IdsOfNodes):
4290 Add a quadratic polygonal face defined by a list of node IDs
4293 IdsOfNodes: the list of node IDs for creation of the element;
4294 corner nodes follow first.
4300 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4302 def AddVolume(self, IDsOfNodes):
4304 Create both simple and quadratic volume (this is determined
4305 by the number of given nodes).
4308 IDsOfNodes: list of node IDs for creation of the element.
4309 The order of nodes in this list should correspond to
4310 the :ref:`connectivity convention <connectivity_page>`.
4313 ID of the new volumic element
4316 return self.editor.AddVolume(IDsOfNodes)
4318 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4320 Create a volume of many faces, giving nodes for each face.
4323 IdsOfNodes: list of node IDs for volume creation, face by face.
4324 Quantities: list of integer values, Quantities[i]
4325 gives the quantity of nodes in face number i.
4328 ID of the new volumic element
4331 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4333 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4335 Create a volume of many faces, giving the IDs of the existing faces.
4338 The created volume will refer only to the nodes
4339 of the given faces, not to the faces themselves.
4342 IdsOfFaces: the list of face IDs for volume creation.
4345 ID of the new volumic element
4348 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4351 def SetNodeOnVertex(self, NodeID, Vertex):
4353 Bind a node to a vertex
4357 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4360 True if succeed else raises an exception
4363 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4364 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4368 self.editor.SetNodeOnVertex(NodeID, VertexID)
4369 except SALOME.SALOME_Exception as inst:
4370 raise ValueError(inst.details.text)
4374 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4376 Store the node position on an edge
4380 Edge: an edge (GEOM.GEOM_Object) or edge ID
4381 paramOnEdge: a parameter on the edge where the node is located
4384 True if succeed else raises an exception
4387 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4388 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4392 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4393 except SALOME.SALOME_Exception as inst:
4394 raise ValueError(inst.details.text)
4397 def SetNodeOnFace(self, NodeID, Face, u, v):
4399 Store node position on a face
4403 Face: a face (GEOM.GEOM_Object) or face ID
4404 u: U parameter on the face where the node is located
4405 v: V parameter on the face where the node is located
4408 True if succeed else raises an exception
4411 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4412 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4416 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4417 except SALOME.SALOME_Exception as inst:
4418 raise ValueError(inst.details.text)
4421 def SetNodeInVolume(self, NodeID, Solid):
4423 Bind a node to a solid
4427 Solid: a solid (GEOM.GEOM_Object) or solid ID
4430 True if succeed else raises an exception
4433 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4434 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4438 self.editor.SetNodeInVolume(NodeID, SolidID)
4439 except SALOME.SALOME_Exception as inst:
4440 raise ValueError(inst.details.text)
4443 def SetMeshElementOnShape(self, ElementID, Shape):
4445 Bind an element to a shape
4448 ElementID: an element ID
4449 Shape: a shape (GEOM.GEOM_Object) or shape ID
4452 True if succeed else raises an exception
4455 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4456 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4460 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4461 except SALOME.SALOME_Exception as inst:
4462 raise ValueError(inst.details.text)
4466 def MoveNode(self, NodeID, x, y, z):
4468 Move the node with the given id
4471 NodeID: the id of the node
4472 x: a new X coordinate
4473 y: a new Y coordinate
4474 z: a new Z coordinate
4477 True if succeed else False
4480 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4481 if hasVars: self.mesh.SetParameters(Parameters)
4482 return self.editor.MoveNode(NodeID, x, y, z)
4484 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4486 Find the node closest to a point and moves it to a point location
4489 x: the X coordinate of a point
4490 y: the Y coordinate of a point
4491 z: the Z coordinate of a point
4492 NodeID: if specified (>0), the node with this ID is moved,
4493 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4496 the ID of a moved node
4499 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4500 if hasVars: self.mesh.SetParameters(Parameters)
4501 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4503 def FindNodeClosestTo(self, x, y, z):
4505 Find the node closest to a point
4508 x: the X coordinate of a point
4509 y: the Y coordinate of a point
4510 z: the Z coordinate of a point
4516 return self.editor.FindNodeClosestTo(x, y, z)
4518 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4520 Find the elements where a point lays IN or ON
4523 x,y,z (float): coordinates of the point
4524 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4525 means elements of any type excluding nodes, discrete and 0D elements.
4526 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4529 list of IDs of found elements
4532 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4534 return self.editor.FindElementsByPoint(x, y, z, elementType)
4536 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4538 Project a point to a mesh object.
4539 Return ID of an element of given type where the given point is projected
4540 and coordinates of the projection point.
4541 In the case if nothing found, return -1 and []
4543 if isinstance( meshObject, Mesh ):
4544 meshObject = meshObject.GetMesh()
4546 meshObject = self.GetMesh()
4547 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4549 def GetPointState(self, x, y, z):
4551 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4552 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4553 UNKNOWN state means that either mesh is wrong or the analysis fails.
4556 return self.editor.GetPointState(x, y, z)
4558 def IsManifold(self):
4560 Check if a 2D mesh is manifold
4563 return self.editor.IsManifold()
4565 def IsCoherentOrientation2D(self):
4567 Check if orientation of 2D elements is coherent
4570 return self.editor.IsCoherentOrientation2D()
4572 def Get1DBranches( self, edges, startNode = 0 ):
4574 Partition given 1D elements into groups of contiguous edges.
4575 A node where number of meeting edges != 2 is a group end.
4576 An optional startNode is used to orient groups it belongs to.
4579 A list of edge groups and a list of corresponding node groups,
4580 where the group is a list of IDs of edges or nodes, like follows
4581 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4582 If a group is closed, the first and last nodes of the group are same.
4584 if isinstance( edges, Mesh ):
4585 edges = edges.GetMesh()
4586 unRegister = genObjUnRegister()
4587 if isinstance( edges, list ):
4588 edges = self.GetIDSource( edges, SMESH.EDGE )
4589 unRegister.set( edges )
4590 return self.editor.Get1DBranches( edges, startNode )
4592 def FindSharpEdges( self, angle, addExisting=False ):
4594 Return sharp edges of faces and non-manifold ones.
4595 Optionally add existing edges.
4598 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4599 addExisting: to return existing edges (1D elements) as well
4602 list of FaceEdge structures
4604 angle = ParseParameters( angle )[0]
4605 return self.editor.FindSharpEdges( angle, addExisting )
4607 def MeshToPassThroughAPoint(self, x, y, z):
4609 Find the node closest to a point and moves it to a point location
4612 x: the X coordinate of a point
4613 y: the Y coordinate of a point
4614 z: the Z coordinate of a point
4617 the ID of a moved node
4620 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4622 def InverseDiag(self, NodeID1, NodeID2):
4624 Replace two neighbour triangles sharing Node1-Node2 link
4625 with the triangles built on the same 4 nodes but having other common link.
4628 NodeID1: the ID of the first node
4629 NodeID2: the ID of the second node
4632 False if proper faces were not found
4634 return self.editor.InverseDiag(NodeID1, NodeID2)
4636 def DeleteDiag(self, NodeID1, NodeID2):
4638 Replace two neighbour triangles sharing *Node1-Node2* link
4639 with a quadrangle built on the same 4 nodes.
4642 NodeID1: ID of the first node
4643 NodeID2: ID of the second node
4646 False if proper faces were not found
4649 This operation can create gaps in numeration of elements.
4650 Call :meth:`RenumberElements` to remove the gaps.
4653 return self.editor.DeleteDiag(NodeID1, NodeID2)
4655 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4657 Replace each triangle bound by Node1-Node2 segment with
4658 two triangles by connecting a node made on the link with a node
4659 opposite to the link.
4662 Node1: ID of the first node
4663 Node2: ID of the second node
4664 position: location [0,1] of the new node on the segment
4666 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4668 def AddNodeOnFace(self, face, x, y, z):
4670 Split a face into triangles by adding a new node onto the face
4671 and connecting the new node with face nodes
4674 face: ID of the face
4675 x,y,z: coordinates of the new node
4677 return self.editor.AddNodeOnFace(face, x, y, z)
4679 def Reorient(self, IDsOfElements=None):
4681 Reorient elements by ids
4684 IDsOfElements: if undefined reorients all mesh elements
4687 True if succeed else False
4690 if IDsOfElements == None:
4691 IDsOfElements = self.GetElementsId()
4692 return self.editor.Reorient(IDsOfElements)
4694 def ReorientObject(self, theObject):
4696 Reorient all elements of the object
4699 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4702 True if succeed else False
4705 if ( isinstance( theObject, Mesh )):
4706 theObject = theObject.GetMesh()
4707 return self.editor.ReorientObject(theObject)
4709 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4711 Reorient faces contained in *the2DObject*.
4714 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4715 theDirection: a desired direction of normal of *theFace*.
4716 It can be either a GEOM vector or a list of coordinates [x,y,z].
4717 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4718 compared with theDirection. It can be either ID of face or a point
4719 by which the face will be found. The point can be given as either
4720 a GEOM vertex or a list of point coordinates.
4723 number of reoriented faces
4726 unRegister = genObjUnRegister()
4728 if isinstance( the2DObject, Mesh ):
4729 the2DObject = the2DObject.GetMesh()
4730 if isinstance( the2DObject, list ):
4731 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4732 unRegister.set( the2DObject )
4733 # check theDirection
4734 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4735 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4736 if isinstance( theDirection, list ):
4737 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4738 # prepare theFace and thePoint
4739 theFace = theFaceOrPoint
4740 thePoint = PointStruct(0,0,0)
4741 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4742 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4744 if isinstance( theFaceOrPoint, list ):
4745 thePoint = PointStruct( *theFaceOrPoint )
4747 if isinstance( theFaceOrPoint, PointStruct ):
4748 thePoint = theFaceOrPoint
4750 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4752 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4754 Reorient faces contained in a list of *objectFaces*
4755 equally to faces contained in a list of *referenceFaces*.
4758 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4759 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.
4762 number of reoriented faces.
4764 if not isinstance( objectFaces, list ):
4765 objectFaces = [ objectFaces ]
4766 for i,obj2D in enumerate( objectFaces ):
4767 if isinstance( obj2D, Mesh ):
4768 objectFaces[i] = obj2D.GetMesh()
4769 if not isinstance( referenceFaces, list ):
4770 referenceFaces = [ referenceFaces ]
4772 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4775 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4777 Reorient faces according to adjacent volumes.
4780 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4781 either IDs of faces or face groups.
4782 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4783 theOutsideNormal: to orient faces to have their normals
4784 pointing either *outside* or *inside* the adjacent volumes.
4787 number of reoriented faces.
4790 unRegister = genObjUnRegister()
4792 if not isinstance( the2DObject, list ):
4793 the2DObject = [ the2DObject ]
4794 elif the2DObject and isinstance( the2DObject[0], int ):
4795 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4796 unRegister.set( the2DObject )
4797 the2DObject = [ the2DObject ]
4798 for i,obj2D in enumerate( the2DObject ):
4799 if isinstance( obj2D, Mesh ):
4800 the2DObject[i] = obj2D.GetMesh()
4801 if isinstance( obj2D, list ):
4802 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4803 unRegister.set( the2DObject[i] )
4805 if isinstance( the3DObject, Mesh ):
4806 the3DObject = the3DObject.GetMesh()
4807 if isinstance( the3DObject, list ):
4808 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4809 unRegister.set( the3DObject )
4810 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4812 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4814 Fuse the neighbouring triangles into quadrangles.
4817 IDsOfElements: The triangles to be fused.
4818 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4819 applied to possible quadrangles to choose a neighbour to fuse with.
4820 Note that not all items of :class:`SMESH.FunctorType` corresponds
4821 to numerical functors.
4822 MaxAngle: is the maximum angle between element normals at which the fusion
4823 is still performed; theMaxAngle is measured in radians.
4824 Also it could be a name of variable which defines angle in degrees.
4827 True in case of success, False otherwise.
4830 This operation can create gaps in numeration of elements.
4831 Call :meth:`RenumberElements` to remove the gaps.
4834 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4835 self.mesh.SetParameters(Parameters)
4836 if not IDsOfElements:
4837 IDsOfElements = self.GetElementsId()
4838 Functor = self.smeshpyD.GetFunctor(theCriterion)
4839 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4841 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4843 Fuse the neighbouring triangles of the object into quadrangles
4846 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4847 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4848 applied to possible quadrangles to choose a neighbour to fuse with.
4849 Note that not all items of :class:`SMESH.FunctorType` corresponds
4850 to numerical functors.
4851 MaxAngle: a max angle between element normals at which the fusion
4852 is still performed; theMaxAngle is measured in radians.
4855 True in case of success, False otherwise.
4858 This operation can create gaps in numeration of elements.
4859 Call :meth:`RenumberElements` to remove the gaps.
4862 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4863 self.mesh.SetParameters(Parameters)
4864 if isinstance( theObject, Mesh ):
4865 theObject = theObject.GetMesh()
4866 Functor = self.smeshpyD.GetFunctor(theCriterion)
4867 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4869 def QuadToTri (self, IDsOfElements, theCriterion = None):
4871 Split quadrangles into triangles.
4874 IDsOfElements: the faces to be splitted.
4875 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4876 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4877 value, then quadrangles will be split by the smallest diagonal.
4878 Note that not all items of :class:`SMESH.FunctorType` corresponds
4879 to numerical functors.
4882 True in case of success, False otherwise.
4885 This operation can create gaps in numeration of elements.
4886 Call :meth:`RenumberElements` to remove the gaps.
4888 if IDsOfElements == []:
4889 IDsOfElements = self.GetElementsId()
4890 if theCriterion is None:
4891 theCriterion = FT_MaxElementLength2D
4892 Functor = self.smeshpyD.GetFunctor(theCriterion)
4893 return self.editor.QuadToTri(IDsOfElements, Functor)
4895 def QuadToTriObject (self, theObject, theCriterion = None):
4897 Split quadrangles into triangles.
4900 theObject: the object from which the list of elements is taken,
4901 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4902 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4903 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4904 value, then quadrangles will be split by the smallest diagonal.
4905 Note that not all items of :class:`SMESH.FunctorType` corresponds
4906 to numerical functors.
4909 True in case of success, False otherwise.
4912 This operation can create gaps in numeration of elements.
4913 Call :meth:`RenumberElements` to remove the gaps.
4915 if ( isinstance( theObject, Mesh )):
4916 theObject = theObject.GetMesh()
4917 if theCriterion is None:
4918 theCriterion = FT_MaxElementLength2D
4919 Functor = self.smeshpyD.GetFunctor(theCriterion)
4920 return self.editor.QuadToTriObject(theObject, Functor)
4922 def QuadTo4Tri (self, theElements=[]):
4924 Split each of given quadrangles into 4 triangles. A node is added at the center of
4928 theElements: the faces to be splitted. This can be either
4929 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4930 or a list of face IDs. By default all quadrangles are split
4933 This operation can create gaps in numeration of elements.
4934 Call :meth:`RenumberElements` to remove the gaps.
4936 unRegister = genObjUnRegister()
4937 if isinstance( theElements, Mesh ):
4938 theElements = theElements.mesh
4939 elif not theElements:
4940 theElements = self.mesh
4941 elif isinstance( theElements, list ):
4942 theElements = self.GetIDSource( theElements, SMESH.FACE )
4943 unRegister.set( theElements )
4944 return self.editor.QuadTo4Tri( theElements )
4946 def SplitQuad (self, IDsOfElements, Diag13):
4948 Split quadrangles into triangles.
4951 IDsOfElements: the faces to be splitted
4952 Diag13 (boolean): is used to choose a diagonal for splitting.
4955 True in case of success, False otherwise.
4958 This operation can create gaps in numeration of elements.
4959 Call :meth:`RenumberElements` to remove the gaps.
4961 if IDsOfElements == []:
4962 IDsOfElements = self.GetElementsId()
4963 return self.editor.SplitQuad(IDsOfElements, Diag13)
4965 def SplitQuadObject (self, theObject, Diag13):
4967 Split quadrangles into triangles.
4970 theObject: the object from which the list of elements is taken,
4971 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4972 Diag13 (boolean): is used to choose a diagonal for splitting.
4975 True in case of success, False otherwise.
4978 This operation can create gaps in numeration of elements.
4979 Call :meth:`RenumberElements` to remove the gaps.
4981 if ( isinstance( theObject, Mesh )):
4982 theObject = theObject.GetMesh()
4983 return self.editor.SplitQuadObject(theObject, Diag13)
4985 def BestSplit (self, IDOfQuad, theCriterion):
4987 Find a better splitting of the given quadrangle.
4990 IDOfQuad: the ID of the quadrangle to be splitted.
4991 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4992 choose a diagonal for splitting.
4993 Note that not all items of :class:`SMESH.FunctorType` corresponds
4994 to numerical functors.
4997 * 1 if 1-3 diagonal is better,
4998 * 2 if 2-4 diagonal is better,
4999 * 0 if error occurs.
5002 This operation can create gaps in numeration of elements.
5003 Call :meth:`RenumberElements` to remove the gaps.
5005 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5007 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5009 Split volumic elements into tetrahedrons
5012 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5013 method: flags passing splitting method:
5014 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5015 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5018 This operation can create gaps in numeration of elements.
5019 Call :meth:`RenumberElements` to remove the gaps.
5021 unRegister = genObjUnRegister()
5022 if isinstance( elems, Mesh ):
5023 elems = elems.GetMesh()
5024 if ( isinstance( elems, list )):
5025 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5026 unRegister.set( elems )
5027 self.editor.SplitVolumesIntoTetra(elems, method)
5030 def SplitBiQuadraticIntoLinear(self, elems=None):
5032 Split bi-quadratic elements into linear ones without creation of additional nodes:
5034 - bi-quadratic triangle will be split into 3 linear quadrangles;
5035 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5036 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5038 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5039 will be split in order to keep the mesh conformal.
5042 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5043 if None (default), all bi-quadratic elements will be split
5046 This operation can create gaps in numeration of elements.
5047 Call :meth:`RenumberElements` to remove the gaps.
5049 unRegister = genObjUnRegister()
5050 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5051 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5052 unRegister.set( elems )
5054 elems = [ self.GetMesh() ]
5055 if isinstance( elems, Mesh ):
5056 elems = [ elems.GetMesh() ]
5057 if not isinstance( elems, list ):
5059 self.editor.SplitBiQuadraticIntoLinear( elems )
5061 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5062 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5064 Split hexahedra into prisms
5067 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5068 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5069 gives a normal vector defining facets to split into triangles.
5070 *startHexPoint* can be either a triple of coordinates or a vertex.
5071 facetNormal: a normal to a facet to split into triangles of a
5072 hexahedron found by *startHexPoint*.
5073 *facetNormal* can be either a triple of coordinates or an edge.
5074 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5075 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5076 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5077 to *startHexPoint* are split, else *startHexPoint*
5078 is used to find the facet to split in all domains present in *elems*.
5081 This operation can create gaps in numeration of elements.
5082 Call :meth:`RenumberElements` to remove the gaps.
5085 unRegister = genObjUnRegister()
5086 if isinstance( elems, Mesh ):
5087 elems = elems.GetMesh()
5088 if ( isinstance( elems, list )):
5089 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5090 unRegister.set( elems )
5093 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5094 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5095 elif isinstance( startHexPoint, list ):
5096 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5099 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5100 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5101 elif isinstance( facetNormal, list ):
5102 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5105 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5107 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5109 def SplitQuadsNearTriangularFacets(self):
5111 Split quadrangle faces near triangular facets of volumes
5114 This operation can create gaps in numeration of elements.
5115 Call :meth:`RenumberElements` to remove the gaps.
5117 faces_array = self.GetElementsByType(SMESH.FACE)
5118 for face_id in faces_array:
5119 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5120 quad_nodes = self.mesh.GetElemNodes(face_id)
5121 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5122 isVolumeFound = False
5123 for node1_elem in node1_elems:
5124 if not isVolumeFound:
5125 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5126 nb_nodes = self.GetElemNbNodes(node1_elem)
5127 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5128 volume_elem = node1_elem
5129 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5130 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5131 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5132 isVolumeFound = True
5133 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5134 self.SplitQuad([face_id], False) # diagonal 2-4
5135 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5136 isVolumeFound = True
5137 self.SplitQuad([face_id], True) # diagonal 1-3
5138 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5139 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5140 isVolumeFound = True
5141 self.SplitQuad([face_id], True) # diagonal 1-3
5143 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5145 Split hexahedrons into tetrahedrons.
5147 This operation uses :doc:`pattern_mapping` functionality for splitting.
5150 theObject: the object from which the list of hexahedrons is taken;
5151 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5152 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5153 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5154 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5155 key-point will be mapped into *theNode001*-th node of each volume.
5156 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5159 True in case of success, False otherwise.
5162 This operation can create gaps in numeration of elements.
5163 Call :meth:`RenumberElements` to remove the gaps.
5171 # (0,0,1) 4.---------.7 * |
5178 # (0,0,0) 0.---------.3
5179 pattern_tetra = "!!! Nb of points: \n 8 \n\
5189 !!! Indices of points of 6 tetras: \n\
5197 pattern = self.smeshpyD.GetPattern()
5198 isDone = pattern.LoadFromFile(pattern_tetra)
5200 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5203 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5204 isDone = pattern.MakeMesh(self.mesh, False, False)
5205 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5207 # split quafrangle faces near triangular facets of volumes
5208 self.SplitQuadsNearTriangularFacets()
5212 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5214 Split hexahedrons into prisms.
5216 Uses the :doc:`pattern_mapping` functionality for splitting.
5219 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5220 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5221 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5222 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5223 will be mapped into the *theNode001* -th node of each volume.
5224 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5227 True in case of success, False otherwise.
5230 This operation can create gaps in numeration of elements.
5231 Call :meth:`RenumberElements` to remove the gaps.
5233 # Pattern: 5.---------.6
5238 # (0,0,1) 4.---------.7 |
5245 # (0,0,0) 0.---------.3
5246 pattern_prism = "!!! Nb of points: \n 8 \n\
5256 !!! Indices of points of 2 prisms: \n\
5260 pattern = self.smeshpyD.GetPattern()
5261 isDone = pattern.LoadFromFile(pattern_prism)
5263 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5266 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5267 isDone = pattern.MakeMesh(self.mesh, False, False)
5268 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5270 # Split quafrangle faces near triangular facets of volumes
5271 self.SplitQuadsNearTriangularFacets()
5275 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5276 MaxNbOfIterations, MaxAspectRatio, Method):
5281 IDsOfElements: the list if ids of elements to smooth
5282 IDsOfFixedNodes: the list of ids of fixed nodes.
5283 Note that nodes built on edges and boundary nodes are always fixed.
5284 MaxNbOfIterations: the maximum number of iterations
5285 MaxAspectRatio: varies in range [1.0, inf]
5286 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5287 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5290 True in case of success, False otherwise.
5293 if IDsOfElements == []:
5294 IDsOfElements = self.GetElementsId()
5295 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5296 self.mesh.SetParameters(Parameters)
5297 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5298 MaxNbOfIterations, MaxAspectRatio, Method)
5300 def SmoothObject(self, theObject, IDsOfFixedNodes,
5301 MaxNbOfIterations, MaxAspectRatio, Method):
5303 Smooth elements which belong to the given object
5306 theObject: the object to smooth
5307 IDsOfFixedNodes: the list of ids of fixed nodes.
5308 Note that nodes built on edges and boundary nodes are always fixed.
5309 MaxNbOfIterations: the maximum number of iterations
5310 MaxAspectRatio: varies in range [1.0, inf]
5311 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5312 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5315 True in case of success, False otherwise.
5318 if ( isinstance( theObject, Mesh )):
5319 theObject = theObject.GetMesh()
5320 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5321 MaxNbOfIterations, MaxAspectRatio, Method)
5323 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5324 MaxNbOfIterations, MaxAspectRatio, Method):
5326 Parametrically smooth the given elements
5329 IDsOfElements: the list if ids of elements to smooth
5330 IDsOfFixedNodes: the list of ids of fixed nodes.
5331 Note that nodes built on edges and boundary nodes are always fixed.
5332 MaxNbOfIterations: the maximum number of iterations
5333 MaxAspectRatio: varies in range [1.0, inf]
5334 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5335 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5338 True in case of success, False otherwise.
5341 if IDsOfElements == []:
5342 IDsOfElements = self.GetElementsId()
5343 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5344 self.mesh.SetParameters(Parameters)
5345 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5346 MaxNbOfIterations, MaxAspectRatio, Method)
5348 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5349 MaxNbOfIterations, MaxAspectRatio, Method):
5351 Parametrically smooth the elements which belong to the given object
5354 theObject: the object to smooth
5355 IDsOfFixedNodes: the list of ids of fixed nodes.
5356 Note that nodes built on edges and boundary nodes are always fixed.
5357 MaxNbOfIterations: the maximum number of iterations
5358 MaxAspectRatio: varies in range [1.0, inf]
5359 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5360 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5363 True in case of success, False otherwise.
5366 if ( isinstance( theObject, Mesh )):
5367 theObject = theObject.GetMesh()
5368 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5369 MaxNbOfIterations, MaxAspectRatio, Method)
5371 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5373 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5374 them with quadratic with the same id.
5377 theForce3d: method of new node creation:
5379 * False - the medium node lies at the geometrical entity from which the mesh element is built
5380 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5381 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5382 theToBiQuad: If True, converts the mesh to bi-quadratic
5385 :class:`SMESH.ComputeError` which can hold a warning
5388 If *theSubMesh* is provided, the mesh can become non-conformal
5391 This operation can create gaps in numeration of nodes or elements.
5392 Call :meth:`RenumberElements` to remove the gaps.
5395 if isinstance( theSubMesh, Mesh ):
5396 theSubMesh = theSubMesh.mesh
5398 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5401 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5403 self.editor.ConvertToQuadratic(theForce3d)
5404 error = self.editor.GetLastError()
5405 if error and error.comment:
5406 print(error.comment)
5409 def ConvertFromQuadratic(self, theSubMesh=None):
5411 Convert the mesh from quadratic to ordinary,
5412 deletes old quadratic elements,
5413 replacing them with ordinary mesh elements with the same id.
5416 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5419 If *theSubMesh* is provided, the mesh can become non-conformal
5422 This operation can create gaps in numeration of nodes or elements.
5423 Call :meth:`RenumberElements` to remove the gaps.
5427 self.editor.ConvertFromQuadraticObject(theSubMesh)
5429 return self.editor.ConvertFromQuadratic()
5431 def Make2DMeshFrom3D(self):
5433 Create 2D mesh as skin on boundary faces of a 3D mesh
5436 True if operation has been completed successfully, False otherwise
5439 return self.editor.Make2DMeshFrom3D()
5441 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5442 toCopyElements=False, toCopyExistingBondary=False):
5444 Create missing boundary elements
5447 elements: elements whose boundary is to be checked:
5448 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5449 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5450 dimension: defines type of boundary elements to create, either of
5451 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5452 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5453 groupName: a name of group to store created boundary elements in,
5454 "" means not to create the group
5455 meshName: a name of new mesh to store created boundary elements in,
5456 "" means not to create the new mesh
5457 toCopyElements: if True, the checked elements will be copied into
5458 the new mesh else only boundary elements will be copied into the new mesh
5459 toCopyExistingBondary: if True, not only new but also pre-existing
5460 boundary elements will be copied into the new mesh
5463 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5466 unRegister = genObjUnRegister()
5467 if isinstance( elements, Mesh ):
5468 elements = elements.GetMesh()
5469 if ( isinstance( elements, list )):
5470 elemType = SMESH.ALL
5471 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5472 elements = self.editor.MakeIDSource(elements, elemType)
5473 unRegister.set( elements )
5474 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5475 toCopyElements,toCopyExistingBondary)
5476 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5479 def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
5481 Create boundary elements around the whole mesh or groups of elements
5484 groupName: a name of group to store all boundary elements in,
5485 "" means not to create the group
5486 meshName: a name of a new mesh, which is a copy of the initial
5487 mesh + created boundary elements; "" means not to create the new mesh
5488 toCopyAll: if True, the whole initial mesh will be copied into
5489 the new mesh else only boundary elements will be copied into the new mesh
5490 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5493 tuple( long, mesh, group )
5494 - long - number of added boundary elements
5495 - mesh - the :class:`Mesh` where elements were added to
5496 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5498 dimension=SMESH.BND_2DFROM3D
5499 toCreateAllElements = True # create all boundary elements in the mesh
5500 nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
5501 toCopyAll,toCreateAllElements,groups)
5502 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5503 return nb, mesh, group
5505 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5506 toCopyAll=False, groups=[]):
5508 Create missing boundary elements around either the whole mesh or
5512 dimension: defines type of boundary elements to create, either of
5513 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5514 groupName: a name of group to store all boundary elements in,
5515 "" means not to create the group
5516 meshName: a name of a new mesh, which is a copy of the initial
5517 mesh + created boundary elements; "" means not to create the new mesh
5518 toCopyAll: if True, the whole initial mesh will be copied into
5519 the new mesh else only boundary elements will be copied into the new mesh
5520 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5523 tuple( long, mesh, group )
5524 - long - number of added boundary elements
5525 - mesh - the :class:`Mesh` where elements were added to
5526 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5528 toCreateAllElements = False # create only elements in the boundary of the solid
5529 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5530 toCopyAll,toCreateAllElements,groups)
5531 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5532 return nb, mesh, group
5534 def RenumberNodes(self):
5536 Renumber mesh nodes to remove unused node IDs
5538 self.editor.RenumberNodes()
5540 def RenumberElements(self):
5542 Renumber mesh elements to remove unused element IDs
5544 self.editor.RenumberElements()
5546 def _getIdSourceList(self, arg, idType, unRegister):
5548 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5550 if arg and isinstance( arg, list ):
5551 if isinstance( arg[0], int ):
5552 arg = self.GetIDSource( arg, idType )
5553 unRegister.set( arg )
5554 elif isinstance( arg[0], Mesh ):
5555 arg[0] = arg[0].GetMesh()
5556 elif isinstance( arg, Mesh ):
5558 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5562 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5563 MakeGroups=False, TotalAngle=False):
5565 Generate new elements by rotation of the given elements and nodes around the axis
5568 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5569 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5570 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5571 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5572 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5573 which defines angle in degrees
5574 NbOfSteps: the number of steps
5575 Tolerance: tolerance
5576 MakeGroups: forces the generation of new groups from existing ones
5577 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5578 of all steps, else - size of each step
5581 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5584 unRegister = genObjUnRegister()
5585 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5586 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5587 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5589 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5590 Axis = self.smeshpyD.GetAxisStruct( Axis )
5591 if isinstance( Axis, list ):
5592 Axis = SMESH.AxisStruct( *Axis )
5594 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5595 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5596 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5597 self.mesh.SetParameters(Parameters)
5598 if TotalAngle and NbOfSteps:
5599 AngleInRadians /= NbOfSteps
5600 return self.editor.RotationSweepObjects( nodes, edges, faces,
5601 Axis, AngleInRadians,
5602 NbOfSteps, Tolerance, MakeGroups)
5604 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5605 MakeGroups=False, TotalAngle=False):
5607 Generate new elements by rotation of the elements around the axis
5610 IDsOfElements: the list of ids of elements to sweep
5611 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5612 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5613 NbOfSteps: the number of steps
5614 Tolerance: tolerance
5615 MakeGroups: forces the generation of new groups from existing ones
5616 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5617 of all steps, else - size of each step
5620 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5623 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5624 AngleInRadians, NbOfSteps, Tolerance,
5625 MakeGroups, TotalAngle)
5627 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5628 MakeGroups=False, TotalAngle=False):
5630 Generate new elements by rotation of the elements of object around the axis
5631 theObject object which elements should be sweeped.
5632 It can be a mesh, a sub mesh or a group.
5635 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5636 AngleInRadians: the angle of Rotation
5637 NbOfSteps: number of steps
5638 Tolerance: tolerance
5639 MakeGroups: forces the generation of new groups from existing ones
5640 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5641 of all steps, else - size of each step
5644 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5647 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5648 AngleInRadians, NbOfSteps, Tolerance,
5649 MakeGroups, TotalAngle )
5651 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5652 MakeGroups=False, TotalAngle=False):
5654 Generate new elements by rotation of the elements of object around the axis
5655 theObject object which elements should be sweeped.
5656 It can be a mesh, a sub mesh or a group.
5659 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5660 AngleInRadians: the angle of Rotation
5661 NbOfSteps: number of steps
5662 Tolerance: tolerance
5663 MakeGroups: forces the generation of new groups from existing ones
5664 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5665 of all steps, else - size of each step
5668 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5669 empty list otherwise
5672 return self.RotationSweepObjects([],theObject,[], Axis,
5673 AngleInRadians, NbOfSteps, Tolerance,
5674 MakeGroups, TotalAngle)
5676 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5677 MakeGroups=False, TotalAngle=False):
5679 Generate new elements by rotation of the elements of object around the axis
5680 theObject object which elements should be sweeped.
5681 It can be a mesh, a sub mesh or a group.
5684 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5685 AngleInRadians: the angle of Rotation
5686 NbOfSteps: number of steps
5687 Tolerance: tolerance
5688 MakeGroups: forces the generation of new groups from existing ones
5689 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5690 of all steps, else - size of each step
5693 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5696 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5697 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5699 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5700 scaleFactors=[], linearVariation=False, basePoint=[],
5701 angles=[], anglesVariation=False):
5703 Generate new elements by extrusion of the given elements and nodes
5706 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5707 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5708 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5709 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5710 the direction and value of extrusion for one step (the total extrusion
5711 length will be NbOfSteps * ||StepVector||)
5712 NbOfSteps: the number of steps
5713 MakeGroups: forces the generation of new groups from existing ones
5714 scaleFactors: optional scale factors to apply during extrusion
5715 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5716 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5717 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5718 nodes and elements being extruded is used as the scaling center.
5721 - a list of tree components of the point or
5724 angles: list of angles in radians. Nodes at each extrusion step are rotated
5725 around *basePoint*, additionally to previous steps.
5726 anglesVariation: forces the computation of rotation angles as linear
5727 variation of the given *angles* along path steps
5729 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5731 Example: :ref:`tui_extrusion`
5733 unRegister = genObjUnRegister()
5734 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5735 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5736 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5738 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5739 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5740 if isinstance( StepVector, list ):
5741 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5743 if isinstance( basePoint, int):
5744 xyz = self.GetNodeXYZ( basePoint )
5746 raise RuntimeError("Invalid node ID: %s" % basePoint)
5748 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5749 basePoint = self.geompyD.PointCoordinates( basePoint )
5751 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5752 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5753 angles,angleParameters,hasVars = ParseAngles(angles)
5754 Parameters = StepVector.PS.parameters + var_separator + \
5755 Parameters + var_separator + \
5756 scaleParameters + var_separator + angleParameters
5757 self.mesh.SetParameters(Parameters)
5759 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5760 StepVector, NbOfSteps, MakeGroups,
5761 scaleFactors, linearVariation, basePoint,
5762 angles, anglesVariation )
5765 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5767 Generate new elements by extrusion of the elements with given ids
5770 IDsOfElements: the list of ids of elements or nodes for extrusion
5771 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5772 the direction and value of extrusion for one step (the total extrusion
5773 length will be NbOfSteps * ||StepVector||)
5774 NbOfSteps: the number of steps
5775 MakeGroups: forces the generation of new groups from existing ones
5776 IsNodes: is True if elements with given ids are nodes
5779 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5781 Example: :ref:`tui_extrusion`
5784 if IsNodes: n = IDsOfElements
5785 else : e,f, = IDsOfElements,IDsOfElements
5786 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5788 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5789 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5791 Generate new elements by extrusion along the normal to a discretized surface or wire
5794 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5795 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5796 StepSize: length of one extrusion step (the total extrusion
5797 length will be *NbOfSteps* *StepSize*).
5798 NbOfSteps: number of extrusion steps.
5799 ByAverageNormal: if True each node is translated by *StepSize*
5800 along the average of the normal vectors to the faces sharing the node;
5801 else each node is translated along the same average normal till
5802 intersection with the plane got by translation of the face sharing
5803 the node along its own normal by *StepSize*.
5804 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5805 for every node of *Elements*.
5806 MakeGroups: forces generation of new groups from existing ones.
5807 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5808 is not yet implemented. This parameter is used if *Elements* contains
5809 both faces and edges, i.e. *Elements* is a Mesh.
5812 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5813 empty list otherwise.
5814 Example: :ref:`tui_extrusion`
5817 unRegister = genObjUnRegister()
5818 if isinstance( Elements, Mesh ):
5819 Elements = [ Elements.GetMesh() ]
5820 if isinstance( Elements, list ):
5822 raise RuntimeError("Elements empty!")
5823 if isinstance( Elements[0], Mesh ):
5824 Elements = [ Elements[0].GetMesh() ]
5825 if isinstance( Elements[0], int ):
5826 Elements = self.GetIDSource( Elements, SMESH.ALL )
5827 unRegister.set( Elements )
5828 if not isinstance( Elements, list ):
5829 Elements = [ Elements ]
5830 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5831 self.mesh.SetParameters(Parameters)
5832 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5833 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5835 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5837 Generate new elements by extrusion of the elements or nodes which belong to the object
5840 theObject: the object whose elements or nodes should be processed.
5841 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5842 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5843 the direction and value of extrusion for one step (the total extrusion
5844 length will be NbOfSteps * ||StepVector||)
5845 NbOfSteps: the number of steps
5846 MakeGroups: forces the generation of new groups from existing ones
5847 IsNodes: is True if elements to extrude are nodes
5850 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5851 Example: :ref:`tui_extrusion`
5855 if IsNodes: n = theObject
5856 else : e,f, = theObject,theObject
5857 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5859 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5861 Generate new elements by extrusion of edges which belong to the object
5864 theObject: object whose 1D elements should be processed.
5865 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5866 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5867 the direction and value of extrusion for one step (the total extrusion
5868 length will be NbOfSteps * ||StepVector||)
5869 NbOfSteps: the number of steps
5870 MakeGroups: to generate new groups from existing ones
5873 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5874 Example: :ref:`tui_extrusion`
5877 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5879 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5881 Generate new elements by extrusion of faces which belong to the object
5884 theObject: object whose 2D elements should be processed.
5885 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5886 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5887 the direction and value of extrusion for one step (the total extrusion
5888 length will be NbOfSteps * ||StepVector||)
5889 NbOfSteps: the number of steps
5890 MakeGroups: forces the generation of new groups from existing ones
5893 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5894 Example: :ref:`tui_extrusion`
5897 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5899 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5900 ExtrFlags, SewTolerance, MakeGroups=False):
5902 Generate new elements by extrusion of the elements with given ids
5905 IDsOfElements: is ids of elements
5906 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5907 the direction and value of extrusion for one step (the total extrusion
5908 length will be NbOfSteps * ||StepVector||)
5909 NbOfSteps: the number of steps
5910 ExtrFlags: sets flags for extrusion
5911 SewTolerance: uses for comparing locations of nodes if flag
5912 EXTRUSION_FLAG_SEW is set
5913 MakeGroups: forces the generation of new groups from existing ones
5916 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5919 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5920 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5921 if isinstance( StepVector, list ):
5922 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5923 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5924 ExtrFlags, SewTolerance, MakeGroups)
5926 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5927 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5928 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5929 ScaleFactors=[], ScalesVariation=False):
5931 Generate new elements by extrusion of the given elements and nodes along the path.
5932 The path of extrusion must be a meshed edge.
5935 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5936 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5937 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5938 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5939 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
5940 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5941 HasAngles: not used obsolete
5942 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5943 around *basePoint*, additionally to previous steps.
5944 LinearVariation: forces the computation of rotation angles as linear
5945 variation of the given Angles along path steps
5946 HasRefPoint: allows using the reference point
5947 RefPoint: optional scaling and rotation center (mass center of the extruded
5948 elements by default). The User can specify any point as the Reference Point.
5949 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5950 MakeGroups: forces the generation of new groups from existing ones
5951 ScaleFactors: optional scale factors to apply during extrusion
5952 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5953 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5956 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5957 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5958 Example: :ref:`tui_extrusion_along_path`
5961 unRegister = genObjUnRegister()
5962 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5963 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5964 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5966 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5967 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5968 if isinstance( RefPoint, list ):
5969 if not RefPoint: RefPoint = [0,0,0]
5970 RefPoint = SMESH.PointStruct( *RefPoint )
5971 if isinstance( PathObject, Mesh ):
5972 PathObject = PathObject.GetMesh()
5973 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5974 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5975 Parameters = AnglesParameters + var_separator + \
5976 RefPoint.parameters + var_separator + ScalesParameters
5977 self.mesh.SetParameters(Parameters)
5978 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5979 PathObject, PathShape, NodeStart,
5980 HasAngles, Angles, LinearVariation,
5981 HasRefPoint, RefPoint, MakeGroups,
5982 ScaleFactors, ScalesVariation)
5984 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5985 HasAngles=False, Angles=[], LinearVariation=False,
5986 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5987 ElemType=SMESH.FACE):
5989 Generate new elements by extrusion of the given elements.
5990 The path of extrusion must be a meshed edge.
5993 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5994 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5995 NodeStart: the start node from Path. Defines the direction of extrusion
5996 HasAngles: not used obsolete
5997 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5998 around *basePoint*, additionally to previous steps.
5999 LinearVariation: forces the computation of rotation angles as linear
6000 variation of the given Angles along path steps
6001 HasRefPoint: allows using the reference point
6002 RefPoint: the reference point around which the elements are rotated (the mass
6003 center of the elements by default).
6004 The User can specify any point as the Reference Point.
6005 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6006 MakeGroups: forces the generation of new groups from existing ones
6007 ElemType: type of elements for extrusion (if param Base is a mesh)
6010 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6011 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6012 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6014 Example: :ref:`tui_extrusion_along_path`
6018 if ElemType == SMESH.NODE: n = Base
6019 if ElemType == SMESH.EDGE: e = Base
6020 if ElemType == SMESH.FACE: f = Base
6021 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
6022 HasAngles, Angles, LinearVariation,
6023 HasRefPoint, RefPoint, MakeGroups)
6024 if MakeGroups: return gr,er
6027 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
6028 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6029 MakeGroups=False, LinearVariation=False):
6031 Generate new elements by extrusion of the given elements.
6032 The path of extrusion must be a meshed edge.
6035 IDsOfElements: ids of elements
6036 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6037 PathShape: shape (edge) defines the sub-mesh for the path
6038 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6039 HasAngles: not used obsolete
6040 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6041 around *basePoint*, additionally to previous steps.
6042 HasRefPoint: allows using the reference point
6043 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6044 The User can specify any point as the Reference Point.
6045 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6046 MakeGroups: forces the generation of new groups from existing ones
6047 LinearVariation: forces the computation of rotation angles as linear
6048 variation of the given Angles along path steps
6051 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6052 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6053 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6054 Example: :ref:`tui_extrusion_along_path`
6057 if not IDsOfElements:
6058 IDsOfElements = [ self.GetMesh() ]
6059 n,e,f = [],IDsOfElements,IDsOfElements
6060 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6061 NodeStart, HasAngles, Angles,
6063 HasRefPoint, RefPoint, MakeGroups)
6064 if MakeGroups: return gr,er
6067 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6068 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6069 MakeGroups=False, LinearVariation=False):
6071 Generate new elements by extrusion of the elements which belong to the object.
6072 The path of extrusion must be a meshed edge.
6075 theObject: the object whose elements should be processed.
6076 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6077 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6078 PathShape: shape (edge) defines the sub-mesh for the path
6079 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6080 HasAngles: not used obsolete
6081 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6082 around *basePoint*, additionally to previous steps.
6083 HasRefPoint: allows using the reference point
6084 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6085 The User can specify any point as the Reference Point.
6086 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6087 MakeGroups: forces the generation of new groups from existing ones
6088 LinearVariation: forces the computation of rotation angles as linear
6089 variation of the given Angles along path steps
6092 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6093 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6094 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6095 Example: :ref:`tui_extrusion_along_path`
6098 n,e,f = [],theObject,theObject
6099 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6100 HasAngles, Angles, LinearVariation,
6101 HasRefPoint, RefPoint, MakeGroups)
6102 if MakeGroups: return gr,er
6105 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6106 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6107 MakeGroups=False, LinearVariation=False):
6109 Generate new elements by extrusion of mesh segments which belong to the object.
6110 The path of extrusion must be a meshed edge.
6113 theObject: the object whose 1D elements should be processed.
6114 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6115 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6116 PathShape: shape (edge) defines the sub-mesh for the path
6117 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6118 HasAngles: not used obsolete
6119 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6120 around *basePoint*, additionally to previous steps.
6121 HasRefPoint: allows using the reference point
6122 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6123 The User can specify any point as the Reference Point.
6124 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6125 MakeGroups: forces the generation of new groups from existing ones
6126 LinearVariation: forces the computation of rotation angles as linear
6127 variation of the given Angles along path steps
6130 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6131 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6132 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6133 Example: :ref:`tui_extrusion_along_path`
6136 n,e,f = [],theObject,[]
6137 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6138 HasAngles, Angles, LinearVariation,
6139 HasRefPoint, RefPoint, MakeGroups)
6140 if MakeGroups: return gr,er
6143 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6144 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6145 MakeGroups=False, LinearVariation=False):
6147 Generate new elements by extrusion of faces which belong to the object.
6148 The path of extrusion must be a meshed edge.
6151 theObject: the object whose 2D elements should be processed.
6152 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6153 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6154 PathShape: shape (edge) defines the sub-mesh for the path
6155 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6156 HasAngles: not used obsolete
6157 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6158 around *basePoint*, additionally to previous steps.
6159 HasRefPoint: allows using the reference point
6160 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6161 The User can specify any point as the Reference Point.
6162 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6163 MakeGroups: forces the generation of new groups from existing ones
6164 LinearVariation: forces the computation of rotation angles as linear
6165 variation of the given Angles along path steps
6168 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6169 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6170 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6171 Example: :ref:`tui_extrusion_along_path`
6174 n,e,f = [],[],theObject
6175 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6176 HasAngles, Angles, LinearVariation,
6177 HasRefPoint, RefPoint, MakeGroups)
6178 if MakeGroups: return gr,er
6181 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6183 Create a symmetrical copy of mesh elements
6186 IDsOfElements: list of elements ids
6187 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6188 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6189 If the *Mirror* is a geom object this parameter is unnecessary
6190 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6191 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6194 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6197 if IDsOfElements == []:
6198 IDsOfElements = self.GetElementsId()
6199 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6200 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6201 theMirrorType = Mirror._mirrorType
6203 self.mesh.SetParameters(Mirror.parameters)
6204 if Copy and MakeGroups:
6205 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6206 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6209 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6211 Create a new mesh by a symmetrical copy of mesh elements
6214 IDsOfElements: the list of elements ids
6215 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6216 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6217 If the *Mirror* is a geom object this parameter is unnecessary
6218 MakeGroups: to generate new groups from existing ones
6219 NewMeshName: a name of the new mesh to create
6222 instance of class :class:`Mesh`
6225 if IDsOfElements == []:
6226 IDsOfElements = self.GetElementsId()
6227 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6228 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6229 theMirrorType = Mirror._mirrorType
6231 self.mesh.SetParameters(Mirror.parameters)
6232 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6233 MakeGroups, NewMeshName)
6234 return Mesh(self.smeshpyD,self.geompyD,mesh)
6236 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6238 Create a symmetrical copy of the object
6241 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6242 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6243 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6244 If the *Mirror* is a geom object this parameter is unnecessary
6245 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6246 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6249 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6252 if ( isinstance( theObject, Mesh )):
6253 theObject = theObject.GetMesh()
6254 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6255 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6256 theMirrorType = Mirror._mirrorType
6258 self.mesh.SetParameters(Mirror.parameters)
6259 if Copy and MakeGroups:
6260 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6261 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6264 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6266 Create a new mesh by a symmetrical copy of the object
6269 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6270 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6271 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6272 If the *Mirror* is a geom object this parameter is unnecessary
6273 MakeGroups: forces the generation of new groups from existing ones
6274 NewMeshName: the name of the new mesh to create
6277 instance of class :class:`Mesh`
6280 if ( isinstance( theObject, Mesh )):
6281 theObject = theObject.GetMesh()
6282 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6283 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6284 theMirrorType = Mirror._mirrorType
6286 self.mesh.SetParameters(Mirror.parameters)
6287 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6288 MakeGroups, NewMeshName)
6289 return Mesh( self.smeshpyD,self.geompyD,mesh )
6291 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6293 Translate the elements
6296 IDsOfElements: list of elements ids
6297 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6298 Copy: allows copying the translated elements
6299 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6302 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6305 if IDsOfElements == []:
6306 IDsOfElements = self.GetElementsId()
6307 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6308 Vector = self.smeshpyD.GetDirStruct(Vector)
6309 if isinstance( Vector, list ):
6310 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6311 self.mesh.SetParameters(Vector.PS.parameters)
6312 if Copy and MakeGroups:
6313 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6314 self.editor.Translate(IDsOfElements, Vector, Copy)
6317 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6319 Create a new mesh of translated elements
6322 IDsOfElements: list of elements ids
6323 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6324 MakeGroups: forces the generation of new groups from existing ones
6325 NewMeshName: the name of the newly created mesh
6328 instance of class :class:`Mesh`
6331 if IDsOfElements == []:
6332 IDsOfElements = self.GetElementsId()
6333 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6334 Vector = self.smeshpyD.GetDirStruct(Vector)
6335 if isinstance( Vector, list ):
6336 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6337 self.mesh.SetParameters(Vector.PS.parameters)
6338 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6339 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6341 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6343 Translate the object
6346 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6347 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6348 Copy: allows copying the translated elements
6349 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6352 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6355 if ( isinstance( theObject, Mesh )):
6356 theObject = theObject.GetMesh()
6357 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6358 Vector = self.smeshpyD.GetDirStruct(Vector)
6359 if isinstance( Vector, list ):
6360 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6361 self.mesh.SetParameters(Vector.PS.parameters)
6362 if Copy and MakeGroups:
6363 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6364 self.editor.TranslateObject(theObject, Vector, Copy)
6367 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6369 Create a new mesh from the translated object
6372 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6373 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6374 MakeGroups: forces the generation of new groups from existing ones
6375 NewMeshName: the name of the newly created mesh
6378 instance of class :class:`Mesh`
6381 if isinstance( theObject, Mesh ):
6382 theObject = theObject.GetMesh()
6383 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6384 Vector = self.smeshpyD.GetDirStruct(Vector)
6385 if isinstance( Vector, list ):
6386 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6387 self.mesh.SetParameters(Vector.PS.parameters)
6388 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6389 return Mesh( self.smeshpyD, self.geompyD, mesh )
6393 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6398 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6399 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6400 theScaleFact: list of 1-3 scale factors for axises
6401 Copy: allows copying the translated elements
6402 MakeGroups: forces the generation of new groups from existing
6406 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6407 empty list otherwise
6409 unRegister = genObjUnRegister()
6410 if ( isinstance( theObject, Mesh )):
6411 theObject = theObject.GetMesh()
6412 if ( isinstance( theObject, list )):
6413 theObject = self.GetIDSource(theObject, SMESH.ALL)
6414 unRegister.set( theObject )
6415 if ( isinstance( thePoint, list )):
6416 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6417 if ( isinstance( theScaleFact, float )):
6418 theScaleFact = [theScaleFact]
6419 if ( isinstance( theScaleFact, int )):
6420 theScaleFact = [ float(theScaleFact)]
6422 self.mesh.SetParameters(thePoint.parameters)
6424 if Copy and MakeGroups:
6425 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6426 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6429 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6431 Create a new mesh from the translated object
6434 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6435 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6436 theScaleFact: list of 1-3 scale factors for axises
6437 MakeGroups: forces the generation of new groups from existing ones
6438 NewMeshName: the name of the newly created mesh
6441 instance of class :class:`Mesh`
6443 unRegister = genObjUnRegister()
6444 if (isinstance(theObject, Mesh)):
6445 theObject = theObject.GetMesh()
6446 if ( isinstance( theObject, list )):
6447 theObject = self.GetIDSource(theObject,SMESH.ALL)
6448 unRegister.set( theObject )
6449 if ( isinstance( thePoint, list )):
6450 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6451 if ( isinstance( theScaleFact, float )):
6452 theScaleFact = [theScaleFact]
6453 if ( isinstance( theScaleFact, int )):
6454 theScaleFact = [ float(theScaleFact)]
6456 self.mesh.SetParameters(thePoint.parameters)
6457 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6458 MakeGroups, NewMeshName)
6459 return Mesh( self.smeshpyD, self.geompyD, mesh )
6463 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6468 IDsOfElements: list of elements ids
6469 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6470 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6471 Copy: allows copying the rotated elements
6472 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6475 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6479 if IDsOfElements == []:
6480 IDsOfElements = self.GetElementsId()
6481 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6482 Axis = self.smeshpyD.GetAxisStruct(Axis)
6483 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6484 Parameters = Axis.parameters + var_separator + Parameters
6485 self.mesh.SetParameters(Parameters)
6486 if Copy and MakeGroups:
6487 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6488 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6491 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6493 Create a new mesh of rotated elements
6496 IDsOfElements: list of element ids
6497 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6498 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6499 MakeGroups: forces the generation of new groups from existing ones
6500 NewMeshName: the name of the newly created mesh
6503 instance of class :class:`Mesh`
6506 if IDsOfElements == []:
6507 IDsOfElements = self.GetElementsId()
6508 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6509 Axis = self.smeshpyD.GetAxisStruct(Axis)
6510 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6511 Parameters = Axis.parameters + var_separator + Parameters
6512 self.mesh.SetParameters(Parameters)
6513 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6514 MakeGroups, NewMeshName)
6515 return Mesh( self.smeshpyD, self.geompyD, mesh )
6517 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6522 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6523 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6524 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6525 Copy: allows copying the rotated elements
6526 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6529 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6532 if (isinstance(theObject, Mesh)):
6533 theObject = theObject.GetMesh()
6534 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6535 Axis = self.smeshpyD.GetAxisStruct(Axis)
6536 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6537 Parameters = Axis.parameters + ":" + Parameters
6538 self.mesh.SetParameters(Parameters)
6539 if Copy and MakeGroups:
6540 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6541 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6544 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6546 Create a new mesh from the rotated object
6549 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6550 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6551 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6552 MakeGroups: forces the generation of new groups from existing ones
6553 NewMeshName: the name of the newly created mesh
6556 instance of class :class:`Mesh`
6559 if (isinstance( theObject, Mesh )):
6560 theObject = theObject.GetMesh()
6561 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6562 Axis = self.smeshpyD.GetAxisStruct(Axis)
6563 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6564 Parameters = Axis.parameters + ":" + Parameters
6565 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6566 MakeGroups, NewMeshName)
6567 self.mesh.SetParameters(Parameters)
6568 return Mesh( self.smeshpyD, self.geompyD, mesh )
6570 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6572 Create an offset mesh from the given 2D object
6575 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6576 theValue (float): signed offset size
6577 MakeGroups (boolean): forces the generation of new groups from existing ones
6578 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6579 False means to remove original elements.
6580 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6583 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6586 if isinstance( theObject, Mesh ):
6587 theObject = theObject.GetMesh()
6588 theValue,Parameters,hasVars = ParseParameters(Value)
6589 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6590 self.mesh.SetParameters(Parameters)
6592 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6595 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6597 Find groups of adjacent nodes within Tolerance.
6600 Tolerance (float): the value of tolerance
6601 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6602 corner and medium nodes in separate groups thus preventing
6603 their further merge.
6606 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6609 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6611 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6612 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6614 Find groups of adjacent nodes within Tolerance.
6617 Tolerance: the value of tolerance
6618 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6619 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6620 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6621 corner and medium nodes in separate groups thus preventing
6622 their further merge.
6625 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6628 unRegister = genObjUnRegister()
6629 if not isinstance( SubMeshOrGroup, list ):
6630 SubMeshOrGroup = [ SubMeshOrGroup ]
6631 for i,obj in enumerate( SubMeshOrGroup ):
6632 if isinstance( obj, Mesh ):
6633 SubMeshOrGroup = [ obj.GetMesh() ]
6635 if isinstance( obj, int ):
6636 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6637 unRegister.set( SubMeshOrGroup )
6640 if not isinstance( exceptNodes, list ):
6641 exceptNodes = [ exceptNodes ]
6642 if exceptNodes and isinstance( exceptNodes[0], int ):
6643 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6644 unRegister.set( exceptNodes )
6646 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6647 exceptNodes, SeparateCornerAndMediumNodes)
6649 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6654 GroupsOfNodes: a list of groups of nodes IDs for merging.
6655 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6656 in all elements and mesh groups by nodes 1 and 25 correspondingly
6657 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6658 If *NodesToKeep* does not include a node to keep for some group to merge,
6659 then the first node in the group is kept.
6660 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6664 This operation can create gaps in numeration of nodes or elements.
6665 Call :meth:`RenumberElements` to remove the gaps.
6667 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6669 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6671 Find the elements built on the same nodes.
6674 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6675 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6679 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6682 unRegister = genObjUnRegister()
6683 if MeshOrSubMeshOrGroup is None:
6684 MeshOrSubMeshOrGroup = [ self.mesh ]
6685 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6686 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6687 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6688 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6689 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6690 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6691 unRegister.set( MeshOrSubMeshOrGroup )
6692 for item in MeshOrSubMeshOrGroup:
6693 if isinstance( item, Mesh ):
6694 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6696 if not isinstance( exceptElements, list ):
6697 exceptElements = [ exceptElements ]
6698 if exceptElements and isinstance( exceptElements[0], int ):
6699 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6700 unRegister.set( exceptElements )
6702 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6704 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6706 Merge elements in each given group.
6709 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6710 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6711 replaced in all mesh groups by elements 1 and 25)
6712 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6713 If *ElementsToKeep* does not include an element to keep for some group to merge,
6714 then the first element in the group is kept.
6717 This operation can create gaps in numeration of elements.
6718 Call :meth:`RenumberElements` to remove the gaps.
6721 unRegister = genObjUnRegister()
6723 if not isinstance( ElementsToKeep, list ):
6724 ElementsToKeep = [ ElementsToKeep ]
6725 if isinstance( ElementsToKeep[0], int ):
6726 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6727 unRegister.set( ElementsToKeep )
6729 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6731 def MergeEqualElements(self):
6733 Leave one element and remove all other elements built on the same nodes.
6736 This operation can create gaps in numeration of elements.
6737 Call :meth:`RenumberElements` to remove the gaps.
6740 self.editor.MergeEqualElements()
6742 def FindFreeBorders(self, ClosedOnly=True):
6744 Returns all or only closed free borders
6747 list of SMESH.FreeBorder's
6750 return self.editor.FindFreeBorders( ClosedOnly )
6752 def FillHole(self, holeNodes, groupName=""):
6754 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6757 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6758 must describe all sequential nodes of the hole border. The first and the last
6759 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6760 groupName (string): name of a group to add new faces
6762 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6766 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6767 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6768 if not isinstance( holeNodes, SMESH.FreeBorder ):
6769 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6770 return self.editor.FillHole( holeNodes, groupName )
6772 def FindCoincidentFreeBorders (self, tolerance=0.):
6774 Return groups of FreeBorder's coincident within the given tolerance.
6777 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6778 size of elements adjacent to free borders being compared is used.
6781 SMESH.CoincidentFreeBorders structure
6784 return self.editor.FindCoincidentFreeBorders( tolerance )
6786 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6788 Sew FreeBorder's of each group
6791 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6792 where each enclosed list contains node IDs of a group of coincident free
6793 borders such that each consequent triple of IDs within a group describes
6794 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6795 last node of a border.
6796 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6797 groups of coincident free borders, each group including two borders.
6798 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6799 polygons if a node of opposite border falls on a face edge, else such
6800 faces are split into several ones.
6801 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6802 polyhedra if a node of opposite border falls on a volume edge, else such
6803 volumes, if any, remain intact and the mesh becomes non-conformal.
6806 a number of successfully sewed groups
6809 This operation can create gaps in numeration of nodes or elements.
6810 Call :meth:`RenumberElements` to remove the gaps.
6813 if freeBorders and isinstance( freeBorders, list ):
6814 # construct SMESH.CoincidentFreeBorders
6815 if isinstance( freeBorders[0], int ):
6816 freeBorders = [freeBorders]
6818 coincidentGroups = []
6819 for nodeList in freeBorders:
6820 if not nodeList or len( nodeList ) % 3:
6821 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6824 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6825 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6826 nodeList = nodeList[3:]
6828 coincidentGroups.append( group )
6830 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6832 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6834 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6835 FirstNodeID2, SecondNodeID2, LastNodeID2,
6836 CreatePolygons, CreatePolyedrs):
6841 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6844 This operation can create gaps in numeration of nodes or elements.
6845 Call :meth:`RenumberElements` to remove the gaps.
6848 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6849 FirstNodeID2, SecondNodeID2, LastNodeID2,
6850 CreatePolygons, CreatePolyedrs)
6852 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6853 FirstNodeID2, SecondNodeID2):
6855 Sew conform free borders
6858 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6861 This operation can create gaps in numeration of elements.
6862 Call :meth:`RenumberElements` to remove the gaps.
6865 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6866 FirstNodeID2, SecondNodeID2)
6868 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6869 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6874 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6877 This operation can create gaps in numeration of elements.
6878 Call :meth:`RenumberElements` to remove the gaps.
6881 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6882 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6884 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6885 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6886 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6888 Sew two sides of a mesh. The nodes belonging to Side1 are
6889 merged with the nodes of elements of Side2.
6890 The number of elements in theSide1 and in theSide2 must be
6891 equal and they should have similar nodal connectivity.
6892 The nodes to merge should belong to side borders and
6893 the first node should be linked to the second.
6896 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6899 This operation can create gaps in numeration of nodes.
6900 Call :meth:`RenumberElements` to remove the gaps.
6903 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6904 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6905 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6907 def ChangeElemNodes(self, ide, newIDs):
6909 Set new nodes for the given element. Number of nodes should be kept.
6916 False if the number of nodes does not correspond to the type of element
6919 return self.editor.ChangeElemNodes(ide, newIDs)
6921 def GetLastCreatedNodes(self):
6923 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6924 created, this method return the list of their IDs.
6925 If new nodes were not created - return empty list
6928 the list of integer values (can be empty)
6931 return self.editor.GetLastCreatedNodes()
6933 def GetLastCreatedElems(self):
6935 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6936 created this method return the list of their IDs.
6937 If new elements were not created - return empty list
6940 the list of integer values (can be empty)
6943 return self.editor.GetLastCreatedElems()
6945 def ClearLastCreated(self):
6947 Forget what nodes and elements were created by the last mesh edition operation
6950 self.editor.ClearLastCreated()
6952 def DoubleElements(self, theElements, theGroupName=""):
6954 Create duplicates of given elements, i.e. create new elements based on the
6955 same nodes as the given ones.
6958 theElements: container of elements to duplicate. It can be a
6959 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6960 or a list of element IDs. If *theElements* is
6961 a :class:`Mesh`, elements of highest dimension are duplicated
6962 theGroupName: a name of group to contain the generated elements.
6963 If a group with such a name already exists, the new elements
6964 are added to the existing group, else a new group is created.
6965 If *theGroupName* is empty, new elements are not added
6969 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6970 None if *theGroupName* == "".
6973 unRegister = genObjUnRegister()
6974 if isinstance( theElements, Mesh ):
6975 theElements = theElements.mesh
6976 elif isinstance( theElements, list ):
6977 theElements = self.GetIDSource( theElements, SMESH.ALL )
6978 unRegister.set( theElements )
6979 return self.editor.DoubleElements(theElements, theGroupName)
6981 def DoubleNodes(self, theNodes, theModifiedElems):
6983 Create a hole in a mesh by doubling the nodes of some particular elements
6986 theNodes: IDs of nodes to be doubled
6987 theModifiedElems: IDs of elements to be updated by the new (doubled)
6988 nodes. If list of element identifiers is empty then nodes are doubled but
6989 they not assigned to elements
6992 True if operation has been completed successfully, False otherwise
6995 return self.editor.DoubleNodes(theNodes, theModifiedElems)
6997 def DoubleNode(self, theNodeId, theModifiedElems):
6999 Create a hole in a mesh by doubling the nodes of some particular elements.
7000 This method provided for convenience works as :meth:`DoubleNodes`.
7003 theNodeId: IDs of node to double
7004 theModifiedElems: IDs of elements to update
7007 True if operation has been completed successfully, False otherwise
7010 return self.editor.DoubleNode(theNodeId, theModifiedElems)
7012 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
7014 Create a hole in a mesh by doubling the nodes of some particular elements.
7015 This method provided for convenience works as :meth:`DoubleNodes`.
7018 theNodes: group of nodes to double.
7019 theModifiedElems: group of elements to update.
7020 theMakeGroup: forces the generation of a group containing new nodes.
7023 True or a created group if operation has been completed successfully,
7024 False or None otherwise
7028 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
7029 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7031 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7033 Create a hole in a mesh by doubling the nodes of some particular elements.
7034 This method provided for convenience works as :meth:`DoubleNodes`.
7037 theNodes: list of groups of nodes to double.
7038 theModifiedElems: list of groups of elements to update.
7039 theMakeGroup: forces the generation of a group containing new nodes.
7042 True if operation has been completed successfully, False otherwise
7046 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7047 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7049 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7051 Create a hole in a mesh by doubling the nodes of some particular elements
7054 theElems: the list of elements (edges or faces) to replicate.
7055 The nodes for duplication could be found from these elements
7056 theNodesNot: list of nodes NOT to replicate
7057 theAffectedElems: the list of elements (cells and edges) to which the
7058 replicated nodes should be associated to
7061 True if operation has been completed successfully, False otherwise
7064 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7066 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7068 Create a hole in a mesh by doubling the nodes of some particular elements
7071 theElems: the list of elements (edges or faces) to replicate.
7072 The nodes for duplication could be found from these elements
7073 theNodesNot: list of nodes NOT to replicate
7074 theShape: shape to detect affected elements (element which geometric center
7075 located on or inside shape).
7076 The replicated nodes should be associated to affected elements.
7079 True if operation has been completed successfully, False otherwise
7082 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7084 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7085 theMakeGroup=False, theMakeNodeGroup=False):
7087 Create a hole in a mesh by doubling the nodes of some particular elements.
7088 This method provided for convenience works as :meth:`DoubleNodes`.
7091 theElems: group of of elements (edges or faces) to replicate.
7092 theNodesNot: group of nodes NOT to replicate.
7093 theAffectedElems: group of elements to which the replicated nodes
7094 should be associated to.
7095 theMakeGroup: forces the generation of a group containing new elements.
7096 theMakeNodeGroup: forces the generation of a group containing new nodes.
7099 True or created groups (one or two) if operation has been completed successfully,
7100 False or None otherwise
7103 if theMakeGroup or theMakeNodeGroup:
7104 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7106 theMakeGroup, theMakeNodeGroup)
7107 if theMakeGroup and theMakeNodeGroup:
7110 return twoGroups[ int(theMakeNodeGroup) ]
7111 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7113 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7115 Create a hole in a mesh by doubling the nodes of some particular elements.
7116 This method provided for convenience works as :meth:`DoubleNodes`.
7119 theElems: group of of elements (edges or faces) to replicate
7120 theNodesNot: group of nodes not to replicate
7121 theShape: shape to detect affected elements (element which geometric center
7122 located on or inside shape).
7123 The replicated nodes should be associated to affected elements
7126 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7128 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7129 theMakeGroup=False, theMakeNodeGroup=False):
7131 Create a hole in a mesh by doubling the nodes of some particular elements.
7132 This method provided for convenience works as :meth:`DoubleNodes`.
7135 theElems: list of groups of elements (edges or faces) to replicate
7136 theNodesNot: list of groups of nodes NOT to replicate
7137 theAffectedElems: group of elements to which the replicated nodes
7138 should be associated to
7139 theMakeGroup: forces generation of a group containing new elements.
7140 theMakeNodeGroup: forces generation of a group containing new nodes
7143 True or created groups (one or two) if operation has been completed successfully,
7144 False or None otherwise
7147 if theMakeGroup or theMakeNodeGroup:
7148 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7150 theMakeGroup, theMakeNodeGroup)
7151 if theMakeGroup and theMakeNodeGroup:
7154 return twoGroups[ int(theMakeNodeGroup) ]
7155 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7157 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7159 Create a hole in a mesh by doubling the nodes of some particular elements.
7160 This method provided for convenience works as :meth:`DoubleNodes`.
7163 theElems: list of groups of elements (edges or faces) to replicate
7164 theNodesNot: list of groups of nodes NOT to replicate
7165 theShape: shape to detect affected elements (element which geometric center
7166 located on or inside shape).
7167 The replicated nodes should be associated to affected elements
7170 True if operation has been completed successfully, False otherwise
7173 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7175 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7177 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7178 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7181 theElems: list of groups of nodes or elements (edges or faces) to replicate
7182 theNodesNot: list of groups of nodes NOT to replicate
7183 theShape: shape to detect affected elements (element which geometric center
7184 located on or inside shape).
7185 The replicated nodes should be associated to affected elements
7188 groups of affected elements in order: volumes, faces, edges
7191 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7193 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7196 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7197 The list of groups must describe a partition of the mesh volumes.
7198 The nodes of the internal faces at the boundaries of the groups are doubled.
7199 In option, the internal faces are replaced by flat elements.
7200 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7203 theDomains: list of groups of volumes
7204 createJointElems: if True, create the elements
7205 onAllBoundaries: if True, the nodes and elements are also created on
7206 the boundary between *theDomains* and the rest mesh
7209 True if operation has been completed successfully, False otherwise
7212 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7214 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7216 Double nodes on some external faces and create flat elements.
7217 Flat elements are mainly used by some types of mechanic calculations.
7219 Each group of the list must be constituted of faces.
7220 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7223 theGroupsOfFaces: list of groups of faces
7226 True if operation has been completed successfully, False otherwise
7229 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7231 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7233 Identify all the elements around a geom shape, get the faces delimiting the hole
7235 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7237 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7239 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7240 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7241 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7242 If there are several paths connecting a pair of points, the shortest path is
7243 selected by the module. Position of the cutting plane is defined by the two
7244 points and an optional vector lying on the plane specified by a PolySegment.
7245 By default the vector is defined by Mesh module as following. A middle point
7246 of the two given points is computed. The middle point is projected to the mesh.
7247 The vector goes from the middle point to the projection point. In case of planar
7248 mesh, the vector is normal to the mesh.
7250 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7253 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7254 groupName: optional name of a group where created mesh segments will be added.
7257 editor = self.editor
7259 editor = self.mesh.GetMeshEditPreviewer()
7260 segmentsRes = editor.MakePolyLine( segments, groupName )
7261 for i, seg in enumerate( segmentsRes ):
7262 segments[i].vector = seg.vector
7264 return editor.GetPreviewData()
7267 def MakeSlot(self, segmentGroup, width ):
7269 Create a slot of given width around given 1D elements lying on a triangle mesh.
7270 The slot is constructed by cutting faces by cylindrical surfaces made
7271 around each segment. Segments are expected to be created by MakePolyLine().
7274 FaceEdge's located at the slot boundary
7276 return self.editor.MakeSlot( segmentGroup, width )
7278 def GetFunctor(self, funcType ):
7280 Return a cached numerical functor by its type.
7283 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7284 Note that not all items correspond to numerical functors.
7287 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7290 fn = self.functors[ funcType._v ]
7292 fn = self.smeshpyD.GetFunctor(funcType)
7293 fn.SetMesh(self.mesh)
7294 self.functors[ funcType._v ] = fn
7297 def FunctorValue(self, funcType, elemId, isElem=True):
7299 Return value of a functor for a given element
7302 funcType: an item of :class:`SMESH.FunctorType` enum.
7303 elemId: element or node ID
7304 isElem: *elemId* is ID of element or node
7307 the functor value or zero in case of invalid arguments
7310 fn = self.GetFunctor( funcType )
7311 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7312 val = fn.GetValue(elemId)
7317 def GetLength(self, elemId=None):
7319 Get length of given 1D elements or of all 1D mesh elements
7322 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.
7325 Sum of lengths of given elements
7330 length = self.smeshpyD.GetLength(self)
7331 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7332 length = self.smeshpyD.GetLength(elemId)
7335 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7337 length += self.smeshpyD.GetLength(obj)
7338 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7339 unRegister = genObjUnRegister()
7340 obj = self.GetIDSource( elemId )
7341 unRegister.set( obj )
7342 length = self.smeshpyD.GetLength( obj )
7344 length = self.FunctorValue(SMESH.FT_Length, elemId)
7347 def GetArea(self, elemId=None):
7349 Get area of given 2D elements or of all 2D mesh elements
7352 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.
7355 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7360 area = self.smeshpyD.GetArea(self)
7361 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7362 area = self.smeshpyD.GetArea(elemId)
7365 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7367 area += self.smeshpyD.GetArea(obj)
7368 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7369 unRegister = genObjUnRegister()
7370 obj = self.GetIDSource( elemId )
7371 unRegister.set( obj )
7372 area = self.smeshpyD.GetArea( obj )
7374 area = self.FunctorValue(SMESH.FT_Area, elemId)
7377 def GetVolume(self, elemId=None):
7379 Get volume of given 3D elements or of all 3D mesh elements
7382 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.
7385 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7390 volume= self.smeshpyD.GetVolume(self)
7391 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7392 volume= self.smeshpyD.GetVolume(elemId)
7395 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7397 volume+= self.smeshpyD.GetVolume(obj)
7398 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7399 unRegister = genObjUnRegister()
7400 obj = self.GetIDSource( elemId )
7401 unRegister.set( obj )
7402 volume= self.smeshpyD.GetVolume( obj )
7404 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7407 def GetAngle(self, node1, node2, node3 ):
7409 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7412 node1,node2,node3: IDs of the three nodes
7415 Angle in radians [0,PI]. -1 if failure case.
7417 p1 = self.GetNodeXYZ( node1 )
7418 p2 = self.GetNodeXYZ( node2 )
7419 p3 = self.GetNodeXYZ( node3 )
7420 if p1 and p2 and p3:
7421 return self.smeshpyD.GetAngle( p1,p2,p3 )
7425 def GetMaxElementLength(self, elemId):
7427 Get maximum element length.
7430 elemId: mesh element ID
7433 element's maximum length value
7436 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7437 ftype = SMESH.FT_MaxElementLength3D
7439 ftype = SMESH.FT_MaxElementLength2D
7440 return self.FunctorValue(ftype, elemId)
7442 def GetAspectRatio(self, elemId):
7444 Get aspect ratio of 2D or 3D element.
7447 elemId: mesh element ID
7450 element's aspect ratio value
7453 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7454 ftype = SMESH.FT_AspectRatio3D
7456 ftype = SMESH.FT_AspectRatio
7457 return self.FunctorValue(ftype, elemId)
7459 def GetWarping(self, elemId):
7461 Get warping angle of 2D element.
7464 elemId: mesh element ID
7467 element's warping angle value
7470 return self.FunctorValue(SMESH.FT_Warping, elemId)
7472 def GetWarping3D(self, elemId):
7474 Get warping angle of faces element of 3D elements.
7477 elemId: mesh element ID
7480 element's warping angle value
7483 return self.FunctorValue(SMESH.FT_Warping3D, elemId)
7485 def GetMinimumAngle(self, elemId):
7487 Get minimum angle of 2D element.
7490 elemId: mesh element ID
7493 element's minimum angle value
7496 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7498 def GetTaper(self, elemId):
7500 Get taper of 2D element.
7503 elemId: mesh element ID
7506 element's taper value
7509 return self.FunctorValue(SMESH.FT_Taper, elemId)
7511 def GetSkew(self, elemId):
7513 Get skew of 2D element.
7516 elemId: mesh element ID
7519 element's skew value
7522 return self.FunctorValue(SMESH.FT_Skew, elemId)
7524 def GetScaledJacobian(self, elemId):
7526 Get the scaled jacobian of 3D element id
7529 elemId: mesh element ID
7535 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7537 def GetMinMax(self, funType, meshPart=None):
7539 Return minimal and maximal value of a given functor.
7542 funType (SMESH.FunctorType): a functor type.
7543 Note that not all items of :class:`SMESH.FunctorType` corresponds
7544 to numerical functors.
7545 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7551 unRegister = genObjUnRegister()
7552 if isinstance( meshPart, list ):
7553 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7554 unRegister.set( meshPart )
7555 if isinstance( meshPart, Mesh ):
7556 meshPart = meshPart.mesh
7557 fun = self.GetFunctor( funType )
7560 if hasattr( meshPart, "SetMesh" ):
7561 meshPart.SetMesh( self.mesh ) # set mesh to filter
7562 hist = fun.GetLocalHistogram( 1, False, meshPart )
7564 hist = fun.GetHistogram( 1, False )
7566 return hist[0].min, hist[0].max
7569 pass # end of Mesh class
7571 def _copy_gmsh_param(dim, local_param, global_param):
7573 local_param.SetMaxSize(global_param.GetMaxSize())
7574 local_param.SetMinSize(global_param.GetMinSize())
7575 local_param.Set3DAlgo(global_param.Get3DAlgo())
7576 local_param.SetRecombineAll(global_param.GetRecombineAll())
7577 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7578 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7579 local_param.SetRemeshPara(global_param.GetRemeshPara())
7580 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7581 local_param.SetSizeFactor(global_param.GetSizeFactor())
7582 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7583 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7584 local_param.SetSecondOrder(global_param.GetSecondOrder())
7585 local_param.SetIs2d(global_param.GetIs2d())
7587 local_param.SetMaxSize(global_param.GetMaxSize())
7588 local_param.SetMinSize(global_param.GetMinSize())
7589 local_param.Set2DAlgo(global_param.Get2DAlgo())
7590 local_param.SetRecomb2DAlgo(global_param.GetRecomb2DAlgo())
7591 local_param.SetRecombineAll(global_param.GetRecombineAll())
7592 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7593 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7594 local_param.SetRemeshPara(global_param.GetRemeshPara())
7595 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7596 local_param.SetSizeFactor(global_param.GetSizeFactor())
7597 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7598 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7599 local_param.SetSecondOrder(global_param.GetSecondOrder())
7600 local_param.SetIs2d(global_param.GetIs2d())
7602 def _copy_netgen_param(dim, local_param, global_param):
7604 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7607 #TODO: More global conversion ? or let user define it
7608 local_param.NumberOfSegments(int(global_param.GetMaxSize()))
7610 local_param.SetMaxSize(global_param.GetMaxSize())
7611 local_param.SetMinSize(global_param.GetMinSize())
7612 local_param.SetOptimize(global_param.GetOptimize())
7613 local_param.SetFineness(global_param.GetFineness())
7614 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7615 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7616 #TODO: Why the 0.9 to have same results
7617 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7618 local_param.SetChordalError(global_param.GetChordalError())
7619 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7620 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7621 local_param.SetUseDelauney(global_param.GetUseDelauney())
7622 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7623 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7624 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7625 local_param.SetNbThreads(global_param.GetNbThreads())
7627 local_param.SetMaxSize(global_param.GetMaxSize())
7628 local_param.SetMinSize(global_param.GetMinSize())
7629 local_param.SetOptimize(global_param.GetOptimize())
7630 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7631 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7632 local_param.SetFineness(global_param.GetFineness())
7633 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7634 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7635 local_param.SetGrowthRate(global_param.GetGrowthRate())
7636 local_param.SetNbThreads(global_param.GetNbThreads())
7639 def _shaperstudy2geom(geompyD, shaper_obj):
7641 Convertion of shaper object to geom object
7644 geompyD: geomBuilder instance
7645 shaper_obj: Shaper study object
7652 #Writing shaperstudy object into a brep file
7653 fid, tmp_file = tempfile.mkstemp(suffix='.brep')
7654 with open(fid, 'wb') as f:
7655 f.write(shaper_obj.GetShapeStream())
7656 # Reimporting brep file into geom
7657 real_geom = geompyD.ImportBREP(tmp_file)
7663 def _split_geom(geompyD, geom):
7665 Splitting geometry into n solids and a 2D/1D compound
7668 geompyD: geomBuilder instance
7669 geom: geometrical object for meshing
7672 compound containing all the 1D,2D elements
7676 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7677 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7682 for solid in object_solids:
7684 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7685 solids.append(solid)
7686 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7692 solid_faces = geompyD.ExtractShapes(geom, geompyD.ShapeType["FACE"],
7694 for face in solid_faces:
7697 geompyD.addToStudyInFather(geom, face,
7698 'Face_{}'.format(iface))
7700 return faces, solids
7703 MULTITHREAD, MULTINODE = range(2)
7704 class ParallelismSettings:
7706 Defines the parameters for the parallelism of ParallelMesh
7708 def __init__(self, mesh):
7713 mesh: Instance of ParallelMesh
7715 if not(isinstance(mesh, ParallelMesh)):
7716 raise ValueError("mesh should be a ParallelMesh")
7721 class MTParallelismSettings(ParallelismSettings):
7723 Defines the parameters for the parallelism of ParallelMesh using MultiThreading
7725 def __init__(self, mesh):
7726 ParallelismSettings.__init__(self, mesh)
7728 # Multithreading methods
7729 def SetNbThreads(self, nbThreads):
7730 """ Set the number of threads for multithread """
7732 raise ValueError("Number of threads must be stricly greater than 1")
7734 self._mesh.mesh.SetNbThreads(nbThreads)
7736 def GetNbThreads(self):
7737 """ Get Number of threads """
7738 return self._mesh.mesh.GetNbThreads()
7741 """ str conversion """
7742 string = "\nParameter for MultiThreading parallelism:\n"
7743 string += "NbThreads: {}\n".format(self.GetNbThreads())
7748 class MNParallelismSettings(ParallelismSettings):
7750 Defines the parameters for the parallelism of ParallelMesh using MultiNodal
7752 def __init__(self, mesh):
7753 ParallelismSettings.__init__(self, mesh)
7755 def GetResource(self):
7756 """ Get the resource on which to run """
7757 return self._mesh.mesh.GetResource()
7759 def SetResource(self, resource):
7760 """ Set the resource on which to run """
7761 self._mesh.mesh.SetResource(resource)
7763 def SetNbProc(self, nbProc):
7764 """ Set the number of Processor for multinode """
7766 raise ValueError("Number of Proc must be stricly greater than 1")
7767 self._mesh.mesh.SetNbProc(nbProc)
7769 def GetNbProc(self):
7770 """ Get Number of Processor """
7771 return self._mesh.mesh.GetNbProc()
7773 def SetNbProcPerNode(self, nbProcPerNode):
7774 """ Set the number of Processor Per Node for multinode """
7775 if nbProcPerNode < 1:
7776 raise ValueError("Number of Processor Per Node must be stricly greater than 1")
7778 self._mesh.mesh.SetNbProcPerNode(nbProcPerNode)
7780 def GetNbProcPerNode(self):
7781 """ Get Number of Processor Per Node """
7782 return self._mesh.mesh.GetNbProcPerNode()
7784 def SetNbNode(self, nbNode):
7785 """ Set the number of Node for multinode """
7787 raise ValueError("Number of Node must be stricly greater than 1")
7788 self._mesh.mesh.SetNbNode(nbNode)
7790 def GetNbNode(self):
7791 """ Get Number of Node """
7792 return self._mesh.mesh.GetNbNode()
7794 def SetWcKey(self, wcKey):
7795 """ Set the number of Node for multinode """
7796 self._mesh.mesh.SetWcKey(wcKey)
7799 """ Get Number of Node """
7800 return self._mesh.mesh.GetWcKey()
7802 def SetWalltime(self, walltime):
7803 """ Set the number of Node for multinode """
7804 self._mesh.mesh.SetWalltime(walltime)
7806 def GetWalltime(self):
7807 """ Get Number of Node """
7808 return self._mesh.mesh.GetWalltime()
7811 """ str conversion """
7812 string = "\nParameter for MultiNode parallelism:\n"
7813 string += "Reource: {}\n".format(self.GetResource())
7814 string += "NbProc: {}\n".format(self.GetNbProc())
7815 string += "NbProcPerNode: {}\n".format(self.GetNbProcPerNode())
7816 string += "NbNode: {}\n".format(self.GetNbNode())
7817 string += "WcKey: {}\n".format(self.GetWcKey())
7818 string += "Walltime: {}\n".format(self.GetWalltime())
7823 class ParallelMesh(Mesh):
7825 Surcharge on Mesh for parallel computation of a mesh
7827 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7829 Create a parallel mesh.
7832 smeshpyD: instance of smeshBuilder
7833 geompyD: instance of geomBuilder
7834 geom: geometrical object for meshing
7835 split_geom: If true will divide geometry on solids and 1D/2D
7836 coumpound and create the associated submeshes
7837 name: the name for the new mesh.
7840 an instance of class :class:`ParallelMesh`.
7843 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7844 raise ValueError("geom argument must be a geometry")
7848 shaper_object = SHAPERSTUDY.SHAPERSTUDY_ORB._objref_SHAPER_Object
7854 # If we have a shaper object converting it into geom (temporary solution)
7855 if isinstance(geom, shaper_object):
7856 self._geom_obj = _shaperstudy2geom(geompyD, geom)
7857 elif isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7858 self._geom_obj = geom
7862 msg = "\nShaper was not compiled"
7863 raise Exception("Could not handle geom format {}.{} ".format(type(geom), msg))
7865 # Splitting geometry into one geom containing 1D and 2D elements and a
7866 # list of 3D elements
7867 super(ParallelMesh, self).__init__(smeshpyD, geompyD, self._geom_obj, name, parallel=True)
7870 self._faces, self._solids = _split_geom(geompyD, self._geom_obj)
7874 def _build_submeshes(self, mesher2D, mesher3D):
7876 Contruct the submeshes for a parallel use of smesh
7879 mesher2D: name of 2D mesher for 2D parallel compute (NETGEN)
7880 mesher3D: name of 3D mesher for 3D parallel compute (NETGEN or
7884 # Building global 2D mesher
7886 if mesher3D == "NETGEN":
7887 algo2D = "NETGEN_2D"
7888 elif mesher3D == "GMSH":
7891 raise ValueError("mesher3D should be either NETGEN or GMSH")
7893 self._algo2d = self.Triangle(geom=self._geom_obj, algo=algo2D)
7897 #Means that we want to mesh face of solids in parallel and not
7900 #For the moment use AutomaticLength based on finesse
7901 # TODO: replace by input hypothesis
7902 self._algo1d = self.Segment(geom=self._geom_obj)
7904 for face_id, face in enumerate(self._faces):
7905 name = "face_{}".format(face_id)
7906 algo2d = self.Triangle(geom=face, algo="NETGEN_2D_Remote")
7907 self._algo2d.append(algo2d)
7911 for solid_id, solid in enumerate(self._solids):
7912 name = "Solid_{}".format(solid_id)
7913 if ( mesher3D == "NETGEN" ):
7914 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7915 self._algo3d.append(algo3d)
7916 elif ( mesher3D == "GMSH" ):
7917 algo3d = self.Tetrahedron(geom=solid, algo="GMSH_3D_Remote")
7918 self._algo3d.append(algo3d)
7920 def GetNbSolids(self):
7922 Return the number of 3D solids
7924 return len(self._solids)
7926 def GetNbFaces(self):
7928 Return the number of 2D faces
7930 return len(self._faces)
7932 def GetParallelismMethod(self):
7933 """ Get the parallelims method """
7934 return self.mesh.GetParallelismMethod()
7936 def SetParallelismMethod(self, method):
7937 """ Set the parallelims method """
7938 if method not in [MULTITHREAD , MULTINODE]:
7939 raise ValueError("Parallelism method can only be 0:MultiThread or 1:MultiNode")
7941 self.mesh.SetParallelismMethod(method)
7943 if method == MULTITHREAD:
7944 self._param = MTParallelismSettings(self)
7946 self._param = MNParallelismSettings(self)
7948 def GetParallelismSettings(self):
7950 Return class to set parameters for the parallelism
7952 if self._param is None:
7953 raise Exception("You need to set Parallelism method first (SetParallelismMethod)")
7956 def AddGlobalHypothesis(self, hyp):
7958 Split hypothesis to apply it to all the submeshes:
7960 - each of the 3D solids
7963 hyp: a hypothesis to assign
7966 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7967 copy_param = _copy_netgen_param
7969 elif isinstance(hyp, GMSHPlugin._objref_GMSHPlugin_Hypothesis):
7970 copy_param = _copy_gmsh_param
7973 raise ValueError("param must come from NETGENPlugin or GMSHPlugin")
7975 self.mesh.SetParallelismDimension(3)
7976 self._build_submeshes(None, mesher3D)
7978 param2d = self._algo2d.Parameters()
7979 copy_param(2, param2d, hyp)
7981 for algo3d in self._algo3d:
7982 param3d = algo3d.Parameters()
7983 copy_param(3, param3d, hyp)
7985 def Add2DGlobalHypothesis(self, hyp):
7987 Split hypothesis to apply it to all the submeshes:
7989 - each of the 2D faces
7992 hyp: a hypothesis to assign
7995 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
7996 copy_param = _copy_netgen_param
7999 raise ValueError("param must come from NETGENPlugin")
8001 self.mesh.SetParallelismDimension(2)
8002 self._build_submeshes(mesher2D, None)
8004 param1d = self._algo1d
8005 copy_param(1, param1d, hyp)
8007 for algo2d in self._algo2d:
8008 param2d = algo2d.Parameters()
8009 copy_param(2, param2d, hyp)
8011 pass # End of ParallelMesh
8013 class meshProxy(SMESH._objref_SMESH_Mesh):
8015 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
8016 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
8018 def __init__(self,*args):
8019 SMESH._objref_SMESH_Mesh.__init__(self,*args)
8020 def __deepcopy__(self, memo=None):
8021 new = self.__class__(self)
8023 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
8024 if len( args ) == 3:
8025 args += SMESH.ALL_NODES, True
8026 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
8027 def ExportToMEDX(self, *args): # function removed
8028 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
8029 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8030 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
8031 def ExportToMED(self, *args): # function removed
8032 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
8033 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8035 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8037 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8038 def ExportPartToMED(self, *args): # 'version' parameter removed
8039 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8040 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
8041 def ExportMED(self, *args): # signature of method changed
8042 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8044 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8046 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8047 def ExportUNV(self, *args): # renumber arg added
8048 if len( args ) == 1:
8050 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
8051 def ExportDAT(self, *args): # renumber arg added
8052 if len( args ) == 1:
8054 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
8056 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
8059 class parallelMeshProxy(SMESH._objref_SMESH_ParallelMesh):
8060 def __init__(self,*args):
8061 SMESH._objref_SMESH_ParallelMesh.__init__(self,*args)
8062 def __deepcopy__(self, memo=None):
8063 new = self.__class__(self)
8065 omniORB.registerObjref(SMESH._objref_SMESH_ParallelMesh._NP_RepositoryId, parallelMeshProxy)
8069 class submeshProxy(SMESH._objref_SMESH_subMesh):
8072 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
8074 def __init__(self,*args):
8075 SMESH._objref_SMESH_subMesh.__init__(self,*args)
8077 def __deepcopy__(self, memo=None):
8078 new = self.__class__(self)
8081 def Compute(self,refresh=False):
8083 Compute the sub-mesh and return the status of the computation
8086 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
8091 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
8092 :meth:`smeshBuilder.Mesh.GetSubMesh`.
8096 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
8098 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
8100 if salome.sg.hasDesktop():
8101 if refresh: salome.sg.updateObjBrowser()
8106 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
8109 class meshEditor(SMESH._objref_SMESH_MeshEditor):
8111 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
8112 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
8115 def __init__(self,*args):
8116 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
8118 def __getattr__(self, name ): # method called if an attribute not found
8119 if not self.mesh: # look for name() method in Mesh class
8120 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
8121 if hasattr( self.mesh, name ):
8122 return getattr( self.mesh, name )
8123 if name == "ExtrusionAlongPathObjX":
8124 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
8125 print("meshEditor: attribute '%s' NOT FOUND" % name)
8127 def __deepcopy__(self, memo=None):
8128 new = self.__class__(self)
8130 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
8131 if len( args ) == 1: args += False,
8132 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
8133 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
8134 if len( args ) == 2: args += False,
8135 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
8136 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
8137 if len( args ) == 1:
8138 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
8139 NodesToKeep = args[1]
8140 AvoidMakingHoles = args[2] if len( args ) == 3 else False
8141 unRegister = genObjUnRegister()
8143 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
8144 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
8145 if not isinstance( NodesToKeep, list ):
8146 NodesToKeep = [ NodesToKeep ]
8147 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
8149 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
8151 class Pattern(SMESH._objref_SMESH_Pattern):
8153 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
8154 variables in some methods
8157 def LoadFromFile(self, patternTextOrFile ):
8158 text = patternTextOrFile
8159 if os.path.exists( text ):
8160 text = open( patternTextOrFile ).read()
8162 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
8164 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
8165 decrFun = lambda i: i-1
8166 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
8167 theMesh.SetParameters(Parameters)
8168 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
8170 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
8171 decrFun = lambda i: i-1
8172 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
8173 theMesh.SetParameters(Parameters)
8174 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
8176 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
8177 if isinstance( mesh, Mesh ):
8178 mesh = mesh.GetMesh()
8179 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
8181 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
8183 Registering the new proxy for Pattern
8188 Private class used to bind methods creating algorithms to the class Mesh
8191 def __init__(self, method):
8193 self.defaultAlgoType = ""
8194 self.algoTypeToClass = {}
8195 self.method = method
8197 def add(self, algoClass):
8199 Store a python class of algorithm
8201 if inspect.isclass(algoClass) and \
8202 hasattr( algoClass, "algoType"):
8203 self.algoTypeToClass[ algoClass.algoType ] = algoClass
8204 if not self.defaultAlgoType and \
8205 hasattr( algoClass, "isDefault") and algoClass.isDefault:
8206 self.defaultAlgoType = algoClass.algoType
8207 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
8209 def copy(self, mesh):
8211 Create a copy of self and assign mesh to the copy
8214 other = algoCreator( self.method )
8215 other.defaultAlgoType = self.defaultAlgoType
8216 other.algoTypeToClass = self.algoTypeToClass
8220 def __call__(self,algo="",geom=0,*args):
8222 Create an instance of algorithm
8226 if isinstance( algo, str ):
8228 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
8229 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
8234 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
8236 elif not algoType and isinstance( geom, str ):
8241 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
8243 elif isinstance( arg, str ) and not algoType:
8246 import traceback, sys
8247 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
8248 sys.stderr.write( msg + '\n' )
8249 tb = traceback.extract_stack(None,2)
8250 traceback.print_list( [tb[0]] )
8252 algoType = self.defaultAlgoType
8253 if not algoType and self.algoTypeToClass:
8254 algoType = sorted( self.algoTypeToClass.keys() )[0]
8255 if algoType in self.algoTypeToClass:
8256 #print("Create algo",algoType)
8257 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
8258 raise RuntimeError( "No class found for algo type %s" % algoType)
8261 class hypMethodWrapper:
8263 Private class used to substitute and store variable parameters of hypotheses.
8266 def __init__(self, hyp, method):
8268 self.method = method
8269 #print("REBIND:", method.__name__)
8272 def __call__(self,*args):
8274 call a method of hypothesis with calling SetVarParameter() before
8278 return self.method( self.hyp, *args ) # hypothesis method with no args
8280 #print("MethWrapper.__call__", self.method.__name__, args)
8282 parsed = ParseParameters(*args) # replace variables with their values
8283 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
8284 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
8285 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
8286 # maybe there is a replaced string arg which is not variable
8287 result = self.method( self.hyp, *args )
8288 except ValueError as detail: # raised by ParseParameters()
8290 result = self.method( self.hyp, *args )
8291 except omniORB.CORBA.BAD_PARAM:
8292 raise ValueError(detail) # wrong variable name
8297 class genObjUnRegister:
8299 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
8302 def __init__(self, genObj=None):
8303 self.genObjList = []
8307 def set(self, genObj):
8308 "Store one or a list of of SALOME.GenericObj'es"
8309 if isinstance( genObj, list ):
8310 self.genObjList.extend( genObj )
8312 self.genObjList.append( genObj )
8316 for genObj in self.genObjList:
8317 if genObj and hasattr( genObj, "UnRegister" ):
8320 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8322 Bind methods creating mesher plug-ins to the Mesh class
8325 # print("pluginName: ", pluginName)
8326 pluginBuilderName = pluginName + "Builder"
8328 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8329 except Exception as e:
8330 from salome_utils import verbose
8331 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8333 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8334 plugin = eval( pluginBuilderName )
8335 # print(" plugin:" , str(plugin))
8337 # add methods creating algorithms to Mesh
8338 for k in dir( plugin ):
8339 if k[0] == '_': continue
8340 algo = getattr( plugin, k )
8341 #print(" algo:", str(algo))
8342 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8343 #print(" meshMethod:" , str(algo.meshMethod))
8344 if not hasattr( Mesh, algo.meshMethod ):
8345 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8347 _mmethod = getattr( Mesh, algo.meshMethod )
8348 if hasattr( _mmethod, "add" ):