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 CreateMeshesFromMESHIO(self, theFileName):
746 Create a Mesh object(s) importing data from from any file supported by meshio library.
749 a tuple ( list of class :class:`Mesh` instances,
750 :class:`SMESH.DriverMED_ReadStatus` )
753 aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMESHIO(self, theFileName)
754 aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
755 return aMeshes, aStatus
757 def Concatenate( self, meshes, uniteIdenticalGroups,
758 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
759 name = "", meshToAppendTo = None):
761 Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
762 All groups of input meshes will be present in the new mesh.
765 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
766 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
767 mergeNodesAndElements: if True, equal nodes and elements are merged
768 mergeTolerance: tolerance for merging nodes
769 allGroups: forces creation of groups corresponding to every input mesh
770 name: name of a new mesh
771 meshToAppendTo: a mesh to append all given meshes
774 an instance of class :class:`Mesh`
780 if not meshes: return None
781 if not isinstance( meshes, list ):
783 for i,m in enumerate( meshes ):
784 if isinstance( m, Mesh ):
785 meshes[i] = m.GetMesh()
786 mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
787 if hasattr(meshes[0], "SetParameters"):
788 meshes[0].SetParameters( Parameters )
790 meshes[0].GetMesh().SetParameters( Parameters )
791 if isinstance( meshToAppendTo, Mesh ):
792 meshToAppendTo = meshToAppendTo.GetMesh()
794 aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
795 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
796 mergeTolerance,meshToAppendTo )
798 aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
799 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
800 mergeTolerance,meshToAppendTo )
802 aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
805 def CreateDualMesh( self, mesh, meshName, adaptToShape):
807 Create a dual of a mesh.
810 mesh: Tetrahedron mesh
811 :class:`mesh, <SMESH.SMESH_IDSource>`.
813 meshName: a name of the new mesh
814 adpatToShape: if true project boundary points on shape
817 an instance of class :class:`Mesh`
819 if isinstance( mesh, Mesh ):
820 mesh = mesh.GetMesh()
821 dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
822 return Mesh(self, self.geompyD, dualMesh)
825 def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
827 Create a mesh by copying a part of another mesh.
830 meshPart: a part of mesh to copy, either
831 :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
832 To copy nodes or elements not forming any mesh object,
833 pass result of :meth:`Mesh.GetIDSource` as *meshPart*
834 meshName: a name of the new mesh
835 toCopyGroups: to create in the new mesh groups the copied elements belongs to
836 toKeepIDs: to preserve order of the copied elements or not
839 an instance of class :class:`Mesh`
842 if isinstance( meshPart, Mesh ):
843 meshPart = meshPart.GetMesh()
844 mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
845 return Mesh(self, self.geompyD, mesh)
847 def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
848 toReuseHypotheses=True, toCopyElements=True):
850 Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
851 It is supposed that the new geometry is a modified geometry of *sourceMesh*.
852 To facilitate and speed up the operation, consider using
853 "Set presentation parameters and sub-shapes from arguments" option in
854 a dialog of geometrical operation used to create the new geometry.
857 sourceMesh: the mesh to copy definition of.
858 newGeom: the new geometry.
859 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
860 toCopyGroups: to create groups in the new mesh.
861 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
862 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
865 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
866 *invalidEntries* are study entries of objects whose
867 counterparts are not found in the *newGeom*, followed by entries
868 of mesh sub-objects that are invalid because they depend on a not found
871 if isinstance( sourceMesh, Mesh ):
872 sourceMesh = sourceMesh.GetMesh()
874 ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
875 SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
879 return ( ok, Mesh(self, self.geompyD, newMesh),
880 newGroups, newSubMeshes, newHypotheses, invalidEntries )
882 def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
884 Return IDs of sub-shapes
887 theMainObject (GEOM.GEOM_Object): a shape
888 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
890 the list of integer values
893 return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
895 def GetPattern(self):
897 Create a pattern mapper.
900 an instance of :class:`SMESH.SMESH_Pattern`
902 :ref:`Example of Patterns usage <tui_pattern_mapping>`
905 return SMESH._objref_SMESH_Gen.GetPattern(self)
907 def SetBoundaryBoxSegmentation(self, nbSegments):
909 Set number of segments per diagonal of boundary box of geometry, by which
910 default segment length of appropriate 1D hypotheses is defined in GUI.
914 SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
916 # Filtering. Auxiliary functions:
917 # ------------------------------
919 def GetEmptyCriterion(self):
921 Create an empty criterion
924 :class:`SMESH.Filter.Criterion`
927 Type = self.EnumToLong(FT_Undefined)
928 Compare = self.EnumToLong(FT_Undefined)
932 UnaryOp = self.EnumToLong(FT_Undefined)
933 BinaryOp = self.EnumToLong(FT_Undefined)
936 Precision = -1 ##@1e-07
937 return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
938 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
940 def GetCriterion(self,elementType,
942 Compare = FT_EqualTo,
944 UnaryOp=FT_Undefined,
945 BinaryOp=FT_Undefined,
948 Create a criterion by the given parameters
949 Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
952 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
953 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
954 Note that the items starting from FT_LessThan are not suitable for *CritType*.
955 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
956 Threshold: the threshold value (range of ids as string, shape, numeric)
957 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
958 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
960 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
961 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
964 :class:`SMESH.Filter.Criterion`
966 Example: :ref:`combining_filters`
969 if not CritType in SMESH.FunctorType._items:
970 raise TypeError("CritType should be of SMESH.FunctorType")
971 aCriterion = self.GetEmptyCriterion()
972 aCriterion.TypeOfElement = elementType
973 aCriterion.Type = self.EnumToLong(CritType)
974 aCriterion.Tolerance = Tolerance
976 aThreshold = Threshold
978 if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
979 aCriterion.Compare = self.EnumToLong(Compare)
980 elif Compare == "=" or Compare == "==":
981 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
983 aCriterion.Compare = self.EnumToLong(FT_LessThan)
985 aCriterion.Compare = self.EnumToLong(FT_MoreThan)
986 elif Compare != FT_Undefined:
987 aCriterion.Compare = self.EnumToLong(FT_EqualTo)
990 if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
991 FT_BelongToCylinder, FT_LyingOnGeom]:
992 # Check that Threshold is GEOM object
993 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
994 aCriterion.ThresholdStr = GetName(aThreshold)
995 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
996 if not aCriterion.ThresholdID:
997 name = aCriterion.ThresholdStr
999 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1000 geompyD = aThreshold.GetGen()
1001 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1002 # or a name of GEOM object
1003 elif isinstance( aThreshold, str ):
1004 aCriterion.ThresholdStr = aThreshold
1006 raise TypeError("The Threshold should be a shape.")
1007 if isinstance(UnaryOp,float):
1008 aCriterion.Tolerance = UnaryOp
1009 UnaryOp = FT_Undefined
1011 elif CritType == FT_BelongToMeshGroup:
1012 # Check that Threshold is a group
1013 if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
1014 if aThreshold.GetType() != elementType:
1015 raise ValueError("Group type mismatches Element type")
1016 aCriterion.ThresholdStr = aThreshold.GetName()
1017 aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
1018 study = salome.myStudy
1020 so = study.FindObjectIOR( aCriterion.ThresholdID )
1024 aCriterion.ThresholdID = entry
1026 raise TypeError("The Threshold should be a Mesh Group")
1027 elif CritType == FT_RangeOfIds:
1028 # Check that Threshold is string
1029 if isinstance(aThreshold, str):
1030 aCriterion.ThresholdStr = aThreshold
1032 raise TypeError("The Threshold should be a string.")
1033 elif CritType == FT_CoplanarFaces:
1034 # Check the Threshold
1035 if isinstance(aThreshold, int):
1036 aCriterion.ThresholdID = str(aThreshold)
1037 elif isinstance(aThreshold, str):
1038 ID = int(aThreshold)
1040 raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1041 aCriterion.ThresholdID = aThreshold
1043 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1044 elif CritType == FT_ConnectedElements:
1045 # Check the Threshold
1046 if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1047 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1048 if not aCriterion.ThresholdID:
1049 name = aThreshold.GetName()
1051 name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1052 geompyD = aThreshold.GetGen()
1053 aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1054 elif isinstance(aThreshold, int): # node id
1055 aCriterion.Threshold = aThreshold
1056 elif isinstance(aThreshold, list): # 3 point coordinates
1057 if len( aThreshold ) < 3:
1058 raise ValueError("too few point coordinates, must be 3")
1059 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1060 elif isinstance(aThreshold, str):
1061 if aThreshold.isdigit():
1062 aCriterion.Threshold = aThreshold # node id
1064 aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1066 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1067 "or a list of point coordinates and not '%s'"%aThreshold)
1068 elif CritType == FT_ElemGeomType:
1069 # Check the Threshold
1071 aCriterion.Threshold = self.EnumToLong(aThreshold)
1072 assert( aThreshold in SMESH.GeometryType._items )
1074 if isinstance(aThreshold, int):
1075 aCriterion.Threshold = aThreshold
1077 raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1080 elif CritType == FT_EntityType:
1081 # Check the Threshold
1083 aCriterion.Threshold = self.EnumToLong(aThreshold)
1084 assert( aThreshold in SMESH.EntityType._items )
1086 if isinstance(aThreshold, int):
1087 aCriterion.Threshold = aThreshold
1089 raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1093 elif CritType == FT_GroupColor:
1094 # Check the Threshold
1096 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1098 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1100 elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1101 FT_LinearOrQuadratic, FT_BadOrientedVolume,
1102 FT_BareBorderFace, FT_BareBorderVolume,
1103 FT_OverConstrainedFace, FT_OverConstrainedVolume,
1104 FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1105 # At this point the Threshold is unnecessary
1106 if aThreshold == FT_LogicalNOT:
1107 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1108 elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1109 aCriterion.BinaryOp = aThreshold
1113 aThreshold = float(aThreshold)
1114 aCriterion.Threshold = aThreshold
1116 raise TypeError("The Threshold should be a number.")
1119 if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT:
1120 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1122 if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1123 aCriterion.BinaryOp = self.EnumToLong(Threshold)
1125 if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1126 aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1128 if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1129 aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1133 def GetFilter(self,elementType,
1134 CritType=FT_Undefined,
1137 UnaryOp=FT_Undefined,
1141 Create a filter with the given parameters
1144 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1145 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1146 Note that the items starting from FT_LessThan are not suitable for CritType.
1147 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1148 Threshold: the threshold value (range of ids as string, shape, numeric)
1149 UnaryOp: SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1150 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1151 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1152 mesh: the mesh to initialize the filter with
1155 :class:`SMESH.Filter`
1158 See :doc:`Filters usage examples <tui_filters>`
1161 aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1162 aFilterMgr = self.CreateFilterManager()
1163 aFilter = aFilterMgr.CreateFilter()
1165 aCriteria.append(aCriterion)
1166 aFilter.SetCriteria(aCriteria)
1168 if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1169 else : aFilter.SetMesh( mesh )
1170 aFilterMgr.UnRegister()
1173 def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1175 Create a filter from criteria
1178 criteria: a list of :class:`SMESH.Filter.Criterion`
1179 binOp: binary operator used when binary operator of criteria is undefined
1182 :class:`SMESH.Filter`
1185 See :doc:`Filters usage examples <tui_filters>`
1188 for i in range( len( criteria ) - 1 ):
1189 if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1190 criteria[i].BinaryOp = self.EnumToLong( binOp )
1191 aFilterMgr = self.CreateFilterManager()
1192 aFilter = aFilterMgr.CreateFilter()
1193 aFilter.SetCriteria(criteria)
1194 aFilterMgr.UnRegister()
1197 def GetFunctor(self,theCriterion):
1199 Create a numerical functor by its type
1202 theCriterion (SMESH.FunctorType): functor type.
1203 Note that not all items correspond to numerical functors.
1206 :class:`SMESH.NumericalFunctor`
1209 if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1211 aFilterMgr = self.CreateFilterManager()
1213 if theCriterion == FT_AspectRatio:
1214 functor = aFilterMgr.CreateAspectRatio()
1215 elif theCriterion == FT_AspectRatio3D:
1216 functor = aFilterMgr.CreateAspectRatio3D()
1217 elif theCriterion == FT_Warping:
1218 functor = aFilterMgr.CreateWarping()
1219 elif theCriterion == FT_Warping3D:
1220 functor = aFilterMgr.CreateWarping3D()
1221 elif theCriterion == FT_MinimumAngle:
1222 functor = aFilterMgr.CreateMinimumAngle()
1223 elif theCriterion == FT_Taper:
1224 functor = aFilterMgr.CreateTaper()
1225 elif theCriterion == FT_Skew:
1226 functor = aFilterMgr.CreateSkew()
1227 elif theCriterion == FT_Area:
1228 functor = aFilterMgr.CreateArea()
1229 elif theCriterion == FT_Volume3D:
1230 functor = aFilterMgr.CreateVolume3D()
1231 elif theCriterion == FT_MaxElementLength2D:
1232 functor = aFilterMgr.CreateMaxElementLength2D()
1233 elif theCriterion == FT_MaxElementLength3D:
1234 functor = aFilterMgr.CreateMaxElementLength3D()
1235 elif theCriterion == FT_MultiConnection:
1236 functor = aFilterMgr.CreateMultiConnection()
1237 elif theCriterion == FT_MultiConnection2D:
1238 functor = aFilterMgr.CreateMultiConnection2D()
1239 elif theCriterion == FT_Length:
1240 functor = aFilterMgr.CreateLength()
1241 elif theCriterion == FT_Length2D:
1242 functor = aFilterMgr.CreateLength2D()
1243 elif theCriterion == FT_Length3D:
1244 functor = aFilterMgr.CreateLength3D()
1245 elif theCriterion == FT_Deflection2D:
1246 functor = aFilterMgr.CreateDeflection2D()
1247 elif theCriterion == FT_NodeConnectivityNumber:
1248 functor = aFilterMgr.CreateNodeConnectivityNumber()
1249 elif theCriterion == FT_BallDiameter:
1250 functor = aFilterMgr.CreateBallDiameter()
1251 elif theCriterion == FT_ScaledJacobian:
1252 functor = aFilterMgr.CreateScaledJacobian()
1254 print("Error: given parameter is not numerical functor type.")
1255 aFilterMgr.UnRegister()
1258 def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1263 theHType (string): mesh hypothesis type
1264 theLibName (string): mesh plug-in library name
1267 created hypothesis instance
1269 hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1271 if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1274 # wrap hypothesis methods
1275 for meth_name in dir( hyp.__class__ ):
1276 if not meth_name.startswith("Get") and \
1277 not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1278 method = getattr ( hyp.__class__, meth_name )
1279 if callable(method):
1280 setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1284 def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1286 Create hypothesis initialized according to parameters
1289 hypType (string): hypothesis type
1290 libName (string): plug-in library name
1291 mesh: optional mesh by which a hypotheses can initialize self
1292 shape: optional geometry by size of which a hypotheses can initialize self
1293 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1296 created hypothesis instance
1298 if isinstance( mesh, Mesh ):
1299 mesh = mesh.GetMesh()
1300 if isinstance( initParams, (bool,int)):
1301 initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1302 return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1303 mesh, shape, initParams )
1305 def GetMeshInfo(self, obj):
1307 Get the mesh statistic.
1310 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1313 if isinstance( obj, Mesh ):
1316 if hasattr(obj, "GetMeshInfo"):
1317 values = obj.GetMeshInfo()
1318 for i in range(SMESH.Entity_Last._v):
1319 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1323 def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1325 Get minimum distance between two objects
1327 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1328 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1331 src1 (SMESH.SMESH_IDSource): first source object
1332 src2 (SMESH.SMESH_IDSource): second source object
1333 id1 (int): node/element id from the first source
1334 id2 (int): node/element id from the second (or first) source
1335 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1336 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1339 minimum distance value
1342 :meth:`GetMinDistance`
1345 result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1349 result = result.value
1352 def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1354 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1356 * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1357 * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1360 src1 (SMESH.SMESH_IDSource): first source object
1361 src2 (SMESH.SMESH_IDSource): second source object
1362 id1 (int): node/element id from the first source
1363 id2 (int): node/element id from the second (or first) source
1364 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1365 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1368 :class:`SMESH.Measure` structure or None if input data is invalid
1373 if isinstance(src1, Mesh): src1 = src1.mesh
1374 if isinstance(src2, Mesh): src2 = src2.mesh
1375 if src2 is None and id2 != 0: src2 = src1
1376 if not hasattr(src1, "_narrow"): return None
1377 src1 = src1._narrow(SMESH.SMESH_IDSource)
1378 if not src1: return None
1379 unRegister = genObjUnRegister()
1382 e = m.GetMeshEditor()
1384 src1 = e.MakeIDSource([id1], SMESH.FACE)
1386 src1 = e.MakeIDSource([id1], SMESH.NODE)
1387 unRegister.set( src1 )
1389 if hasattr(src2, "_narrow"):
1390 src2 = src2._narrow(SMESH.SMESH_IDSource)
1391 if src2 and id2 != 0:
1393 e = m.GetMeshEditor()
1395 src2 = e.MakeIDSource([id2], SMESH.FACE)
1397 src2 = e.MakeIDSource([id2], SMESH.NODE)
1398 unRegister.set( src2 )
1401 aMeasurements = self.CreateMeasurements()
1402 unRegister.set( aMeasurements )
1403 result = aMeasurements.MinDistance(src1, src2)
1406 def BoundingBox(self, objects):
1408 Get bounding box of the specified object(s)
1411 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1414 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1417 :meth:`GetBoundingBox`
1420 result = self.GetBoundingBox(objects)
1424 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1427 def GetBoundingBox(self, objects):
1429 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1432 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1435 :class:`SMESH.Measure` structure
1441 if isinstance(objects, tuple):
1442 objects = list(objects)
1443 if not isinstance(objects, list):
1447 if isinstance(o, Mesh):
1448 srclist.append(o.mesh)
1449 elif hasattr(o, "_narrow"):
1450 src = o._narrow(SMESH.SMESH_IDSource)
1451 if src: srclist.append(src)
1454 aMeasurements = self.CreateMeasurements()
1455 result = aMeasurements.BoundingBox(srclist)
1456 aMeasurements.UnRegister()
1459 def GetLength(self, obj):
1461 Get sum of lengths of all 1D elements in the mesh object.
1464 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1467 sum of lengths of all 1D elements
1470 if isinstance(obj, Mesh): obj = obj.mesh
1471 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1472 aMeasurements = self.CreateMeasurements()
1473 value = aMeasurements.Length(obj)
1474 aMeasurements.UnRegister()
1477 def GetArea(self, obj):
1479 Get sum of areas of all 2D elements in the mesh object.
1482 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1485 sum of areas of all 2D elements
1488 if isinstance(obj, Mesh): obj = obj.mesh
1489 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1490 aMeasurements = self.CreateMeasurements()
1491 value = aMeasurements.Area(obj)
1492 aMeasurements.UnRegister()
1495 def GetVolume(self, obj):
1497 Get sum of volumes of all 3D elements in the mesh object.
1500 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1503 sum of volumes of all 3D elements
1506 if isinstance(obj, Mesh): obj = obj.mesh
1507 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1508 aMeasurements = self.CreateMeasurements()
1509 value = aMeasurements.Volume(obj)
1510 aMeasurements.UnRegister()
1513 def GetGravityCenter(self, obj):
1515 Get gravity center of all nodes of a mesh object.
1518 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1521 Three components of the gravity center (x,y,z)
1524 :meth:`Mesh.BaryCenter`
1526 if isinstance(obj, Mesh): obj = obj.mesh
1527 if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1528 aMeasurements = self.CreateMeasurements()
1529 pointStruct = aMeasurements.GravityCenter(obj)
1530 aMeasurements.UnRegister()
1531 return pointStruct.x, pointStruct.y, pointStruct.z
1533 def GetAngle(self, p1, p2, p3 ):
1535 Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1538 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1544 if isinstance( p1, list ): p1 = PointStruct(*p1)
1545 if isinstance( p2, list ): p2 = PointStruct(*p2)
1546 if isinstance( p3, list ): p3 = PointStruct(*p3)
1548 aMeasurements = self.CreateMeasurements()
1549 angle = aMeasurements.Angle(p1,p2,p3)
1550 aMeasurements.UnRegister()
1555 pass # end of class smeshBuilder
1558 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1559 """Registering the new proxy for SMESH.SMESH_Gen"""
1562 def New( instance=None, instanceGeom=None):
1564 Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1565 interface to create or load meshes.
1570 salome.salome_init()
1571 from salome.smesh import smeshBuilder
1572 smesh = smeshBuilder.New()
1575 instance: CORBA proxy of SMESH Engine. If None, the default Engine is used.
1576 instanceGeom: CORBA proxy of GEOM Engine. If None, the default Engine is used.
1578 :class:`smeshBuilder` instance
1583 if instance and isinstance( instance, SALOMEDS._objref_Study ):
1585 sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1590 smeshInst = smeshBuilder()
1591 assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1592 smeshInst.init_smesh(instanceGeom)
1596 # Public class: Mesh
1597 # ==================
1600 class Mesh(metaclass = MeshMeta):
1602 This class allows defining and managing a mesh.
1603 It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1604 It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1605 new nodes and elements and by changing the existing entities), to get information
1606 about a mesh and to export a mesh in different formats.
1613 def __init__(self, smeshpyD, geompyD, obj=0, name=0, parallel=False):
1618 Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1619 sets the GUI name of this mesh to *name*.
1622 smeshpyD: an instance of smeshBuilder class
1623 geompyD: an instance of geomBuilder class
1624 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1625 name: Study name of the mesh
1628 self.smeshpyD = smeshpyD
1629 self.geompyD = geompyD
1634 if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1637 # publish geom of mesh (issue 0021122)
1638 if not self.geom.GetStudyEntry():
1642 geo_name = name + " shape"
1644 geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1645 geompyD.addToStudy( self.geom, geo_name )
1646 if parallel and isinstance(self, ParallelMesh):
1647 mymesh = self.smeshpyD.CreateParallelMesh(self.geom)
1648 mymesh2 = mymesh._narrow(SMESH._objref_SMESH_Mesh)
1649 self.SetMesh( mymesh )
1651 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1653 elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1656 self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1658 self.smeshpyD.SetName(self.mesh, name)
1660 self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1663 self.geom = self.mesh.GetShapeToMesh()
1665 self.editor = self.mesh.GetMeshEditor()
1666 self.functors = [None] * SMESH.FT_Undefined._v
1668 # set self to algoCreator's
1669 for attrName in dir(self):
1670 attr = getattr( self, attrName )
1671 if isinstance( attr, algoCreator ):
1672 setattr( self, attrName, attr.copy( self ))
1679 Destructor. Clean-up resources
1682 #self.mesh.UnRegister()
1686 def SetMesh(self, theMesh):
1688 Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1691 theMesh: a :class:`SMESH.SMESH_Mesh` object
1693 # do not call Register() as this prevents mesh servant deletion at closing study
1694 #if self.mesh: self.mesh.UnRegister()
1697 #self.mesh.Register()
1698 self.geom = self.mesh.GetShapeToMesh()
1702 if salome.sg.hasDesktop():
1703 so = salome.ObjectToSObject( self.geom )
1704 comp = so.GetFatherComponent()
1705 if comp.ComponentDataType() == "SHAPERSTUDY":
1706 import shaperBuilder
1707 self.geompyD = shaperBuilder.New()
1710 if not self.geompyD:
1711 self.geompyD = self.geom.GetGen()
1716 Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1719 a :class:`SMESH.SMESH_Mesh` object
1724 def GetEngine(self):
1726 Return a smeshBuilder instance created this mesh
1728 return self.smeshpyD
1730 def GetGeomEngine(self):
1732 Return a geomBuilder instance
1738 Get the name of the mesh
1741 the name of the mesh as a string
1744 name = GetName(self.GetMesh())
1747 def SetName(self, name):
1749 Set a name to the mesh
1752 name: a new name of the mesh
1755 self.smeshpyD.SetName(self.GetMesh(), name)
1757 def GetSubMesh(self, geom, name):
1759 Get a sub-mesh object associated to a *geom* geometrical object.
1762 geom: a geometrical object (shape)
1763 name: a name for the sub-mesh in the Object Browser
1766 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1767 which lies on the given shape
1770 A sub-mesh is implicitly created when a sub-shape is specified at
1771 creating an algorithm, for example::
1773 algo1D = mesh.Segment(geom=Edge_1)
1775 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1776 The created sub-mesh can be retrieved from the algorithm::
1778 submesh = algo1D.GetSubMesh()
1781 AssureGeomPublished( self, geom, name )
1782 submesh = self.mesh.GetSubMesh( geom, name )
1787 Return the shape associated to the mesh
1795 def SetShape(self, geom):
1797 Associate the given shape to the mesh (entails the recreation of the mesh)
1800 geom: the shape to be meshed (GEOM_Object)
1803 self.mesh = self.smeshpyD.CreateMesh(geom)
1805 def HasShapeToMesh(self):
1807 Return ``True`` if this mesh is based on geometry
1809 return self.mesh.HasShapeToMesh()
1813 Load mesh from the study after opening the study
1817 def IsReadyToCompute(self, theSubObject):
1819 Return true if the hypotheses are defined well
1822 theSubObject: a sub-shape of a mesh shape
1828 return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1830 def GetAlgoState(self, theSubObject):
1832 Return errors of hypotheses definition.
1833 The list of errors is empty if everything is OK.
1836 theSubObject: a sub-shape of a mesh shape
1842 return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1844 def GetGeometryByMeshElement(self, theElementID, theGeomName):
1846 Return a geometrical object on which the given element was built.
1847 The returned geometrical object, if not nil, is either found in the
1848 study or published by this method with the given name
1851 theElementID: the id of the mesh element
1852 theGeomName: the user-defined name of the geometrical object
1855 GEOM.GEOM_Object instance
1858 return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1860 def MeshDimension(self):
1862 Return the mesh dimension depending on the dimension of the underlying shape
1863 or, if the mesh is not based on any shape, basing on deimension of elements
1866 mesh dimension as an integer value [0,3]
1869 if self.mesh.HasShapeToMesh():
1870 shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1871 if len( shells ) > 0 :
1873 elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1875 elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1880 if self.NbVolumes() > 0: return 3
1881 if self.NbFaces() > 0: return 2
1882 if self.NbEdges() > 0: return 1
1885 def Evaluate(self, geom=0):
1887 Evaluate size of prospective mesh on a shape
1890 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1891 To know predicted number of e.g. edges, inquire it this way::
1893 Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1896 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1898 geom = self.mesh.GetShapeToMesh()
1901 return self.smeshpyD.Evaluate(self.mesh, geom)
1903 def Compute(self, geom=0, discardModifs=False, refresh=False):
1905 Compute the mesh and return the status of the computation
1908 geom: geomtrical shape on which mesh data should be computed
1909 discardModifs: if True and the mesh has been edited since
1910 a last total re-compute and that may prevent successful partial re-compute,
1911 then the mesh is cleaned before Compute()
1912 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1918 if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1919 geom = self.mesh.GetShapeToMesh()
1922 if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1924 ok = self.smeshpyD.Compute(self.mesh, geom)
1925 except SALOME.SALOME_Exception as ex:
1926 print("Mesh computation failed, exception caught:")
1927 print(" ", ex.details.text)
1930 print("Mesh computation failed, exception caught:")
1931 traceback.print_exc()
1935 # Treat compute errors
1936 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1938 for err in computeErrors:
1939 if self.mesh.HasShapeToMesh():
1940 shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1942 stdErrors = ["OK", #COMPERR_OK
1943 "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
1944 "std::exception", #COMPERR_STD_EXCEPTION
1945 "OCC exception", #COMPERR_OCC_EXCEPTION
1946 "..", #COMPERR_SLM_EXCEPTION
1947 "Unknown exception", #COMPERR_EXCEPTION
1948 "Memory allocation problem", #COMPERR_MEMORY_PB
1949 "Algorithm failed", #COMPERR_ALGO_FAILED
1950 "Unexpected geometry", #COMPERR_BAD_SHAPE
1951 "Warning", #COMPERR_WARNING
1952 "Computation cancelled",#COMPERR_CANCELED
1953 "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1955 if err.code < len(stdErrors): errText = stdErrors[err.code]
1957 errText = "code %s" % -err.code
1958 if errText: errText += ". "
1959 errText += err.comment
1960 if allReasons: allReasons += "\n"
1962 allReasons += '- "%s"%s - %s' %(err.algoName, shapeText, errText)
1964 allReasons += '- "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1968 errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1970 if err.isGlobalAlgo:
1978 reason = '%s %sD algorithm is missing' % (glob, dim)
1979 elif err.state == HYP_MISSING:
1980 reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1981 % (glob, dim, name, dim))
1982 elif err.state == HYP_NOTCONFORM:
1983 reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1984 elif err.state == HYP_BAD_PARAMETER:
1985 reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1986 % ( glob, dim, name ))
1987 elif err.state == HYP_BAD_GEOMETRY:
1988 reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1989 'geometry' % ( glob, dim, name ))
1990 elif err.state == HYP_HIDDEN_ALGO:
1991 reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1992 'algorithm of upper dimension generating %sD mesh'
1993 % ( glob, dim, name, glob, dim ))
1995 reason = ("For unknown reason. "
1996 "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1998 if allReasons: allReasons += "\n"
1999 allReasons += "- " + reason
2001 if not ok or allReasons != "":
2002 msg = '"' + GetName(self.mesh) + '"'
2003 if ok: msg += " has been computed with warnings"
2004 else: msg += " has not been computed"
2005 if allReasons != "": msg += ":"
2011 if salome.sg.hasDesktop():
2012 if not isinstance( refresh, list): # not a call from subMesh.Compute()
2013 if refresh: salome.sg.updateObjBrowser()
2017 def CheckCompute(self):
2019 Check if the mesh was properly compute
2021 if not self.mesh.IsComputedOK():
2022 raise Exception("Could not compute {}".format(self.GetName()))
2024 def GetComputeErrors(self, shape=0 ):
2026 Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2030 shape = self.mesh.GetShapeToMesh()
2031 return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2033 def GetSubShapeName(self, subShapeID ):
2035 Return a name of a sub-shape by its ID.
2036 Possible variants (for *subShapeID* == 3):
2038 - **"Face_12"** - published sub-shape
2039 - **FACE #3** - not published sub-shape
2040 - **sub-shape #3** - invalid sub-shape ID
2041 - **#3** - error in this function
2044 subShapeID: a unique ID of a sub-shape
2047 a string describing the sub-shape
2051 if not self.mesh.HasShapeToMesh():
2055 mainIOR = salome.orb.object_to_string( self.GetShape() )
2057 mainSO = s.FindObjectIOR(mainIOR)
2060 shapeText = '"%s"' % mainSO.GetName()
2061 subIt = s.NewChildIterator(mainSO)
2063 subSO = subIt.Value()
2065 obj = subSO.GetObject()
2066 if not obj: continue
2067 go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2070 ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2073 if ids == subShapeID:
2074 shapeText = '"%s"' % subSO.GetName()
2077 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2079 shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2081 shapeText = 'sub-shape #%s' % (subShapeID)
2083 shapeText = "#%s" % (subShapeID)
2086 def GetFailedShapes(self, publish=False):
2088 Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2089 error of an algorithm
2092 publish: if *True*, the returned groups will be published in the study
2095 a list of GEOM groups each named after a failed algorithm
2100 computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2101 for err in computeErrors:
2102 shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2103 if not shape: continue
2104 if err.algoName in algo2shapes:
2105 algo2shapes[ err.algoName ].append( shape )
2107 algo2shapes[ err.algoName ] = [ shape ]
2111 for algoName, shapes in list(algo2shapes.items()):
2113 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2114 otherTypeShapes = []
2116 group = self.geompyD.CreateGroup( self.geom, groupType )
2117 for shape in shapes:
2118 if shape.GetShapeType() == shapes[0].GetShapeType():
2119 sameTypeShapes.append( shape )
2121 otherTypeShapes.append( shape )
2122 self.geompyD.UnionList( group, sameTypeShapes )
2124 group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2126 group.SetName( algoName )
2127 groups.append( group )
2128 shapes = otherTypeShapes
2131 for group in groups:
2132 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2135 def GetMeshOrder(self):
2137 Return sub-mesh objects list in meshing order
2140 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2143 return self.mesh.GetMeshOrder()
2145 def SetMeshOrder(self, submeshes):
2147 Set priority of sub-meshes. It works in two ways:
2149 * For sub-meshes with assigned algorithms of same dimension generating mesh of
2150 *several dimensions*, it sets the order in which the sub-meshes are computed.
2151 * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2152 when looking for meshing parameters to apply to a sub-shape. To impose the
2153 order in which sub-meshes with uni-dimensional algorithms are computed,
2154 call **submesh.Compute()** in a desired order.
2157 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2159 Warning: the method is for setting the order for all sub-meshes at once:
2160 SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2163 return self.mesh.SetMeshOrder(submeshes)
2165 def Clear(self, refresh=False):
2167 Remove all nodes and elements generated on geometry. Imported elements remain.
2170 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2174 if ( salome.sg.hasDesktop() ):
2175 if refresh: salome.sg.updateObjBrowser()
2177 def ClearSubMesh(self, geomId, refresh=False):
2179 Remove all nodes and elements of indicated shape
2182 geomId: the ID of a sub-shape to remove elements on
2183 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2186 self.mesh.ClearSubMesh(geomId)
2187 if salome.sg.hasDesktop():
2188 if refresh: salome.sg.updateObjBrowser()
2190 def AutomaticTetrahedralization(self, fineness=0):
2192 Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2195 fineness: [0.0,1.0] defines mesh fineness
2201 dim = self.MeshDimension()
2203 self.RemoveGlobalHypotheses()
2204 self.Segment().AutomaticLength(fineness)
2206 self.Triangle().LengthFromEdges()
2211 return self.Compute()
2213 def AutomaticHexahedralization(self, fineness=0):
2215 Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2218 fineness: [0.0, 1.0] defines mesh fineness
2224 dim = self.MeshDimension()
2225 # assign the hypotheses
2226 self.RemoveGlobalHypotheses()
2227 self.Segment().AutomaticLength(fineness)
2234 return self.Compute()
2236 def AddHypothesis(self, hyp, geom=0):
2241 hyp: a hypothesis to assign
2242 geom: a subhape of mesh geometry
2245 :class:`SMESH.Hypothesis_Status`
2248 if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2249 hyp, geom = geom, hyp
2250 if isinstance( hyp, Mesh_Algorithm ):
2251 hyp = hyp.GetAlgorithm()
2256 geom = self.mesh.GetShapeToMesh()
2259 if self.mesh.HasShapeToMesh():
2260 hyp_type = hyp.GetName()
2261 lib_name = hyp.GetLibName()
2262 # checkAll = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2263 # if checkAll and geom:
2264 # checkAll = geom.GetType() == 37
2266 isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2268 AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2269 status = self.mesh.AddHypothesis(geom, hyp)
2271 status = HYP_BAD_GEOMETRY, ""
2272 hyp_name = GetName( hyp )
2275 geom_name = geom.GetName()
2276 isAlgo = hyp._narrow( SMESH_Algo )
2277 TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2280 def IsUsedHypothesis(self, hyp, geom):
2282 Return True if an algorithm or hypothesis is assigned to a given shape
2285 hyp: an algorithm or hypothesis to check
2286 geom: a subhape of mesh geometry
2292 if not hyp: # or not geom
2294 if isinstance( hyp, Mesh_Algorithm ):
2295 hyp = hyp.GetAlgorithm()
2297 hyps = self.GetHypothesisList(geom)
2299 if h.GetId() == hyp.GetId():
2303 def RemoveHypothesis(self, hyp, geom=0):
2305 Unassign a hypothesis
2308 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2309 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2312 :class:`SMESH.Hypothesis_Status`
2317 if isinstance( hyp, Mesh_Algorithm ):
2318 hyp = hyp.GetAlgorithm()
2324 if self.IsUsedHypothesis( hyp, shape ):
2325 return self.mesh.RemoveHypothesis( shape, hyp )
2326 hypName = GetName( hyp )
2327 geoName = GetName( shape )
2328 print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2331 def GetHypothesisList(self, geom):
2333 Get the list of hypotheses added on a geometry
2336 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2339 the sequence of :class:`SMESH.SMESH_Hypothesis`
2342 return self.mesh.GetHypothesisList( geom )
2344 def RemoveGlobalHypotheses(self):
2346 Remove all global hypotheses
2349 current_hyps = self.mesh.GetHypothesisList( self.geom )
2350 for hyp in current_hyps:
2351 self.mesh.RemoveHypothesis( self.geom, hyp )
2355 def ExportMEDCoupling(self, *args, **kwargs):
2357 Export the mesh in a memory representation.
2360 auto_groups (boolean): parameter for creating/not creating
2361 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2362 the typical use is auto_groups=False.
2363 overwrite (boolean): parameter for overwriting/not overwriting the file
2364 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2365 to export instead of the mesh
2366 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2368 - 1D if all mesh nodes lie on OX coordinate axis, or
2369 - 2D if all mesh nodes lie on XOY coordinate plane, or
2370 - 3D in the rest cases.
2372 If *autoDimension* is *False*, the space dimension is always 3.
2373 fields: list of GEOM fields defined on the shape to mesh.
2374 geomAssocFields: each character of this string means a need to export a
2375 corresponding field; correspondence between fields and characters
2378 - 'v' stands for "_vertices_" field;
2379 - 'e' stands for "_edges_" field;
2380 - 'f' stands for "_faces_" field;
2381 - 's' stands for "_solids_" field.
2383 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2384 close to zero within a given tolerance, the coordinate is set to zero.
2385 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2386 saveNumbers(boolean) : enable saving numbers of nodes and cells.
2388 auto_groups = args[0] if len(args) > 0 else False
2389 meshPart = args[1] if len(args) > 1 else None
2390 autoDimension = args[2] if len(args) > 2 else True
2391 fields = args[3] if len(args) > 3 else []
2392 geomAssocFields = args[4] if len(args) > 4 else ''
2393 z_tolerance = args[5] if len(args) > 5 else -1.
2394 saveNumbers = args[6] if len(args) > 6 else True
2395 # process keywords arguments
2396 auto_groups = kwargs.get("auto_groups", auto_groups)
2397 meshPart = kwargs.get("meshPart", meshPart)
2398 autoDimension = kwargs.get("autoDimension", autoDimension)
2399 fields = kwargs.get("fields", fields)
2400 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2401 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2402 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2404 # invoke engine's function
2405 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2406 unRegister = genObjUnRegister()
2407 if isinstance( meshPart, list ):
2408 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2409 unRegister.set( meshPart )
2411 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2412 self.mesh.SetParameters(Parameters)
2414 intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2415 fields, geomAssocFields, z_tolerance,
2418 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2419 return medcoupling.MEDFileData.New(dab)
2421 intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2423 dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2424 return medcoupling.MEDFileMesh.New(dab)
2426 def ExportMED(self, *args, **kwargs):
2428 Export the mesh in a file in MED format
2429 allowing to overwrite the file if it exists or add the exported data to its contents
2432 fileName: is the file name
2433 auto_groups (boolean): parameter for creating/not creating
2434 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2435 the typical use is auto_groups=False.
2436 version (int): define the version (xy, where version is x.y.z) of MED file format.
2437 For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2438 The rules of compatibility to write a mesh in an older version than
2439 the current version depend on the current version. For instance,
2440 with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2441 or 3.2.1 or 3.3.1 formats.
2442 If the version is equal to -1, the version is not changed (default).
2443 overwrite (boolean): parameter for overwriting/not overwriting the file
2444 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2445 to export instead of the mesh
2446 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2448 - 1D if all mesh nodes lie on OX coordinate axis, or
2449 - 2D if all mesh nodes lie on XOY coordinate plane, or
2450 - 3D in the rest cases.
2452 If *autoDimension* is *False*, the space dimension is always 3.
2453 fields: list of GEOM fields defined on the shape to mesh.
2454 geomAssocFields: each character of this string means a need to export a
2455 corresponding field; correspondence between fields and characters
2458 - 'v' stands for "_vertices_" field;
2459 - 'e' stands for "_edges_" field;
2460 - 'f' stands for "_faces_" field;
2461 - 's' stands for "_solids_" field.
2463 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2464 close to zero within a given tolerance, the coordinate is set to zero.
2465 If *ZTolerance* is negative (default), the node coordinates are kept as is.
2466 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2468 # process positional arguments
2469 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2471 auto_groups = args[1] if len(args) > 1 else False
2472 version = args[2] if len(args) > 2 else -1
2473 overwrite = args[3] if len(args) > 3 else True
2474 meshPart = args[4] if len(args) > 4 else None
2475 autoDimension = args[5] if len(args) > 5 else True
2476 fields = args[6] if len(args) > 6 else []
2477 geomAssocFields = args[7] if len(args) > 7 else ''
2478 z_tolerance = args[8] if len(args) > 8 else -1.
2479 saveNumbers = args[9] if len(args) > 9 else True
2480 # process keywords arguments
2481 auto_groups = kwargs.get("auto_groups", auto_groups)
2482 version = kwargs.get("version", version)
2483 version = kwargs.get("minor", version)
2484 overwrite = kwargs.get("overwrite", overwrite)
2485 meshPart = kwargs.get("meshPart", meshPart)
2486 autoDimension = kwargs.get("autoDimension", autoDimension)
2487 fields = kwargs.get("fields", fields)
2488 geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2489 z_tolerance = kwargs.get("zTolerance", z_tolerance)
2490 saveNumbers = kwargs.get("saveNumbers", saveNumbers)
2492 if isinstance( meshPart, Mesh):
2493 meshPart = meshPart.GetMesh()
2495 # invoke engine's function
2496 if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2497 unRegister = genObjUnRegister()
2498 if isinstance( meshPart, list ):
2499 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2500 unRegister.set( meshPart )
2502 z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2503 self.mesh.SetParameters(Parameters)
2505 self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2506 version, overwrite, autoDimension,
2507 fields, geomAssocFields, z_tolerance, saveNumbers )
2509 self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2511 def ExportDAT(self, f, meshPart=None, renumber=True):
2513 Export the mesh in a file in DAT format
2517 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2518 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2521 if meshPart or not renumber:
2522 unRegister = genObjUnRegister()
2523 if isinstance( meshPart, list ):
2524 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2525 unRegister.set( meshPart )
2526 self.mesh.ExportPartToDAT( meshPart, f, renumber )
2528 self.mesh.ExportDAT( f, renumber )
2530 def ExportUNV(self, f, meshPart=None, renumber=True):
2532 Export the mesh in a file in UNV format
2536 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2537 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2540 if meshPart or not renumber:
2541 unRegister = genObjUnRegister()
2542 if isinstance( meshPart, list ):
2543 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2544 unRegister.set( meshPart )
2545 self.mesh.ExportPartToUNV( meshPart, f, renumber )
2547 self.mesh.ExportUNV( f, renumber )
2549 def ExportSTL(self, f, ascii=1, meshPart=None):
2551 Export the mesh in a file in STL format
2555 ascii: defines the file encoding
2556 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2560 unRegister = genObjUnRegister()
2561 if isinstance( meshPart, list ):
2562 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2563 unRegister.set( meshPart )
2564 self.mesh.ExportPartToSTL( meshPart, f, ascii )
2566 self.mesh.ExportSTL(f, ascii)
2568 def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2570 Export the mesh in a file in CGNS format
2574 overwrite: boolean parameter for overwriting/not overwriting the file
2575 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2576 groupElemsByType: if True all elements of same entity type are exported at ones,
2577 else elements are exported in order of their IDs which can cause creation
2578 of multiple cgns sections
2581 unRegister = genObjUnRegister()
2582 if isinstance( meshPart, list ):
2583 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2584 unRegister.set( meshPart )
2585 if isinstance( meshPart, Mesh ):
2586 meshPart = meshPart.mesh
2588 meshPart = self.mesh
2589 self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2591 def ExportGMF(self, f, meshPart=None):
2593 Export the mesh in a file in GMF format.
2594 GMF files must have .mesh extension for the ASCII format and .meshb for
2595 the bynary format. Other extensions are not allowed.
2599 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2602 unRegister = genObjUnRegister()
2603 if isinstance( meshPart, list ):
2604 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2605 unRegister.set( meshPart )
2606 if isinstance( meshPart, Mesh ):
2607 meshPart = meshPart.mesh
2609 meshPart = self.mesh
2610 self.mesh.ExportGMF(meshPart, f, True)
2619 Exports a part of mesh to a file with meshio library
2620 through an intermediate MED file.
2622 Parametrs described below are the same as for ExportMED() method.
2623 However, we know that _pyMesh::Process(const Handle(_pyCommand)& theCommand) method
2624 change a position of meshPart argument when dump to a Python script for whatever reason
2626 - to 5th place for ExportMED command
2627 - to last place for the rest commands
2629 So, for this method meshPart moved to the end of the args.
2630 Look at src/SMESH_I/SMESH_2smeshpy.cxx for related source code.
2632 The same note is for the name of the method that was dumped as ExportPartToMESHIO(),
2633 but then processing just removes PartTo from the middle of the name as it was done
2634 for all export methods.
2637 fileName: is the file name
2638 selectedFilter: filter string selected by user in a file dialog
2639 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2640 to export instead of the mesh
2643 if isinstance(meshPart, Mesh):
2644 meshPart = meshPart.GetMesh()
2646 self.mesh.ExportPartToMESHIO(
2653 def ExportToMED(self, *args, **kwargs):
2655 Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2656 Export the mesh in a file in MED format
2657 allowing to overwrite the file if it exists or add the exported data to its contents
2660 fileName: the file name
2661 opt (boolean): parameter for creating/not creating
2662 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2663 overwrite: boolean parameter for overwriting/not overwriting the file
2664 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2666 - 1D if all mesh nodes lie on OX coordinate axis, or
2667 - 2D if all mesh nodes lie on XOY coordinate plane, or
2668 - 3D in the rest cases.
2670 If **autoDimension** is *False*, the space dimension is always 3.
2673 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2674 # process positional arguments
2675 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2677 auto_groups = args[1] if len(args) > 1 else False
2678 overwrite = args[2] if len(args) > 2 else True
2679 autoDimension = args[3] if len(args) > 3 else True
2680 # process keywords arguments
2681 auto_groups = kwargs.get("opt", auto_groups) # old keyword name
2682 auto_groups = kwargs.get("auto_groups", auto_groups) # new keyword name
2683 overwrite = kwargs.get("overwrite", overwrite)
2684 autoDimension = kwargs.get("autoDimension", autoDimension)
2686 # invoke engine's function
2687 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2689 def ExportToMEDX(self, *args, **kwargs):
2691 Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2692 Export the mesh in a file in MED format
2695 fileName: the file name
2696 opt (boolean): parameter for creating/not creating
2697 the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2698 overwrite: boolean parameter for overwriting/not overwriting the file
2699 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2701 - 1D if all mesh nodes lie on OX coordinate axis, or
2702 - 2D if all mesh nodes lie on XOY coordinate plane, or
2703 - 3D in the rest cases.
2705 If **autoDimension** is *False*, the space dimension is always 3.
2708 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2709 # process positional arguments
2710 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2712 auto_groups = args[1] if len(args) > 1 else False
2713 overwrite = args[2] if len(args) > 2 else True
2714 autoDimension = args[3] if len(args) > 3 else True
2715 # process keywords arguments
2716 auto_groups = kwargs.get("auto_groups", auto_groups)
2717 overwrite = kwargs.get("overwrite", overwrite)
2718 autoDimension = kwargs.get("autoDimension", autoDimension)
2720 # invoke engine's function
2721 self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2725 def Append(self, meshes, uniteIdenticalGroups = True,
2726 mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2728 Append given meshes into this mesh.
2729 All groups of input meshes will be created in this mesh.
2732 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2733 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2734 mergeNodesAndElements: if True, equal nodes and elements are merged
2735 mergeTolerance: tolerance for merging nodes
2736 allGroups: forces creation of groups corresponding to every input mesh
2738 self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2739 mergeNodesAndElements, mergeTolerance, allGroups,
2740 meshToAppendTo = self.GetMesh() )
2742 # Operations with groups:
2743 # ----------------------
2744 def CreateEmptyGroup(self, elementType, name):
2746 Create an empty standalone mesh group
2749 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2750 either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2751 name: the name of the mesh group
2754 :class:`SMESH.SMESH_Group`
2757 return self.mesh.CreateGroup(elementType, name)
2759 def Group(self, grp, name=""):
2761 Create a mesh group based on the geometric object *grp*
2762 and give it a *name*.
2763 If *name* is not defined the name of the geometric group is used
2766 Works like :meth:`GroupOnGeom`.
2769 grp: a geometric group, a vertex, an edge, a face or a solid
2770 name: the name of the mesh group
2773 :class:`SMESH.SMESH_GroupOnGeom`
2776 return self.GroupOnGeom(grp, name)
2778 def GroupOnGeom(self, grp, name="", typ=None):
2780 Create a mesh group based on the geometrical object *grp*
2781 and give it a *name*.
2782 if *name* is not defined the name of the geometric group is used
2785 grp: a geometrical group, a vertex, an edge, a face or a solid
2786 name: the name of the mesh group
2787 typ: the type of elements in the group; either of
2788 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2789 automatically detected by the type of the geometry
2792 :class:`SMESH.SMESH_GroupOnGeom`
2795 AssureGeomPublished( self, grp, name )
2797 name = grp.GetName()
2799 typ = self._groupTypeFromShape( grp )
2800 return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2802 def _groupTypeFromShape( self, shape ):
2804 Pivate method to get a type of group on geometry
2806 tgeo = str(shape.GetShapeType())
2807 if tgeo == "VERTEX":
2809 elif tgeo == "EDGE" or tgeo == "WIRE":
2811 elif tgeo == "FACE" or tgeo == "SHELL":
2813 elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2815 elif tgeo == "COMPOUND":
2817 sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2819 # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2820 # simplification of access in geomBuilder: omniORB.registerObjref
2821 from SHAPERSTUDY_utils import getEngine
2824 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2826 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2827 return self._groupTypeFromShape( sub[0] )
2829 raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2832 def GroupOnFilter(self, typ, name, filter):
2834 Create a mesh group with given *name* based on the *filter*.
2835 It is a special type of group dynamically updating it's contents during
2839 typ: the type of elements in the group; either of
2840 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2841 name: the name of the mesh group
2842 filter (SMESH.Filter): the filter defining group contents
2845 :class:`SMESH.SMESH_GroupOnFilter`
2848 return self.mesh.CreateGroupFromFilter(typ, name, filter)
2850 def MakeGroupByIds(self, groupName, elementType, elemIDs):
2852 Create a mesh group by the given ids of elements
2855 groupName: the name of the mesh group
2856 elementType: the type of elements in the group; either of
2857 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2858 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2861 :class:`SMESH.SMESH_Group`
2864 group = self.mesh.CreateGroup(elementType, groupName)
2865 if isinstance( elemIDs, Mesh ):
2866 elemIDs = elemIDs.GetMesh()
2867 if hasattr( elemIDs, "GetIDs" ):
2868 if hasattr( elemIDs, "SetMesh" ):
2869 elemIDs.SetMesh( self.GetMesh() )
2870 group.AddFrom( elemIDs )
2878 CritType=FT_Undefined,
2881 UnaryOp=FT_Undefined,
2884 Create a mesh group by the given conditions
2887 groupName: the name of the mesh group
2888 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2889 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2890 Note that the items starting from FT_LessThan are not suitable for CritType.
2891 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2892 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2893 UnaryOp (SMESH.FunctorType): SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2894 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2895 SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2898 :class:`SMESH.SMESH_GroupOnFilter`
2901 aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2902 group = self.MakeGroupByCriterion(groupName, aCriterion)
2905 def MakeGroupByCriterion(self, groupName, Criterion):
2907 Create a mesh group by the given criterion
2910 groupName: the name of the mesh group
2911 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2914 :class:`SMESH.SMESH_GroupOnFilter`
2917 :meth:`smeshBuilder.GetCriterion`
2920 return self.MakeGroupByCriteria( groupName, [Criterion] )
2922 def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2924 Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2927 groupName: the name of the mesh group
2928 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2929 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2932 :class:`SMESH.SMESH_GroupOnFilter`
2935 :meth:`smeshBuilder.GetCriterion`
2938 aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2939 group = self.MakeGroupByFilter(groupName, aFilter)
2942 def MakeGroupByFilter(self, groupName, theFilter):
2944 Create a mesh group by the given filter
2947 groupName (string): the name of the mesh group
2948 theFilter (SMESH.Filter): the filter
2951 :class:`SMESH.SMESH_GroupOnFilter`
2954 :meth:`smeshBuilder.GetFilter`
2957 #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2958 #theFilter.SetMesh( self.mesh )
2959 #group.AddFrom( theFilter )
2960 group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2963 def RemoveGroup(self, group):
2968 group (SMESH.SMESH_GroupBase): group to remove
2971 self.mesh.RemoveGroup(group)
2973 def RemoveGroupWithContents(self, group):
2975 Remove a group with its contents
2978 group (SMESH.SMESH_GroupBase): group to remove
2981 This operation can create gaps in numeration of nodes or elements.
2982 Call :meth:`RenumberElements` to remove the gaps.
2985 self.mesh.RemoveGroupWithContents(group)
2987 def GetGroups(self, elemType = SMESH.ALL):
2989 Get the list of groups existing in the mesh in the order of creation
2990 (starting from the oldest one)
2993 elemType (SMESH.ElementType): type of elements the groups contain;
2994 by default groups of elements of all types are returned
2997 a list of :class:`SMESH.SMESH_GroupBase`
3000 groups = self.mesh.GetGroups()
3001 if elemType == SMESH.ALL:
3005 if g.GetType() == elemType:
3006 typedGroups.append( g )
3013 Get the number of groups existing in the mesh
3016 the quantity of groups as an integer value
3019 return self.mesh.NbGroups()
3021 def GetGroupNames(self):
3023 Get the list of names of groups existing in the mesh
3029 groups = self.GetGroups()
3031 for group in groups:
3032 names.append(group.GetName())
3035 def GetGroupByName(self, name, elemType = None):
3037 Find groups by name and type
3040 name (string): name of the group of interest
3041 elemType (SMESH.ElementType): type of elements the groups contain;
3042 by default one group of any type is returned;
3043 if elemType == SMESH.ALL then all groups of any type are returned
3046 a list of :class:`SMESH.SMESH_GroupBase`
3050 for group in self.GetGroups():
3051 if group.GetName() == name:
3052 if elemType is None:
3054 if ( elemType == SMESH.ALL or
3055 group.GetType() == elemType ):
3056 groups.append( group )
3059 def UnionGroups(self, group1, group2, name):
3061 Produce a union of two groups.
3062 A new group is created. All mesh elements that are
3063 present in the initial groups are added to the new one
3066 group1 (SMESH.SMESH_GroupBase): a group
3067 group2 (SMESH.SMESH_GroupBase): another group
3070 instance of :class:`SMESH.SMESH_Group`
3073 return self.mesh.UnionGroups(group1, group2, name)
3075 def UnionListOfGroups(self, groups, name):
3077 Produce a union list of groups.
3078 New group is created. All mesh elements that are present in
3079 initial groups are added to the new one
3082 groups: list of :class:`SMESH.SMESH_GroupBase`
3085 instance of :class:`SMESH.SMESH_Group`
3087 return self.mesh.UnionListOfGroups(groups, name)
3089 def IntersectGroups(self, group1, group2, name):
3091 Prodice an intersection of two groups.
3092 A new group is created. All mesh elements that are common
3093 for the two initial groups are added to the new one.
3096 group1 (SMESH.SMESH_GroupBase): a group
3097 group2 (SMESH.SMESH_GroupBase): another group
3100 instance of :class:`SMESH.SMESH_Group`
3103 return self.mesh.IntersectGroups(group1, group2, name)
3105 def IntersectListOfGroups(self, groups, name):
3107 Produce an intersection of groups.
3108 New group is created. All mesh elements that are present in all
3109 initial groups simultaneously are added to the new one
3112 groups: a list of :class:`SMESH.SMESH_GroupBase`
3115 instance of :class:`SMESH.SMESH_Group`
3117 return self.mesh.IntersectListOfGroups(groups, name)
3119 def CutGroups(self, main_group, tool_group, name):
3121 Produce a cut of two groups.
3122 A new group is created. All mesh elements that are present in
3123 the main group but are not present in the tool group are added to the new one
3126 main_group (SMESH.SMESH_GroupBase): a group to cut from
3127 tool_group (SMESH.SMESH_GroupBase): a group to cut by
3130 an instance of :class:`SMESH.SMESH_Group`
3133 return self.mesh.CutGroups(main_group, tool_group, name)
3135 def CutListOfGroups(self, main_groups, tool_groups, name):
3137 Produce a cut of groups.
3138 A new group is created. All mesh elements that are present in main groups
3139 but do not present in tool groups are added to the new one
3142 main_group: groups to cut from (list of :class:`SMESH.SMESH_GroupBase`)
3143 tool_group: groups to cut by (list of :class:`SMESH.SMESH_GroupBase`)
3146 an instance of :class:`SMESH.SMESH_Group`
3149 return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3151 def CreateDimGroup(self, groups, elemType, name,
3152 nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3154 Create a standalone group of entities basing on nodes of other groups.
3157 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3158 elemType: a type of elements to include to the new group; either of
3159 (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3160 name: a name of the new group.
3161 nbCommonNodes: a criterion of inclusion of an element to the new group
3162 basing on number of element nodes common with reference *groups*.
3163 Meaning of possible values are:
3165 - SMESH.ALL_NODES - include if all nodes are common,
3166 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3167 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3168 - SMEHS.MAJORITY - include if half of nodes or more are common.
3169 underlyingOnly: if *True* (default), an element is included to the
3170 new group provided that it is based on nodes of an element of *groups*;
3171 in this case the reference *groups* are supposed to be of higher dimension
3172 than *elemType*, which can be useful for example to get all faces lying on
3173 volumes of the reference *groups*.
3176 an instance of :class:`SMESH.SMESH_Group`
3179 if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3181 return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3183 def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3185 Distribute all faces of the mesh among groups using sharp edges and optionally
3186 existing 1D elements as group boundaries.
3189 sharpAngle: edge is considered sharp if an angle between normals of
3190 adjacent faces is more than \a sharpAngle in degrees.
3191 createEdges (boolean): to create 1D elements for detected sharp edges.
3192 useExistingEdges (boolean): to use existing edges as group boundaries
3194 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3196 sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3197 self.mesh.SetParameters(Parameters)
3198 return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3200 def ConvertToStandalone(self, group):
3202 Convert group on geom into standalone group
3205 return self.mesh.ConvertToStandalone(group)
3207 # Get some info about mesh:
3208 # ------------------------
3210 def GetLog(self, clearAfterGet):
3212 Return the log of nodes and elements added or removed
3213 since the previous clear of the log.
3216 clearAfterGet: log is emptied after Get (safe if concurrents access)
3219 list of SMESH.log_block structures { commandType, number, coords, indexes }
3222 return self.mesh.GetLog(clearAfterGet)
3226 Clear the log of nodes and elements added or removed since the previous
3227 clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3230 self.mesh.ClearLog()
3232 def SetAutoColor(self, theAutoColor):
3234 Toggle auto color mode on the object.
3235 If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3238 theAutoColor (boolean): the flag which toggles auto color mode.
3241 self.mesh.SetAutoColor(theAutoColor)
3243 def GetAutoColor(self):
3245 Get flag of object auto color mode.
3251 return self.mesh.GetAutoColor()
3258 integer value, which is the internal Id of the mesh
3261 return self.mesh.GetId()
3263 def HasDuplicatedGroupNamesMED(self):
3265 Check the group names for duplications.
3266 Consider the maximum group name length stored in MED file.
3272 return self.mesh.HasDuplicatedGroupNamesMED()
3274 def GetMeshEditor(self):
3276 Obtain the mesh editor tool
3279 an instance of :class:`SMESH.SMESH_MeshEditor`
3284 def GetIDSource(self, ids, elemType = SMESH.ALL):
3286 Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3287 can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3291 elemType: type of elements; this parameter is used to distinguish
3292 IDs of nodes from IDs of elements; by default ids are treated as
3293 IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3296 an instance of :class:`SMESH.SMESH_IDSource`
3299 call UnRegister() for the returned object as soon as it is no more useful::
3301 idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3302 mesh.DoSomething( idSrc )
3306 if isinstance( ids, int ):
3308 return self.editor.MakeIDSource(ids, elemType)
3311 # Get information about mesh contents:
3312 # ------------------------------------
3314 def GetMeshInfo(self, obj = None):
3316 Get the mesh statistic.
3319 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3322 if not obj: obj = self.mesh
3323 return self.smeshpyD.GetMeshInfo(obj)
3327 Return the number of nodes in the mesh
3333 return self.mesh.NbNodes()
3335 def NbElements(self):
3337 Return the number of elements in the mesh
3343 return self.mesh.NbElements()
3345 def Nb0DElements(self):
3347 Return the number of 0d elements in the mesh
3353 return self.mesh.Nb0DElements()
3357 Return the number of ball discrete elements in the mesh
3363 return self.mesh.NbBalls()
3367 Return the number of edges in the mesh
3373 return self.mesh.NbEdges()
3375 def NbEdgesOfOrder(self, elementOrder):
3377 Return the number of edges with the given order in the mesh
3380 elementOrder: the order of elements
3381 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3387 return self.mesh.NbEdgesOfOrder(elementOrder)
3391 Return the number of faces in the mesh
3397 return self.mesh.NbFaces()
3399 def NbFacesOfOrder(self, elementOrder):
3401 Return the number of faces with the given order in the mesh
3404 elementOrder: the order of elements
3405 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3411 return self.mesh.NbFacesOfOrder(elementOrder)
3413 def NbTriangles(self):
3415 Return the number of triangles in the mesh
3421 return self.mesh.NbTriangles()
3423 def NbTrianglesOfOrder(self, elementOrder):
3425 Return the number of triangles with the given order in the mesh
3428 elementOrder: is the order of elements
3429 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3435 return self.mesh.NbTrianglesOfOrder(elementOrder)
3437 def NbBiQuadTriangles(self):
3439 Return the number of biquadratic triangles in the mesh
3445 return self.mesh.NbBiQuadTriangles()
3447 def NbQuadrangles(self):
3449 Return the number of quadrangles in the mesh
3455 return self.mesh.NbQuadrangles()
3457 def NbQuadranglesOfOrder(self, elementOrder):
3459 Return the number of quadrangles with the given order in the mesh
3462 elementOrder: the order of elements
3463 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3469 return self.mesh.NbQuadranglesOfOrder(elementOrder)
3471 def NbBiQuadQuadrangles(self):
3473 Return the number of biquadratic quadrangles in the mesh
3479 return self.mesh.NbBiQuadQuadrangles()
3481 def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3483 Return the number of polygons of given order in the mesh
3486 elementOrder: the order of elements
3487 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3493 return self.mesh.NbPolygonsOfOrder(elementOrder)
3495 def NbVolumes(self):
3497 Return the number of volumes in the mesh
3503 return self.mesh.NbVolumes()
3506 def NbVolumesOfOrder(self, elementOrder):
3508 Return the number of volumes with the given order in the mesh
3511 elementOrder: the order of elements
3512 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3518 return self.mesh.NbVolumesOfOrder(elementOrder)
3522 Return the number of tetrahedrons in the mesh
3528 return self.mesh.NbTetras()
3530 def NbTetrasOfOrder(self, elementOrder):
3532 Return the number of tetrahedrons with the given order in the mesh
3535 elementOrder: the order of elements
3536 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3542 return self.mesh.NbTetrasOfOrder(elementOrder)
3546 Return the number of hexahedrons in the mesh
3552 return self.mesh.NbHexas()
3554 def NbHexasOfOrder(self, elementOrder):
3556 Return the number of hexahedrons with the given order in the mesh
3559 elementOrder: the order of elements
3560 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3566 return self.mesh.NbHexasOfOrder(elementOrder)
3568 def NbTriQuadraticHexas(self):
3570 Return the number of triquadratic hexahedrons in the mesh
3576 return self.mesh.NbTriQuadraticHexas()
3578 def NbPyramids(self):
3580 Return the number of pyramids in the mesh
3586 return self.mesh.NbPyramids()
3588 def NbPyramidsOfOrder(self, elementOrder):
3590 Return the number of pyramids with the given order in the mesh
3593 elementOrder: the order of elements
3594 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3600 return self.mesh.NbPyramidsOfOrder(elementOrder)
3604 Return the number of prisms in the mesh
3610 return self.mesh.NbPrisms()
3612 def NbPrismsOfOrder(self, elementOrder):
3614 Return the number of prisms with the given order in the mesh
3617 elementOrder: the order of elements
3618 (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3624 return self.mesh.NbPrismsOfOrder(elementOrder)
3626 def NbHexagonalPrisms(self):
3628 Return the number of hexagonal prisms in the mesh
3634 return self.mesh.NbHexagonalPrisms()
3636 def NbPolyhedrons(self):
3638 Return the number of polyhedrons in the mesh
3644 return self.mesh.NbPolyhedrons()
3646 def NbSubMesh(self):
3648 Return the number of submeshes in the mesh
3654 return self.mesh.NbSubMesh()
3656 def GetElementsId(self):
3658 Return the list of all mesh elements IDs
3661 the list of integer values
3664 :meth:`GetElementsByType`
3667 return self.mesh.GetElementsId()
3669 def GetElementsByType(self, elementType):
3671 Return the list of IDs of mesh elements with the given type
3674 elementType (SMESH.ElementType): the required type of elements
3677 list of integer values
3680 return self.mesh.GetElementsByType(elementType)
3682 def GetNodesId(self):
3684 Return the list of mesh nodes IDs
3687 the list of integer values
3690 return self.mesh.GetNodesId()
3692 # Get the information about mesh elements:
3693 # ------------------------------------
3695 def GetElementType(self, id, iselem=True):
3697 Return the type of mesh element or node
3700 the value from :class:`SMESH.ElementType` enumeration.
3701 Return SMESH.ALL if element or node with the given ID does not exist
3704 return self.mesh.GetElementType(id, iselem)
3706 def GetElementGeomType(self, id):
3708 Return the geometric type of mesh element
3711 the value from :class:`SMESH.EntityType` enumeration.
3714 return self.mesh.GetElementGeomType(id)
3716 def GetElementShape(self, id):
3718 Return the shape type of mesh element
3721 the value from :class:`SMESH.GeometryType` enumeration.
3724 return self.mesh.GetElementShape(id)
3726 def GetSubMeshElementsId(self, Shape):
3728 Return the list of sub-mesh elements IDs
3731 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3732 *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3735 list of integer values
3738 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3739 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3742 return self.mesh.GetSubMeshElementsId(ShapeID)
3744 def GetSubMeshNodesId(self, Shape, all):
3746 Return the list of sub-mesh nodes IDs
3749 Shape: a geom object (sub-shape).
3750 *Shape* must be the sub-shape of a :meth:`GetShape`
3751 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3754 list of integer values
3757 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3758 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3761 return self.mesh.GetSubMeshNodesId(ShapeID, all)
3763 def GetSubMeshElementType(self, Shape):
3765 Return type of elements on given shape
3768 Shape: a geom object (sub-shape).
3769 *Shape* must be a sub-shape of a ShapeToMesh()
3772 :class:`SMESH.ElementType`
3775 if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3776 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3779 return self.mesh.GetSubMeshElementType(ShapeID)
3783 Get the mesh description
3789 return self.mesh.Dump()
3792 # Get the information about nodes and elements of a mesh by its IDs:
3793 # -----------------------------------------------------------
3795 def GetNodeXYZ(self, id):
3797 Get XYZ coordinates of a node.
3798 If there is no node for the given ID - return an empty list
3801 list of float values
3804 return self.mesh.GetNodeXYZ(id)
3806 def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3808 Return list of IDs of inverse elements for the given node.
3809 If there is no node for the given ID - return an empty list
3813 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3816 list of integer values
3819 return self.mesh.GetNodeInverseElements(id,elemType)
3821 def GetNodePosition(self,NodeID):
3823 Return the position of a node on the shape
3826 :class:`SMESH.NodePosition`
3829 return self.mesh.GetNodePosition(NodeID)
3831 def GetElementPosition(self,ElemID):
3833 Return the position of an element on the shape
3836 :class:`SMESH.ElementPosition`
3839 return self.mesh.GetElementPosition(ElemID)
3841 def GetShapeID(self, id):
3843 Return the ID of the shape, on which the given node was generated.
3846 an integer value > 0 or -1 if there is no node for the given
3847 ID or the node is not assigned to any geometry
3850 return self.mesh.GetShapeID(id)
3852 def GetShapeIDForElem(self,id):
3854 Return the ID of the shape, on which the given element was generated.
3857 an integer value > 0 or -1 if there is no element for the given
3858 ID or the element is not assigned to any geometry
3861 return self.mesh.GetShapeIDForElem(id)
3863 def GetElemNbNodes(self, id):
3865 Return the number of nodes of the given element
3868 an integer value > 0 or -1 if there is no element for the given ID
3871 return self.mesh.GetElemNbNodes(id)
3873 def GetElemNode(self, id, index):
3875 Return the node ID the given (zero based) index for the given element.
3877 * If there is no element for the given ID - return -1.
3878 * If there is no node for the given index - return -2.
3881 id (int): element ID
3882 index (int): node index within the element
3885 an integer value (ID)
3888 :meth:`GetElemNodes`
3891 return self.mesh.GetElemNode(id, index)
3893 def GetElemNodes(self, id):
3895 Return the IDs of nodes of the given element
3898 a list of integer values
3901 return self.mesh.GetElemNodes(id)
3903 def IsMediumNode(self, elementID, nodeID):
3905 Return true if the given node is the medium node in the given quadratic element
3908 return self.mesh.IsMediumNode(elementID, nodeID)
3910 def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3912 Return true if the given node is the medium node in one of quadratic elements
3915 nodeID: ID of the node
3916 elementType: the type of elements to check a state of the node, either of
3917 (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3920 return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3922 def ElemNbEdges(self, id):
3924 Return the number of edges for the given element
3927 return self.mesh.ElemNbEdges(id)
3929 def ElemNbFaces(self, id):
3931 Return the number of faces for the given element
3934 return self.mesh.ElemNbFaces(id)
3936 def GetElemFaceNodes(self,elemId, faceIndex):
3938 Return nodes of given face (counted from zero) for given volumic element.
3941 return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3943 def GetFaceNormal(self, faceId, normalized=False):
3945 Return three components of normal of given mesh face
3946 (or an empty array in KO case)
3949 return self.mesh.GetFaceNormal(faceId,normalized)
3951 def FindElementByNodes(self, nodes):
3953 Return an element based on all given nodes.
3956 return self.mesh.FindElementByNodes(nodes)
3958 def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3960 Return elements including all given nodes.
3963 return self.mesh.GetElementsByNodes( nodes, elemType )
3965 def IsPoly(self, id):
3967 Return true if the given element is a polygon
3970 return self.mesh.IsPoly(id)
3972 def IsQuadratic(self, id):
3974 Return true if the given element is quadratic
3977 return self.mesh.IsQuadratic(id)
3979 def GetBallDiameter(self, id):
3981 Return diameter of a ball discrete element or zero in case of an invalid *id*
3984 return self.mesh.GetBallDiameter(id)
3986 def BaryCenter(self, id):
3988 Return XYZ coordinates of the barycenter of the given element.
3989 If there is no element for the given ID - return an empty list
3992 a list of three double values
3995 :meth:`smeshBuilder.GetGravityCenter`
3998 return self.mesh.BaryCenter(id)
4000 def GetIdsFromFilter(self, filter, meshParts=[] ):
4002 Pass mesh elements through the given filter and return IDs of fitting elements
4005 filter: :class:`SMESH.Filter`
4006 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
4012 :meth:`SMESH.Filter.GetIDs`
4013 :meth:`SMESH.Filter.GetElementsIdFromParts`
4016 filter.SetMesh( self.mesh )
4019 if isinstance( meshParts, Mesh ):
4020 filter.SetMesh( meshParts.GetMesh() )
4021 return theFilter.GetIDs()
4022 if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
4023 meshParts = [ meshParts ]
4024 return filter.GetElementsIdFromParts( meshParts )
4026 return filter.GetIDs()
4028 # Get mesh measurements information:
4029 # ------------------------------------
4031 def GetFreeBorders(self):
4033 Verify whether a 2D mesh element has free edges (edges connected to one face only).
4034 Return a list of special structures (borders).
4037 a list of :class:`SMESH.FreeEdges.Border`
4040 aFilterMgr = self.smeshpyD.CreateFilterManager()
4041 aPredicate = aFilterMgr.CreateFreeEdges()
4042 aPredicate.SetMesh(self.mesh)
4043 aBorders = aPredicate.GetBorders()
4044 aFilterMgr.UnRegister()
4047 def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4049 Get minimum distance between two nodes, elements or distance to the origin
4052 id1: first node/element id
4053 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4054 isElem1: *True* if *id1* is element id, *False* if it is node id
4055 isElem2: *True* if *id2* is element id, *False* if it is node id
4058 minimum distance value
4060 :meth:`GetMinDistance`
4063 aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4064 return aMeasure.value
4066 def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4068 Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4071 id1: first node/element id
4072 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4073 isElem1: *True* if *id1* is element id, *False* if it is node id
4074 isElem2: *True* if *id2* is element id, *False* if it is node id
4077 :class:`SMESH.Measure` structure
4083 id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4085 id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4088 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4090 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4095 aMeasurements = self.smeshpyD.CreateMeasurements()
4096 aMeasure = aMeasurements.MinDistance(id1, id2)
4097 genObjUnRegister([aMeasurements,id1, id2])
4100 def BoundingBox(self, objects=None, isElem=False):
4102 Get bounding box of the specified object(s)
4105 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4106 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4107 *False* specifies that *objects* are nodes
4110 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4113 :meth:`GetBoundingBox()`
4116 result = self.GetBoundingBox(objects, isElem)
4120 result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4123 def GetBoundingBox(self, objects=None, isElem=False):
4125 Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4128 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4129 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4130 False means that *objects* are nodes
4133 :class:`SMESH.Measure` structure
4136 :meth:`BoundingBox()`
4140 objects = [self.mesh]
4141 elif isinstance(objects, tuple):
4142 objects = list(objects)
4143 if not isinstance(objects, list):
4145 if len(objects) > 0 and isinstance(objects[0], int):
4148 unRegister = genObjUnRegister()
4150 if isinstance(o, Mesh):
4151 srclist.append(o.mesh)
4152 elif hasattr(o, "_narrow"):
4153 src = o._narrow(SMESH.SMESH_IDSource)
4154 if src: srclist.append(src)
4156 elif isinstance(o, list):
4158 srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4160 srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4161 unRegister.set( srclist[-1] )
4164 aMeasurements = self.smeshpyD.CreateMeasurements()
4165 unRegister.set( aMeasurements )
4166 aMeasure = aMeasurements.BoundingBox(srclist)
4169 # Mesh edition (SMESH_MeshEditor functionality):
4170 # ---------------------------------------------
4172 def RemoveElements(self, IDsOfElements):
4174 Remove the elements from the mesh by ids
4177 IDsOfElements: is a list of ids of elements to remove
4183 This operation can create gaps in numeration of elements.
4184 Call :meth:`RenumberElements` to remove the gaps.
4187 return self.editor.RemoveElements(IDsOfElements)
4189 def RemoveNodes(self, IDsOfNodes):
4191 Remove nodes from mesh by ids
4194 IDsOfNodes: is a list of ids of nodes to remove
4200 This operation can create gaps in numeration of nodes.
4201 Call :meth:`RenumberElements` to remove the gaps.
4204 return self.editor.RemoveNodes(IDsOfNodes)
4206 def RemoveNodeWithReconnection(self, nodeID ):
4208 Remove a node along with changing surrounding faces to cover a hole.
4211 nodeID: ID of node to remove
4214 return self.editor.RemoveNodeWithReconnection( nodeID )
4216 def RemoveOrphanNodes(self):
4218 Remove all orphan (free) nodes from mesh
4221 number of the removed nodes
4224 This operation can create gaps in numeration of nodes.
4225 Call :meth:`RenumberElements` to remove the gaps.
4228 return self.editor.RemoveOrphanNodes()
4230 def AddNode(self, x, y, z):
4232 Add a node to the mesh by coordinates
4238 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4239 if hasVars: self.mesh.SetParameters(Parameters)
4240 return self.editor.AddNode( x, y, z)
4242 def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4244 Create a 0D element on a node with given number.
4247 IDOfNode: the ID of node for creation of the element.
4248 DuplicateElements: to add one more 0D element to a node or not
4251 ID of the new 0D element
4254 return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4256 def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4258 Create 0D elements on all nodes of the given elements except those
4259 nodes on which a 0D element already exists.
4262 theObject: an object on whose nodes 0D elements will be created.
4263 It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4264 theGroupName: optional name of a group to add 0D elements created
4265 and/or found on nodes of *theObject*.
4266 DuplicateElements: to add one more 0D element to a node or not
4269 an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4270 IDs of new and/or found 0D elements. IDs of 0D elements
4271 can be retrieved from the returned object by
4272 calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4275 unRegister = genObjUnRegister()
4276 if isinstance( theObject, Mesh ):
4277 theObject = theObject.GetMesh()
4278 elif isinstance( theObject, list ):
4279 theObject = self.GetIDSource( theObject, SMESH.ALL )
4280 unRegister.set( theObject )
4281 return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4283 def AddBall(self, IDOfNode, diameter):
4285 Create a ball element on a node with given ID.
4288 IDOfNode: the ID of node for creation of the element.
4289 diameter: the bal diameter.
4292 ID of the new ball element
4295 return self.editor.AddBall( IDOfNode, diameter )
4297 def AddEdge(self, IDsOfNodes):
4299 Create a linear or quadratic edge (this is determined
4300 by the number of given nodes).
4303 IDsOfNodes: list of node IDs for creation of the element.
4304 The order of nodes in this list should correspond to
4305 the :ref:`connectivity convention <connectivity_page>`.
4311 return self.editor.AddEdge(IDsOfNodes)
4313 def AddFace(self, IDsOfNodes):
4315 Create a linear or quadratic face (this is determined
4316 by the number of given nodes).
4319 IDsOfNodes: list of node IDs for creation of the element.
4320 The order of nodes in this list should correspond to
4321 the :ref:`connectivity convention <connectivity_page>`.
4327 return self.editor.AddFace(IDsOfNodes)
4329 def AddPolygonalFace(self, IdsOfNodes):
4331 Add a polygonal face defined by a list of node IDs
4334 IdsOfNodes: the list of node IDs for creation of the element.
4340 return self.editor.AddPolygonalFace(IdsOfNodes)
4342 def AddQuadPolygonalFace(self, IdsOfNodes):
4344 Add a quadratic polygonal face defined by a list of node IDs
4347 IdsOfNodes: the list of node IDs for creation of the element;
4348 corner nodes follow first.
4354 return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4356 def AddVolume(self, IDsOfNodes):
4358 Create both simple and quadratic volume (this is determined
4359 by the number of given nodes).
4362 IDsOfNodes: list of node IDs for creation of the element.
4363 The order of nodes in this list should correspond to
4364 the :ref:`connectivity convention <connectivity_page>`.
4367 ID of the new volumic element
4370 return self.editor.AddVolume(IDsOfNodes)
4372 def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4374 Create a volume of many faces, giving nodes for each face.
4377 IdsOfNodes: list of node IDs for volume creation, face by face.
4378 Quantities: list of integer values, Quantities[i]
4379 gives the quantity of nodes in face number i.
4382 ID of the new volumic element
4385 return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4387 def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4389 Create a volume of many faces, giving the IDs of the existing faces.
4392 The created volume will refer only to the nodes
4393 of the given faces, not to the faces themselves.
4396 IdsOfFaces: the list of face IDs for volume creation.
4399 ID of the new volumic element
4402 return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4405 def SetNodeOnVertex(self, NodeID, Vertex):
4407 Bind a node to a vertex
4411 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4414 True if succeed else raises an exception
4417 if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4418 VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4422 self.editor.SetNodeOnVertex(NodeID, VertexID)
4423 except SALOME.SALOME_Exception as inst:
4424 raise ValueError(inst.details.text)
4428 def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4430 Store the node position on an edge
4434 Edge: an edge (GEOM.GEOM_Object) or edge ID
4435 paramOnEdge: a parameter on the edge where the node is located
4438 True if succeed else raises an exception
4441 if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4442 EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4446 self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4447 except SALOME.SALOME_Exception as inst:
4448 raise ValueError(inst.details.text)
4451 def SetNodeOnFace(self, NodeID, Face, u, v):
4453 Store node position on a face
4457 Face: a face (GEOM.GEOM_Object) or face ID
4458 u: U parameter on the face where the node is located
4459 v: V parameter on the face where the node is located
4462 True if succeed else raises an exception
4465 if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4466 FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4470 self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4471 except SALOME.SALOME_Exception as inst:
4472 raise ValueError(inst.details.text)
4475 def SetNodeInVolume(self, NodeID, Solid):
4477 Bind a node to a solid
4481 Solid: a solid (GEOM.GEOM_Object) or solid ID
4484 True if succeed else raises an exception
4487 if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4488 SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4492 self.editor.SetNodeInVolume(NodeID, SolidID)
4493 except SALOME.SALOME_Exception as inst:
4494 raise ValueError(inst.details.text)
4497 def SetMeshElementOnShape(self, ElementID, Shape):
4499 Bind an element to a shape
4502 ElementID: an element ID
4503 Shape: a shape (GEOM.GEOM_Object) or shape ID
4506 True if succeed else raises an exception
4509 if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4510 ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4514 self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4515 except SALOME.SALOME_Exception as inst:
4516 raise ValueError(inst.details.text)
4520 def MoveNode(self, NodeID, x, y, z):
4522 Move the node with the given id
4525 NodeID: the id of the node
4526 x: a new X coordinate
4527 y: a new Y coordinate
4528 z: a new Z coordinate
4531 True if succeed else False
4534 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4535 if hasVars: self.mesh.SetParameters(Parameters)
4536 return self.editor.MoveNode(NodeID, x, y, z)
4538 def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4540 Find the node closest to a point and moves it to a point location
4543 x: the X coordinate of a point
4544 y: the Y coordinate of a point
4545 z: the Z coordinate of a point
4546 NodeID: if specified (>0), the node with this ID is moved,
4547 otherwise, the node closest to point (*x*, *y*, *z*) is moved
4550 the ID of a moved node
4553 x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4554 if hasVars: self.mesh.SetParameters(Parameters)
4555 return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4557 def FindNodeClosestTo(self, x, y, z):
4559 Find the node closest to a point
4562 x: the X coordinate of a point
4563 y: the Y coordinate of a point
4564 z: the Z coordinate of a point
4570 return self.editor.FindNodeClosestTo(x, y, z)
4572 def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4574 Find the elements where a point lays IN or ON
4577 x,y,z (float): coordinates of the point
4578 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4579 means elements of any type excluding nodes, discrete and 0D elements.
4580 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4583 list of IDs of found elements
4586 return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4588 return self.editor.FindElementsByPoint(x, y, z, elementType)
4590 def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4592 Project a point to a mesh object.
4593 Return ID of an element of given type where the given point is projected
4594 and coordinates of the projection point.
4595 In the case if nothing found, return -1 and []
4597 if isinstance( meshObject, Mesh ):
4598 meshObject = meshObject.GetMesh()
4600 meshObject = self.GetMesh()
4601 return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4603 def GetPointState(self, x, y, z):
4605 Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4606 smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4607 UNKNOWN state means that either mesh is wrong or the analysis fails.
4610 return self.editor.GetPointState(x, y, z)
4612 def IsManifold(self):
4614 Check if a 2D mesh is manifold
4617 return self.editor.IsManifold()
4619 def IsCoherentOrientation2D(self):
4621 Check if orientation of 2D elements is coherent
4624 return self.editor.IsCoherentOrientation2D()
4626 def Get1DBranches( self, edges, startNode = 0 ):
4628 Partition given 1D elements into groups of contiguous edges.
4629 A node where number of meeting edges != 2 is a group end.
4630 An optional startNode is used to orient groups it belongs to.
4633 A list of edge groups and a list of corresponding node groups,
4634 where the group is a list of IDs of edges or nodes, like follows
4635 [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4636 If a group is closed, the first and last nodes of the group are same.
4638 if isinstance( edges, Mesh ):
4639 edges = edges.GetMesh()
4640 unRegister = genObjUnRegister()
4641 if isinstance( edges, list ):
4642 edges = self.GetIDSource( edges, SMESH.EDGE )
4643 unRegister.set( edges )
4644 return self.editor.Get1DBranches( edges, startNode )
4646 def FindSharpEdges( self, angle, addExisting=False ):
4648 Return sharp edges of faces and non-manifold ones.
4649 Optionally add existing edges.
4652 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4653 addExisting: to return existing edges (1D elements) as well
4656 list of FaceEdge structures
4658 angle = ParseParameters( angle )[0]
4659 return self.editor.FindSharpEdges( angle, addExisting )
4661 def MeshToPassThroughAPoint(self, x, y, z):
4663 Find the node closest to a point and moves it to a point location
4666 x: the X coordinate of a point
4667 y: the Y coordinate of a point
4668 z: the Z coordinate of a point
4671 the ID of a moved node
4674 return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4676 def InverseDiag(self, NodeID1, NodeID2):
4678 Replace two neighbour triangles sharing Node1-Node2 link
4679 with the triangles built on the same 4 nodes but having other common link.
4682 NodeID1: the ID of the first node
4683 NodeID2: the ID of the second node
4686 False if proper faces were not found
4688 return self.editor.InverseDiag(NodeID1, NodeID2)
4690 def DeleteDiag(self, NodeID1, NodeID2):
4692 Replace two neighbour triangles sharing *Node1-Node2* link
4693 with a quadrangle built on the same 4 nodes.
4696 NodeID1: ID of the first node
4697 NodeID2: ID of the second node
4700 False if proper faces were not found
4703 This operation can create gaps in numeration of elements.
4704 Call :meth:`RenumberElements` to remove the gaps.
4707 return self.editor.DeleteDiag(NodeID1, NodeID2)
4709 def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4711 Replace each triangle bound by Node1-Node2 segment with
4712 two triangles by connecting a node made on the link with a node
4713 opposite to the link.
4716 Node1: ID of the first node
4717 Node2: ID of the second node
4718 position: location [0,1] of the new node on the segment
4720 return self.editor.AddNodeOnSegment(Node1, Node2, position)
4722 def AddNodeOnFace(self, face, x, y, z):
4724 Split a face into triangles by adding a new node onto the face
4725 and connecting the new node with face nodes
4728 face: ID of the face
4729 x,y,z: coordinates of the new node
4731 return self.editor.AddNodeOnFace(face, x, y, z)
4733 def Reorient(self, IDsOfElements=None):
4735 Reorient elements by ids
4738 IDsOfElements: if undefined reorients all mesh elements
4741 True if succeed else False
4744 if IDsOfElements == None:
4745 IDsOfElements = self.GetElementsId()
4746 return self.editor.Reorient(IDsOfElements)
4748 def ReorientObject(self, theObject):
4750 Reorient all elements of the object
4753 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4756 True if succeed else False
4759 if ( isinstance( theObject, Mesh )):
4760 theObject = theObject.GetMesh()
4761 return self.editor.ReorientObject(theObject)
4763 def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4765 Reorient faces contained in *the2DObject*.
4768 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4769 theDirection: a desired direction of normal of *theFace*.
4770 It can be either a GEOM vector or a list of coordinates [x,y,z].
4771 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4772 compared with theDirection. It can be either ID of face or a point
4773 by which the face will be found. The point can be given as either
4774 a GEOM vertex or a list of point coordinates.
4777 number of reoriented faces
4780 unRegister = genObjUnRegister()
4782 if isinstance( the2DObject, Mesh ):
4783 the2DObject = the2DObject.GetMesh()
4784 if isinstance( the2DObject, list ):
4785 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4786 unRegister.set( the2DObject )
4787 # check theDirection
4788 if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4789 theDirection = self.smeshpyD.GetDirStruct( theDirection )
4790 if isinstance( theDirection, list ):
4791 theDirection = self.smeshpyD.MakeDirStruct( *theDirection )
4792 # prepare theFace and thePoint
4793 theFace = theFaceOrPoint
4794 thePoint = PointStruct(0,0,0)
4795 if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4796 thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4798 if isinstance( theFaceOrPoint, list ):
4799 thePoint = PointStruct( *theFaceOrPoint )
4801 if isinstance( theFaceOrPoint, PointStruct ):
4802 thePoint = theFaceOrPoint
4804 return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4806 def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4808 Reorient faces contained in a list of *objectFaces*
4809 equally to faces contained in a list of *referenceFaces*.
4812 objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4813 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.
4816 number of reoriented faces.
4818 if not isinstance( objectFaces, list ):
4819 objectFaces = [ objectFaces ]
4820 for i,obj2D in enumerate( objectFaces ):
4821 if isinstance( obj2D, Mesh ):
4822 objectFaces[i] = obj2D.GetMesh()
4823 if not isinstance( referenceFaces, list ):
4824 referenceFaces = [ referenceFaces ]
4826 return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4829 def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4831 Reorient faces according to adjacent volumes.
4834 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4835 either IDs of faces or face groups.
4836 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4837 theOutsideNormal: to orient faces to have their normals
4838 pointing either *outside* or *inside* the adjacent volumes.
4841 number of reoriented faces.
4844 unRegister = genObjUnRegister()
4846 if not isinstance( the2DObject, list ):
4847 the2DObject = [ the2DObject ]
4848 elif the2DObject and isinstance( the2DObject[0], int ):
4849 the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4850 unRegister.set( the2DObject )
4851 the2DObject = [ the2DObject ]
4852 for i,obj2D in enumerate( the2DObject ):
4853 if isinstance( obj2D, Mesh ):
4854 the2DObject[i] = obj2D.GetMesh()
4855 if isinstance( obj2D, list ):
4856 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4857 unRegister.set( the2DObject[i] )
4859 if isinstance( the3DObject, Mesh ):
4860 the3DObject = the3DObject.GetMesh()
4861 if isinstance( the3DObject, list ):
4862 the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4863 unRegister.set( the3DObject )
4864 return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4866 def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4868 Fuse the neighbouring triangles into quadrangles.
4871 IDsOfElements: The triangles to be fused.
4872 theCriterion: a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4873 applied to possible quadrangles to choose a neighbour to fuse with.
4874 Note that not all items of :class:`SMESH.FunctorType` corresponds
4875 to numerical functors.
4876 MaxAngle: is the maximum angle between element normals at which the fusion
4877 is still performed; theMaxAngle is measured in radians.
4878 Also it could be a name of variable which defines angle in degrees.
4881 True in case of success, False otherwise.
4884 This operation can create gaps in numeration of elements.
4885 Call :meth:`RenumberElements` to remove the gaps.
4888 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4889 self.mesh.SetParameters(Parameters)
4890 if not IDsOfElements:
4891 IDsOfElements = self.GetElementsId()
4892 Functor = self.smeshpyD.GetFunctor(theCriterion)
4893 return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4895 def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4897 Fuse the neighbouring triangles of the object into quadrangles
4900 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4901 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4902 applied to possible quadrangles to choose a neighbour to fuse with.
4903 Note that not all items of :class:`SMESH.FunctorType` corresponds
4904 to numerical functors.
4905 MaxAngle: a max angle between element normals at which the fusion
4906 is still performed; theMaxAngle is measured in radians.
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.
4916 MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4917 self.mesh.SetParameters(Parameters)
4918 if isinstance( theObject, Mesh ):
4919 theObject = theObject.GetMesh()
4920 Functor = self.smeshpyD.GetFunctor(theCriterion)
4921 return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4923 def QuadToTri (self, IDsOfElements, theCriterion = None):
4925 Split quadrangles into triangles.
4928 IDsOfElements: the faces to be splitted.
4929 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4930 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4931 value, then quadrangles will be split by the smallest diagonal.
4932 Note that not all items of :class:`SMESH.FunctorType` corresponds
4933 to numerical functors.
4936 True in case of success, False otherwise.
4939 This operation can create gaps in numeration of elements.
4940 Call :meth:`RenumberElements` to remove the gaps.
4942 if IDsOfElements == []:
4943 IDsOfElements = self.GetElementsId()
4944 if theCriterion is None:
4945 theCriterion = FT_MaxElementLength2D
4946 Functor = self.smeshpyD.GetFunctor(theCriterion)
4947 return self.editor.QuadToTri(IDsOfElements, Functor)
4949 def QuadToTriObject (self, theObject, theCriterion = None):
4951 Split quadrangles into triangles.
4954 theObject: the object from which the list of elements is taken,
4955 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4956 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4957 choose a diagonal for splitting. If *theCriterion* is None, which is a default
4958 value, then quadrangles will be split by the smallest diagonal.
4959 Note that not all items of :class:`SMESH.FunctorType` corresponds
4960 to numerical functors.
4963 True in case of success, False otherwise.
4966 This operation can create gaps in numeration of elements.
4967 Call :meth:`RenumberElements` to remove the gaps.
4969 if ( isinstance( theObject, Mesh )):
4970 theObject = theObject.GetMesh()
4971 if theCriterion is None:
4972 theCriterion = FT_MaxElementLength2D
4973 Functor = self.smeshpyD.GetFunctor(theCriterion)
4974 return self.editor.QuadToTriObject(theObject, Functor)
4976 def QuadTo4Tri (self, theElements=[]):
4978 Split each of given quadrangles into 4 triangles. A node is added at the center of
4982 theElements: the faces to be splitted. This can be either
4983 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4984 or a list of face IDs. By default all quadrangles are split
4987 This operation can create gaps in numeration of elements.
4988 Call :meth:`RenumberElements` to remove the gaps.
4990 unRegister = genObjUnRegister()
4991 if isinstance( theElements, Mesh ):
4992 theElements = theElements.mesh
4993 elif not theElements:
4994 theElements = self.mesh
4995 elif isinstance( theElements, list ):
4996 theElements = self.GetIDSource( theElements, SMESH.FACE )
4997 unRegister.set( theElements )
4998 return self.editor.QuadTo4Tri( theElements )
5000 def SplitQuad (self, IDsOfElements, Diag13):
5002 Split quadrangles into triangles.
5005 IDsOfElements: the faces to be splitted
5006 Diag13 (boolean): is used to choose a diagonal for splitting.
5009 True in case of success, False otherwise.
5012 This operation can create gaps in numeration of elements.
5013 Call :meth:`RenumberElements` to remove the gaps.
5015 if IDsOfElements == []:
5016 IDsOfElements = self.GetElementsId()
5017 return self.editor.SplitQuad(IDsOfElements, Diag13)
5019 def SplitQuadObject (self, theObject, Diag13):
5021 Split quadrangles into triangles.
5024 theObject: the object from which the list of elements is taken,
5025 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5026 Diag13 (boolean): is used to choose a diagonal for splitting.
5029 True in case of success, False otherwise.
5032 This operation can create gaps in numeration of elements.
5033 Call :meth:`RenumberElements` to remove the gaps.
5035 if ( isinstance( theObject, Mesh )):
5036 theObject = theObject.GetMesh()
5037 return self.editor.SplitQuadObject(theObject, Diag13)
5039 def BestSplit (self, IDOfQuad, theCriterion):
5041 Find a better splitting of the given quadrangle.
5044 IDOfQuad: the ID of the quadrangle to be splitted.
5045 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
5046 choose a diagonal for splitting.
5047 Note that not all items of :class:`SMESH.FunctorType` corresponds
5048 to numerical functors.
5051 * 1 if 1-3 diagonal is better,
5052 * 2 if 2-4 diagonal is better,
5053 * 0 if error occurs.
5056 This operation can create gaps in numeration of elements.
5057 Call :meth:`RenumberElements` to remove the gaps.
5059 return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5061 def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5063 Split volumic elements into tetrahedrons
5066 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5067 method: flags passing splitting method:
5068 smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5069 smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5072 This operation can create gaps in numeration of elements.
5073 Call :meth:`RenumberElements` to remove the gaps.
5075 unRegister = genObjUnRegister()
5076 if isinstance( elems, Mesh ):
5077 elems = elems.GetMesh()
5078 if ( isinstance( elems, list )):
5079 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5080 unRegister.set( elems )
5081 self.editor.SplitVolumesIntoTetra(elems, method)
5084 def SplitBiQuadraticIntoLinear(self, elems=None):
5086 Split bi-quadratic elements into linear ones without creation of additional nodes:
5088 - bi-quadratic triangle will be split into 3 linear quadrangles;
5089 - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5090 - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5092 Quadratic elements of lower dimension adjacent to the split bi-quadratic element
5093 will be split in order to keep the mesh conformal.
5096 elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5097 if None (default), all bi-quadratic elements will be split
5100 This operation can create gaps in numeration of elements.
5101 Call :meth:`RenumberElements` to remove the gaps.
5103 unRegister = genObjUnRegister()
5104 if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5105 elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5106 unRegister.set( elems )
5108 elems = [ self.GetMesh() ]
5109 if isinstance( elems, Mesh ):
5110 elems = [ elems.GetMesh() ]
5111 if not isinstance( elems, list ):
5113 self.editor.SplitBiQuadraticIntoLinear( elems )
5115 def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5116 method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5118 Split hexahedra into prisms
5121 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5122 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5123 gives a normal vector defining facets to split into triangles.
5124 *startHexPoint* can be either a triple of coordinates or a vertex.
5125 facetNormal: a normal to a facet to split into triangles of a
5126 hexahedron found by *startHexPoint*.
5127 *facetNormal* can be either a triple of coordinates or an edge.
5128 method: flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5129 smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5130 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5131 to *startHexPoint* are split, else *startHexPoint*
5132 is used to find the facet to split in all domains present in *elems*.
5135 This operation can create gaps in numeration of elements.
5136 Call :meth:`RenumberElements` to remove the gaps.
5139 unRegister = genObjUnRegister()
5140 if isinstance( elems, Mesh ):
5141 elems = elems.GetMesh()
5142 if ( isinstance( elems, list )):
5143 elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5144 unRegister.set( elems )
5147 if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5148 startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5149 elif isinstance( startHexPoint, list ):
5150 startHexPoint = SMESH.PointStruct( startHexPoint[0],
5153 if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5154 facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5155 elif isinstance( facetNormal, list ):
5156 facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5159 self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5161 self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5163 def SplitQuadsNearTriangularFacets(self):
5165 Split quadrangle faces near triangular facets of volumes
5168 This operation can create gaps in numeration of elements.
5169 Call :meth:`RenumberElements` to remove the gaps.
5171 faces_array = self.GetElementsByType(SMESH.FACE)
5172 for face_id in faces_array:
5173 if self.GetElemNbNodes(face_id) == 4: # quadrangle
5174 quad_nodes = self.mesh.GetElemNodes(face_id)
5175 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5176 isVolumeFound = False
5177 for node1_elem in node1_elems:
5178 if not isVolumeFound:
5179 if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5180 nb_nodes = self.GetElemNbNodes(node1_elem)
5181 if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5182 volume_elem = node1_elem
5183 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5184 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5185 if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5186 isVolumeFound = True
5187 if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5188 self.SplitQuad([face_id], False) # diagonal 2-4
5189 elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5190 isVolumeFound = True
5191 self.SplitQuad([face_id], True) # diagonal 1-3
5192 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5193 if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5194 isVolumeFound = True
5195 self.SplitQuad([face_id], True) # diagonal 1-3
5197 def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5199 Split hexahedrons into tetrahedrons.
5201 This operation uses :doc:`pattern_mapping` functionality for splitting.
5204 theObject: the object from which the list of hexahedrons is taken;
5205 this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5206 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5207 pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5208 will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5209 key-point will be mapped into *theNode001*-th node of each volume.
5210 The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5213 True in case of success, False otherwise.
5216 This operation can create gaps in numeration of elements.
5217 Call :meth:`RenumberElements` to remove the gaps.
5225 # (0,0,1) 4.---------.7 * |
5232 # (0,0,0) 0.---------.3
5233 pattern_tetra = "!!! Nb of points: \n 8 \n\
5243 !!! Indices of points of 6 tetras: \n\
5251 pattern = self.smeshpyD.GetPattern()
5252 isDone = pattern.LoadFromFile(pattern_tetra)
5254 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5257 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5258 isDone = pattern.MakeMesh(self.mesh, False, False)
5259 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5261 # split quafrangle faces near triangular facets of volumes
5262 self.SplitQuadsNearTriangularFacets()
5266 def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5268 Split hexahedrons into prisms.
5270 Uses the :doc:`pattern_mapping` functionality for splitting.
5273 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5274 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5275 pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5276 will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5277 will be mapped into the *theNode001* -th node of each volume.
5278 Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5281 True in case of success, False otherwise.
5284 This operation can create gaps in numeration of elements.
5285 Call :meth:`RenumberElements` to remove the gaps.
5287 # Pattern: 5.---------.6
5292 # (0,0,1) 4.---------.7 |
5299 # (0,0,0) 0.---------.3
5300 pattern_prism = "!!! Nb of points: \n 8 \n\
5310 !!! Indices of points of 2 prisms: \n\
5314 pattern = self.smeshpyD.GetPattern()
5315 isDone = pattern.LoadFromFile(pattern_prism)
5317 print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5320 pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5321 isDone = pattern.MakeMesh(self.mesh, False, False)
5322 if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5324 # Split quafrangle faces near triangular facets of volumes
5325 self.SplitQuadsNearTriangularFacets()
5329 def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5330 MaxNbOfIterations, MaxAspectRatio, Method):
5335 IDsOfElements: the list if ids of elements to smooth
5336 IDsOfFixedNodes: the list of ids of fixed nodes.
5337 Note that nodes built on edges and boundary nodes are always fixed.
5338 MaxNbOfIterations: the maximum number of iterations
5339 MaxAspectRatio: varies in range [1.0, inf]
5340 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5341 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5344 True in case of success, False otherwise.
5347 if IDsOfElements == []:
5348 IDsOfElements = self.GetElementsId()
5349 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5350 self.mesh.SetParameters(Parameters)
5351 return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5352 MaxNbOfIterations, MaxAspectRatio, Method)
5354 def SmoothObject(self, theObject, IDsOfFixedNodes,
5355 MaxNbOfIterations, MaxAspectRatio, Method):
5357 Smooth elements which belong to the given object
5360 theObject: the object to smooth
5361 IDsOfFixedNodes: the list of ids of fixed nodes.
5362 Note that nodes built on edges and boundary nodes are always fixed.
5363 MaxNbOfIterations: the maximum number of iterations
5364 MaxAspectRatio: varies in range [1.0, inf]
5365 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5366 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5369 True in case of success, False otherwise.
5372 if ( isinstance( theObject, Mesh )):
5373 theObject = theObject.GetMesh()
5374 return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5375 MaxNbOfIterations, MaxAspectRatio, Method)
5377 def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5378 MaxNbOfIterations, MaxAspectRatio, Method):
5380 Parametrically smooth the given elements
5383 IDsOfElements: the list if ids of elements to smooth
5384 IDsOfFixedNodes: the list of ids of fixed nodes.
5385 Note that nodes built on edges and boundary nodes are always fixed.
5386 MaxNbOfIterations: the maximum number of iterations
5387 MaxAspectRatio: varies in range [1.0, inf]
5388 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5389 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5392 True in case of success, False otherwise.
5395 if IDsOfElements == []:
5396 IDsOfElements = self.GetElementsId()
5397 MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5398 self.mesh.SetParameters(Parameters)
5399 return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5400 MaxNbOfIterations, MaxAspectRatio, Method)
5402 def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5403 MaxNbOfIterations, MaxAspectRatio, Method):
5405 Parametrically smooth the elements which belong to the given object
5408 theObject: the object to smooth
5409 IDsOfFixedNodes: the list of ids of fixed nodes.
5410 Note that nodes built on edges and boundary nodes are always fixed.
5411 MaxNbOfIterations: the maximum number of iterations
5412 MaxAspectRatio: varies in range [1.0, inf]
5413 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5414 or Centroidal (smesh.CENTROIDAL_SMOOTH)
5417 True in case of success, False otherwise.
5420 if ( isinstance( theObject, Mesh )):
5421 theObject = theObject.GetMesh()
5422 return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5423 MaxNbOfIterations, MaxAspectRatio, Method)
5425 def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5427 Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5428 them with quadratic with the same id.
5431 theForce3d: method of new node creation:
5433 * False - the medium node lies at the geometrical entity from which the mesh element is built
5434 * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5435 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5436 theToBiQuad: If True, converts the mesh to bi-quadratic
5439 :class:`SMESH.ComputeError` which can hold a warning
5442 If *theSubMesh* is provided, the mesh can become non-conformal
5445 This operation can create gaps in numeration of nodes or elements.
5446 Call :meth:`RenumberElements` to remove the gaps.
5449 if isinstance( theSubMesh, Mesh ):
5450 theSubMesh = theSubMesh.mesh
5452 self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5455 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5457 self.editor.ConvertToQuadratic(theForce3d)
5458 error = self.editor.GetLastError()
5459 if error and error.comment:
5460 print(error.comment)
5463 def ConvertFromQuadratic(self, theSubMesh=None):
5465 Convert the mesh from quadratic to ordinary,
5466 deletes old quadratic elements,
5467 replacing them with ordinary mesh elements with the same id.
5470 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5473 If *theSubMesh* is provided, the mesh can become non-conformal
5476 This operation can create gaps in numeration of nodes or elements.
5477 Call :meth:`RenumberElements` to remove the gaps.
5481 self.editor.ConvertFromQuadraticObject(theSubMesh)
5483 return self.editor.ConvertFromQuadratic()
5485 def Make2DMeshFrom3D(self):
5487 Create 2D mesh as skin on boundary faces of a 3D mesh
5490 True if operation has been completed successfully, False otherwise
5493 return self.editor.Make2DMeshFrom3D()
5495 def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5496 toCopyElements=False, toCopyExistingBondary=False):
5498 Create missing boundary elements
5501 elements: elements whose boundary is to be checked:
5502 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5503 If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5504 dimension: defines type of boundary elements to create, either of
5505 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5506 SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5507 groupName: a name of group to store created boundary elements in,
5508 "" means not to create the group
5509 meshName: a name of new mesh to store created boundary elements in,
5510 "" means not to create the new mesh
5511 toCopyElements: if True, the checked elements will be copied into
5512 the new mesh else only boundary elements will be copied into the new mesh
5513 toCopyExistingBondary: if True, not only new but also pre-existing
5514 boundary elements will be copied into the new mesh
5517 tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5520 unRegister = genObjUnRegister()
5521 if isinstance( elements, Mesh ):
5522 elements = elements.GetMesh()
5523 if ( isinstance( elements, list )):
5524 elemType = SMESH.ALL
5525 if elements: elemType = self.GetElementType( elements[0], iselem=True)
5526 elements = self.editor.MakeIDSource(elements, elemType)
5527 unRegister.set( elements )
5528 mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5529 toCopyElements,toCopyExistingBondary)
5530 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5533 def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
5535 Create boundary elements around the whole mesh or groups of elements
5538 groupName: a name of group to store all boundary elements in,
5539 "" means not to create the group
5540 meshName: a name of a new mesh, which is a copy of the initial
5541 mesh + created boundary elements; "" means not to create the new mesh
5542 toCopyAll: if True, the whole initial mesh will be copied into
5543 the new mesh else only boundary elements will be copied into the new mesh
5544 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5547 tuple( long, mesh, group )
5548 - long - number of added boundary elements
5549 - mesh - the :class:`Mesh` where elements were added to
5550 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5552 dimension=SMESH.BND_2DFROM3D
5553 toCreateAllElements = True # create all boundary elements in the mesh
5554 nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
5555 toCopyAll,toCreateAllElements,groups)
5556 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5557 return nb, mesh, group
5559 def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5560 toCopyAll=False, groups=[]):
5562 Create missing boundary elements around either the whole mesh or
5566 dimension: defines type of boundary elements to create, either of
5567 { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5568 groupName: a name of group to store all boundary elements in,
5569 "" means not to create the group
5570 meshName: a name of a new mesh, which is a copy of the initial
5571 mesh + created boundary elements; "" means not to create the new mesh
5572 toCopyAll: if True, the whole initial mesh will be copied into
5573 the new mesh else only boundary elements will be copied into the new mesh
5574 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5577 tuple( long, mesh, group )
5578 - long - number of added boundary elements
5579 - mesh - the :class:`Mesh` where elements were added to
5580 - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5582 toCreateAllElements = False # create only elements in the boundary of the solid
5583 nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5584 toCopyAll,toCreateAllElements,groups)
5585 if mesh: mesh = self.smeshpyD.Mesh(mesh)
5586 return nb, mesh, group
5588 def RenumberNodes(self):
5590 Renumber mesh nodes to remove unused node IDs
5592 self.editor.RenumberNodes()
5594 def RenumberElements(self):
5596 Renumber mesh elements to remove unused element IDs
5598 self.editor.RenumberElements()
5600 def _getIdSourceList(self, arg, idType, unRegister):
5602 Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5604 if arg and isinstance( arg, list ):
5605 if isinstance( arg[0], int ):
5606 arg = self.GetIDSource( arg, idType )
5607 unRegister.set( arg )
5608 elif isinstance( arg[0], Mesh ):
5609 arg[0] = arg[0].GetMesh()
5610 elif isinstance( arg, Mesh ):
5612 if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5616 def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5617 MakeGroups=False, TotalAngle=False):
5619 Generate new elements by rotation of the given elements and nodes around the axis
5622 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5623 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5624 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5625 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5626 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5627 which defines angle in degrees
5628 NbOfSteps: the number of steps
5629 Tolerance: tolerance
5630 MakeGroups: forces the generation of new groups from existing ones
5631 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5632 of all steps, else - size of each step
5635 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5638 unRegister = genObjUnRegister()
5639 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5640 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5641 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5643 if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5644 Axis = self.smeshpyD.GetAxisStruct( Axis )
5645 if isinstance( Axis, list ):
5646 Axis = SMESH.AxisStruct( *Axis )
5648 AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5649 NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5650 Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5651 self.mesh.SetParameters(Parameters)
5652 if TotalAngle and NbOfSteps:
5653 AngleInRadians /= NbOfSteps
5654 return self.editor.RotationSweepObjects( nodes, edges, faces,
5655 Axis, AngleInRadians,
5656 NbOfSteps, Tolerance, MakeGroups)
5658 def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5659 MakeGroups=False, TotalAngle=False):
5661 Generate new elements by rotation of the elements around the axis
5664 IDsOfElements: the list of ids of elements to sweep
5665 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5666 AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5667 NbOfSteps: the number of steps
5668 Tolerance: tolerance
5669 MakeGroups: forces the generation of new groups from existing ones
5670 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5671 of all steps, else - size of each step
5674 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5677 return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5678 AngleInRadians, NbOfSteps, Tolerance,
5679 MakeGroups, TotalAngle)
5681 def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5682 MakeGroups=False, TotalAngle=False):
5684 Generate new elements by rotation of the elements of object around the axis
5685 theObject object which elements should be sweeped.
5686 It can be a mesh, a sub mesh or a group.
5689 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5690 AngleInRadians: the angle of Rotation
5691 NbOfSteps: number of steps
5692 Tolerance: tolerance
5693 MakeGroups: forces the generation of new groups from existing ones
5694 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5695 of all steps, else - size of each step
5698 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5701 return self.RotationSweepObjects( [], theObject, theObject, Axis,
5702 AngleInRadians, NbOfSteps, Tolerance,
5703 MakeGroups, TotalAngle )
5705 def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5706 MakeGroups=False, TotalAngle=False):
5708 Generate new elements by rotation of the elements of object around the axis
5709 theObject object which elements should be sweeped.
5710 It can be a mesh, a sub mesh or a group.
5713 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5714 AngleInRadians: the angle of Rotation
5715 NbOfSteps: number of steps
5716 Tolerance: tolerance
5717 MakeGroups: forces the generation of new groups from existing ones
5718 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5719 of all steps, else - size of each step
5722 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5723 empty list otherwise
5726 return self.RotationSweepObjects([],theObject,[], Axis,
5727 AngleInRadians, NbOfSteps, Tolerance,
5728 MakeGroups, TotalAngle)
5730 def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5731 MakeGroups=False, TotalAngle=False):
5733 Generate new elements by rotation of the elements of object around the axis
5734 theObject object which elements should be sweeped.
5735 It can be a mesh, a sub mesh or a group.
5738 Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5739 AngleInRadians: the angle of Rotation
5740 NbOfSteps: number of steps
5741 Tolerance: tolerance
5742 MakeGroups: forces the generation of new groups from existing ones
5743 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5744 of all steps, else - size of each step
5747 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5750 return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5751 NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5753 def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5754 scaleFactors=[], linearVariation=False, basePoint=[],
5755 angles=[], anglesVariation=False):
5757 Generate new elements by extrusion of the given elements and nodes
5760 nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5761 edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5762 faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5763 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5764 the direction and value of extrusion for one step (the total extrusion
5765 length will be NbOfSteps * ||StepVector||)
5766 NbOfSteps: the number of steps
5767 MakeGroups: forces the generation of new groups from existing ones
5768 scaleFactors: optional scale factors to apply during extrusion
5769 linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5770 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5771 basePoint: optional scaling and rotation center; if not provided, a gravity center of
5772 nodes and elements being extruded is used as the scaling center.
5775 - a list of tree components of the point or
5778 angles: list of angles in radians. Nodes at each extrusion step are rotated
5779 around *basePoint*, additionally to previous steps.
5780 anglesVariation: forces the computation of rotation angles as linear
5781 variation of the given *angles* along path steps
5783 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5785 Example: :ref:`tui_extrusion`
5787 unRegister = genObjUnRegister()
5788 nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5789 edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5790 faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5792 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5793 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5794 if isinstance( StepVector, list ):
5795 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5797 if isinstance( basePoint, int):
5798 xyz = self.GetNodeXYZ( basePoint )
5800 raise RuntimeError("Invalid node ID: %s" % basePoint)
5802 if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5803 basePoint = self.geompyD.PointCoordinates( basePoint )
5805 NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5806 scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5807 angles,angleParameters,hasVars = ParseAngles(angles)
5808 Parameters = StepVector.PS.parameters + var_separator + \
5809 Parameters + var_separator + \
5810 scaleParameters + var_separator + angleParameters
5811 self.mesh.SetParameters(Parameters)
5813 return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5814 StepVector, NbOfSteps, MakeGroups,
5815 scaleFactors, linearVariation, basePoint,
5816 angles, anglesVariation )
5819 def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5821 Generate new elements by extrusion of the elements with given ids
5824 IDsOfElements: the list of ids of elements or nodes for extrusion
5825 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5826 the direction and value of extrusion for one step (the total extrusion
5827 length will be NbOfSteps * ||StepVector||)
5828 NbOfSteps: the number of steps
5829 MakeGroups: forces the generation of new groups from existing ones
5830 IsNodes: is True if elements with given ids are nodes
5833 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5835 Example: :ref:`tui_extrusion`
5838 if IsNodes: n = IDsOfElements
5839 else : e,f, = IDsOfElements,IDsOfElements
5840 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5842 def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5843 ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5845 Generate new elements by extrusion along the normal to a discretized surface or wire
5848 Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5849 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5850 StepSize: length of one extrusion step (the total extrusion
5851 length will be *NbOfSteps* *StepSize*).
5852 NbOfSteps: number of extrusion steps.
5853 ByAverageNormal: if True each node is translated by *StepSize*
5854 along the average of the normal vectors to the faces sharing the node;
5855 else each node is translated along the same average normal till
5856 intersection with the plane got by translation of the face sharing
5857 the node along its own normal by *StepSize*.
5858 UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5859 for every node of *Elements*.
5860 MakeGroups: forces generation of new groups from existing ones.
5861 Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5862 is not yet implemented. This parameter is used if *Elements* contains
5863 both faces and edges, i.e. *Elements* is a Mesh.
5866 the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5867 empty list otherwise.
5868 Example: :ref:`tui_extrusion`
5871 unRegister = genObjUnRegister()
5872 if isinstance( Elements, Mesh ):
5873 Elements = [ Elements.GetMesh() ]
5874 if isinstance( Elements, list ):
5876 raise RuntimeError("Elements empty!")
5877 if isinstance( Elements[0], Mesh ):
5878 Elements = [ Elements[0].GetMesh() ]
5879 if isinstance( Elements[0], int ):
5880 Elements = self.GetIDSource( Elements, SMESH.ALL )
5881 unRegister.set( Elements )
5882 if not isinstance( Elements, list ):
5883 Elements = [ Elements ]
5884 StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5885 self.mesh.SetParameters(Parameters)
5886 return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5887 ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5889 def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5891 Generate new elements by extrusion of the elements or nodes which belong to the object
5894 theObject: the object whose elements or nodes should be processed.
5895 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5896 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5897 the direction and value of extrusion for one step (the total extrusion
5898 length will be NbOfSteps * ||StepVector||)
5899 NbOfSteps: the number of steps
5900 MakeGroups: forces the generation of new groups from existing ones
5901 IsNodes: is True if elements to extrude are nodes
5904 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5905 Example: :ref:`tui_extrusion`
5909 if IsNodes: n = theObject
5910 else : e,f, = theObject,theObject
5911 return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5913 def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5915 Generate new elements by extrusion of edges which belong to the object
5918 theObject: object whose 1D elements should be processed.
5919 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5920 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5921 the direction and value of extrusion for one step (the total extrusion
5922 length will be NbOfSteps * ||StepVector||)
5923 NbOfSteps: the number of steps
5924 MakeGroups: to generate new groups from existing ones
5927 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5928 Example: :ref:`tui_extrusion`
5931 return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5933 def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5935 Generate new elements by extrusion of faces which belong to the object
5938 theObject: object whose 2D elements should be processed.
5939 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5940 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5941 the direction and value of extrusion for one step (the total extrusion
5942 length will be NbOfSteps * ||StepVector||)
5943 NbOfSteps: the number of steps
5944 MakeGroups: forces the generation of new groups from existing ones
5947 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5948 Example: :ref:`tui_extrusion`
5951 return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5953 def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5954 ExtrFlags, SewTolerance, MakeGroups=False):
5956 Generate new elements by extrusion of the elements with given ids
5959 IDsOfElements: is ids of elements
5960 StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5961 the direction and value of extrusion for one step (the total extrusion
5962 length will be NbOfSteps * ||StepVector||)
5963 NbOfSteps: the number of steps
5964 ExtrFlags: sets flags for extrusion
5965 SewTolerance: uses for comparing locations of nodes if flag
5966 EXTRUSION_FLAG_SEW is set
5967 MakeGroups: forces the generation of new groups from existing ones
5970 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5973 if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5974 StepVector = self.smeshpyD.GetDirStruct(StepVector)
5975 if isinstance( StepVector, list ):
5976 StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5977 return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5978 ExtrFlags, SewTolerance, MakeGroups)
5980 def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5981 NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5982 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5983 ScaleFactors=[], ScalesVariation=False):
5985 Generate new elements by extrusion of the given elements and nodes along the path.
5986 The path of extrusion must be a meshed edge.
5989 Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5990 Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5991 Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5992 PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5993 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
5994 NodeStart: the first or the last node on the path. Defines the direction of extrusion
5995 HasAngles: not used obsolete
5996 Angles: list of angles in radians. Nodes at each extrusion step are rotated
5997 around *basePoint*, additionally to previous steps.
5998 LinearVariation: forces the computation of rotation angles as linear
5999 variation of the given Angles along path steps
6000 HasRefPoint: allows using the reference point
6001 RefPoint: optional scaling and rotation center (mass center of the extruded
6002 elements by default). The User can specify any point as the Reference Point.
6003 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6004 MakeGroups: forces the generation of new groups from existing ones
6005 ScaleFactors: optional scale factors to apply during extrusion
6006 ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
6007 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
6010 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6011 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6012 Example: :ref:`tui_extrusion_along_path`
6015 unRegister = genObjUnRegister()
6016 Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
6017 Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
6018 Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
6020 if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
6021 RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
6022 if isinstance( RefPoint, list ):
6023 if not RefPoint: RefPoint = [0,0,0]
6024 RefPoint = SMESH.PointStruct( *RefPoint )
6025 if isinstance( PathObject, Mesh ):
6026 PathObject = PathObject.GetMesh()
6027 Angles,AnglesParameters,hasVars = ParseAngles(Angles)
6028 ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
6029 Parameters = AnglesParameters + var_separator + \
6030 RefPoint.parameters + var_separator + ScalesParameters
6031 self.mesh.SetParameters(Parameters)
6032 return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
6033 PathObject, PathShape, NodeStart,
6034 HasAngles, Angles, LinearVariation,
6035 HasRefPoint, RefPoint, MakeGroups,
6036 ScaleFactors, ScalesVariation)
6038 def ExtrusionAlongPathX(self, Base, Path, NodeStart,
6039 HasAngles=False, Angles=[], LinearVariation=False,
6040 HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
6041 ElemType=SMESH.FACE):
6043 Generate new elements by extrusion of the given elements.
6044 The path of extrusion must be a meshed edge.
6047 Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
6048 Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
6049 NodeStart: the start node from Path. Defines the direction of extrusion
6050 HasAngles: not used obsolete
6051 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6052 around *basePoint*, additionally to previous steps.
6053 LinearVariation: forces the computation of rotation angles as linear
6054 variation of the given Angles along path steps
6055 HasRefPoint: allows using the reference point
6056 RefPoint: the reference point around which the elements are rotated (the mass
6057 center of the elements by default).
6058 The User can specify any point as the Reference Point.
6059 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6060 MakeGroups: forces the generation of new groups from existing ones
6061 ElemType: type of elements for extrusion (if param Base is a mesh)
6064 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6065 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6066 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6068 Example: :ref:`tui_extrusion_along_path`
6072 if ElemType == SMESH.NODE: n = Base
6073 if ElemType == SMESH.EDGE: e = Base
6074 if ElemType == SMESH.FACE: f = Base
6075 gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
6076 HasAngles, Angles, LinearVariation,
6077 HasRefPoint, RefPoint, MakeGroups)
6078 if MakeGroups: return gr,er
6081 def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
6082 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6083 MakeGroups=False, LinearVariation=False):
6085 Generate new elements by extrusion of the given elements.
6086 The path of extrusion must be a meshed edge.
6089 IDsOfElements: ids of elements
6090 PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6091 PathShape: shape (edge) defines the sub-mesh for the path
6092 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6093 HasAngles: not used obsolete
6094 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6095 around *basePoint*, additionally to previous steps.
6096 HasRefPoint: allows using the reference point
6097 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6098 The User can specify any point as the Reference Point.
6099 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6100 MakeGroups: forces the generation of new groups from existing ones
6101 LinearVariation: forces the computation of rotation angles as linear
6102 variation of the given Angles along path steps
6105 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6106 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6107 if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6108 Example: :ref:`tui_extrusion_along_path`
6111 if not IDsOfElements:
6112 IDsOfElements = [ self.GetMesh() ]
6113 n,e,f = [],IDsOfElements,IDsOfElements
6114 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6115 NodeStart, HasAngles, Angles,
6117 HasRefPoint, RefPoint, MakeGroups)
6118 if MakeGroups: return gr,er
6121 def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6122 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6123 MakeGroups=False, LinearVariation=False):
6125 Generate new elements by extrusion of the elements which belong to the object.
6126 The path of extrusion must be a meshed edge.
6129 theObject: the object whose elements should be processed.
6130 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6131 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6132 PathShape: shape (edge) defines the sub-mesh for the path
6133 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6134 HasAngles: not used obsolete
6135 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6136 around *basePoint*, additionally to previous steps.
6137 HasRefPoint: allows using the reference point
6138 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6139 The User can specify any point as the Reference Point.
6140 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6141 MakeGroups: forces the generation of new groups from existing ones
6142 LinearVariation: forces the computation of rotation angles as linear
6143 variation of the given Angles along path steps
6146 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6147 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6148 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6149 Example: :ref:`tui_extrusion_along_path`
6152 n,e,f = [],theObject,theObject
6153 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6154 HasAngles, Angles, LinearVariation,
6155 HasRefPoint, RefPoint, MakeGroups)
6156 if MakeGroups: return gr,er
6159 def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6160 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6161 MakeGroups=False, LinearVariation=False):
6163 Generate new elements by extrusion of mesh segments which belong to the object.
6164 The path of extrusion must be a meshed edge.
6167 theObject: the object whose 1D elements should be processed.
6168 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6169 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6170 PathShape: shape (edge) defines the sub-mesh for the path
6171 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6172 HasAngles: not used obsolete
6173 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6174 around *basePoint*, additionally to previous steps.
6175 HasRefPoint: allows using the reference point
6176 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6177 The User can specify any point as the Reference Point.
6178 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6179 MakeGroups: forces the generation of new groups from existing ones
6180 LinearVariation: forces the computation of rotation angles as linear
6181 variation of the given Angles along path steps
6184 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6185 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6186 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6187 Example: :ref:`tui_extrusion_along_path`
6190 n,e,f = [],theObject,[]
6191 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6192 HasAngles, Angles, LinearVariation,
6193 HasRefPoint, RefPoint, MakeGroups)
6194 if MakeGroups: return gr,er
6197 def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6198 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6199 MakeGroups=False, LinearVariation=False):
6201 Generate new elements by extrusion of faces which belong to the object.
6202 The path of extrusion must be a meshed edge.
6205 theObject: the object whose 2D elements should be processed.
6206 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6207 PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6208 PathShape: shape (edge) defines the sub-mesh for the path
6209 NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6210 HasAngles: not used obsolete
6211 Angles: list of angles in radians. Nodes at each extrusion step are rotated
6212 around *basePoint*, additionally to previous steps.
6213 HasRefPoint: allows using the reference point
6214 RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6215 The User can specify any point as the Reference Point.
6216 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6217 MakeGroups: forces the generation of new groups from existing ones
6218 LinearVariation: forces the computation of rotation angles as linear
6219 variation of the given Angles along path steps
6222 list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6223 :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6224 only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6225 Example: :ref:`tui_extrusion_along_path`
6228 n,e,f = [],[],theObject
6229 gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6230 HasAngles, Angles, LinearVariation,
6231 HasRefPoint, RefPoint, MakeGroups)
6232 if MakeGroups: return gr,er
6235 def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6237 Create a symmetrical copy of mesh elements
6240 IDsOfElements: list of elements ids
6241 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6242 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6243 If the *Mirror* is a geom object this parameter is unnecessary
6244 Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6245 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6248 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6251 if IDsOfElements == []:
6252 IDsOfElements = self.GetElementsId()
6253 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6254 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6255 theMirrorType = Mirror._mirrorType
6257 self.mesh.SetParameters(Mirror.parameters)
6258 if Copy and MakeGroups:
6259 return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6260 self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6263 def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6265 Create a new mesh by a symmetrical copy of mesh elements
6268 IDsOfElements: the list of elements ids
6269 Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6270 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6271 If the *Mirror* is a geom object this parameter is unnecessary
6272 MakeGroups: to generate new groups from existing ones
6273 NewMeshName: a name of the new mesh to create
6276 instance of class :class:`Mesh`
6279 if IDsOfElements == []:
6280 IDsOfElements = self.GetElementsId()
6281 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6282 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6283 theMirrorType = Mirror._mirrorType
6285 self.mesh.SetParameters(Mirror.parameters)
6286 mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6287 MakeGroups, NewMeshName)
6288 return Mesh(self.smeshpyD,self.geompyD,mesh)
6290 def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6292 Create a symmetrical copy of the object
6295 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6296 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6297 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6298 If the *Mirror* is a geom object this parameter is unnecessary
6299 Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6300 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6303 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6306 if ( isinstance( theObject, Mesh )):
6307 theObject = theObject.GetMesh()
6308 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6309 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6310 theMirrorType = Mirror._mirrorType
6312 self.mesh.SetParameters(Mirror.parameters)
6313 if Copy and MakeGroups:
6314 return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6315 self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6318 def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6320 Create a new mesh by a symmetrical copy of the object
6323 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6324 Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6325 theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6326 If the *Mirror* is a geom object this parameter is unnecessary
6327 MakeGroups: forces the generation of new groups from existing ones
6328 NewMeshName: the name of the new mesh to create
6331 instance of class :class:`Mesh`
6334 if ( isinstance( theObject, Mesh )):
6335 theObject = theObject.GetMesh()
6336 if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6337 Mirror = self.smeshpyD.GetAxisStruct(Mirror)
6338 theMirrorType = Mirror._mirrorType
6340 self.mesh.SetParameters(Mirror.parameters)
6341 mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6342 MakeGroups, NewMeshName)
6343 return Mesh( self.smeshpyD,self.geompyD,mesh )
6345 def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6347 Translate the elements
6350 IDsOfElements: list of elements ids
6351 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6352 Copy: allows copying the translated elements
6353 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6356 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6359 if IDsOfElements == []:
6360 IDsOfElements = self.GetElementsId()
6361 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6362 Vector = self.smeshpyD.GetDirStruct(Vector)
6363 if isinstance( Vector, list ):
6364 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6365 self.mesh.SetParameters(Vector.PS.parameters)
6366 if Copy and MakeGroups:
6367 return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6368 self.editor.Translate(IDsOfElements, Vector, Copy)
6371 def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6373 Create a new mesh of translated elements
6376 IDsOfElements: list of elements ids
6377 Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6378 MakeGroups: forces the generation of new groups from existing ones
6379 NewMeshName: the name of the newly created mesh
6382 instance of class :class:`Mesh`
6385 if IDsOfElements == []:
6386 IDsOfElements = self.GetElementsId()
6387 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6388 Vector = self.smeshpyD.GetDirStruct(Vector)
6389 if isinstance( Vector, list ):
6390 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6391 self.mesh.SetParameters(Vector.PS.parameters)
6392 mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6393 return Mesh ( self.smeshpyD, self.geompyD, mesh )
6395 def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6397 Translate the object
6400 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6401 Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6402 Copy: allows copying the translated elements
6403 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6406 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6409 if ( isinstance( theObject, Mesh )):
6410 theObject = theObject.GetMesh()
6411 if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6412 Vector = self.smeshpyD.GetDirStruct(Vector)
6413 if isinstance( Vector, list ):
6414 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6415 self.mesh.SetParameters(Vector.PS.parameters)
6416 if Copy and MakeGroups:
6417 return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6418 self.editor.TranslateObject(theObject, Vector, Copy)
6421 def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6423 Create a new mesh from the translated object
6426 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6427 Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6428 MakeGroups: forces the generation of new groups from existing ones
6429 NewMeshName: the name of the newly created mesh
6432 instance of class :class:`Mesh`
6435 if isinstance( theObject, Mesh ):
6436 theObject = theObject.GetMesh()
6437 if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6438 Vector = self.smeshpyD.GetDirStruct(Vector)
6439 if isinstance( Vector, list ):
6440 Vector = self.smeshpyD.MakeDirStruct(*Vector)
6441 self.mesh.SetParameters(Vector.PS.parameters)
6442 mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6443 return Mesh( self.smeshpyD, self.geompyD, mesh )
6447 def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6452 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6453 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6454 theScaleFact: list of 1-3 scale factors for axises
6455 Copy: allows copying the translated elements
6456 MakeGroups: forces the generation of new groups from existing
6460 list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6461 empty list otherwise
6463 unRegister = genObjUnRegister()
6464 if ( isinstance( theObject, Mesh )):
6465 theObject = theObject.GetMesh()
6466 if ( isinstance( theObject, list )):
6467 theObject = self.GetIDSource(theObject, SMESH.ALL)
6468 unRegister.set( theObject )
6469 if ( isinstance( thePoint, list )):
6470 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6471 if ( isinstance( theScaleFact, float )):
6472 theScaleFact = [theScaleFact]
6473 if ( isinstance( theScaleFact, int )):
6474 theScaleFact = [ float(theScaleFact)]
6476 self.mesh.SetParameters(thePoint.parameters)
6478 if Copy and MakeGroups:
6479 return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6480 self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6483 def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6485 Create a new mesh from the translated object
6488 theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6489 thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6490 theScaleFact: list of 1-3 scale factors for axises
6491 MakeGroups: forces the generation of new groups from existing ones
6492 NewMeshName: the name of the newly created mesh
6495 instance of class :class:`Mesh`
6497 unRegister = genObjUnRegister()
6498 if (isinstance(theObject, Mesh)):
6499 theObject = theObject.GetMesh()
6500 if ( isinstance( theObject, list )):
6501 theObject = self.GetIDSource(theObject,SMESH.ALL)
6502 unRegister.set( theObject )
6503 if ( isinstance( thePoint, list )):
6504 thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6505 if ( isinstance( theScaleFact, float )):
6506 theScaleFact = [theScaleFact]
6507 if ( isinstance( theScaleFact, int )):
6508 theScaleFact = [ float(theScaleFact)]
6510 self.mesh.SetParameters(thePoint.parameters)
6511 mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6512 MakeGroups, NewMeshName)
6513 return Mesh( self.smeshpyD, self.geompyD, mesh )
6517 def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6522 IDsOfElements: list of elements ids
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
6533 if IDsOfElements == []:
6534 IDsOfElements = self.GetElementsId()
6535 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6536 Axis = self.smeshpyD.GetAxisStruct(Axis)
6537 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6538 Parameters = Axis.parameters + var_separator + Parameters
6539 self.mesh.SetParameters(Parameters)
6540 if Copy and MakeGroups:
6541 return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6542 self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6545 def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6547 Create a new mesh of rotated elements
6550 IDsOfElements: list of element ids
6551 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6552 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6553 MakeGroups: forces the generation of new groups from existing ones
6554 NewMeshName: the name of the newly created mesh
6557 instance of class :class:`Mesh`
6560 if IDsOfElements == []:
6561 IDsOfElements = self.GetElementsId()
6562 if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6563 Axis = self.smeshpyD.GetAxisStruct(Axis)
6564 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6565 Parameters = Axis.parameters + var_separator + Parameters
6566 self.mesh.SetParameters(Parameters)
6567 mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6568 MakeGroups, NewMeshName)
6569 return Mesh( self.smeshpyD, self.geompyD, mesh )
6571 def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6576 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6577 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6578 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6579 Copy: allows copying the rotated elements
6580 MakeGroups: forces the generation of new groups from existing ones (if Copy)
6583 list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6586 if (isinstance(theObject, Mesh)):
6587 theObject = theObject.GetMesh()
6588 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6589 Axis = self.smeshpyD.GetAxisStruct(Axis)
6590 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6591 Parameters = Axis.parameters + ":" + Parameters
6592 self.mesh.SetParameters(Parameters)
6593 if Copy and MakeGroups:
6594 return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6595 self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6598 def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6600 Create a new mesh from the rotated object
6603 theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6604 Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6605 AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6606 MakeGroups: forces the generation of new groups from existing ones
6607 NewMeshName: the name of the newly created mesh
6610 instance of class :class:`Mesh`
6613 if (isinstance( theObject, Mesh )):
6614 theObject = theObject.GetMesh()
6615 if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6616 Axis = self.smeshpyD.GetAxisStruct(Axis)
6617 AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6618 Parameters = Axis.parameters + ":" + Parameters
6619 mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6620 MakeGroups, NewMeshName)
6621 self.mesh.SetParameters(Parameters)
6622 return Mesh( self.smeshpyD, self.geompyD, mesh )
6624 def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6626 Create an offset mesh from the given 2D object
6629 theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6630 theValue (float): signed offset size
6631 MakeGroups (boolean): forces the generation of new groups from existing ones
6632 CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6633 False means to remove original elements.
6634 NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6637 A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6640 if isinstance( theObject, Mesh ):
6641 theObject = theObject.GetMesh()
6642 theValue,Parameters,hasVars = ParseParameters(Value)
6643 mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6644 self.mesh.SetParameters(Parameters)
6646 return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6649 def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6651 Find groups of adjacent nodes within Tolerance.
6654 Tolerance (float): the value of tolerance
6655 SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6656 corner and medium nodes in separate groups thus preventing
6657 their further merge.
6660 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6663 return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6665 def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6666 exceptNodes=[], SeparateCornerAndMediumNodes=False):
6668 Find groups of adjacent nodes within Tolerance.
6671 Tolerance: the value of tolerance
6672 SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6673 exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6674 SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6675 corner and medium nodes in separate groups thus preventing
6676 their further merge.
6679 the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6682 unRegister = genObjUnRegister()
6683 if not isinstance( SubMeshOrGroup, list ):
6684 SubMeshOrGroup = [ SubMeshOrGroup ]
6685 for i,obj in enumerate( SubMeshOrGroup ):
6686 if isinstance( obj, Mesh ):
6687 SubMeshOrGroup = [ obj.GetMesh() ]
6689 if isinstance( obj, int ):
6690 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6691 unRegister.set( SubMeshOrGroup )
6694 if not isinstance( exceptNodes, list ):
6695 exceptNodes = [ exceptNodes ]
6696 if exceptNodes and isinstance( exceptNodes[0], int ):
6697 exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6698 unRegister.set( exceptNodes )
6700 return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6701 exceptNodes, SeparateCornerAndMediumNodes)
6703 def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6708 GroupsOfNodes: a list of groups of nodes IDs for merging.
6709 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6710 in all elements and mesh groups by nodes 1 and 25 correspondingly
6711 NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6712 If *NodesToKeep* does not include a node to keep for some group to merge,
6713 then the first node in the group is kept.
6714 AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6718 This operation can create gaps in numeration of nodes or elements.
6719 Call :meth:`RenumberElements` to remove the gaps.
6721 self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6723 def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6725 Find the elements built on the same nodes.
6728 MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6729 exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6733 the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6736 unRegister = genObjUnRegister()
6737 if MeshOrSubMeshOrGroup is None:
6738 MeshOrSubMeshOrGroup = [ self.mesh ]
6739 elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6740 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6741 elif not isinstance( MeshOrSubMeshOrGroup, list ):
6742 MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6743 if isinstance( MeshOrSubMeshOrGroup[0], int ):
6744 MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6745 unRegister.set( MeshOrSubMeshOrGroup )
6746 for item in MeshOrSubMeshOrGroup:
6747 if isinstance( item, Mesh ):
6748 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6750 if not isinstance( exceptElements, list ):
6751 exceptElements = [ exceptElements ]
6752 if exceptElements and isinstance( exceptElements[0], int ):
6753 exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6754 unRegister.set( exceptElements )
6756 return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6758 def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6760 Merge elements in each given group.
6763 GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6764 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6765 replaced in all mesh groups by elements 1 and 25)
6766 ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6767 If *ElementsToKeep* does not include an element to keep for some group to merge,
6768 then the first element in the group is kept.
6771 This operation can create gaps in numeration of elements.
6772 Call :meth:`RenumberElements` to remove the gaps.
6775 unRegister = genObjUnRegister()
6777 if not isinstance( ElementsToKeep, list ):
6778 ElementsToKeep = [ ElementsToKeep ]
6779 if isinstance( ElementsToKeep[0], int ):
6780 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6781 unRegister.set( ElementsToKeep )
6783 self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6785 def MergeEqualElements(self):
6787 Leave one element and remove all other elements built on the same nodes.
6790 This operation can create gaps in numeration of elements.
6791 Call :meth:`RenumberElements` to remove the gaps.
6794 self.editor.MergeEqualElements()
6796 def FindFreeBorders(self, ClosedOnly=True):
6798 Returns all or only closed free borders
6801 list of SMESH.FreeBorder's
6804 return self.editor.FindFreeBorders( ClosedOnly )
6806 def FillHole(self, holeNodes, groupName=""):
6808 Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6811 holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6812 must describe all sequential nodes of the hole border. The first and the last
6813 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6814 groupName (string): name of a group to add new faces
6816 a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6820 if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6821 holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6822 if not isinstance( holeNodes, SMESH.FreeBorder ):
6823 raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6824 return self.editor.FillHole( holeNodes, groupName )
6826 def FindCoincidentFreeBorders (self, tolerance=0.):
6828 Return groups of FreeBorder's coincident within the given tolerance.
6831 tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6832 size of elements adjacent to free borders being compared is used.
6835 SMESH.CoincidentFreeBorders structure
6838 return self.editor.FindCoincidentFreeBorders( tolerance )
6840 def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6842 Sew FreeBorder's of each group
6845 freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6846 where each enclosed list contains node IDs of a group of coincident free
6847 borders such that each consequent triple of IDs within a group describes
6848 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6849 last node of a border.
6850 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6851 groups of coincident free borders, each group including two borders.
6852 createPolygons: if :code:`True` faces adjacent to free borders are converted to
6853 polygons if a node of opposite border falls on a face edge, else such
6854 faces are split into several ones.
6855 createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6856 polyhedra if a node of opposite border falls on a volume edge, else such
6857 volumes, if any, remain intact and the mesh becomes non-conformal.
6860 a number of successfully sewed groups
6863 This operation can create gaps in numeration of nodes or elements.
6864 Call :meth:`RenumberElements` to remove the gaps.
6867 if freeBorders and isinstance( freeBorders, list ):
6868 # construct SMESH.CoincidentFreeBorders
6869 if isinstance( freeBorders[0], int ):
6870 freeBorders = [freeBorders]
6872 coincidentGroups = []
6873 for nodeList in freeBorders:
6874 if not nodeList or len( nodeList ) % 3:
6875 raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6878 group.append ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6879 borders.append( SMESH.FreeBorder( nodeList[:3] ))
6880 nodeList = nodeList[3:]
6882 coincidentGroups.append( group )
6884 freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6886 return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6888 def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6889 FirstNodeID2, SecondNodeID2, LastNodeID2,
6890 CreatePolygons, CreatePolyedrs):
6895 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6898 This operation can create gaps in numeration of nodes or elements.
6899 Call :meth:`RenumberElements` to remove the gaps.
6902 return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6903 FirstNodeID2, SecondNodeID2, LastNodeID2,
6904 CreatePolygons, CreatePolyedrs)
6906 def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6907 FirstNodeID2, SecondNodeID2):
6909 Sew conform free borders
6912 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6915 This operation can create gaps in numeration of elements.
6916 Call :meth:`RenumberElements` to remove the gaps.
6919 return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6920 FirstNodeID2, SecondNodeID2)
6922 def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6923 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6928 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6931 This operation can create gaps in numeration of elements.
6932 Call :meth:`RenumberElements` to remove the gaps.
6935 return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6936 FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6938 def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6939 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6940 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6942 Sew two sides of a mesh. The nodes belonging to Side1 are
6943 merged with the nodes of elements of Side2.
6944 The number of elements in theSide1 and in theSide2 must be
6945 equal and they should have similar nodal connectivity.
6946 The nodes to merge should belong to side borders and
6947 the first node should be linked to the second.
6950 :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6953 This operation can create gaps in numeration of nodes.
6954 Call :meth:`RenumberElements` to remove the gaps.
6957 return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6958 NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6959 NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6961 def ChangeElemNodes(self, ide, newIDs):
6963 Set new nodes for the given element. Number of nodes should be kept.
6970 False if the number of nodes does not correspond to the type of element
6973 return self.editor.ChangeElemNodes(ide, newIDs)
6975 def GetLastCreatedNodes(self):
6977 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6978 created, this method return the list of their IDs.
6979 If new nodes were not created - return empty list
6982 the list of integer values (can be empty)
6985 return self.editor.GetLastCreatedNodes()
6987 def GetLastCreatedElems(self):
6989 If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6990 created this method return the list of their IDs.
6991 If new elements were not created - return empty list
6994 the list of integer values (can be empty)
6997 return self.editor.GetLastCreatedElems()
6999 def ClearLastCreated(self):
7001 Forget what nodes and elements were created by the last mesh edition operation
7004 self.editor.ClearLastCreated()
7006 def DoubleElements(self, theElements, theGroupName=""):
7008 Create duplicates of given elements, i.e. create new elements based on the
7009 same nodes as the given ones.
7012 theElements: container of elements to duplicate. It can be a
7013 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
7014 or a list of element IDs. If *theElements* is
7015 a :class:`Mesh`, elements of highest dimension are duplicated
7016 theGroupName: a name of group to contain the generated elements.
7017 If a group with such a name already exists, the new elements
7018 are added to the existing group, else a new group is created.
7019 If *theGroupName* is empty, new elements are not added
7023 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
7024 None if *theGroupName* == "".
7027 unRegister = genObjUnRegister()
7028 if isinstance( theElements, Mesh ):
7029 theElements = theElements.mesh
7030 elif isinstance( theElements, list ):
7031 theElements = self.GetIDSource( theElements, SMESH.ALL )
7032 unRegister.set( theElements )
7033 return self.editor.DoubleElements(theElements, theGroupName)
7035 def DoubleNodes(self, theNodes, theModifiedElems):
7037 Create a hole in a mesh by doubling the nodes of some particular elements
7040 theNodes: IDs of nodes to be doubled
7041 theModifiedElems: IDs of elements to be updated by the new (doubled)
7042 nodes. If list of element identifiers is empty then nodes are doubled but
7043 they not assigned to elements
7046 True if operation has been completed successfully, False otherwise
7049 return self.editor.DoubleNodes(theNodes, theModifiedElems)
7051 def DoubleNode(self, theNodeId, theModifiedElems):
7053 Create a hole in a mesh by doubling the nodes of some particular elements.
7054 This method provided for convenience works as :meth:`DoubleNodes`.
7057 theNodeId: IDs of node to double
7058 theModifiedElems: IDs of elements to update
7061 True if operation has been completed successfully, False otherwise
7064 return self.editor.DoubleNode(theNodeId, theModifiedElems)
7066 def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
7068 Create a hole in a mesh by doubling the nodes of some particular elements.
7069 This method provided for convenience works as :meth:`DoubleNodes`.
7072 theNodes: group of nodes to double.
7073 theModifiedElems: group of elements to update.
7074 theMakeGroup: forces the generation of a group containing new nodes.
7077 True or a created group if operation has been completed successfully,
7078 False or None otherwise
7082 return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
7083 return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
7085 def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=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 theNodes: list of groups of nodes to double.
7092 theModifiedElems: list of groups of elements to update.
7093 theMakeGroup: forces the generation of a group containing new nodes.
7096 True if operation has been completed successfully, False otherwise
7100 return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7101 return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7103 def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7105 Create a hole in a mesh by doubling the nodes of some particular elements
7108 theElems: the list of elements (edges or faces) to replicate.
7109 The nodes for duplication could be found from these elements
7110 theNodesNot: list of nodes NOT to replicate
7111 theAffectedElems: the list of elements (cells and edges) to which the
7112 replicated nodes should be associated to
7115 True if operation has been completed successfully, False otherwise
7118 return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7120 def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7122 Create a hole in a mesh by doubling the nodes of some particular elements
7125 theElems: the list of elements (edges or faces) to replicate.
7126 The nodes for duplication could be found from these elements
7127 theNodesNot: list of nodes NOT to replicate
7128 theShape: shape to detect affected elements (element which geometric center
7129 located on or inside shape).
7130 The replicated nodes should be associated to affected elements.
7133 True if operation has been completed successfully, False otherwise
7136 return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7138 def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7139 theMakeGroup=False, theMakeNodeGroup=False):
7141 Create a hole in a mesh by doubling the nodes of some particular elements.
7142 This method provided for convenience works as :meth:`DoubleNodes`.
7145 theElems: group of of elements (edges or faces) to replicate.
7146 theNodesNot: group of nodes NOT to replicate.
7147 theAffectedElems: group of elements to which the replicated nodes
7148 should be associated to.
7149 theMakeGroup: forces the generation of a group containing new elements.
7150 theMakeNodeGroup: forces the generation of a group containing new nodes.
7153 True or created groups (one or two) if operation has been completed successfully,
7154 False or None otherwise
7157 if theMakeGroup or theMakeNodeGroup:
7158 twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7160 theMakeGroup, theMakeNodeGroup)
7161 if theMakeGroup and theMakeNodeGroup:
7164 return twoGroups[ int(theMakeNodeGroup) ]
7165 return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7167 def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7169 Create a hole in a mesh by doubling the nodes of some particular elements.
7170 This method provided for convenience works as :meth:`DoubleNodes`.
7173 theElems: group of of elements (edges or faces) to replicate
7174 theNodesNot: group of nodes not to replicate
7175 theShape: shape to detect affected elements (element which geometric center
7176 located on or inside shape).
7177 The replicated nodes should be associated to affected elements
7180 return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7182 def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7183 theMakeGroup=False, theMakeNodeGroup=False):
7185 Create a hole in a mesh by doubling the nodes of some particular elements.
7186 This method provided for convenience works as :meth:`DoubleNodes`.
7189 theElems: list of groups of elements (edges or faces) to replicate
7190 theNodesNot: list of groups of nodes NOT to replicate
7191 theAffectedElems: group of elements to which the replicated nodes
7192 should be associated to
7193 theMakeGroup: forces generation of a group containing new elements.
7194 theMakeNodeGroup: forces generation of a group containing new nodes
7197 True or created groups (one or two) if operation has been completed successfully,
7198 False or None otherwise
7201 if theMakeGroup or theMakeNodeGroup:
7202 twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7204 theMakeGroup, theMakeNodeGroup)
7205 if theMakeGroup and theMakeNodeGroup:
7208 return twoGroups[ int(theMakeNodeGroup) ]
7209 return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7211 def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7213 Create a hole in a mesh by doubling the nodes of some particular elements.
7214 This method provided for convenience works as :meth:`DoubleNodes`.
7217 theElems: list of groups of elements (edges or faces) to replicate
7218 theNodesNot: list of groups of nodes NOT to replicate
7219 theShape: shape to detect affected elements (element which geometric center
7220 located on or inside shape).
7221 The replicated nodes should be associated to affected elements
7224 True if operation has been completed successfully, False otherwise
7227 return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7229 def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7231 Identify the elements that will be affected by node duplication (actual duplication is not performed).
7232 This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7235 theElems: list of groups of nodes or elements (edges or faces) to replicate
7236 theNodesNot: list of groups of nodes NOT to replicate
7237 theShape: shape to detect affected elements (element which geometric center
7238 located on or inside shape).
7239 The replicated nodes should be associated to affected elements
7242 groups of affected elements in order: volumes, faces, edges
7245 return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7247 def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7250 Double nodes on shared faces between groups of volumes and create flat elements on demand.
7251 The list of groups must describe a partition of the mesh volumes.
7252 The nodes of the internal faces at the boundaries of the groups are doubled.
7253 In option, the internal faces are replaced by flat elements.
7254 Triangles are transformed to prisms, and quadrangles to hexahedrons.
7257 theDomains: list of groups of volumes
7258 createJointElems: if True, create the elements
7259 onAllBoundaries: if True, the nodes and elements are also created on
7260 the boundary between *theDomains* and the rest mesh
7263 True if operation has been completed successfully, False otherwise
7266 return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7268 def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7270 Double nodes on some external faces and create flat elements.
7271 Flat elements are mainly used by some types of mechanic calculations.
7273 Each group of the list must be constituted of faces.
7274 Triangles are transformed in prisms, and quadrangles in hexahedrons.
7277 theGroupsOfFaces: list of groups of faces
7280 True if operation has been completed successfully, False otherwise
7283 return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7285 def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7287 Identify all the elements around a geom shape, get the faces delimiting the hole
7289 return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7291 def MakePolyLine(self, segments, groupName='', isPreview=False ):
7293 Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7294 the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7295 plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7296 If there are several paths connecting a pair of points, the shortest path is
7297 selected by the module. Position of the cutting plane is defined by the two
7298 points and an optional vector lying on the plane specified by a PolySegment.
7299 By default the vector is defined by Mesh module as following. A middle point
7300 of the two given points is computed. The middle point is projected to the mesh.
7301 The vector goes from the middle point to the projection point. In case of planar
7302 mesh, the vector is normal to the mesh.
7304 In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7307 segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7308 groupName: optional name of a group where created mesh segments will be added.
7311 editor = self.editor
7313 editor = self.mesh.GetMeshEditPreviewer()
7314 segmentsRes = editor.MakePolyLine( segments, groupName )
7315 for i, seg in enumerate( segmentsRes ):
7316 segments[i].vector = seg.vector
7318 return editor.GetPreviewData()
7321 def MakeSlot(self, segmentGroup, width ):
7323 Create a slot of given width around given 1D elements lying on a triangle mesh.
7324 The slot is constructed by cutting faces by cylindrical surfaces made
7325 around each segment. Segments are expected to be created by MakePolyLine().
7328 FaceEdge's located at the slot boundary
7330 return self.editor.MakeSlot( segmentGroup, width )
7332 def GetFunctor(self, funcType ):
7334 Return a cached numerical functor by its type.
7337 funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7338 Note that not all items correspond to numerical functors.
7341 :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7344 fn = self.functors[ funcType._v ]
7346 fn = self.smeshpyD.GetFunctor(funcType)
7347 fn.SetMesh(self.mesh)
7348 self.functors[ funcType._v ] = fn
7351 def FunctorValue(self, funcType, elemId, isElem=True):
7353 Return value of a functor for a given element
7356 funcType: an item of :class:`SMESH.FunctorType` enum.
7357 elemId: element or node ID
7358 isElem: *elemId* is ID of element or node
7361 the functor value or zero in case of invalid arguments
7364 fn = self.GetFunctor( funcType )
7365 if fn.GetElementType() == self.GetElementType(elemId, isElem):
7366 val = fn.GetValue(elemId)
7371 def GetLength(self, elemId=None):
7373 Get length of given 1D elements or of all 1D mesh elements
7376 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.
7379 Sum of lengths of given elements
7384 length = self.smeshpyD.GetLength(self)
7385 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7386 length = self.smeshpyD.GetLength(elemId)
7389 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7391 length += self.smeshpyD.GetLength(obj)
7392 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7393 unRegister = genObjUnRegister()
7394 obj = self.GetIDSource( elemId )
7395 unRegister.set( obj )
7396 length = self.smeshpyD.GetLength( obj )
7398 length = self.FunctorValue(SMESH.FT_Length, elemId)
7401 def GetArea(self, elemId=None):
7403 Get area of given 2D elements or of all 2D mesh elements
7406 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.
7409 Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7414 area = self.smeshpyD.GetArea(self)
7415 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7416 area = self.smeshpyD.GetArea(elemId)
7419 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7421 area += self.smeshpyD.GetArea(obj)
7422 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7423 unRegister = genObjUnRegister()
7424 obj = self.GetIDSource( elemId )
7425 unRegister.set( obj )
7426 area = self.smeshpyD.GetArea( obj )
7428 area = self.FunctorValue(SMESH.FT_Area, elemId)
7431 def GetVolume(self, elemId=None):
7433 Get volume of given 3D elements or of all 3D mesh elements
7436 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.
7439 Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7444 volume= self.smeshpyD.GetVolume(self)
7445 elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7446 volume= self.smeshpyD.GetVolume(elemId)
7449 elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7451 volume+= self.smeshpyD.GetVolume(obj)
7452 elif isinstance(elemId, list) and isinstance(elemId[0], int):
7453 unRegister = genObjUnRegister()
7454 obj = self.GetIDSource( elemId )
7455 unRegister.set( obj )
7456 volume= self.smeshpyD.GetVolume( obj )
7458 volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7461 def GetAngle(self, node1, node2, node3 ):
7463 Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7466 node1,node2,node3: IDs of the three nodes
7469 Angle in radians [0,PI]. -1 if failure case.
7471 p1 = self.GetNodeXYZ( node1 )
7472 p2 = self.GetNodeXYZ( node2 )
7473 p3 = self.GetNodeXYZ( node3 )
7474 if p1 and p2 and p3:
7475 return self.smeshpyD.GetAngle( p1,p2,p3 )
7479 def GetMaxElementLength(self, elemId):
7481 Get maximum element length.
7484 elemId: mesh element ID
7487 element's maximum length value
7490 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7491 ftype = SMESH.FT_MaxElementLength3D
7493 ftype = SMESH.FT_MaxElementLength2D
7494 return self.FunctorValue(ftype, elemId)
7496 def GetAspectRatio(self, elemId):
7498 Get aspect ratio of 2D or 3D element.
7501 elemId: mesh element ID
7504 element's aspect ratio value
7507 if self.GetElementType(elemId, True) == SMESH.VOLUME:
7508 ftype = SMESH.FT_AspectRatio3D
7510 ftype = SMESH.FT_AspectRatio
7511 return self.FunctorValue(ftype, elemId)
7513 def GetWarping(self, elemId):
7515 Get warping angle of 2D element.
7518 elemId: mesh element ID
7521 element's warping angle value
7524 return self.FunctorValue(SMESH.FT_Warping, elemId)
7526 def GetWarping3D(self, elemId):
7528 Get warping angle of faces element of 3D elements.
7531 elemId: mesh element ID
7534 element's warping angle value
7537 return self.FunctorValue(SMESH.FT_Warping3D, elemId)
7539 def GetMinimumAngle(self, elemId):
7541 Get minimum angle of 2D element.
7544 elemId: mesh element ID
7547 element's minimum angle value
7550 return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7552 def GetTaper(self, elemId):
7554 Get taper of 2D element.
7557 elemId: mesh element ID
7560 element's taper value
7563 return self.FunctorValue(SMESH.FT_Taper, elemId)
7565 def GetSkew(self, elemId):
7567 Get skew of 2D element.
7570 elemId: mesh element ID
7573 element's skew value
7576 return self.FunctorValue(SMESH.FT_Skew, elemId)
7578 def GetScaledJacobian(self, elemId):
7580 Get the scaled jacobian of 3D element id
7583 elemId: mesh element ID
7589 return self.FunctorValue(SMESH.FT_ScaledJacobian, elemId)
7591 def GetMinMax(self, funType, meshPart=None):
7593 Return minimal and maximal value of a given functor.
7596 funType (SMESH.FunctorType): a functor type.
7597 Note that not all items of :class:`SMESH.FunctorType` corresponds
7598 to numerical functors.
7599 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7605 unRegister = genObjUnRegister()
7606 if isinstance( meshPart, list ):
7607 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7608 unRegister.set( meshPart )
7609 if isinstance( meshPart, Mesh ):
7610 meshPart = meshPart.mesh
7611 fun = self.GetFunctor( funType )
7614 if hasattr( meshPart, "SetMesh" ):
7615 meshPart.SetMesh( self.mesh ) # set mesh to filter
7616 hist = fun.GetLocalHistogram( 1, False, meshPart )
7618 hist = fun.GetHistogram( 1, False )
7620 return hist[0].min, hist[0].max
7623 pass # end of Mesh class
7625 def _copy_gmsh_param(dim, local_param, global_param):
7627 local_param.SetMaxSize(global_param.GetMaxSize())
7628 local_param.SetMinSize(global_param.GetMinSize())
7629 local_param.Set3DAlgo(global_param.Get3DAlgo())
7630 local_param.SetRecombineAll(global_param.GetRecombineAll())
7631 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7632 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7633 local_param.SetRemeshPara(global_param.GetRemeshPara())
7634 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7635 local_param.SetSizeFactor(global_param.GetSizeFactor())
7636 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7637 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7638 local_param.SetSecondOrder(global_param.GetSecondOrder())
7639 local_param.SetIs2d(global_param.GetIs2d())
7641 local_param.SetMaxSize(global_param.GetMaxSize())
7642 local_param.SetMinSize(global_param.GetMinSize())
7643 local_param.Set2DAlgo(global_param.Get2DAlgo())
7644 local_param.SetRecomb2DAlgo(global_param.GetRecomb2DAlgo())
7645 local_param.SetRecombineAll(global_param.GetRecombineAll())
7646 local_param.SetSubdivAlgo(global_param.GetSubdivAlgo())
7647 local_param.SetRemeshAlgo(global_param.GetRemeshAlgo())
7648 local_param.SetRemeshPara(global_param.GetRemeshPara())
7649 local_param.SetSmouthSteps(global_param.GetSmouthSteps())
7650 local_param.SetSizeFactor(global_param.GetSizeFactor())
7651 local_param.SetUseIncomplElem(global_param.GetUseIncomplElem())
7652 local_param.SetMeshCurvatureSize(global_param.GetMeshCurvatureSize())
7653 local_param.SetSecondOrder(global_param.GetSecondOrder())
7654 local_param.SetIs2d(global_param.GetIs2d())
7656 def _copy_netgen_param(dim, local_param, global_param):
7658 Create 1D/2D/3D netgen parameters from a NETGEN 1D2D3D parameter
7661 #TODO: More global conversion ? or let user define it
7662 local_param.NumberOfSegments(int(global_param.GetMaxSize()))
7664 local_param.SetMaxSize(global_param.GetMaxSize())
7665 local_param.SetMinSize(global_param.GetMinSize())
7666 local_param.SetOptimize(global_param.GetOptimize())
7667 local_param.SetFineness(global_param.GetFineness())
7668 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7669 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7670 #TODO: Why the 0.9 to have same results
7671 local_param.SetGrowthRate(global_param.GetGrowthRate()*0.9)
7672 local_param.SetChordalError(global_param.GetChordalError())
7673 local_param.SetChordalErrorEnabled(global_param.GetChordalErrorEnabled())
7674 local_param.SetUseSurfaceCurvature(global_param.GetUseSurfaceCurvature())
7675 local_param.SetUseDelauney(global_param.GetUseDelauney())
7676 local_param.SetQuadAllowed(global_param.GetQuadAllowed())
7677 local_param.SetWorstElemMeasure(global_param.GetWorstElemMeasure())
7678 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7679 local_param.SetNbThreads(global_param.GetNbThreads())
7681 local_param.SetMaxSize(global_param.GetMaxSize())
7682 local_param.SetMinSize(global_param.GetMinSize())
7683 local_param.SetOptimize(global_param.GetOptimize())
7684 local_param.SetCheckOverlapping(global_param.GetCheckOverlapping())
7685 local_param.SetCheckChartBoundary(global_param.GetCheckChartBoundary())
7686 local_param.SetFineness(global_param.GetFineness())
7687 local_param.SetNbSegPerEdge(global_param.GetNbSegPerEdge())
7688 local_param.SetNbSegPerRadius(global_param.GetNbSegPerRadius())
7689 local_param.SetGrowthRate(global_param.GetGrowthRate())
7690 local_param.SetNbThreads(global_param.GetNbThreads())
7693 def _shaperstudy2geom(geompyD, shaper_obj):
7695 Convertion of shaper object to geom object
7698 geompyD: geomBuilder instance
7699 shaper_obj: Shaper study object
7706 #Writing shaperstudy object into a brep file
7707 fid, tmp_file = tempfile.mkstemp(suffix='.brep')
7708 with open(fid, 'wb') as f:
7709 f.write(shaper_obj.GetShapeStream())
7710 # Reimporting brep file into geom
7711 real_geom = geompyD.ImportBREP(tmp_file)
7717 def _split_geom(geompyD, geom):
7719 Splitting geometry into n solids and a 2D/1D compound
7722 geompyD: geomBuilder instance
7723 geom: geometrical object for meshing
7726 compound containing all the 1D,2D elements
7730 # Splitting geometry into 3D elements and all the 2D/1D into one compound
7731 object_solids = geompyD.ExtractShapes(geom, geompyD.ShapeType["SOLID"],
7736 for solid in object_solids:
7738 geompyD.addToStudyInFather( geom, solid, 'Solid_{}'.format(isolid) )
7739 solids.append(solid)
7740 # If geom is a solid ExtractShapes will return nothin in that case geom is the solids
7746 solid_faces = geompyD.ExtractShapes(geom, geompyD.ShapeType["FACE"],
7748 for face in solid_faces:
7751 geompyD.addToStudyInFather(geom, face,
7752 'Face_{}'.format(iface))
7754 return faces, solids
7757 MULTITHREAD, MULTINODE = range(2)
7758 class ParallelismSettings:
7760 Defines the parameters for the parallelism of ParallelMesh
7762 def __init__(self, mesh):
7767 mesh: Instance of ParallelMesh
7769 if not(isinstance(mesh, ParallelMesh)):
7770 raise ValueError("mesh should be a ParallelMesh")
7775 class MTParallelismSettings(ParallelismSettings):
7777 Defines the parameters for the parallelism of ParallelMesh using MultiThreading
7779 def __init__(self, mesh):
7780 ParallelismSettings.__init__(self, mesh)
7782 # Multithreading methods
7783 def SetNbThreads(self, nbThreads):
7784 """ Set the number of threads for multithread """
7786 raise ValueError("Number of threads must be stricly greater than 1")
7788 self._mesh.mesh.SetNbThreads(nbThreads)
7790 def GetNbThreads(self):
7791 """ Get Number of threads """
7792 return self._mesh.mesh.GetNbThreads()
7795 """ str conversion """
7796 string = "\nParameter for MultiThreading parallelism:\n"
7797 string += "NbThreads: {}\n".format(self.GetNbThreads())
7802 class MNParallelismSettings(ParallelismSettings):
7804 Defines the parameters for the parallelism of ParallelMesh using MultiNodal
7806 def __init__(self, mesh):
7807 ParallelismSettings.__init__(self, mesh)
7809 def GetResource(self):
7810 """ Get the resource on which to run """
7811 return self._mesh.mesh.GetResource()
7813 def SetResource(self, resource):
7814 """ Set the resource on which to run """
7815 self._mesh.mesh.SetResource(resource)
7817 def SetNbProc(self, nbProc):
7818 """ Set the number of Processor for multinode """
7820 raise ValueError("Number of Proc must be stricly greater than 1")
7821 self._mesh.mesh.SetNbProc(nbProc)
7823 def GetNbProc(self):
7824 """ Get Number of Processor """
7825 return self._mesh.mesh.GetNbProc()
7827 def SetNbProcPerNode(self, nbProcPerNode):
7828 """ Set the number of Processor Per Node for multinode """
7829 if nbProcPerNode < 1:
7830 raise ValueError("Number of Processor Per Node must be stricly greater than 1")
7832 self._mesh.mesh.SetNbProcPerNode(nbProcPerNode)
7834 def GetNbProcPerNode(self):
7835 """ Get Number of Processor Per Node """
7836 return self._mesh.mesh.GetNbProcPerNode()
7838 def SetNbNode(self, nbNode):
7839 """ Set the number of Node for multinode """
7841 raise ValueError("Number of Node must be stricly greater than 1")
7842 self._mesh.mesh.SetNbNode(nbNode)
7844 def GetNbNode(self):
7845 """ Get Number of Node """
7846 return self._mesh.mesh.GetNbNode()
7848 def SetWcKey(self, wcKey):
7849 """ Set the number of Node for multinode """
7850 self._mesh.mesh.SetWcKey(wcKey)
7853 """ Get Number of Node """
7854 return self._mesh.mesh.GetWcKey()
7856 def SetWalltime(self, walltime):
7857 """ Set the number of Node for multinode """
7858 self._mesh.mesh.SetWalltime(walltime)
7860 def GetWalltime(self):
7861 """ Get Number of Node """
7862 return self._mesh.mesh.GetWalltime()
7865 """ str conversion """
7866 string = "\nParameter for MultiNode parallelism:\n"
7867 string += "Reource: {}\n".format(self.GetResource())
7868 string += "NbProc: {}\n".format(self.GetNbProc())
7869 string += "NbProcPerNode: {}\n".format(self.GetNbProcPerNode())
7870 string += "NbNode: {}\n".format(self.GetNbNode())
7871 string += "WcKey: {}\n".format(self.GetWcKey())
7872 string += "Walltime: {}\n".format(self.GetWalltime())
7877 class ParallelMesh(Mesh):
7879 Surcharge on Mesh for parallel computation of a mesh
7881 def __init__(self, smeshpyD, geompyD, geom, split_geom=True, name=0):
7883 Create a parallel mesh.
7886 smeshpyD: instance of smeshBuilder
7887 geompyD: instance of geomBuilder
7888 geom: geometrical object for meshing
7889 split_geom: If true will divide geometry on solids and 1D/2D
7890 coumpound and create the associated submeshes
7891 name: the name for the new mesh.
7894 an instance of class :class:`ParallelMesh`.
7897 if not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7898 raise ValueError("geom argument must be a geometry")
7902 shaper_object = SHAPERSTUDY.SHAPERSTUDY_ORB._objref_SHAPER_Object
7908 # If we have a shaper object converting it into geom (temporary solution)
7909 if isinstance(geom, shaper_object):
7910 self._geom_obj = _shaperstudy2geom(geompyD, geom)
7911 elif isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
7912 self._geom_obj = geom
7916 msg = "\nShaper was not compiled"
7917 raise Exception("Could not handle geom format {}.{} ".format(type(geom), msg))
7919 # Splitting geometry into one geom containing 1D and 2D elements and a
7920 # list of 3D elements
7921 super(ParallelMesh, self).__init__(smeshpyD, geompyD, self._geom_obj, name, parallel=True)
7924 self._faces, self._solids = _split_geom(geompyD, self._geom_obj)
7928 def _build_submeshes(self, mesher2D, mesher3D):
7930 Contruct the submeshes for a parallel use of smesh
7933 mesher2D: name of 2D mesher for 2D parallel compute (NETGEN)
7934 mesher3D: name of 3D mesher for 3D parallel compute (NETGEN or
7938 # Building global 2D mesher
7940 if mesher3D == "NETGEN":
7941 algo2D = "NETGEN_2D"
7942 elif mesher3D == "GMSH":
7945 raise ValueError("mesher3D should be either NETGEN or GMSH")
7947 self._algo2d = self.Triangle(geom=self._geom_obj, algo=algo2D)
7951 #Means that we want to mesh face of solids in parallel and not
7954 #For the moment use AutomaticLength based on finesse
7955 # TODO: replace by input hypothesis
7956 self._algo1d = self.Segment(geom=self._geom_obj)
7958 for face_id, face in enumerate(self._faces):
7959 name = "face_{}".format(face_id)
7960 algo2d = self.Triangle(geom=face, algo="NETGEN_2D_Remote")
7961 self._algo2d.append(algo2d)
7965 for solid_id, solid in enumerate(self._solids):
7966 name = "Solid_{}".format(solid_id)
7967 if ( mesher3D == "NETGEN" ):
7968 algo3d = self.Tetrahedron(geom=solid, algo="NETGEN_3D_Remote")
7969 self._algo3d.append(algo3d)
7970 elif ( mesher3D == "GMSH" ):
7971 algo3d = self.Tetrahedron(geom=solid, algo="GMSH_3D_Remote")
7972 self._algo3d.append(algo3d)
7974 def GetNbSolids(self):
7976 Return the number of 3D solids
7978 return len(self._solids)
7980 def GetNbFaces(self):
7982 Return the number of 2D faces
7984 return len(self._faces)
7986 def GetParallelismMethod(self):
7987 """ Get the parallelims method """
7988 return self.mesh.GetParallelismMethod()
7990 def SetParallelismMethod(self, method):
7991 """ Set the parallelims method """
7992 if method not in [MULTITHREAD , MULTINODE]:
7993 raise ValueError("Parallelism method can only be 0:MultiThread or 1:MultiNode")
7995 self.mesh.SetParallelismMethod(method)
7997 if method == MULTITHREAD:
7998 self._param = MTParallelismSettings(self)
8000 self._param = MNParallelismSettings(self)
8002 def GetParallelismSettings(self):
8004 Return class to set parameters for the parallelism
8006 if self._param is None:
8007 raise Exception("You need to set Parallelism method first (SetParallelismMethod)")
8010 def AddGlobalHypothesis(self, hyp):
8012 Split hypothesis to apply it to all the submeshes:
8014 - each of the 3D solids
8017 hyp: a hypothesis to assign
8020 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
8021 copy_param = _copy_netgen_param
8023 elif isinstance(hyp, GMSHPlugin._objref_GMSHPlugin_Hypothesis):
8024 copy_param = _copy_gmsh_param
8027 raise ValueError("param must come from NETGENPlugin or GMSHPlugin")
8029 self.mesh.SetParallelismDimension(3)
8030 self._build_submeshes(None, mesher3D)
8032 param2d = self._algo2d.Parameters()
8033 copy_param(2, param2d, hyp)
8035 for algo3d in self._algo3d:
8036 param3d = algo3d.Parameters()
8037 copy_param(3, param3d, hyp)
8039 def Add2DGlobalHypothesis(self, hyp):
8041 Split hypothesis to apply it to all the submeshes:
8043 - each of the 2D faces
8046 hyp: a hypothesis to assign
8049 if isinstance(hyp, NETGENPlugin._objref_NETGENPlugin_Hypothesis):
8050 copy_param = _copy_netgen_param
8053 raise ValueError("param must come from NETGENPlugin")
8055 self.mesh.SetParallelismDimension(2)
8056 self._build_submeshes(mesher2D, None)
8058 param1d = self._algo1d
8059 copy_param(1, param1d, hyp)
8061 for algo2d in self._algo2d:
8062 param2d = algo2d.Parameters()
8063 copy_param(2, param2d, hyp)
8065 pass # End of ParallelMesh
8067 class meshProxy(SMESH._objref_SMESH_Mesh):
8069 Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
8070 with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
8072 def __init__(self,*args):
8073 SMESH._objref_SMESH_Mesh.__init__(self,*args)
8074 def __deepcopy__(self, memo=None):
8075 new = self.__class__(self)
8077 def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
8078 if len( args ) == 3:
8079 args += SMESH.ALL_NODES, True
8080 return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
8081 def ExportToMEDX(self, *args): # function removed
8082 print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
8083 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8084 SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
8085 def ExportToMED(self, *args): # function removed
8086 print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
8087 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8089 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8091 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8092 def ExportPartToMED(self, *args): # 'version' parameter removed
8093 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8094 SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
8095 def ExportMED(self, *args): # signature of method changed
8096 #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
8098 while len(args2) < 5: # !!!! nb of parameters for ExportToMED IDL's method
8100 SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
8101 def ExportUNV(self, *args): # renumber arg added
8102 if len( args ) == 1:
8104 return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
8105 def ExportDAT(self, *args): # renumber arg added
8106 if len( args ) == 1:
8108 return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
8110 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
8113 class parallelMeshProxy(SMESH._objref_SMESH_ParallelMesh):
8114 def __init__(self,*args):
8115 SMESH._objref_SMESH_ParallelMesh.__init__(self,*args)
8116 def __deepcopy__(self, memo=None):
8117 new = self.__class__(self)
8119 omniORB.registerObjref(SMESH._objref_SMESH_ParallelMesh._NP_RepositoryId, parallelMeshProxy)
8123 class submeshProxy(SMESH._objref_SMESH_subMesh):
8126 Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
8128 def __init__(self,*args):
8129 SMESH._objref_SMESH_subMesh.__init__(self,*args)
8131 def __deepcopy__(self, memo=None):
8132 new = self.__class__(self)
8135 def Compute(self,refresh=False):
8137 Compute the sub-mesh and return the status of the computation
8140 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
8145 This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
8146 :meth:`smeshBuilder.Mesh.GetSubMesh`.
8150 self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
8152 ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
8154 if salome.sg.hasDesktop():
8155 if refresh: salome.sg.updateObjBrowser()
8160 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
8163 class meshEditor(SMESH._objref_SMESH_MeshEditor):
8165 Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
8166 compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
8169 def __init__(self,*args):
8170 SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
8172 def __getattr__(self, name ): # method called if an attribute not found
8173 if not self.mesh: # look for name() method in Mesh class
8174 self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
8175 if hasattr( self.mesh, name ):
8176 return getattr( self.mesh, name )
8177 if name == "ExtrusionAlongPathObjX":
8178 return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
8179 print("meshEditor: attribute '%s' NOT FOUND" % name)
8181 def __deepcopy__(self, memo=None):
8182 new = self.__class__(self)
8184 def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
8185 if len( args ) == 1: args += False,
8186 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
8187 def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
8188 if len( args ) == 2: args += False,
8189 return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
8190 def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
8191 if len( args ) == 1:
8192 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
8193 NodesToKeep = args[1]
8194 AvoidMakingHoles = args[2] if len( args ) == 3 else False
8195 unRegister = genObjUnRegister()
8197 if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
8198 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
8199 if not isinstance( NodesToKeep, list ):
8200 NodesToKeep = [ NodesToKeep ]
8201 return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
8203 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
8205 class Pattern(SMESH._objref_SMESH_Pattern):
8207 Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
8208 variables in some methods
8211 def LoadFromFile(self, patternTextOrFile ):
8212 text = patternTextOrFile
8213 if os.path.exists( text ):
8214 text = open( patternTextOrFile ).read()
8216 return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
8218 def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
8219 decrFun = lambda i: i-1
8220 theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
8221 theMesh.SetParameters(Parameters)
8222 return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
8224 def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
8225 decrFun = lambda i: i-1
8226 theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
8227 theMesh.SetParameters(Parameters)
8228 return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
8230 def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
8231 if isinstance( mesh, Mesh ):
8232 mesh = mesh.GetMesh()
8233 return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
8235 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
8237 Registering the new proxy for Pattern
8242 Private class used to bind methods creating algorithms to the class Mesh
8245 def __init__(self, method):
8247 self.defaultAlgoType = ""
8248 self.algoTypeToClass = {}
8249 self.method = method
8251 def add(self, algoClass):
8253 Store a python class of algorithm
8255 if inspect.isclass(algoClass) and \
8256 hasattr( algoClass, "algoType"):
8257 self.algoTypeToClass[ algoClass.algoType ] = algoClass
8258 if not self.defaultAlgoType and \
8259 hasattr( algoClass, "isDefault") and algoClass.isDefault:
8260 self.defaultAlgoType = algoClass.algoType
8261 #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
8263 def copy(self, mesh):
8265 Create a copy of self and assign mesh to the copy
8268 other = algoCreator( self.method )
8269 other.defaultAlgoType = self.defaultAlgoType
8270 other.algoTypeToClass = self.algoTypeToClass
8274 def __call__(self,algo="",geom=0,*args):
8276 Create an instance of algorithm
8280 if isinstance( algo, str ):
8282 elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
8283 not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
8288 if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
8290 elif not algoType and isinstance( geom, str ):
8295 if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
8297 elif isinstance( arg, str ) and not algoType:
8300 import traceback, sys
8301 msg = "Warning. Unexpected argument in mesh.%s() ---> %s" % ( self.method, arg )
8302 sys.stderr.write( msg + '\n' )
8303 tb = traceback.extract_stack(None,2)
8304 traceback.print_list( [tb[0]] )
8306 algoType = self.defaultAlgoType
8307 if not algoType and self.algoTypeToClass:
8308 algoType = sorted( self.algoTypeToClass.keys() )[0]
8309 if algoType in self.algoTypeToClass:
8310 #print("Create algo",algoType)
8311 return self.algoTypeToClass[ algoType ]( self.mesh, shape )
8312 raise RuntimeError( "No class found for algo type %s" % algoType)
8315 class hypMethodWrapper:
8317 Private class used to substitute and store variable parameters of hypotheses.
8320 def __init__(self, hyp, method):
8322 self.method = method
8323 #print("REBIND:", method.__name__)
8326 def __call__(self,*args):
8328 call a method of hypothesis with calling SetVarParameter() before
8332 return self.method( self.hyp, *args ) # hypothesis method with no args
8334 #print("MethWrapper.__call__", self.method.__name__, args)
8336 parsed = ParseParameters(*args) # replace variables with their values
8337 self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
8338 result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
8339 except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
8340 # maybe there is a replaced string arg which is not variable
8341 result = self.method( self.hyp, *args )
8342 except ValueError as detail: # raised by ParseParameters()
8344 result = self.method( self.hyp, *args )
8345 except omniORB.CORBA.BAD_PARAM:
8346 raise ValueError(detail) # wrong variable name
8351 class genObjUnRegister:
8353 A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
8356 def __init__(self, genObj=None):
8357 self.genObjList = []
8361 def set(self, genObj):
8362 "Store one or a list of of SALOME.GenericObj'es"
8363 if isinstance( genObj, list ):
8364 self.genObjList.extend( genObj )
8366 self.genObjList.append( genObj )
8370 for genObj in self.genObjList:
8371 if genObj and hasattr( genObj, "UnRegister" ):
8374 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
8376 Bind methods creating mesher plug-ins to the Mesh class
8379 # print("pluginName: ", pluginName)
8380 pluginBuilderName = pluginName + "Builder"
8382 exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
8383 except Exception as e:
8384 from salome_utils import verbose
8385 if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
8387 exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
8388 plugin = eval( pluginBuilderName )
8389 # print(" plugin:" , str(plugin))
8391 # add methods creating algorithms to Mesh
8392 for k in dir( plugin ):
8393 if k[0] == '_': continue
8394 algo = getattr( plugin, k )
8395 #print(" algo:", str(algo))
8396 if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
8397 #print(" meshMethod:" , str(algo.meshMethod))
8398 if not hasattr( Mesh, algo.meshMethod ):
8399 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
8401 _mmethod = getattr( Mesh, algo.meshMethod )
8402 if hasattr( _mmethod, "add" ):