Salome HOME
Splitting gen compute seq/para + clean up + remove int argument + solve bug (commente...
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
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.
7 #
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.
12 #
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
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 #  File   : smeshBuilder.py
20 #  Author : Francis KLOSS, OCC
21 #  Module : SMESH
22
23 import salome
24 from salome.geom import geomBuilder
25
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
40
41 from SMESH import *
42 from salome.smesh.smesh_algorithm import Mesh_Algorithm
43 from StdMeshers import BlockCS
44
45 import SALOME
46 import SALOMEDS
47 import os
48 import inspect
49
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
52 # defined
53 #
54 try:
55     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
56 except TypeError:
57     def enumitem_eq(self, other):
58         try:
59             if isinstance(other, omniORB.EnumItem):
60                 if other._parent_id == self._parent_id:
61                     return self._v == other._v
62                 else:
63                     return self._parent_id == other._parent_id
64             else:
65                 return id(self) == id(other)
66         except:
67             return id(self) == id(other)
68
69     def enumitem_lt(self, other):
70         try:
71             if isinstance(other, omniORB.EnumItem):
72                 if other._parent_id == self._parent_id:
73                     return self._v < other._v
74                 else:
75                     return self._parent_id < other._parent_id
76             else:
77                 return id(self) < id(other)
78         except:
79             return id(self) < id(other)
80
81     def enumitem_le(self, other):
82         try:
83             if isinstance(other, omniORB.EnumItem):
84                 if other._parent_id == self._parent_id:
85                     return self._v <= other._v
86                 else:
87                     return self._parent_id <= other._parent_id
88             else:
89                 return id(self) <= id(other)
90         except:
91             return id(self) <= id(other)
92
93     def enumitem_gt(self, other):
94         try:
95             if isinstance(other, omniORB.EnumItem):
96                 if other._parent_id == self._parent_id:
97                     return self._v > other._v
98                 else:
99                     return self._parent_id > other._parent_id
100             else:
101                 return id(self) > id(other)
102         except:
103             return id(self) > id(other)
104
105     def enumitem_ge(self, other):
106         try:
107             if isinstance(other, omniORB.EnumItem):
108                 if other._parent_id == self._parent_id:
109                     return self._v >= other._v
110                 else:
111                     return self._parent_id >= other._parent_id
112             else:
113                 return id(self) >= id(other)
114         except:
115             return id(self) >= id(other)
116
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
122
123
124 class MeshMeta(type):
125     """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
126     """
127     def __instancecheck__(cls, inst):
128         """Implement isinstance(inst, cls)."""
129         return any(cls.__subclasscheck__(c)
130                    for c in {type(inst), inst.__class__})
131
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__)
135
136 def DegreesToRadians(AngleInDegrees):
137     """Convert an angle from degrees to radians
138     """
139     from math import pi
140     return AngleInDegrees * pi / 180.0
141
142 import salome_notebook
143 notebook = salome_notebook.notebook
144 # Salome notebook variable separator
145 var_separator = ":"
146
147 def ParseParameters(*args):
148     """
149     Return list of variable values from salome notebook.
150     The last argument, if is callable, is used to modify values got from notebook
151     """
152     Result = []
153     Parameters = ""
154     hasVariables = False
155     varModifFun=None
156     if args and callable(args[-1]):
157         args, varModifFun = args[:-1], args[-1]
158     for parameter in args:
159
160         Parameters += str(parameter) + var_separator
161
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)
167             hasVariables = True
168             if varModifFun:
169                 parameter = varModifFun(parameter)
170                 pass
171             pass
172         Result.append(parameter)
173
174         pass
175     Parameters = Parameters[:-1]
176     Result.append( Parameters )
177     Result.append( hasVariables )
178     return Result
179
180 def ParseAngles(*args):
181     """
182     Parse parameters while converting variables to radians
183     """
184     return ParseParameters( *( args + (DegreesToRadians, )))
185
186 def __initPointStruct(point,*args):
187     """
188     Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
189     Parameters are stored in PointStruct.parameters attribute
190     """
191     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
192     pass
193 SMESH.PointStruct.__init__ = __initPointStruct
194
195 def __initAxisStruct(ax,*args):
196     """
197     Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
198     Parameters are stored in AxisStruct.parameters attribute
199     """
200     if len( args ) != 6:
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)
203     pass
204 SMESH.AxisStruct.__init__ = __initAxisStruct
205
206 smeshPrecisionConfusion = 1.e-07
207 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
208     """Compare real values using smeshPrecisionConfusion as tolerance
209     """
210     if abs(val1 - val2) < tol:
211         return True
212     return False
213
214 NO_NAME = "NoName"
215
216 def GetName(obj):
217     """
218     Return a name of an object
219
220     Returns:
221         object name
222     """
223     if obj:
224         # object not null
225         if isinstance(obj, SALOMEDS._objref_SObject):
226             # study object
227             return obj.GetName()
228         try:
229             ior  = salome.orb.object_to_string(obj)
230         except:
231             ior = None
232         if ior:
233             sobj = salome.myStudy.FindObjectIOR(ior)
234             if sobj:
235                 return sobj.GetName()
236             if hasattr(obj, "GetName"):
237                 # unknown CORBA object, having GetName() method
238                 return obj.GetName()
239             else:
240                 # unknown CORBA object, no GetName() method
241                 return NO_NAME
242             pass
243         if hasattr(obj, "GetName"):
244             # unknown non-CORBA object, having GetName() method
245             return obj.GetName()
246         pass
247     raise RuntimeError("Null or invalid object")
248
249 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
250     """
251     Print error message if a hypothesis was not assigned.
252     """
253     if isAlgo:
254         hypType = "algorithm"
255     else:
256         hypType = "hypothesis"
257         pass
258     reason = ""
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:
285         pass
286     else:
287         return
288     where = geomName
289     if where:
290         where = '"%s"' % geomName
291         if mesh:
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 ))
297     elif where:
298         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
299     else:
300         print('"%s" was not assigned : %s' %( hypName, reason ))
301         pass
302
303 def AssureGeomPublished(mesh, geom, name=''):
304     """
305     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
306     """
307     if not mesh.smeshpyD.IsEnablePublish():
308         return
309     if not hasattr( geom, "GetShapeType" ):
310         return
311     if not geom.GetStudyEntry():
312         ## get a name
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)
316         if not name:
317             name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
318         ## publish
319         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
320     return
321
322 # def FirstVertexOnCurve(mesh, edge):
323 #     """
324 #     Returns:
325 #         the first vertex of a geometrical edge by ignoring orientation
326 #     """
327 #     return mesh.geompyD.GetVertexByIndex( edge, 0, False )
328
329
330 smeshInst = None
331 """
332 Warning:
333     smeshInst is a singleton
334 """
335 engine = None
336 doLcc = False
337 created = False
338
339 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
340     """
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.
344     """
345
346     # MirrorType enumeration
347     POINT = SMESH_MeshEditor.POINT
348     AXIS =  SMESH_MeshEditor.AXIS
349     PLANE = SMESH_MeshEditor.PLANE
350
351     # Smooth_Method enumeration
352     LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
353     CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
354
355     PrecisionConfusion = smeshPrecisionConfusion
356
357     # TopAbs_State enumeration
358     [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
359
360     # Methods of splitting a hexahedron into tetrahedra
361     Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
362
363     def __new__(cls, *args):
364         global engine
365         global smeshInst
366         global doLcc
367         #print("==== __new__", engine, smeshInst, doLcc)
368
369         if smeshInst is None:
370             # smesh engine is either retrieved from engine, or created
371             smeshInst = engine
372             # Following test avoids a recursive loop
373             if doLcc:
374                 if smeshInst is not None:
375                     # smesh engine not created: existing engine found
376                     doLcc = False
377                 if doLcc:
378                     doLcc = False
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" )
384             else:
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)
390                 else:
391                     # smesh engine not created: existing engine found
392                     #print("==== existing ", engine, smeshInst, doLcc)
393                     pass
394             #print("====1 ", smeshInst)
395             return smeshInst
396
397         #print("====2 ", smeshInst)
398         return smeshInst
399
400     def __init__(self, *args):
401         global created
402         #print("--------------- smeshbuilder __init__ ---", created)
403         if not created:
404             created = True
405             SMESH._objref_SMESH_Gen.__init__(self, *args)
406
407
408     def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
409         """
410         Dump component to the Python script.
411         This method overrides IDL function to allow default values for the parameters.
412         """
413
414         return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
415
416     def SetDumpPythonHistorical(self, isHistorical):
417         """
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
423         """
424
425         if isHistorical: val = "true"
426         else:            val = "false"
427         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
428
429     def init_smesh(self,geompyD = None):
430         """
431         Set Geometry component
432         """
433         #print("init_smesh")
434         self.UpdateStudy(geompyD)
435         notebook.myStudy = salome.myStudy
436
437     def Mesh(self, obj=0, name=0):
438         """
439         Create a mesh. This mesh can be either
440
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.
444
445         Parameters:
446             obj: either
447
448                    1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
449                       ::
450
451                         salome.myStudy.FindObjectID("0:1:2:3").GetObject()
452
453                    2. a geometrical object for meshing
454                    3. none.
455             name: the name for the new mesh.
456
457         Returns:
458             an instance of class :class:`Mesh`.
459         """
460
461         if isinstance(obj,str):
462             obj,name = name,obj
463         return Mesh(self, self.geompyD, obj, name)
464
465     def RemoveMesh( self, mesh ):
466         """
467         Delete a mesh
468         """
469         if isinstance( mesh, Mesh ):
470             mesh = mesh.GetMesh()
471             pass
472         if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
473             raise TypeError("%s is not a mesh" % mesh )
474         so = salome.ObjectToSObject( mesh )
475         if so:
476             sb = salome.myStudy.NewBuilder()
477             sb.RemoveObjectWithChildren( so )
478         else:
479             mesh.UnRegister()
480             pass
481         return
482
483     def EnumToLong(self,theItem):
484         """
485         Return a long value from enumeration
486         """
487
488         return theItem._v
489
490     def ColorToString(self,c):
491         """
492         Convert SALOMEDS.Color to string.
493         To be used with filters.
494
495         Parameters:
496             c: color value (SALOMEDS.Color)
497
498         Returns:
499             a string representation of the color.
500         """
501
502         val = ""
503         if isinstance(c, SALOMEDS.Color):
504             val = "%s;%s;%s" % (c.R, c.G, c.B)
505         elif isinstance(c, str):
506             val = c
507         else:
508             raise ValueError("Color value should be of string or SALOMEDS.Color type")
509         return val
510
511     def GetPointStruct(self,theVertex):
512         """
513         Get :class:`SMESH.PointStruct` from vertex
514
515         Parameters:
516                 theVertex (GEOM.GEOM_Object): vertex
517
518         Returns:
519                 :class:`SMESH.PointStruct`
520         """
521         geompyD = theVertex.GetGen()
522         [x, y, z] = geompyD.PointCoordinates(theVertex)
523         return PointStruct(x,y,z)
524
525     def GetDirStruct(self,theVector):
526         """
527         Get :class:`SMESH.DirStruct` from vector
528
529         Parameters:
530                 theVector (GEOM.GEOM_Object): vector
531
532         Returns:
533                 :class:`SMESH.DirStruct`
534         """
535         geompyD = theVector.GetGen()
536         vertices = geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
537         if(len(vertices) != 2):
538             print("Error: vector object is incorrect.")
539             return None
540         p1 = geompyD.PointCoordinates(vertices[0])
541         p2 = geompyD.PointCoordinates(vertices[1])
542         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
543         dirst = DirStruct(pnt)
544         return dirst
545
546     def MakeDirStruct(self,x,y,z):
547         """
548         Make :class:`SMESH.DirStruct` from a triplet of floats
549
550         Parameters:
551                 x,y,z (float): vector components
552
553         Returns:
554                 :class:`SMESH.DirStruct`
555         """
556
557         pnt = PointStruct(x,y,z)
558         return DirStruct(pnt)
559
560     def GetAxisStruct(self,theObj):
561         """
562         Get :class:`SMESH.AxisStruct` from a geometrical object
563
564         Parameters:
565             theObj (GEOM.GEOM_Object): line or plane
566
567         Returns:
568             :class:`SMESH.AxisStruct`
569         """
570         import GEOM
571         geompyD = theObj.GetGen()
572         edges = geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
573         axis = None
574         if len(edges) > 1:
575             vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
576             vertex3, vertex4 = geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
577             vertex1 = geompyD.PointCoordinates(vertex1)
578             vertex2 = geompyD.PointCoordinates(vertex2)
579             vertex3 = geompyD.PointCoordinates(vertex3)
580             vertex4 = geompyD.PointCoordinates(vertex4)
581             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
582             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
583             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] ]
584             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
585             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
586         elif len(edges) == 1:
587             vertex1, vertex2 = geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588             p1 = geompyD.PointCoordinates( vertex1 )
589             p2 = geompyD.PointCoordinates( vertex2 )
590             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
591             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
592         elif theObj.GetShapeType() == GEOM.VERTEX:
593             x,y,z = geompyD.PointCoordinates( theObj )
594             axis = AxisStruct( x,y,z, 1,0,0,)
595             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
596         return axis
597
598     # From SMESH_Gen interface:
599     # ------------------------
600
601     def SetName(self, obj, name):
602         """
603         Set the given name to an object
604
605         Parameters:
606                 obj: the object to rename
607                 name: a new object name
608         """
609
610         if isinstance( obj, Mesh ):
611             obj = obj.GetMesh()
612         elif isinstance( obj, Mesh_Algorithm ):
613             obj = obj.GetAlgorithm()
614         ior  = salome.orb.object_to_string(obj)
615         SMESH._objref_SMESH_Gen.SetName(self, ior, name)
616
617     def SetEmbeddedMode( self,theMode ):
618         """
619         Set the current mode
620         """
621
622         SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
623
624     def IsEmbeddedMode(self):
625         """
626         Get the current mode
627         """
628
629         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
630
631     def UpdateStudy( self, geompyD = None  ):
632         """
633         Update the current study. Calling UpdateStudy() allows to
634         update meshes at switching GEOM->SMESH
635         """
636         #self.UpdateStudy()
637         if not geompyD:
638             from salome.geom import geomBuilder
639             geompyD = geomBuilder.geom
640             if not geompyD:
641                 geompyD = geomBuilder.New()
642             pass
643         self.geompyD=geompyD
644         self.SetGeomEngine(geompyD)
645         SMESH._objref_SMESH_Gen.UpdateStudy(self)
646         sb = salome.myStudy.NewBuilder()
647         sc = salome.myStudy.FindComponent("SMESH")
648         if sc:
649             sb.LoadWith(sc, self)
650         pass
651
652     def SetEnablePublish( self, theIsEnablePublish ):
653         """
654         Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
655         switch **off** publishing in the Study of mesh objects.
656         """
657        #self.SetEnablePublish(theIsEnablePublish)
658         SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
659         global notebook
660         notebook = salome_notebook.NoteBook( theIsEnablePublish )
661
662
663     def CreateMeshesFromUNV( self,theFileName ):
664         """
665         Create a Mesh object importing data from the given UNV file
666
667         Returns:
668                 an instance of class :class:`Mesh`
669         """
670
671         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
672         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
673         return aMesh
674
675     def CreateMeshesFromMED( self,theFileName ):
676         """
677         Create a Mesh object(s) importing data from the given MED file
678
679         Returns:
680                 a tuple ( list of class :class:`Mesh` instances,
681                 :class:`SMESH.DriverMED_ReadStatus` )
682         """
683
684         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
685         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
686         return aMeshes, aStatus
687
688     def CreateMeshesFromSTL( self, theFileName ):
689         """
690         Create a Mesh object importing data from the given STL file
691
692         Returns:
693                 an instance of class :class:`Mesh`
694         """
695
696         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
697         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
698         return aMesh
699
700     def CreateMeshesFromCGNS( self, theFileName ):
701         """
702         Create Mesh objects importing data from the given CGNS file
703
704         Returns:
705                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
706         """
707
708         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
709         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710         return aMeshes, aStatus
711
712     def CreateMeshesFromGMF( self, theFileName ):
713         """
714         Create a Mesh object importing data from the given GMF file.
715         GMF files must have .mesh extension for the ASCII format and .meshb for
716         the binary format.
717
718         Returns:
719                 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
720         """
721
722         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
723                                                                         theFileName,
724                                                                         True)
725         if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
726         return Mesh(self, self.geompyD, aSmeshMesh), error
727
728     def Concatenate( self, meshes, uniteIdenticalGroups,
729                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
730                      name = "", meshToAppendTo = None):
731         """
732         Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
733         All groups of input meshes will be present in the new mesh.
734
735         Parameters:
736                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
737                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
738                 mergeNodesAndElements: if True, equal nodes and elements are merged
739                 mergeTolerance: tolerance for merging nodes
740                 allGroups: forces creation of groups corresponding to every input mesh
741                 name: name of a new mesh
742                 meshToAppendTo: a mesh to append all given meshes
743
744         Returns:
745                 an instance of class :class:`Mesh`
746
747         See also:
748                 :meth:`Mesh.Append`
749         """
750
751         if not meshes: return None
752         if not isinstance( meshes, list ):
753             meshes = [ meshes ]
754         for i,m in enumerate( meshes ):
755             if isinstance( m, Mesh ):
756                 meshes[i] = m.GetMesh()
757         mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
758         if hasattr(meshes[0], "SetParameters"):
759             meshes[0].SetParameters( Parameters )
760         else:
761             meshes[0].GetMesh().SetParameters( Parameters )
762         if isinstance( meshToAppendTo, Mesh ):
763             meshToAppendTo = meshToAppendTo.GetMesh()
764         if allGroups:
765             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
766                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
767                 mergeTolerance,meshToAppendTo )
768         else:
769             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
770                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
771                 mergeTolerance,meshToAppendTo )
772
773         aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
774         return aMesh
775
776     def CreateDualMesh( self, mesh, meshName, adaptToShape):
777         """
778         Create a dual of a mesh.
779
780         Parameters:
781                 mesh: Tetrahedron mesh
782                         :class:`mesh, <SMESH.SMESH_IDSource>`.
783
784                 meshName: a name of the new mesh
785                 adpatToShape: if true project boundary points on shape
786
787         Returns:
788                 an instance of class :class:`Mesh`
789         """
790         if isinstance( mesh, Mesh ):
791             mesh = mesh.GetMesh()
792         print("calling createdualmesh from Python")
793         dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape)
794         return Mesh(self, self.geompyD, dualMesh)
795
796
797     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
798         """
799         Create a mesh by copying a part of another mesh.
800
801         Parameters:
802                 meshPart: a part of mesh to copy, either
803                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
804                         To copy nodes or elements not forming any mesh object,
805                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
806                 meshName: a name of the new mesh
807                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
808                 toKeepIDs: to preserve order of the copied elements or not
809
810         Returns:
811                 an instance of class :class:`Mesh`
812         """
813
814         if isinstance( meshPart, Mesh ):
815             meshPart = meshPart.GetMesh()
816         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
817         return Mesh(self, self.geompyD, mesh)
818
819     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
820                           toReuseHypotheses=True, toCopyElements=True):
821         """
822         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
823         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
824         To facilitate and speed up the operation, consider using
825         "Set presentation parameters and sub-shapes from arguments" option in
826         a dialog of geometrical operation used to create the new geometry.
827
828         Parameters:
829                 sourceMesh: the mesh to copy definition of.
830                 newGeom: the new geometry.
831                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
832                 toCopyGroups: to create groups in the new mesh.
833                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
834                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of
835                                 *sourceMesh*.
836         Returns:
837                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
838                 *invalidEntries* are study entries of objects whose
839                 counterparts are not found in the *newGeom*, followed by entries
840                 of mesh sub-objects that are invalid because they depend on a not found
841                 preceding sub-shape
842         """
843         if isinstance( sourceMesh, Mesh ):
844             sourceMesh = sourceMesh.GetMesh()
845
846         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
847            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
848                                                      toCopyGroups,
849                                                      toReuseHypotheses,
850                                                      toCopyElements)
851         return ( ok, Mesh(self, self.geompyD, newMesh),
852                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
853
854     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
855         """
856         Return IDs of sub-shapes
857
858         Parameters:
859                 theMainObject (GEOM.GEOM_Object): a shape
860                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
861         Returns:
862                 the list of integer values
863         """
864
865         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
866
867     def GetPattern(self):
868         """
869         Create a pattern mapper.
870
871         Returns:
872                 an instance of :class:`SMESH.SMESH_Pattern`
873
874         :ref:`Example of Patterns usage <tui_pattern_mapping>`
875         """
876
877         return SMESH._objref_SMESH_Gen.GetPattern(self)
878
879     def SetBoundaryBoxSegmentation(self, nbSegments):
880         """
881         Set number of segments per diagonal of boundary box of geometry, by which
882         default segment length of appropriate 1D hypotheses is defined in GUI.
883         Default value is 10.
884         """
885
886         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
887
888     # Filtering. Auxiliary functions:
889     # ------------------------------
890
891     def GetEmptyCriterion(self):
892         """
893         Create an empty criterion
894
895         Returns:
896                 :class:`SMESH.Filter.Criterion`
897         """
898
899         Type = self.EnumToLong(FT_Undefined)
900         Compare = self.EnumToLong(FT_Undefined)
901         Threshold = 0
902         ThresholdStr = ""
903         ThresholdID = ""
904         UnaryOp = self.EnumToLong(FT_Undefined)
905         BinaryOp = self.EnumToLong(FT_Undefined)
906         Tolerance = 1e-07
907         TypeOfElement = ALL
908         Precision = -1 ##@1e-07
909         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
910                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
911
912     def GetCriterion(self,elementType,
913                      CritType,
914                      Compare = FT_EqualTo,
915                      Threshold="",
916                      UnaryOp=FT_Undefined,
917                      BinaryOp=FT_Undefined,
918                      Tolerance=1e-07):
919         """
920         Create a criterion by the given parameters
921         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
922
923         Parameters:
924                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
925                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
926                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
927                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
928                 Threshold: the threshold value (range of ids as string, shape, numeric)
929                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
930                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
931                         SMESH.FT_Undefined
932                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
933                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
934
935         Returns:
936                 :class:`SMESH.Filter.Criterion`
937
938         Example: :ref:`combining_filters`
939         """
940
941         if not CritType in SMESH.FunctorType._items:
942             raise TypeError("CritType should be of SMESH.FunctorType")
943         aCriterion               = self.GetEmptyCriterion()
944         aCriterion.TypeOfElement = elementType
945         aCriterion.Type          = self.EnumToLong(CritType)
946         aCriterion.Tolerance     = Tolerance
947
948         aThreshold = Threshold
949
950         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
951             aCriterion.Compare = self.EnumToLong(Compare)
952         elif Compare == "=" or Compare == "==":
953             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
954         elif Compare == "<":
955             aCriterion.Compare = self.EnumToLong(FT_LessThan)
956         elif Compare == ">":
957             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
958         elif Compare != FT_Undefined:
959             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
960             aThreshold = Compare
961
962         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
963                         FT_BelongToCylinder, FT_LyingOnGeom]:
964             # Check that Threshold is GEOM object
965             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
966                 aCriterion.ThresholdStr = GetName(aThreshold)
967                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
968                 if not aCriterion.ThresholdID:
969                     name = aCriterion.ThresholdStr
970                     if not name:
971                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
972                     geompyD = aThreshold.GetGen()
973                     aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
974             # or a name of GEOM object
975             elif isinstance( aThreshold, str ):
976                 aCriterion.ThresholdStr = aThreshold
977             else:
978                 raise TypeError("The Threshold should be a shape.")
979             if isinstance(UnaryOp,float):
980                 aCriterion.Tolerance = UnaryOp
981                 UnaryOp = FT_Undefined
982                 pass
983         elif CritType == FT_BelongToMeshGroup:
984             # Check that Threshold is a group
985             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
986                 if aThreshold.GetType() != elementType:
987                     raise ValueError("Group type mismatches Element type")
988                 aCriterion.ThresholdStr = aThreshold.GetName()
989                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
990                 study = salome.myStudy
991                 if study:
992                     so = study.FindObjectIOR( aCriterion.ThresholdID )
993                     if so:
994                         entry = so.GetID()
995                         if entry:
996                             aCriterion.ThresholdID = entry
997             else:
998                 raise TypeError("The Threshold should be a Mesh Group")
999         elif CritType == FT_RangeOfIds:
1000             # Check that Threshold is string
1001             if isinstance(aThreshold, str):
1002                 aCriterion.ThresholdStr = aThreshold
1003             else:
1004                 raise TypeError("The Threshold should be a string.")
1005         elif CritType == FT_CoplanarFaces:
1006             # Check the Threshold
1007             if isinstance(aThreshold, int):
1008                 aCriterion.ThresholdID = str(aThreshold)
1009             elif isinstance(aThreshold, str):
1010                 ID = int(aThreshold)
1011                 if ID < 1:
1012                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1013                 aCriterion.ThresholdID = aThreshold
1014             else:
1015                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1016         elif CritType == FT_ConnectedElements:
1017             # Check the Threshold
1018             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1019                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1020                 if not aCriterion.ThresholdID:
1021                     name = aThreshold.GetName()
1022                     if not name:
1023                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1024                     geompyD = aThreshold.GetGen()
1025                     aCriterion.ThresholdID = geompyD.addToStudy( aThreshold, name )
1026             elif isinstance(aThreshold, int): # node id
1027                 aCriterion.Threshold = aThreshold
1028             elif isinstance(aThreshold, list): # 3 point coordinates
1029                 if len( aThreshold ) < 3:
1030                     raise ValueError("too few point coordinates, must be 3")
1031                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1032             elif isinstance(aThreshold, str):
1033                 if aThreshold.isdigit():
1034                     aCriterion.Threshold = aThreshold # node id
1035                 else:
1036                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1037             else:
1038                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1039                       "or a list of point coordinates and not '%s'"%aThreshold)
1040         elif CritType == FT_ElemGeomType:
1041             # Check the Threshold
1042             try:
1043                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1044                 assert( aThreshold in SMESH.GeometryType._items )
1045             except:
1046                 if isinstance(aThreshold, int):
1047                     aCriterion.Threshold = aThreshold
1048                 else:
1049                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1050                 pass
1051             pass
1052         elif CritType == FT_EntityType:
1053             # Check the Threshold
1054             try:
1055                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1056                 assert( aThreshold in SMESH.EntityType._items )
1057             except:
1058                 if isinstance(aThreshold, int):
1059                     aCriterion.Threshold = aThreshold
1060                 else:
1061                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1062                 pass
1063             pass
1064
1065         elif CritType == FT_GroupColor:
1066             # Check the Threshold
1067             try:
1068                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1069             except:
1070                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1071             pass
1072         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1073                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1074                           FT_BareBorderFace, FT_BareBorderVolume,
1075                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1076                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1077             # At this point the Threshold is unnecessary
1078             if aThreshold ==  FT_LogicalNOT:
1079                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1080             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1081                 aCriterion.BinaryOp = aThreshold
1082         else:
1083             # Check Threshold
1084             try:
1085                 aThreshold = float(aThreshold)
1086                 aCriterion.Threshold = aThreshold
1087             except:
1088                 raise TypeError("The Threshold should be a number.")
1089                 return None
1090
1091         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1092             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1093
1094         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1095             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1096
1097         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1098             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1099
1100         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1101             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1102
1103         return aCriterion
1104
1105     def GetFilter(self,elementType,
1106                   CritType=FT_Undefined,
1107                   Compare=FT_EqualTo,
1108                   Threshold="",
1109                   UnaryOp=FT_Undefined,
1110                   Tolerance=1e-07,
1111                   mesh=None):
1112         """
1113         Create a filter with the given parameters
1114
1115         Parameters:
1116                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1117                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1118                         Note that the items starting from FT_LessThan are not suitable for CritType.
1119                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1120                 Threshold: the threshold value (range of ids as string, shape, numeric)
1121                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1122                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1123                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1124                 mesh: the mesh to initialize the filter with
1125
1126         Returns:
1127                 :class:`SMESH.Filter`
1128
1129         Examples:
1130                See :doc:`Filters usage examples <tui_filters>`
1131         """
1132
1133         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1134         aFilterMgr = self.CreateFilterManager()
1135         aFilter = aFilterMgr.CreateFilter()
1136         aCriteria = []
1137         aCriteria.append(aCriterion)
1138         aFilter.SetCriteria(aCriteria)
1139         if mesh:
1140             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1141             else                       : aFilter.SetMesh( mesh )
1142         aFilterMgr.UnRegister()
1143         return aFilter
1144
1145     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1146         """
1147         Create a filter from criteria
1148
1149         Parameters:
1150                 criteria: a list of :class:`SMESH.Filter.Criterion`
1151                 binOp: binary operator used when binary operator of criteria is undefined
1152
1153         Returns:
1154                 :class:`SMESH.Filter`
1155
1156         Examples:
1157                See :doc:`Filters usage examples <tui_filters>`
1158         """
1159
1160         for i in range( len( criteria ) - 1 ):
1161             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1162                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1163         aFilterMgr = self.CreateFilterManager()
1164         aFilter = aFilterMgr.CreateFilter()
1165         aFilter.SetCriteria(criteria)
1166         aFilterMgr.UnRegister()
1167         return aFilter
1168
1169     def GetFunctor(self,theCriterion):
1170         """
1171         Create a numerical functor by its type
1172
1173         Parameters:
1174                 theCriterion (SMESH.FunctorType): functor type.
1175                         Note that not all items correspond to numerical functors.
1176
1177         Returns:
1178                 :class:`SMESH.NumericalFunctor`
1179         """
1180
1181         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1182             return theCriterion
1183         aFilterMgr = self.CreateFilterManager()
1184         functor = None
1185         if theCriterion == FT_AspectRatio:
1186             functor = aFilterMgr.CreateAspectRatio()
1187         elif theCriterion == FT_AspectRatio3D:
1188             functor = aFilterMgr.CreateAspectRatio3D()
1189         elif theCriterion == FT_Warping:
1190             functor = aFilterMgr.CreateWarping()
1191         elif theCriterion == FT_MinimumAngle:
1192             functor = aFilterMgr.CreateMinimumAngle()
1193         elif theCriterion == FT_Taper:
1194             functor = aFilterMgr.CreateTaper()
1195         elif theCriterion == FT_Skew:
1196             functor = aFilterMgr.CreateSkew()
1197         elif theCriterion == FT_Area:
1198             functor = aFilterMgr.CreateArea()
1199         elif theCriterion == FT_Volume3D:
1200             functor = aFilterMgr.CreateVolume3D()
1201         elif theCriterion == FT_MaxElementLength2D:
1202             functor = aFilterMgr.CreateMaxElementLength2D()
1203         elif theCriterion == FT_MaxElementLength3D:
1204             functor = aFilterMgr.CreateMaxElementLength3D()
1205         elif theCriterion == FT_MultiConnection:
1206             functor = aFilterMgr.CreateMultiConnection()
1207         elif theCriterion == FT_MultiConnection2D:
1208             functor = aFilterMgr.CreateMultiConnection2D()
1209         elif theCriterion == FT_Length:
1210             functor = aFilterMgr.CreateLength()
1211         elif theCriterion == FT_Length2D:
1212             functor = aFilterMgr.CreateLength2D()
1213         elif theCriterion == FT_Length3D:
1214             functor = aFilterMgr.CreateLength3D()
1215         elif theCriterion == FT_Deflection2D:
1216             functor = aFilterMgr.CreateDeflection2D()
1217         elif theCriterion == FT_NodeConnectivityNumber:
1218             functor = aFilterMgr.CreateNodeConnectivityNumber()
1219         elif theCriterion == FT_BallDiameter:
1220             functor = aFilterMgr.CreateBallDiameter()
1221         else:
1222             print("Error: given parameter is not numerical functor type.")
1223         aFilterMgr.UnRegister()
1224         return functor
1225
1226     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1227         """
1228         Create hypothesis
1229
1230         Parameters:
1231                 theHType (string): mesh hypothesis type
1232                 theLibName (string): mesh plug-in library name
1233
1234         Returns:
1235                 created hypothesis instance
1236         """
1237         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1238
1239         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1240             return hyp
1241
1242         # wrap hypothesis methods
1243         for meth_name in dir( hyp.__class__ ):
1244             if not meth_name.startswith("Get") and \
1245                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1246                 method = getattr ( hyp.__class__, meth_name )
1247                 if callable(method):
1248                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1249
1250         return hyp
1251
1252     def GetHypothesisParameterValues( self, hypType, libName, mesh, shape, initParams ):
1253         """
1254         Create hypothesis initialized according to parameters
1255
1256         Parameters:
1257                 hypType (string): hypothesis type
1258                 libName (string): plug-in library name
1259                 mesh: optional mesh by which a hypotheses can initialize self
1260                 shape: optional geometry  by size of which a hypotheses can initialize self
1261                 initParams: structure SMESH.HypInitParams defining how to initialize a hypothesis
1262
1263         Returns:
1264                 created hypothesis instance
1265         """
1266         if isinstance( mesh, Mesh ):
1267             mesh = mesh.GetMesh()
1268         if isinstance( initParams, (bool,int)):
1269             initParams = SMESH.HypInitParams( not initParams, 1.0, not mesh )
1270         return SMESH._objref_SMESH_Gen.GetHypothesisParameterValues(self, hypType, libName,
1271                                                                     mesh, shape, initParams )
1272
1273     def GetMeshInfo(self, obj):
1274         """
1275         Get the mesh statistic.
1276
1277         Returns:
1278                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1279         """
1280
1281         if isinstance( obj, Mesh ):
1282             obj = obj.GetMesh()
1283         d = {}
1284         if hasattr(obj, "GetMeshInfo"):
1285             values = obj.GetMeshInfo()
1286             for i in range(SMESH.Entity_Last._v):
1287                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1288             pass
1289         return d
1290
1291     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1292         """
1293         Get minimum distance between two objects
1294
1295         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1296         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1297
1298         Parameters:
1299                 src1 (SMESH.SMESH_IDSource): first source object
1300                 src2 (SMESH.SMESH_IDSource): second source object
1301                 id1 (int): node/element id from the first source
1302                 id2 (int): node/element id from the second (or first) source
1303                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1304                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1305
1306         Returns:
1307                 minimum distance value
1308
1309         See also:
1310                 :meth:`GetMinDistance`
1311         """
1312
1313         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1314         if result is None:
1315             result = 0.0
1316         else:
1317             result = result.value
1318         return result
1319
1320     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1321         """
1322         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1323
1324         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1325         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1326
1327         Parameters:
1328                 src1 (SMESH.SMESH_IDSource): first source object
1329                 src2 (SMESH.SMESH_IDSource): second source object
1330                 id1 (int): node/element id from the first source
1331                 id2 (int): node/element id from the second (or first) source
1332                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1333                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1334
1335         Returns:
1336                 :class:`SMESH.Measure` structure or None if input data is invalid
1337         See also:
1338                 :meth:`MinDistance`
1339         """
1340
1341         if isinstance(src1, Mesh): src1 = src1.mesh
1342         if isinstance(src2, Mesh): src2 = src2.mesh
1343         if src2 is None and id2 != 0: src2 = src1
1344         if not hasattr(src1, "_narrow"): return None
1345         src1 = src1._narrow(SMESH.SMESH_IDSource)
1346         if not src1: return None
1347         unRegister = genObjUnRegister()
1348         if id1 != 0:
1349             m = src1.GetMesh()
1350             e = m.GetMeshEditor()
1351             if isElem1:
1352                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1353             else:
1354                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1355             unRegister.set( src1 )
1356             pass
1357         if hasattr(src2, "_narrow"):
1358             src2 = src2._narrow(SMESH.SMESH_IDSource)
1359             if src2 and id2 != 0:
1360                 m = src2.GetMesh()
1361                 e = m.GetMeshEditor()
1362                 if isElem2:
1363                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1364                 else:
1365                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1366                 unRegister.set( src2 )
1367                 pass
1368             pass
1369         aMeasurements = self.CreateMeasurements()
1370         unRegister.set( aMeasurements )
1371         result = aMeasurements.MinDistance(src1, src2)
1372         return result
1373
1374     def BoundingBox(self, objects):
1375         """
1376         Get bounding box of the specified object(s)
1377
1378         Parameters:
1379                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1380
1381         Returns:
1382                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1383
1384         See also:
1385                :meth:`GetBoundingBox`
1386         """
1387
1388         result = self.GetBoundingBox(objects)
1389         if result is None:
1390             result = (0.0,)*6
1391         else:
1392             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1393         return result
1394
1395     def GetBoundingBox(self, objects):
1396         """
1397         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1398
1399         Parameters:
1400                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1401
1402         Returns:
1403                 :class:`SMESH.Measure` structure
1404
1405         See also:
1406                 :meth:`BoundingBox`
1407         """
1408
1409         if isinstance(objects, tuple):
1410             objects = list(objects)
1411         if not isinstance(objects, list):
1412             objects = [objects]
1413         srclist = []
1414         for o in objects:
1415             if isinstance(o, Mesh):
1416                 srclist.append(o.mesh)
1417             elif hasattr(o, "_narrow"):
1418                 src = o._narrow(SMESH.SMESH_IDSource)
1419                 if src: srclist.append(src)
1420                 pass
1421             pass
1422         aMeasurements = self.CreateMeasurements()
1423         result = aMeasurements.BoundingBox(srclist)
1424         aMeasurements.UnRegister()
1425         return result
1426
1427     def GetLength(self, obj):
1428         """
1429         Get sum of lengths of all 1D elements in the mesh object.
1430
1431         Parameters:
1432                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1433
1434         Returns:
1435                 sum of lengths of all 1D elements
1436         """
1437
1438         if isinstance(obj, Mesh): obj = obj.mesh
1439         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1440         aMeasurements = self.CreateMeasurements()
1441         value = aMeasurements.Length(obj)
1442         aMeasurements.UnRegister()
1443         return value
1444
1445     def GetArea(self, obj):
1446         """
1447         Get sum of areas of all 2D elements in the mesh object.
1448
1449         Parameters:
1450                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1451
1452         Returns:
1453                 sum of areas of all 2D elements
1454         """
1455
1456         if isinstance(obj, Mesh): obj = obj.mesh
1457         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1458         aMeasurements = self.CreateMeasurements()
1459         value = aMeasurements.Area(obj)
1460         aMeasurements.UnRegister()
1461         return value
1462
1463     def GetVolume(self, obj):
1464         """
1465         Get sum of volumes of all 3D elements in the mesh object.
1466
1467         Parameters:
1468                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1469
1470         Returns:
1471                 sum of volumes of all 3D elements
1472         """
1473
1474         if isinstance(obj, Mesh): obj = obj.mesh
1475         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476         aMeasurements = self.CreateMeasurements()
1477         value = aMeasurements.Volume(obj)
1478         aMeasurements.UnRegister()
1479         return value
1480
1481     def GetGravityCenter(self, obj):
1482         """
1483         Get gravity center of all nodes of a mesh object.
1484
1485         Parameters:
1486                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1487
1488         Returns:
1489                 Three components of the gravity center (x,y,z)
1490
1491         See also:
1492                 :meth:`Mesh.BaryCenter`
1493         """
1494         if isinstance(obj, Mesh): obj = obj.mesh
1495         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1496         aMeasurements = self.CreateMeasurements()
1497         pointStruct = aMeasurements.GravityCenter(obj)
1498         aMeasurements.UnRegister()
1499         return pointStruct.x, pointStruct.y, pointStruct.z
1500
1501     def GetAngle(self, p1, p2, p3 ):
1502         """
1503         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1504
1505         Parameters:
1506                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct
1507                           or list [x,y,z]
1508
1509         Returns:
1510             Angle in radians
1511         """
1512         if isinstance( p1, list ): p1 = PointStruct(*p1)
1513         if isinstance( p2, list ): p2 = PointStruct(*p2)
1514         if isinstance( p3, list ): p3 = PointStruct(*p3)
1515
1516         aMeasurements = self.CreateMeasurements()
1517         angle = aMeasurements.Angle(p1,p2,p3)
1518         aMeasurements.UnRegister()
1519
1520         return angle
1521
1522
1523     pass # end of class smeshBuilder
1524
1525 import omniORB
1526 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1527 """Registering the new proxy for SMESH.SMESH_Gen"""
1528
1529
1530 def New( instance=None, instanceGeom=None):
1531     """
1532     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1533     interface to create or load meshes.
1534
1535     Typical use is::
1536
1537         import salome
1538         salome.salome_init()
1539         from salome.smesh import smeshBuilder
1540         smesh = smeshBuilder.New()
1541
1542     Parameters:
1543         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1544         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1545     Returns:
1546         :class:`smeshBuilder` instance
1547     """
1548     global engine
1549     global smeshInst
1550     global doLcc
1551     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1552         import sys
1553         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1554         instance = None
1555     engine = instance
1556     if engine is None:
1557         doLcc = True
1558     smeshInst = smeshBuilder()
1559     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1560     smeshInst.init_smesh(instanceGeom)
1561     return smeshInst
1562
1563
1564 # Public class: Mesh
1565 # ==================
1566
1567
1568 class Mesh(metaclass = MeshMeta):
1569     """
1570     This class allows defining and managing a mesh.
1571     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1572     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1573     new nodes and elements and by changing the existing entities), to get information
1574     about a mesh and to export a mesh in different formats.
1575     """
1576
1577     geom = 0
1578     mesh = 0
1579     editor = 0
1580
1581     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1582
1583         """
1584         Constructor
1585
1586         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1587         sets the GUI name of this mesh to *name*.
1588
1589         Parameters:
1590                 smeshpyD: an instance of smeshBuilder class
1591                 geompyD: an instance of geomBuilder class
1592                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1593                 name: Study name of the mesh
1594         """
1595
1596         self.smeshpyD = smeshpyD
1597         self.geompyD = geompyD
1598         if obj is None:
1599             obj = 0
1600         objHasName = False
1601         if obj != 0:
1602             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1603                 self.geom = obj
1604                 objHasName = True
1605                 # publish geom of mesh (issue 0021122)
1606                 if not self.geom.GetStudyEntry():
1607                     objHasName = False
1608                     geompyD.init_geom()
1609                     if name:
1610                         geo_name = name + " shape"
1611                     else:
1612                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1613                     geompyD.addToStudy( self.geom, geo_name )
1614                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1615
1616             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1617                 self.SetMesh(obj)
1618         else:
1619             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1620         if name:
1621             self.smeshpyD.SetName(self.mesh, name)
1622         elif objHasName:
1623             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1624
1625         if not self.geom:
1626             self.geom = self.mesh.GetShapeToMesh()
1627
1628         self.editor   = self.mesh.GetMeshEditor()
1629         self.functors = [None] * SMESH.FT_Undefined._v
1630
1631         # set self to algoCreator's
1632         for attrName in dir(self):
1633             attr = getattr( self, attrName )
1634             if isinstance( attr, algoCreator ):
1635                 setattr( self, attrName, attr.copy( self ))
1636                 pass
1637             pass
1638         pass
1639
1640     def __del__(self):
1641         """
1642         Destructor. Clean-up resources
1643         """
1644         if self.mesh:
1645             self.mesh.UnRegister()
1646             pass
1647         pass
1648
1649     def SetMesh(self, theMesh):
1650         """
1651         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1652
1653         Parameters:
1654                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1655         """
1656         # do not call Register() as this prevents mesh servant deletion at closing study
1657         #if self.mesh: self.mesh.UnRegister()
1658         self.mesh = theMesh
1659         if self.mesh:
1660             #self.mesh.Register()
1661             self.geom = self.mesh.GetShapeToMesh()
1662             if self.geom:
1663                 self.geompyD = None
1664                 try:
1665                     if salome.sg.hasDesktop():
1666                         so = salome.ObjectToSObject( self.geom )
1667                         comp = so.GetFatherComponent()
1668                         if comp.ComponentDataType() == "SHAPERSTUDY":
1669                             import shaperBuilder
1670                             self.geompyD = shaperBuilder.New()
1671                 except:
1672                     pass
1673                 if not self.geompyD:
1674                     self.geompyD = self.geom.GetGen()
1675                 pass
1676
1677     def GetMesh(self):
1678         """
1679         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1680
1681         Returns:
1682                 a :class:`SMESH.SMESH_Mesh` object
1683         """
1684
1685         return self.mesh
1686
1687     def GetEngine(self):
1688         """
1689         Return a smeshBuilder instance created this mesh
1690         """
1691         return self.smeshpyD
1692
1693     def GetGeomEngine(self):
1694         """
1695         Return a geomBuilder instance
1696         """
1697         return self.geompyD
1698
1699     def GetName(self):
1700         """
1701         Get the name of the mesh
1702
1703         Returns:
1704                 the name of the mesh as a string
1705         """
1706
1707         name = GetName(self.GetMesh())
1708         return name
1709
1710     def SetName(self, name):
1711         """
1712         Set a name to the mesh
1713
1714         Parameters:
1715                 name: a new name of the mesh
1716         """
1717
1718         self.smeshpyD.SetName(self.GetMesh(), name)
1719
1720     def GetSubMesh(self, geom, name):
1721         """
1722         Get a sub-mesh object associated to a *geom* geometrical object.
1723
1724         Parameters:
1725                 geom: a geometrical object (shape)
1726                 name: a name for the sub-mesh in the Object Browser
1727
1728         Returns:
1729                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1730                 which lies on the given shape
1731
1732         Note:
1733                 A sub-mesh is implicitly created when a sub-shape is specified at
1734                 creating an algorithm, for example::
1735
1736                    algo1D = mesh.Segment(geom=Edge_1)
1737
1738                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1739                 The created sub-mesh can be retrieved from the algorithm::
1740
1741                    submesh = algo1D.GetSubMesh()
1742         """
1743
1744         AssureGeomPublished( self, geom, name )
1745         submesh = self.mesh.GetSubMesh( geom, name )
1746         return submesh
1747
1748     def GetShape(self):
1749         """
1750         Return the shape associated to the mesh
1751
1752         Returns:
1753                 a GEOM_Object
1754         """
1755
1756         return self.geom
1757
1758     def SetShape(self, geom):
1759         """
1760         Associate the given shape to the mesh (entails the recreation of the mesh)
1761
1762         Parameters:
1763                 geom: the shape to be meshed (GEOM_Object)
1764         """
1765
1766         self.mesh = self.smeshpyD.CreateMesh(geom)
1767
1768     def HasShapeToMesh(self):
1769         """
1770         Return ``True`` if this mesh is based on geometry
1771         """
1772         return self.mesh.HasShapeToMesh()
1773
1774     def Load(self):
1775         """
1776         Load mesh from the study after opening the study
1777         """
1778         self.mesh.Load()
1779
1780     def IsReadyToCompute(self, theSubObject):
1781         """
1782         Return true if the hypotheses are defined well
1783
1784         Parameters:
1785                 theSubObject: a sub-shape of a mesh shape
1786
1787         Returns:
1788                 True or False
1789         """
1790
1791         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1792
1793     def GetAlgoState(self, theSubObject):
1794         """
1795         Return errors of hypotheses definition.
1796         The list of errors is empty if everything is OK.
1797
1798         Parameters:
1799                 theSubObject: a sub-shape of a mesh shape
1800
1801         Returns:
1802                 a list of errors
1803         """
1804
1805         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1806
1807     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1808         """
1809         Return a geometrical object on which the given element was built.
1810         The returned geometrical object, if not nil, is either found in the
1811         study or published by this method with the given name
1812
1813         Parameters:
1814             theElementID: the id of the mesh element
1815             theGeomName: the user-defined name of the geometrical object
1816
1817         Returns:
1818             GEOM.GEOM_Object instance
1819         """
1820
1821         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1822
1823     def MeshDimension(self):
1824         """
1825         Return the mesh dimension depending on the dimension of the underlying shape
1826         or, if the mesh is not based on any shape, basing on deimension of elements
1827
1828         Returns:
1829                 mesh dimension as an integer value [0,3]
1830         """
1831
1832         if self.mesh.HasShapeToMesh():
1833             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1834             if len( shells ) > 0 :
1835                 return 3
1836             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1837                 return 2
1838             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1839                 return 1
1840             else:
1841                 return 0;
1842         else:
1843             if self.NbVolumes() > 0: return 3
1844             if self.NbFaces()   > 0: return 2
1845             if self.NbEdges()   > 0: return 1
1846         return 0
1847
1848     def Evaluate(self, geom=0):
1849         """
1850         Evaluate size of prospective mesh on a shape
1851
1852         Returns:
1853                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1854                 To know predicted number of e.g. edges, inquire it this way::
1855
1856                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1857         """
1858
1859         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1860             if self.geom == 0:
1861                 geom = self.mesh.GetShapeToMesh()
1862             else:
1863                 geom = self.geom
1864         return self.smeshpyD.Evaluate(self.mesh, geom)
1865
1866     def ParallelCompute(self, nbThreads, mesherNbThreads=1, geom=0, discardModifs=False, refresh=False):
1867         """
1868         Parallel computation of the mesh and return the status of the computation
1869         The mesh must contains have be constructed using create_parallel_mesh
1870
1871         Parameters:
1872                 nbThreads: Number of threads to use for a parallel computation
1873                 geom: geomtrical shape on which mesh data should be computed
1874                 discardModifs: if True and the mesh has been edited since
1875                         a last total re-compute and that may prevent successful partial re-compute,
1876                         then the mesh is cleaned before Compute()
1877                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1878
1879         Returns:
1880                 True or False
1881         """
1882         if (nbThreads <= 1):
1883             raise ValueError("nbThreads must be strictly greater than 1")
1884         if (mesherNbThreads < 1):
1885             raise ValueError("nbThreads must be greater than 1")
1886
1887         self.mesh.SetMesherNbThreads(mesherNbThreads)
1888         self.mesh.SetNbThreads(nbThreads)
1889         return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh)
1890
1891     def Compute(self, geom=0, discardModifs=False, refresh=False):
1892         """
1893         Compute the mesh and return the status of the computation
1894
1895         Parameters:
1896                 geom: geomtrical shape on which mesh data should be computed
1897                 discardModifs: if True and the mesh has been edited since
1898                         a last total re-compute and that may prevent successful partial re-compute,
1899                         then the mesh is cleaned before Compute()
1900                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1901
1902         Returns:
1903                 True or False
1904         """
1905
1906         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1907             geom = self.mesh.GetShapeToMesh()
1908         ok = False
1909         try:
1910             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1911                 self.mesh.Clear()
1912             ok = self.smeshpyD.Compute(self.mesh, geom)
1913         except SALOME.SALOME_Exception as ex:
1914             print("Mesh computation failed, exception caught:")
1915             print("    ", ex.details.text)
1916         except:
1917             import traceback
1918             print("Mesh computation failed, exception caught:")
1919             traceback.print_exc()
1920         if True:#not ok:
1921             allReasons = ""
1922
1923             # Treat compute errors
1924             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1925             shapeText = ""
1926             for err in computeErrors:
1927                 if self.mesh.HasShapeToMesh():
1928                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1929                 errText = ""
1930                 stdErrors = ["OK",                   #COMPERR_OK
1931                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1932                              "std::exception",       #COMPERR_STD_EXCEPTION
1933                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1934                              "..",                   #COMPERR_SLM_EXCEPTION
1935                              "Unknown exception",    #COMPERR_EXCEPTION
1936                              "Memory allocation problem", #COMPERR_MEMORY_PB
1937                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1938                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1939                              "Warning",              #COMPERR_WARNING
1940                              "Computation cancelled",#COMPERR_CANCELED
1941                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1942                 if err.code > 0:
1943                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1944                 else:
1945                     errText = "code %s" % -err.code
1946                 if errText: errText += ". "
1947                 errText += err.comment
1948                 if allReasons: allReasons += "\n"
1949                 if ok:
1950                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1951                 else:
1952                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1953                 pass
1954
1955             # Treat hyp errors
1956             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1957             for err in errors:
1958                 if err.isGlobalAlgo:
1959                     glob = "global"
1960                 else:
1961                     glob = "local"
1962                     pass
1963                 dim = err.algoDim
1964                 name = err.algoName
1965                 if len(name) == 0:
1966                     reason = '%s %sD algorithm is missing' % (glob, dim)
1967                 elif err.state == HYP_MISSING:
1968                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1969                               % (glob, dim, name, dim))
1970                 elif err.state == HYP_NOTCONFORM:
1971                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1972                 elif err.state == HYP_BAD_PARAMETER:
1973                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1974                               % ( glob, dim, name ))
1975                 elif err.state == HYP_BAD_GEOMETRY:
1976                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1977                               'geometry' % ( glob, dim, name ))
1978                 elif err.state == HYP_HIDDEN_ALGO:
1979                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1980                               'algorithm of upper dimension generating %sD mesh'
1981                               % ( glob, dim, name, glob, dim ))
1982                 else:
1983                     reason = ("For unknown reason. "
1984                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1985                     pass
1986                 if allReasons: allReasons += "\n"
1987                 allReasons += "-  " + reason
1988                 pass
1989             if not ok or allReasons != "":
1990                 msg = '"' + GetName(self.mesh) + '"'
1991                 if ok: msg += " has been computed with warnings"
1992                 else:  msg += " has not been computed"
1993                 if allReasons != "": msg += ":"
1994                 else:                msg += "."
1995                 print(msg)
1996                 print(allReasons)
1997             pass
1998         if salome.sg:
1999             if salome.sg.hasDesktop():
2000                 if not isinstance( refresh, list): # not a call from subMesh.Compute()
2001                     if refresh: salome.sg.updateObjBrowser()
2002
2003         return ok
2004
2005     def GetComputeErrors(self, shape=0 ):
2006         """
2007         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
2008         """
2009
2010         if shape == 0:
2011             shape = self.mesh.GetShapeToMesh()
2012         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
2013
2014     def GetSubShapeName(self, subShapeID ):
2015         """
2016         Return a name of a sub-shape by its ID.
2017         Possible variants (for *subShapeID* == 3):
2018
2019                 - **"Face_12"** - published sub-shape
2020                 - **FACE #3** - not published sub-shape
2021                 - **sub-shape #3** - invalid sub-shape ID
2022                 - **#3** - error in this function
2023
2024         Parameters:
2025                 subShapeID: a unique ID of a sub-shape
2026
2027         Returns:
2028                 a string describing the sub-shape
2029
2030         """
2031
2032         if not self.mesh.HasShapeToMesh():
2033             return ""
2034         try:
2035             shapeText = ""
2036             mainIOR  = salome.orb.object_to_string( self.GetShape() )
2037             s = salome.myStudy
2038             mainSO = s.FindObjectIOR(mainIOR)
2039             if mainSO:
2040                 if subShapeID == 1:
2041                     shapeText = '"%s"' % mainSO.GetName()
2042                 subIt = s.NewChildIterator(mainSO)
2043                 while subIt.More():
2044                     subSO = subIt.Value()
2045                     subIt.Next()
2046                     obj = subSO.GetObject()
2047                     if not obj: continue
2048                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2049                     if not go: continue
2050                     try:
2051                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2052                     except:
2053                         continue
2054                     if ids == subShapeID:
2055                         shapeText = '"%s"' % subSO.GetName()
2056                         break
2057             if not shapeText:
2058                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2059                 if shape:
2060                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2061                 else:
2062                     shapeText = 'sub-shape #%s' % (subShapeID)
2063         except:
2064             shapeText = "#%s" % (subShapeID)
2065         return shapeText
2066
2067     def GetFailedShapes(self, publish=False):
2068         """
2069         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2070         error of an algorithm
2071
2072         Parameters:
2073                 publish: if *True*, the returned groups will be published in the study
2074
2075         Returns:
2076                 a list of GEOM groups each named after a failed algorithm
2077         """
2078
2079
2080         algo2shapes = {}
2081         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2082         for err in computeErrors:
2083             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2084             if not shape: continue
2085             if err.algoName in algo2shapes:
2086                 algo2shapes[ err.algoName ].append( shape )
2087             else:
2088                 algo2shapes[ err.algoName ] = [ shape ]
2089             pass
2090
2091         groups = []
2092         for algoName, shapes in list(algo2shapes.items()):
2093             while shapes:
2094                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2095                 otherTypeShapes = []
2096                 sameTypeShapes  = []
2097                 group = self.geompyD.CreateGroup( self.geom, groupType )
2098                 for shape in shapes:
2099                     if shape.GetShapeType() == shapes[0].GetShapeType():
2100                         sameTypeShapes.append( shape )
2101                     else:
2102                         otherTypeShapes.append( shape )
2103                 self.geompyD.UnionList( group, sameTypeShapes )
2104                 if otherTypeShapes:
2105                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2106                 else:
2107                     group.SetName( algoName )
2108                 groups.append( group )
2109                 shapes = otherTypeShapes
2110             pass
2111         if publish:
2112             for group in groups:
2113                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2114         return groups
2115
2116     def GetMeshOrder(self):
2117         """
2118         Return sub-mesh objects list in meshing order
2119
2120         Returns:
2121                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2122         """
2123
2124         return self.mesh.GetMeshOrder()
2125
2126     def SetMeshOrder(self, submeshes):
2127         """
2128         Set priority of sub-meshes. It works in two ways:
2129
2130         * For sub-meshes with assigned algorithms of same dimension generating mesh of
2131           *several dimensions*, it sets the order in which the sub-meshes are computed.
2132         * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2133           when looking for meshing parameters to apply to a sub-shape. To impose the
2134           order in which sub-meshes with uni-dimensional algorithms are computed,
2135           call **submesh.Compute()** in a desired order.
2136
2137         Parameters:
2138                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2139
2140         Warning: the method is for setting the order for all sub-meshes at once:
2141                  SetMeshOrder( [ [sm1, sm2, sm3], [sm4, sm5] ] )
2142         """
2143
2144         return self.mesh.SetMeshOrder(submeshes)
2145
2146     def Clear(self, refresh=False):
2147         """
2148         Remove all nodes and elements generated on geometry. Imported elements remain.
2149
2150         Parameters:
2151                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2152         """
2153
2154         self.mesh.Clear()
2155         if ( salome.sg.hasDesktop() ):
2156             if refresh: salome.sg.updateObjBrowser()
2157
2158     def ClearSubMesh(self, geomId, refresh=False):
2159         """
2160         Remove all nodes and elements of indicated shape
2161
2162         Parameters:
2163                 geomId: the ID of a sub-shape to remove elements on
2164                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2165         """
2166
2167         self.mesh.ClearSubMesh(geomId)
2168         if salome.sg.hasDesktop():
2169             if refresh: salome.sg.updateObjBrowser()
2170
2171     def AutomaticTetrahedralization(self, fineness=0):
2172         """
2173         Compute a tetrahedral mesh using AutomaticLength + Triangle + Tetrahedron
2174
2175         Parameters:
2176                 fineness: [0.0,1.0] defines mesh fineness
2177
2178         Returns:
2179                 True or False
2180         """
2181
2182         dim = self.MeshDimension()
2183         # assign hypotheses
2184         self.RemoveGlobalHypotheses()
2185         self.Segment().AutomaticLength(fineness)
2186         if dim > 1 :
2187             self.Triangle().LengthFromEdges()
2188             pass
2189         if dim > 2 :
2190             self.Tetrahedron()
2191             pass
2192         return self.Compute()
2193
2194     def AutomaticHexahedralization(self, fineness=0):
2195         """
2196         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2197
2198         Parameters:
2199                 fineness: [0.0, 1.0] defines mesh fineness
2200
2201         Returns:
2202                 True or False
2203         """
2204
2205         dim = self.MeshDimension()
2206         # assign the hypotheses
2207         self.RemoveGlobalHypotheses()
2208         self.Segment().AutomaticLength(fineness)
2209         if dim > 1 :
2210             self.Quadrangle()
2211             pass
2212         if dim > 2 :
2213             self.Hexahedron()
2214             pass
2215         return self.Compute()
2216
2217     def AddHypothesis(self, hyp, geom=0):
2218         """
2219         Assign a hypothesis
2220
2221         Parameters:
2222                 hyp: a hypothesis to assign
2223                 geom: a subhape of mesh geometry
2224
2225         Returns:
2226                 :class:`SMESH.Hypothesis_Status`
2227         """
2228
2229         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2230             hyp, geom = geom, hyp
2231         if isinstance( hyp, Mesh_Algorithm ):
2232             hyp = hyp.GetAlgorithm()
2233             pass
2234         if not geom:
2235             geom = self.geom
2236             if not geom:
2237                 geom = self.mesh.GetShapeToMesh()
2238             pass
2239         isApplicable = True
2240         if self.mesh.HasShapeToMesh():
2241             hyp_type     = hyp.GetName()
2242             lib_name     = hyp.GetLibName()
2243             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2244             # if checkAll and geom:
2245             #     checkAll = geom.GetType() == 37
2246             checkAll     = False
2247             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2248         if isApplicable:
2249             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2250             status = self.mesh.AddHypothesis(geom, hyp)
2251         else:
2252             status = HYP_BAD_GEOMETRY, ""
2253         hyp_name = GetName( hyp )
2254         geom_name = ""
2255         if geom:
2256             geom_name = geom.GetName()
2257         isAlgo = hyp._narrow( SMESH_Algo )
2258         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2259         return status
2260
2261     def IsUsedHypothesis(self, hyp, geom):
2262         """
2263         Return True if an algorithm or hypothesis is assigned to a given shape
2264
2265         Parameters:
2266                 hyp: an algorithm or hypothesis to check
2267                 geom: a subhape of mesh geometry
2268
2269         Returns:
2270                 True of False
2271         """
2272
2273         if not hyp: # or not geom
2274             return False
2275         if isinstance( hyp, Mesh_Algorithm ):
2276             hyp = hyp.GetAlgorithm()
2277             pass
2278         hyps = self.GetHypothesisList(geom)
2279         for h in hyps:
2280             if h.GetId() == hyp.GetId():
2281                 return True
2282         return False
2283
2284     def RemoveHypothesis(self, hyp, geom=0):
2285         """
2286         Unassign a hypothesis
2287
2288         Parameters:
2289                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2290                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2291
2292         Returns:
2293                 :class:`SMESH.Hypothesis_Status`
2294         """
2295
2296         if not hyp:
2297             return None
2298         if isinstance( hyp, Mesh_Algorithm ):
2299             hyp = hyp.GetAlgorithm()
2300             pass
2301         shape = geom
2302         if not shape:
2303             shape = self.geom
2304             pass
2305         if self.IsUsedHypothesis( hyp, shape ):
2306             return self.mesh.RemoveHypothesis( shape, hyp )
2307         hypName = GetName( hyp )
2308         geoName = GetName( shape )
2309         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2310         return None
2311
2312     def GetHypothesisList(self, geom):
2313         """
2314         Get the list of hypotheses added on a geometry
2315
2316         Parameters:
2317                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2318
2319         Returns:
2320                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2321         """
2322
2323         return self.mesh.GetHypothesisList( geom )
2324
2325     def RemoveGlobalHypotheses(self):
2326         """
2327         Remove all global hypotheses
2328         """
2329
2330         current_hyps = self.mesh.GetHypothesisList( self.geom )
2331         for hyp in current_hyps:
2332             self.mesh.RemoveHypothesis( self.geom, hyp )
2333             pass
2334         pass
2335
2336     def ExportMEDCoupling(self, *args, **kwargs):
2337         """
2338         Export the mesh in a memory representation.
2339
2340         Parameters:
2341             auto_groups (boolean): parameter for creating/not creating
2342                     the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2343                     the typical use is auto_groups=False.
2344             overwrite (boolean): parameter for overwriting/not overwriting the file
2345             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2346                     to export instead of the mesh
2347             autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2348
2349                     - 1D if all mesh nodes lie on OX coordinate axis, or
2350                     - 2D if all mesh nodes lie on XOY coordinate plane, or
2351                     - 3D in the rest cases.
2352
2353                     If *autoDimension* is *False*, the space dimension is always 3.
2354             fields: list of GEOM fields defined on the shape to mesh.
2355             geomAssocFields: each character of this string means a need to export a
2356                     corresponding field; correspondence between fields and characters
2357                     is following:
2358
2359                     - 'v' stands for "_vertices_" field;
2360                     - 'e' stands for "_edges_" field;
2361                     - 'f' stands for "_faces_" field;
2362                     - 's' stands for "_solids_" field.
2363
2364             zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2365                             close to zero within a given tolerance, the coordinate is set to zero.
2366                             If *ZTolerance* is negative (default), the node coordinates are kept as is.
2367             saveNumbers(boolean) : enable saving numbers of nodes and cells.
2368             """
2369         auto_groups     = args[0] if len(args) > 0 else False
2370         meshPart        = args[1] if len(args) > 1 else None
2371         autoDimension   = args[2] if len(args) > 2 else True
2372         fields          = args[3] if len(args) > 3 else []
2373         geomAssocFields = args[4] if len(args) > 4 else ''
2374         z_tolerance     = args[5] if len(args) > 5 else -1.
2375         saveNumbers     = args[6] if len(args) > 6 else True
2376         # process keywords arguments
2377         auto_groups     = kwargs.get("auto_groups", auto_groups)
2378         meshPart        = kwargs.get("meshPart", meshPart)
2379         autoDimension   = kwargs.get("autoDimension", autoDimension)
2380         fields          = kwargs.get("fields", fields)
2381         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2382         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2383         saveNumbers     = kwargs.get("saveNumbers", saveNumbers)
2384
2385         # invoke engine's function
2386         if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2387             unRegister = genObjUnRegister()
2388             if isinstance( meshPart, list ):
2389                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2390                 unRegister.set( meshPart )
2391
2392             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2393             self.mesh.SetParameters(Parameters)
2394
2395             intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension,
2396                                                        fields, geomAssocFields, z_tolerance,
2397                                                        saveNumbers )
2398             import medcoupling
2399             dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2400             return medcoupling.MEDFileData.New(dab)
2401         else:
2402             intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2403             import medcoupling
2404             dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2405             return medcoupling.MEDFileMesh.New(dab)
2406
2407     def ExportMED(self, *args, **kwargs):
2408         """
2409         Export the mesh in a file in MED format
2410         allowing to overwrite the file if it exists or add the exported data to its contents
2411
2412         Parameters:
2413                 fileName: is the file name
2414                 auto_groups (boolean): parameter for creating/not creating
2415                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2416                         the typical use is auto_groups=False.
2417                 version (int): define the version (xy, where version is x.y.z) of MED file format.
2418                         For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2419                         The rules of compatibility to write a mesh in an older version than
2420                         the current version depend on the current version. For instance,
2421                         with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2422                         or 3.2.1 or 3.3.1 formats.
2423                         If the version is equal to -1, the version is not changed (default).
2424                 overwrite (boolean): parameter for overwriting/not overwriting the file
2425                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
2426                         to export instead of the mesh
2427                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2428
2429                         - 1D if all mesh nodes lie on OX coordinate axis, or
2430                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2431                         - 3D in the rest cases.
2432
2433                         If *autoDimension* is *False*, the space dimension is always 3.
2434                 fields: list of GEOM fields defined on the shape to mesh.
2435                 geomAssocFields: each character of this string means a need to export a
2436                         corresponding field; correspondence between fields and characters
2437                         is following:
2438
2439                         - 'v' stands for "_vertices_" field;
2440                         - 'e' stands for "_edges_" field;
2441                         - 'f' stands for "_faces_" field;
2442                         - 's' stands for "_solids_" field.
2443
2444                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is
2445                              close to zero within a given tolerance, the coordinate is set to zero.
2446                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2447                 saveNumbers (boolean) : enable saving numbers of nodes and cells.
2448         """
2449         # process positional arguments
2450         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2451         fileName        = args[0]
2452         auto_groups     = args[1] if len(args) > 1 else False
2453         version         = args[2] if len(args) > 2 else -1
2454         overwrite       = args[3] if len(args) > 3 else True
2455         meshPart        = args[4] if len(args) > 4 else None
2456         autoDimension   = args[5] if len(args) > 5 else True
2457         fields          = args[6] if len(args) > 6 else []
2458         geomAssocFields = args[7] if len(args) > 7 else ''
2459         z_tolerance     = args[8] if len(args) > 8 else -1.
2460         saveNumbers     = args[9] if len(args) > 9 else True
2461         # process keywords arguments
2462         auto_groups     = kwargs.get("auto_groups", auto_groups)
2463         version         = kwargs.get("version", version)
2464         version         = kwargs.get("minor", version)
2465         overwrite       = kwargs.get("overwrite", overwrite)
2466         meshPart        = kwargs.get("meshPart", meshPart)
2467         autoDimension   = kwargs.get("autoDimension", autoDimension)
2468         fields          = kwargs.get("fields", fields)
2469         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2470         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2471         saveNumbers     = kwargs.get("saveNumbers", saveNumbers)
2472
2473         if isinstance( meshPart, Mesh):
2474             meshPart = meshPart.GetMesh()
2475
2476         # invoke engine's function
2477         if meshPart or fields or geomAssocFields or z_tolerance > 0 or not saveNumbers:
2478             unRegister = genObjUnRegister()
2479             if isinstance( meshPart, list ):
2480                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2481                 unRegister.set( meshPart )
2482
2483             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2484             self.mesh.SetParameters(Parameters)
2485
2486             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2487                                        version, overwrite, autoDimension,
2488                                        fields, geomAssocFields, z_tolerance, saveNumbers )
2489         else:
2490             self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2491
2492     def ExportDAT(self, f, meshPart=None, renumber=True):
2493         """
2494         Export the mesh in a file in DAT format
2495
2496         Parameters:
2497                 f: the file name
2498                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2499                 renumber(boolean): enable renumbering nodes and cells in order to eliminate holes in numbering
2500         """
2501
2502         if meshPart or not renumber:
2503             unRegister = genObjUnRegister()
2504             if isinstance( meshPart, list ):
2505                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2506                 unRegister.set( meshPart )
2507             self.mesh.ExportPartToDAT( meshPart, f, renumber )
2508         else:
2509             self.mesh.ExportDAT( f, renumber )
2510
2511     def ExportUNV(self, f, meshPart=None, renumber=True):
2512         """
2513         Export the mesh in a file in UNV format
2514
2515         Parameters:
2516                 f: the file name
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
2519         """
2520
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.ExportPartToUNV( meshPart, f, renumber )
2527         else:
2528             self.mesh.ExportUNV( f, renumber )
2529
2530     def ExportSTL(self, f, ascii=1, meshPart=None):
2531         """
2532         Export the mesh in a file in STL format
2533
2534         Parameters:
2535                 f: the file name
2536                 ascii: defines the file encoding
2537                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2538         """
2539
2540         if meshPart:
2541             unRegister = genObjUnRegister()
2542             if isinstance( meshPart, list ):
2543                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2544                 unRegister.set( meshPart )
2545             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2546         else:
2547             self.mesh.ExportSTL(f, ascii)
2548
2549     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2550         """
2551         Export the mesh in a file in CGNS format
2552
2553         Parameters:
2554                 f: is the file name
2555                 overwrite: boolean parameter for overwriting/not overwriting the file
2556                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2557                 groupElemsByType: if True all elements of same entity type are exported at ones,
2558                         else elements are exported in order of their IDs which can cause creation
2559                         of multiple cgns sections
2560         """
2561
2562         unRegister = genObjUnRegister()
2563         if isinstance( meshPart, list ):
2564             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2565             unRegister.set( meshPart )
2566         if isinstance( meshPart, Mesh ):
2567             meshPart = meshPart.mesh
2568         elif not meshPart:
2569             meshPart = self.mesh
2570         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2571
2572     def ExportGMF(self, f, meshPart=None):
2573         """
2574         Export the mesh in a file in GMF format.
2575         GMF files must have .mesh extension for the ASCII format and .meshb for
2576         the bynary format. Other extensions are not allowed.
2577
2578         Parameters:
2579                 f: is the file name
2580                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2581         """
2582
2583         unRegister = genObjUnRegister()
2584         if isinstance( meshPart, list ):
2585             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2586             unRegister.set( meshPart )
2587         if isinstance( meshPart, Mesh ):
2588             meshPart = meshPart.mesh
2589         elif not meshPart:
2590             meshPart = self.mesh
2591         self.mesh.ExportGMF(meshPart, f, True)
2592
2593     def ExportToMED(self, *args, **kwargs):
2594         """
2595         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2596         Export the mesh in a file in MED format
2597         allowing to overwrite the file if it exists or add the exported data to its contents
2598
2599         Parameters:
2600                 fileName: the file name
2601                 opt (boolean): parameter for creating/not creating
2602                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2603                 overwrite: boolean parameter for overwriting/not overwriting the file
2604                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2605
2606                         - 1D if all mesh nodes lie on OX coordinate axis, or
2607                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2608                         - 3D in the rest cases.
2609
2610                         If **autoDimension** is *False*, the space dimension is always 3.
2611         """
2612
2613         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2614         # process positional arguments
2615         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2616         fileName      = args[0]
2617         auto_groups   = args[1] if len(args) > 1 else False
2618         overwrite     = args[2] if len(args) > 2 else True
2619         autoDimension = args[3] if len(args) > 3 else True
2620         # process keywords arguments
2621         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2622         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2623         overwrite     = kwargs.get("overwrite", overwrite)
2624         autoDimension = kwargs.get("autoDimension", autoDimension)
2625         minor = -1
2626         # invoke engine's function
2627         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2628
2629     def ExportToMEDX(self, *args, **kwargs):
2630         """
2631         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2632         Export the mesh in a file in MED format
2633
2634         Parameters:
2635                 fileName: the file name
2636                 opt (boolean): parameter for creating/not creating
2637                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2638                 overwrite: boolean parameter for overwriting/not overwriting the file
2639                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2640
2641                         - 1D if all mesh nodes lie on OX coordinate axis, or
2642                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2643                         - 3D in the rest cases.
2644
2645                         If **autoDimension** is *False*, the space dimension is always 3.
2646                 """
2647
2648         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2649         # process positional arguments
2650         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2651         fileName      = args[0]
2652         auto_groups   = args[1] if len(args) > 1 else False
2653         overwrite     = args[2] if len(args) > 2 else True
2654         autoDimension = args[3] if len(args) > 3 else True
2655         # process keywords arguments
2656         auto_groups   = kwargs.get("auto_groups", auto_groups)
2657         overwrite     = kwargs.get("overwrite", overwrite)
2658         autoDimension = kwargs.get("autoDimension", autoDimension)
2659         minor = -1
2660         # invoke engine's function
2661         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2662         return
2663
2664
2665     def Append(self, meshes, uniteIdenticalGroups = True,
2666                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2667         """
2668         Append given meshes into this mesh.
2669         All groups of input meshes will be created in this mesh.
2670
2671         Parameters:
2672                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2673                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2674                 mergeNodesAndElements: if True, equal nodes and elements are merged
2675                 mergeTolerance: tolerance for merging nodes
2676                 allGroups: forces creation of groups corresponding to every input mesh
2677         """
2678         self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2679                                    mergeNodesAndElements, mergeTolerance, allGroups,
2680                                    meshToAppendTo = self.GetMesh() )
2681
2682     # Operations with groups:
2683     # ----------------------
2684     def CreateEmptyGroup(self, elementType, name):
2685         """
2686         Create an empty standalone mesh group
2687
2688         Parameters:
2689                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group;
2690                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2691                 name: the name of the mesh group
2692
2693         Returns:
2694                 :class:`SMESH.SMESH_Group`
2695         """
2696
2697         return self.mesh.CreateGroup(elementType, name)
2698
2699     def Group(self, grp, name=""):
2700         """
2701         Create a mesh group based on the geometric object *grp*
2702         and give it a *name*.
2703         If *name* is not defined the name of the geometric group is used
2704
2705         Note:
2706                 Works like :meth:`GroupOnGeom`.
2707
2708         Parameters:
2709                 grp:  a geometric group, a vertex, an edge, a face or a solid
2710                 name: the name of the mesh group
2711
2712         Returns:
2713                 :class:`SMESH.SMESH_GroupOnGeom`
2714         """
2715
2716         return self.GroupOnGeom(grp, name)
2717
2718     def GroupOnGeom(self, grp, name="", typ=None):
2719         """
2720         Create a mesh group based on the geometrical object *grp*
2721         and give it a *name*.
2722         if *name* is not defined the name of the geometric group is used
2723
2724         Parameters:
2725                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2726                 name: the name of the mesh group
2727                 typ:  the type of elements in the group; either of
2728                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2729                         automatically detected by the type of the geometry
2730
2731         Returns:
2732                 :class:`SMESH.SMESH_GroupOnGeom`
2733         """
2734
2735         AssureGeomPublished( self, grp, name )
2736         if name == "":
2737             name = grp.GetName()
2738         if not typ:
2739             typ = self._groupTypeFromShape( grp )
2740         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2741
2742     def _groupTypeFromShape( self, shape ):
2743         """
2744         Pivate method to get a type of group on geometry
2745         """
2746         tgeo = str(shape.GetShapeType())
2747         if tgeo == "VERTEX":
2748             typ = NODE
2749         elif tgeo == "EDGE" or tgeo == "WIRE":
2750             typ = EDGE
2751         elif tgeo == "FACE" or tgeo == "SHELL":
2752             typ = FACE
2753         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2754             typ = VOLUME
2755         elif tgeo == "COMPOUND":
2756             try:
2757               sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2758             except:
2759               # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2760               # simplification of access in geomBuilder: omniORB.registerObjref
2761               from SHAPERSTUDY_utils import getEngine
2762               gen = getEngine()
2763               if gen:
2764                 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2765             if not sub:
2766                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2767             return self._groupTypeFromShape( sub[0] )
2768         else:
2769             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2770         return typ
2771
2772     def GroupOnFilter(self, typ, name, filter):
2773         """
2774         Create a mesh group with given *name* based on the *filter*.
2775         It is a special type of group dynamically updating it's contents during
2776         mesh modification
2777
2778         Parameters:
2779                 typ: the type of elements in the group; either of
2780                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2781                 name: the name of the mesh group
2782                 filter (SMESH.Filter): the filter defining group contents
2783
2784         Returns:
2785                 :class:`SMESH.SMESH_GroupOnFilter`
2786         """
2787
2788         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2789
2790     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2791         """
2792         Create a mesh group by the given ids of elements
2793
2794         Parameters:
2795                 groupName: the name of the mesh group
2796                 elementType: the type of elements in the group; either of
2797                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2798                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2799
2800         Returns:
2801                 :class:`SMESH.SMESH_Group`
2802         """
2803
2804         group = self.mesh.CreateGroup(elementType, groupName)
2805         if isinstance( elemIDs, Mesh ):
2806             elemIDs = elemIDs.GetMesh()
2807         if hasattr( elemIDs, "GetIDs" ):
2808             if hasattr( elemIDs, "SetMesh" ):
2809                 elemIDs.SetMesh( self.GetMesh() )
2810             group.AddFrom( elemIDs )
2811         else:
2812             group.Add(elemIDs)
2813         return group
2814
2815     def MakeGroup(self,
2816                   groupName,
2817                   elementType,
2818                   CritType=FT_Undefined,
2819                   Compare=FT_EqualTo,
2820                   Threshold="",
2821                   UnaryOp=FT_Undefined,
2822                   Tolerance=1e-07):
2823         """
2824         Create a mesh group by the given conditions
2825
2826         Parameters:
2827                 groupName: the name of the mesh group
2828                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2829                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2830                         Note that the items starting from FT_LessThan are not suitable for CritType.
2831                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2832                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2833                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2834                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2835                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2836
2837         Returns:
2838                 :class:`SMESH.SMESH_GroupOnFilter`
2839         """
2840
2841         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2842         group = self.MakeGroupByCriterion(groupName, aCriterion)
2843         return group
2844
2845     def MakeGroupByCriterion(self, groupName, Criterion):
2846         """
2847         Create a mesh group by the given criterion
2848
2849         Parameters:
2850                 groupName: the name of the mesh group
2851                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2852
2853         Returns:
2854                 :class:`SMESH.SMESH_GroupOnFilter`
2855
2856         See Also:
2857                 :meth:`smeshBuilder.GetCriterion`
2858         """
2859
2860         return self.MakeGroupByCriteria( groupName, [Criterion] )
2861
2862     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2863         """
2864         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2865
2866         Parameters:
2867                 groupName: the name of the mesh group
2868                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2869                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2870
2871         Returns:
2872                 :class:`SMESH.SMESH_GroupOnFilter`
2873
2874         See Also:
2875                 :meth:`smeshBuilder.GetCriterion`
2876         """
2877
2878         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2879         group = self.MakeGroupByFilter(groupName, aFilter)
2880         return group
2881
2882     def MakeGroupByFilter(self, groupName, theFilter):
2883         """
2884         Create a mesh group by the given filter
2885
2886         Parameters:
2887                 groupName (string): the name of the mesh group
2888                 theFilter (SMESH.Filter): the filter
2889
2890         Returns:
2891                 :class:`SMESH.SMESH_GroupOnFilter`
2892
2893         See Also:
2894                 :meth:`smeshBuilder.GetFilter`
2895         """
2896
2897         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2898         #theFilter.SetMesh( self.mesh )
2899         #group.AddFrom( theFilter )
2900         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2901         return group
2902
2903     def RemoveGroup(self, group):
2904         """
2905         Remove a group
2906
2907         Parameters:
2908                 group (SMESH.SMESH_GroupBase): group to remove
2909         """
2910
2911         self.mesh.RemoveGroup(group)
2912
2913     def RemoveGroupWithContents(self, group):
2914         """
2915         Remove a group with its contents
2916
2917         Parameters:
2918                 group (SMESH.SMESH_GroupBase): group to remove
2919
2920         Note:
2921                 This operation can create gaps in numeration of nodes or elements.
2922                 Call :meth:`RenumberElements` to remove the gaps.
2923         """
2924
2925         self.mesh.RemoveGroupWithContents(group)
2926
2927     def GetGroups(self, elemType = SMESH.ALL):
2928         """
2929         Get the list of groups existing in the mesh in the order of creation
2930         (starting from the oldest one)
2931
2932         Parameters:
2933                 elemType (SMESH.ElementType): type of elements the groups contain;
2934                         by default groups of elements of all types are returned
2935
2936         Returns:
2937                 a list of :class:`SMESH.SMESH_GroupBase`
2938         """
2939
2940         groups = self.mesh.GetGroups()
2941         if elemType == SMESH.ALL:
2942             return groups
2943         typedGroups = []
2944         for g in groups:
2945             if g.GetType() == elemType:
2946                 typedGroups.append( g )
2947                 pass
2948             pass
2949         return typedGroups
2950
2951     def NbGroups(self):
2952         """
2953         Get the number of groups existing in the mesh
2954
2955         Returns:
2956                 the quantity of groups as an integer value
2957         """
2958
2959         return self.mesh.NbGroups()
2960
2961     def GetGroupNames(self):
2962         """
2963         Get the list of names of groups existing in the mesh
2964
2965         Returns:
2966                 list of strings
2967         """
2968
2969         groups = self.GetGroups()
2970         names = []
2971         for group in groups:
2972             names.append(group.GetName())
2973         return names
2974
2975     def GetGroupByName(self, name, elemType = None):
2976         """
2977         Find groups by name and type
2978
2979         Parameters:
2980                 name (string): name of the group of interest
2981                 elemType (SMESH.ElementType): type of elements the groups contain;
2982                         by default one group of any type is returned;
2983                         if elemType == SMESH.ALL then all groups of any type are returned
2984
2985         Returns:
2986                 a list of :class:`SMESH.SMESH_GroupBase`
2987         """
2988
2989         groups = []
2990         for group in self.GetGroups():
2991             if group.GetName() == name:
2992                 if elemType is None:
2993                     return [group]
2994                 if ( elemType == SMESH.ALL or
2995                      group.GetType() == elemType ):
2996                     groups.append( group )
2997         return groups
2998
2999     def UnionGroups(self, group1, group2, name):
3000         """
3001         Produce a union of two groups.
3002         A new group is created. All mesh elements that are
3003         present in the initial groups are added to the new one
3004
3005         Parameters:
3006            group1 (SMESH.SMESH_GroupBase): a group
3007            group2 (SMESH.SMESH_GroupBase): another group
3008
3009         Returns:
3010                 instance of :class:`SMESH.SMESH_Group`
3011         """
3012
3013         return self.mesh.UnionGroups(group1, group2, name)
3014
3015     def UnionListOfGroups(self, groups, name):
3016         """
3017         Produce a union list of groups.
3018         New group is created. All mesh elements that are present in
3019         initial groups are added to the new one
3020
3021         Parameters:
3022            groups: list of :class:`SMESH.SMESH_GroupBase`
3023
3024         Returns:
3025                 instance of :class:`SMESH.SMESH_Group`
3026         """
3027         return self.mesh.UnionListOfGroups(groups, name)
3028
3029     def IntersectGroups(self, group1, group2, name):
3030         """
3031         Prodice an intersection of two groups.
3032         A new group is created. All mesh elements that are common
3033         for the two initial groups are added to the new one.
3034
3035         Parameters:
3036            group1 (SMESH.SMESH_GroupBase): a group
3037            group2 (SMESH.SMESH_GroupBase): another group
3038
3039         Returns:
3040                 instance of :class:`SMESH.SMESH_Group`
3041         """
3042
3043         return self.mesh.IntersectGroups(group1, group2, name)
3044
3045     def IntersectListOfGroups(self, groups, name):
3046         """
3047         Produce an intersection of groups.
3048         New group is created. All mesh elements that are present in all
3049         initial groups simultaneously are added to the new one
3050
3051         Parameters:
3052            groups: a list of :class:`SMESH.SMESH_GroupBase`
3053
3054         Returns:
3055                 instance of :class:`SMESH.SMESH_Group`
3056         """
3057         return self.mesh.IntersectListOfGroups(groups, name)
3058
3059     def CutGroups(self, main_group, tool_group, name):
3060         """
3061         Produce a cut of two groups.
3062         A new group is created. All mesh elements that are present in
3063         the main group but are not present in the tool group are added to the new one
3064
3065         Parameters:
3066            main_group (SMESH.SMESH_GroupBase): a group to cut from
3067            tool_group (SMESH.SMESH_GroupBase): a group to cut by
3068
3069         Returns:
3070                 an instance of :class:`SMESH.SMESH_Group`
3071         """
3072
3073         return self.mesh.CutGroups(main_group, tool_group, name)
3074
3075     def CutListOfGroups(self, main_groups, tool_groups, name):
3076         """
3077         Produce a cut of groups.
3078         A new group is created. All mesh elements that are present in main groups
3079         but do not present in tool groups are added to the new one
3080
3081         Parameters:
3082            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
3083            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
3084
3085         Returns:
3086                 an instance of :class:`SMESH.SMESH_Group`
3087         """
3088
3089         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3090
3091     def CreateDimGroup(self, groups, elemType, name,
3092                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3093         """
3094         Create a standalone group of entities basing on nodes of other groups.
3095
3096         Parameters:
3097                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3098                 elemType: a type of elements to include to the new group; either of
3099                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3100                 name: a name of the new group.
3101                 nbCommonNodes: a criterion of inclusion of an element to the new group
3102                         basing on number of element nodes common with reference *groups*.
3103                         Meaning of possible values are:
3104
3105                                 - SMESH.ALL_NODES - include if all nodes are common,
3106                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3107                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3108                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
3109                 underlyingOnly: if *True* (default), an element is included to the
3110                         new group provided that it is based on nodes of an element of *groups*;
3111                         in this case the reference *groups* are supposed to be of higher dimension
3112                         than *elemType*, which can be useful for example to get all faces lying on
3113                         volumes of the reference *groups*.
3114
3115         Returns:
3116                 an instance of :class:`SMESH.SMESH_Group`
3117         """
3118
3119         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3120             groups = [groups]
3121         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3122
3123     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3124         """
3125         Distribute all faces of the mesh among groups using sharp edges and optionally
3126         existing 1D elements as group boundaries.
3127
3128         Parameters:
3129                 sharpAngle: edge is considered sharp if an angle between normals of
3130                             adjacent faces is more than \a sharpAngle in degrees.
3131                 createEdges (boolean): to create 1D elements for detected sharp edges.
3132                 useExistingEdges (boolean): to use existing edges as group boundaries
3133         Returns:
3134                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3135         """
3136         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3137         self.mesh.SetParameters(Parameters)
3138         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3139
3140     def ConvertToStandalone(self, group):
3141         """
3142         Convert group on geom into standalone group
3143         """
3144
3145         return self.mesh.ConvertToStandalone(group)
3146
3147     # Get some info about mesh:
3148     # ------------------------
3149
3150     def GetLog(self, clearAfterGet):
3151         """
3152         Return the log of nodes and elements added or removed
3153         since the previous clear of the log.
3154
3155         Parameters:
3156                 clearAfterGet: log is emptied after Get (safe if concurrents access)
3157
3158         Returns:
3159                 list of SMESH.log_block structures { commandType, number, coords, indexes }
3160         """
3161
3162         return self.mesh.GetLog(clearAfterGet)
3163
3164     def ClearLog(self):
3165         """
3166         Clear the log of nodes and elements added or removed since the previous
3167         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3168         """
3169
3170         self.mesh.ClearLog()
3171
3172     def SetAutoColor(self, theAutoColor):
3173         """
3174         Toggle auto color mode on the object.
3175         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3176
3177         Parameters:
3178                 theAutoColor (boolean): the flag which toggles auto color mode.
3179         """
3180
3181         self.mesh.SetAutoColor(theAutoColor)
3182
3183     def GetAutoColor(self):
3184         """
3185         Get flag of object auto color mode.
3186
3187         Returns:
3188                 True or False
3189         """
3190
3191         return self.mesh.GetAutoColor()
3192
3193     def GetId(self):
3194         """
3195         Get the internal ID
3196
3197         Returns:
3198             integer value, which is the internal Id of the mesh
3199         """
3200
3201         return self.mesh.GetId()
3202
3203     def HasDuplicatedGroupNamesMED(self):
3204         """
3205         Check the group names for duplications.
3206         Consider the maximum group name length stored in MED file.
3207
3208         Returns:
3209             True or False
3210         """
3211
3212         return self.mesh.HasDuplicatedGroupNamesMED()
3213
3214     def GetMeshEditor(self):
3215         """
3216         Obtain the mesh editor tool
3217
3218         Returns:
3219             an instance of :class:`SMESH.SMESH_MeshEditor`
3220         """
3221
3222         return self.editor
3223
3224     def GetIDSource(self, ids, elemType = SMESH.ALL):
3225         """
3226         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3227         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3228
3229         Parameters:
3230                 ids: list of IDs
3231                 elemType: type of elements; this parameter is used to distinguish
3232                         IDs of nodes from IDs of elements; by default ids are treated as
3233                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3234
3235         Returns:
3236             an instance of :class:`SMESH.SMESH_IDSource`
3237
3238         Warning:
3239                 call UnRegister() for the returned object as soon as it is no more useful::
3240
3241                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3242                         mesh.DoSomething( idSrc )
3243                         idSrc.UnRegister()
3244         """
3245
3246         if isinstance( ids, int ):
3247             ids = [ids]
3248         return self.editor.MakeIDSource(ids, elemType)
3249
3250
3251     # Get information about mesh contents:
3252     # ------------------------------------
3253
3254     def GetMeshInfo(self, obj = None):
3255         """
3256         Get the mesh statistic.
3257
3258         Returns:
3259                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3260         """
3261
3262         if not obj: obj = self.mesh
3263         return self.smeshpyD.GetMeshInfo(obj)
3264
3265     def NbNodes(self):
3266         """
3267         Return the number of nodes in the mesh
3268
3269         Returns:
3270             an integer value
3271         """
3272
3273         return self.mesh.NbNodes()
3274
3275     def NbElements(self):
3276         """
3277         Return the number of elements in the mesh
3278
3279         Returns:
3280             an integer value
3281         """
3282
3283         return self.mesh.NbElements()
3284
3285     def Nb0DElements(self):
3286         """
3287         Return the number of 0d elements in the mesh
3288
3289         Returns:
3290             an integer value
3291         """
3292
3293         return self.mesh.Nb0DElements()
3294
3295     def NbBalls(self):
3296         """
3297         Return the number of ball discrete elements in the mesh
3298
3299         Returns:
3300             an integer value
3301         """
3302
3303         return self.mesh.NbBalls()
3304
3305     def NbEdges(self):
3306         """
3307         Return the number of edges in the mesh
3308
3309         Returns:
3310             an integer value
3311         """
3312
3313         return self.mesh.NbEdges()
3314
3315     def NbEdgesOfOrder(self, elementOrder):
3316         """
3317         Return the number of edges with the given order in the mesh
3318
3319         Parameters:
3320                 elementOrder: the order of elements
3321                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3322
3323         Returns:
3324             an integer value
3325         """
3326
3327         return self.mesh.NbEdgesOfOrder(elementOrder)
3328
3329     def NbFaces(self):
3330         """
3331         Return the number of faces in the mesh
3332
3333         Returns:
3334             an integer value
3335         """
3336
3337         return self.mesh.NbFaces()
3338
3339     def NbFacesOfOrder(self, elementOrder):
3340         """
3341         Return the number of faces with the given order in the mesh
3342
3343         Parameters:
3344                 elementOrder: the order of elements
3345                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3346
3347         Returns:
3348             an integer value
3349         """
3350
3351         return self.mesh.NbFacesOfOrder(elementOrder)
3352
3353     def NbTriangles(self):
3354         """
3355         Return the number of triangles in the mesh
3356
3357         Returns:
3358             an integer value
3359         """
3360
3361         return self.mesh.NbTriangles()
3362
3363     def NbTrianglesOfOrder(self, elementOrder):
3364         """
3365         Return the number of triangles with the given order in the mesh
3366
3367         Parameters:
3368                 elementOrder: is the order of elements
3369                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370
3371         Returns:
3372             an integer value
3373         """
3374
3375         return self.mesh.NbTrianglesOfOrder(elementOrder)
3376
3377     def NbBiQuadTriangles(self):
3378         """
3379         Return the number of biquadratic triangles in the mesh
3380
3381         Returns:
3382             an integer value
3383         """
3384
3385         return self.mesh.NbBiQuadTriangles()
3386
3387     def NbQuadrangles(self):
3388         """
3389         Return the number of quadrangles in the mesh
3390
3391         Returns:
3392             an integer value
3393         """
3394
3395         return self.mesh.NbQuadrangles()
3396
3397     def NbQuadranglesOfOrder(self, elementOrder):
3398         """
3399         Return the number of quadrangles with the given order in the mesh
3400
3401         Parameters:
3402                 elementOrder: the order of elements
3403                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3404
3405         Returns:
3406             an integer value
3407         """
3408
3409         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3410
3411     def NbBiQuadQuadrangles(self):
3412         """
3413         Return the number of biquadratic quadrangles in the mesh
3414
3415         Returns:
3416             an integer value
3417         """
3418
3419         return self.mesh.NbBiQuadQuadrangles()
3420
3421     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3422         """
3423         Return the number of polygons of given order in the mesh
3424
3425         Parameters:
3426                 elementOrder: the order of elements
3427                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3428
3429         Returns:
3430             an integer value
3431         """
3432
3433         return self.mesh.NbPolygonsOfOrder(elementOrder)
3434
3435     def NbVolumes(self):
3436         """
3437         Return the number of volumes in the mesh
3438
3439         Returns:
3440             an integer value
3441         """
3442
3443         return self.mesh.NbVolumes()
3444
3445
3446     def NbVolumesOfOrder(self, elementOrder):
3447         """
3448         Return the number of volumes with the given order in the mesh
3449
3450         Parameters:
3451                 elementOrder:  the order of elements
3452                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3453
3454         Returns:
3455             an integer value
3456         """
3457
3458         return self.mesh.NbVolumesOfOrder(elementOrder)
3459
3460     def NbTetras(self):
3461         """
3462         Return the number of tetrahedrons in the mesh
3463
3464         Returns:
3465             an integer value
3466         """
3467
3468         return self.mesh.NbTetras()
3469
3470     def NbTetrasOfOrder(self, elementOrder):
3471         """
3472         Return the number of tetrahedrons with the given order in the mesh
3473
3474         Parameters:
3475                 elementOrder:  the order of elements
3476                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3477
3478         Returns:
3479             an integer value
3480         """
3481
3482         return self.mesh.NbTetrasOfOrder(elementOrder)
3483
3484     def NbHexas(self):
3485         """
3486         Return the number of hexahedrons in the mesh
3487
3488         Returns:
3489             an integer value
3490         """
3491
3492         return self.mesh.NbHexas()
3493
3494     def NbHexasOfOrder(self, elementOrder):
3495         """
3496         Return the number of hexahedrons with the given order in the mesh
3497
3498         Parameters:
3499                 elementOrder:  the order of elements
3500                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3501
3502         Returns:
3503             an integer value
3504         """
3505
3506         return self.mesh.NbHexasOfOrder(elementOrder)
3507
3508     def NbTriQuadraticHexas(self):
3509         """
3510         Return the number of triquadratic hexahedrons in the mesh
3511
3512         Returns:
3513             an integer value
3514         """
3515
3516         return self.mesh.NbTriQuadraticHexas()
3517
3518     def NbPyramids(self):
3519         """
3520         Return the number of pyramids in the mesh
3521
3522         Returns:
3523             an integer value
3524         """
3525
3526         return self.mesh.NbPyramids()
3527
3528     def NbPyramidsOfOrder(self, elementOrder):
3529         """
3530         Return the number of pyramids with the given order in the mesh
3531
3532         Parameters:
3533                 elementOrder:  the order of elements
3534                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3535
3536         Returns:
3537             an integer value
3538         """
3539
3540         return self.mesh.NbPyramidsOfOrder(elementOrder)
3541
3542     def NbPrisms(self):
3543         """
3544         Return the number of prisms in the mesh
3545
3546         Returns:
3547             an integer value
3548         """
3549
3550         return self.mesh.NbPrisms()
3551
3552     def NbPrismsOfOrder(self, elementOrder):
3553         """
3554         Return the number of prisms with the given order in the mesh
3555
3556         Parameters:
3557                 elementOrder:  the order of elements
3558                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3559
3560         Returns:
3561             an integer value
3562         """
3563
3564         return self.mesh.NbPrismsOfOrder(elementOrder)
3565
3566     def NbHexagonalPrisms(self):
3567         """
3568         Return the number of hexagonal prisms in the mesh
3569
3570         Returns:
3571             an integer value
3572         """
3573
3574         return self.mesh.NbHexagonalPrisms()
3575
3576     def NbPolyhedrons(self):
3577         """
3578         Return the number of polyhedrons in the mesh
3579
3580         Returns:
3581             an integer value
3582         """
3583
3584         return self.mesh.NbPolyhedrons()
3585
3586     def NbSubMesh(self):
3587         """
3588         Return the number of submeshes in the mesh
3589
3590         Returns:
3591             an integer value
3592         """
3593
3594         return self.mesh.NbSubMesh()
3595
3596     def GetElementsId(self):
3597         """
3598         Return the list of all mesh elements IDs
3599
3600         Returns:
3601             the list of integer values
3602
3603         See Also:
3604             :meth:`GetElementsByType`
3605         """
3606
3607         return self.mesh.GetElementsId()
3608
3609     def GetElementsByType(self, elementType):
3610         """
3611         Return the list of IDs of mesh elements with the given type
3612
3613         Parameters:
3614                 elementType (SMESH.ElementType):  the required type of elements
3615
3616         Returns:
3617             list of integer values
3618         """
3619
3620         return self.mesh.GetElementsByType(elementType)
3621
3622     def GetNodesId(self):
3623         """
3624         Return the list of mesh nodes IDs
3625
3626         Returns:
3627             the list of integer values
3628         """
3629
3630         return self.mesh.GetNodesId()
3631
3632     # Get the information about mesh elements:
3633     # ------------------------------------
3634
3635     def GetElementType(self, id, iselem=True):
3636         """
3637         Return the type of mesh element or node
3638
3639         Returns:
3640             the value from :class:`SMESH.ElementType` enumeration.
3641             Return SMESH.ALL if element or node with the given ID does not exist
3642         """
3643
3644         return self.mesh.GetElementType(id, iselem)
3645
3646     def GetElementGeomType(self, id):
3647         """
3648         Return the geometric type of mesh element
3649
3650         Returns:
3651             the value from :class:`SMESH.EntityType` enumeration.
3652         """
3653
3654         return self.mesh.GetElementGeomType(id)
3655
3656     def GetElementShape(self, id):
3657         """
3658         Return the shape type of mesh element
3659
3660         Returns:
3661             the value from :class:`SMESH.GeometryType` enumeration.
3662         """
3663
3664         return self.mesh.GetElementShape(id)
3665
3666     def GetSubMeshElementsId(self, Shape):
3667         """
3668         Return the list of sub-mesh elements IDs
3669
3670         Parameters:
3671                 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3672                        *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3673
3674         Returns:
3675             list of integer values
3676         """
3677
3678         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3679             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3680         else:
3681             ShapeID = Shape
3682         return self.mesh.GetSubMeshElementsId(ShapeID)
3683
3684     def GetSubMeshNodesId(self, Shape, all):
3685         """
3686         Return the list of sub-mesh nodes IDs
3687
3688         Parameters:
3689                 Shape: a geom object (sub-shape).
3690                        *Shape* must be the sub-shape of a :meth:`GetShape`
3691                 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3692
3693         Returns:
3694             list of integer values
3695         """
3696
3697         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3698             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3699         else:
3700             ShapeID = Shape
3701         return self.mesh.GetSubMeshNodesId(ShapeID, all)
3702
3703     def GetSubMeshElementType(self, Shape):
3704         """
3705         Return type of elements on given shape
3706
3707         Parameters:
3708                 Shape: a geom object (sub-shape).
3709                        *Shape* must be a sub-shape of a ShapeToMesh()
3710
3711         Returns:
3712             :class:`SMESH.ElementType`
3713         """
3714
3715         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3716             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3717         else:
3718             ShapeID = Shape
3719         return self.mesh.GetSubMeshElementType(ShapeID)
3720
3721     def Dump(self):
3722         """
3723         Get the mesh description
3724
3725         Returns:
3726             string value
3727         """
3728
3729         return self.mesh.Dump()
3730
3731
3732     # Get the information about nodes and elements of a mesh by its IDs:
3733     # -----------------------------------------------------------
3734
3735     def GetNodeXYZ(self, id):
3736         """
3737         Get XYZ coordinates of a node.
3738         If there is no node for the given ID - return an empty list
3739
3740         Returns:
3741             list of float values
3742         """
3743
3744         return self.mesh.GetNodeXYZ(id)
3745
3746     def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3747         """
3748         Return list of IDs of inverse elements for the given node.
3749         If there is no node for the given ID - return an empty list
3750
3751         Parameters:
3752                 id: node ID
3753                 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3754
3755         Returns:
3756             list of integer values
3757         """
3758
3759         return self.mesh.GetNodeInverseElements(id,elemType)
3760
3761     def GetNodePosition(self,NodeID):
3762         """
3763         Return the position of a node on the shape
3764
3765         Returns:
3766             :class:`SMESH.NodePosition`
3767         """
3768
3769         return self.mesh.GetNodePosition(NodeID)
3770
3771     def GetElementPosition(self,ElemID):
3772         """
3773         Return the position of an element on the shape
3774
3775         Returns:
3776             :class:`SMESH.ElementPosition`
3777         """
3778
3779         return self.mesh.GetElementPosition(ElemID)
3780
3781     def GetShapeID(self, id):
3782         """
3783         Return the ID of the shape, on which the given node was generated.
3784
3785         Returns:
3786             an integer value > 0 or -1 if there is no node for the given
3787             ID or the node is not assigned to any geometry
3788         """
3789
3790         return self.mesh.GetShapeID(id)
3791
3792     def GetShapeIDForElem(self,id):
3793         """
3794         Return the ID of the shape, on which the given element was generated.
3795
3796         Returns:
3797             an integer value > 0 or -1 if there is no element for the given
3798             ID or the element is not assigned to any geometry
3799         """
3800
3801         return self.mesh.GetShapeIDForElem(id)
3802
3803     def GetElemNbNodes(self, id):
3804         """
3805         Return the number of nodes of the given element
3806
3807         Returns:
3808             an integer value > 0 or -1 if there is no element for the given ID
3809         """
3810
3811         return self.mesh.GetElemNbNodes(id)
3812
3813     def GetElemNode(self, id, index):
3814         """
3815         Return the node ID the given (zero based) index for the given element.
3816
3817         * If there is no element for the given ID - return -1.
3818         * If there is no node for the given index - return -2.
3819
3820         Parameters:
3821             id (int): element ID
3822             index (int): node index within the element
3823
3824         Returns:
3825             an integer value (ID)
3826
3827         See Also:
3828             :meth:`GetElemNodes`
3829         """
3830
3831         return self.mesh.GetElemNode(id, index)
3832
3833     def GetElemNodes(self, id):
3834         """
3835         Return the IDs of nodes of the given element
3836
3837         Returns:
3838             a list of integer values
3839         """
3840
3841         return self.mesh.GetElemNodes(id)
3842
3843     def IsMediumNode(self, elementID, nodeID):
3844         """
3845         Return true if the given node is the medium node in the given quadratic element
3846         """
3847
3848         return self.mesh.IsMediumNode(elementID, nodeID)
3849
3850     def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3851         """
3852         Return true if the given node is the medium node in one of quadratic elements
3853
3854         Parameters:
3855                 nodeID: ID of the node
3856                 elementType:  the type of elements to check a state of the node, either of
3857                         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3858         """
3859
3860         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3861
3862     def ElemNbEdges(self, id):
3863         """
3864         Return the number of edges for the given element
3865         """
3866
3867         return self.mesh.ElemNbEdges(id)
3868
3869     def ElemNbFaces(self, id):
3870         """
3871         Return the number of faces for the given element
3872         """
3873
3874         return self.mesh.ElemNbFaces(id)
3875
3876     def GetElemFaceNodes(self,elemId, faceIndex):
3877         """
3878         Return nodes of given face (counted from zero) for given volumic element.
3879         """
3880
3881         return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3882
3883     def GetFaceNormal(self, faceId, normalized=False):
3884         """
3885         Return three components of normal of given mesh face
3886         (or an empty array in KO case)
3887         """
3888
3889         return self.mesh.GetFaceNormal(faceId,normalized)
3890
3891     def FindElementByNodes(self, nodes):
3892         """
3893         Return an element based on all given nodes.
3894         """
3895
3896         return self.mesh.FindElementByNodes(nodes)
3897
3898     def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3899         """
3900         Return elements including all given nodes.
3901         """
3902
3903         return self.mesh.GetElementsByNodes( nodes, elemType )
3904
3905     def IsPoly(self, id):
3906         """
3907         Return true if the given element is a polygon
3908         """
3909
3910         return self.mesh.IsPoly(id)
3911
3912     def IsQuadratic(self, id):
3913         """
3914         Return true if the given element is quadratic
3915         """
3916
3917         return self.mesh.IsQuadratic(id)
3918
3919     def GetBallDiameter(self, id):
3920         """
3921         Return diameter of a ball discrete element or zero in case of an invalid *id*
3922         """
3923
3924         return self.mesh.GetBallDiameter(id)
3925
3926     def BaryCenter(self, id):
3927         """
3928         Return XYZ coordinates of the barycenter of the given element.
3929         If there is no element for the given ID - return an empty list
3930
3931         Returns:
3932             a list of three double values
3933
3934         See also:
3935                 :meth:`smeshBuilder.GetGravityCenter`
3936         """
3937
3938         return self.mesh.BaryCenter(id)
3939
3940     def GetIdsFromFilter(self, filter, meshParts=[] ):
3941         """
3942         Pass mesh elements through the given filter and return IDs of fitting elements
3943
3944         Parameters:
3945                 filter: :class:`SMESH.Filter`
3946                 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3947
3948         Returns:
3949             a list of ids
3950
3951         See Also:
3952             :meth:`SMESH.Filter.GetIDs`
3953             :meth:`SMESH.Filter.GetElementsIdFromParts`
3954         """
3955
3956         filter.SetMesh( self.mesh )
3957
3958         if meshParts:
3959             if isinstance( meshParts, Mesh ):
3960                 filter.SetMesh( meshParts.GetMesh() )
3961                 return theFilter.GetIDs()
3962             if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3963                 meshParts = [ meshParts ]
3964             return filter.GetElementsIdFromParts( meshParts )
3965
3966         return filter.GetIDs()
3967
3968     # Get mesh measurements information:
3969     # ------------------------------------
3970
3971     def GetFreeBorders(self):
3972         """
3973         Verify whether a 2D mesh element has free edges (edges connected to one face only).
3974         Return a list of special structures (borders).
3975
3976         Returns:
3977             a list of :class:`SMESH.FreeEdges.Border`
3978         """
3979
3980         aFilterMgr = self.smeshpyD.CreateFilterManager()
3981         aPredicate = aFilterMgr.CreateFreeEdges()
3982         aPredicate.SetMesh(self.mesh)
3983         aBorders = aPredicate.GetBorders()
3984         aFilterMgr.UnRegister()
3985         return aBorders
3986
3987     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3988         """
3989         Get minimum distance between two nodes, elements or distance to the origin
3990
3991         Parameters:
3992                 id1: first node/element id
3993                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3994                 isElem1: *True* if *id1* is element id, *False* if it is node id
3995                 isElem2: *True* if *id2* is element id, *False* if it is node id
3996
3997         Returns:
3998             minimum distance value
3999         See Also:
4000             :meth:`GetMinDistance`
4001         """
4002
4003         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
4004         return aMeasure.value
4005
4006     def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
4007         """
4008         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
4009
4010         Parameters:
4011                 id1: first node/element id
4012                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
4013                 isElem1: *True* if *id1* is element id, *False* if it is node id
4014                 isElem2: *True* if *id2* is element id, *False* if it is node id
4015
4016         Returns:
4017             :class:`SMESH.Measure` structure
4018         See Also:
4019             :meth:`MinDistance`
4020         """
4021
4022         if isElem1:
4023             id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
4024         else:
4025             id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
4026         if id2 != 0:
4027             if isElem2:
4028                 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
4029             else:
4030                 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
4031             pass
4032         else:
4033             id2 = None
4034
4035         aMeasurements = self.smeshpyD.CreateMeasurements()
4036         aMeasure = aMeasurements.MinDistance(id1, id2)
4037         genObjUnRegister([aMeasurements,id1, id2])
4038         return aMeasure
4039
4040     def BoundingBox(self, objects=None, isElem=False):
4041         """
4042         Get bounding box of the specified object(s)
4043
4044         Parameters:
4045                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4046                 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4047                         *False* specifies that *objects* are nodes
4048
4049         Returns:
4050             tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4051
4052         See Also:
4053             :meth:`GetBoundingBox()`
4054         """
4055
4056         result = self.GetBoundingBox(objects, isElem)
4057         if result is None:
4058             result = (0.0,)*6
4059         else:
4060             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4061         return result
4062
4063     def GetBoundingBox(self, objects=None, isElem=False):
4064         """
4065         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4066
4067         Parameters:
4068                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4069                 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4070                         False means that *objects* are nodes
4071
4072         Returns:
4073             :class:`SMESH.Measure` structure
4074
4075         See Also:
4076             :meth:`BoundingBox()`
4077         """
4078
4079         if objects is None:
4080             objects = [self.mesh]
4081         elif isinstance(objects, tuple):
4082             objects = list(objects)
4083         if not isinstance(objects, list):
4084             objects = [objects]
4085         if len(objects) > 0 and isinstance(objects[0], int):
4086             objects = [objects]
4087         srclist = []
4088         unRegister = genObjUnRegister()
4089         for o in objects:
4090             if isinstance(o, Mesh):
4091                 srclist.append(o.mesh)
4092             elif hasattr(o, "_narrow"):
4093                 src = o._narrow(SMESH.SMESH_IDSource)
4094                 if src: srclist.append(src)
4095                 pass
4096             elif isinstance(o, list):
4097                 if isElem:
4098                     srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4099                 else:
4100                     srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4101                 unRegister.set( srclist[-1] )
4102                 pass
4103             pass
4104         aMeasurements = self.smeshpyD.CreateMeasurements()
4105         unRegister.set( aMeasurements )
4106         aMeasure = aMeasurements.BoundingBox(srclist)
4107         return aMeasure
4108
4109     # Mesh edition (SMESH_MeshEditor functionality):
4110     # ---------------------------------------------
4111
4112     def RemoveElements(self, IDsOfElements):
4113         """
4114         Remove the elements from the mesh by ids
4115
4116         Parameters:
4117                 IDsOfElements: is a list of ids of elements to remove
4118
4119         Returns:
4120             True or False
4121
4122         Note:
4123                 This operation can create gaps in numeration of elements.
4124                 Call :meth:`RenumberElements` to remove the gaps.
4125         """
4126
4127         return self.editor.RemoveElements(IDsOfElements)
4128
4129     def RemoveNodes(self, IDsOfNodes):
4130         """
4131         Remove nodes from mesh by ids
4132
4133         Parameters:
4134                 IDsOfNodes: is a list of ids of nodes to remove
4135
4136         Returns:
4137             True or False
4138
4139         Note:
4140                 This operation can create gaps in numeration of nodes.
4141                 Call :meth:`RenumberElements` to remove the gaps.
4142         """
4143
4144         return self.editor.RemoveNodes(IDsOfNodes)
4145
4146     def RemoveNodeWithReconnection(self, nodeID ):
4147         """
4148         Remove a node along with changing surrounding faces to cover a hole.
4149
4150         Parameters:
4151                 nodeID: ID of node to remove
4152         """
4153
4154         return self.editor.RemoveNodeWithReconnection( nodeID )
4155
4156     def RemoveOrphanNodes(self):
4157         """
4158         Remove all orphan (free) nodes from mesh
4159
4160         Returns:
4161             number of the removed nodes
4162
4163         Note:
4164                 This operation can create gaps in numeration of nodes.
4165                 Call :meth:`RenumberElements` to remove the gaps.
4166         """
4167
4168         return self.editor.RemoveOrphanNodes()
4169
4170     def AddNode(self, x, y, z):
4171         """
4172         Add a node to the mesh by coordinates
4173
4174         Returns:
4175             ID of the new node
4176         """
4177
4178         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4179         if hasVars: self.mesh.SetParameters(Parameters)
4180         return self.editor.AddNode( x, y, z)
4181
4182     def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4183         """
4184         Create a 0D element on a node with given number.
4185
4186         Parameters:
4187                 IDOfNode: the ID of node for creation of the element.
4188                 DuplicateElements: to add one more 0D element to a node or not
4189
4190         Returns:
4191             ID of the new 0D element
4192         """
4193
4194         return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4195
4196     def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4197         """
4198         Create 0D elements on all nodes of the given elements except those
4199         nodes on which a 0D element already exists.
4200
4201         Parameters:
4202                 theObject: an object on whose nodes 0D elements will be created.
4203                         It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4204                 theGroupName: optional name of a group to add 0D elements created
4205                         and/or found on nodes of *theObject*.
4206                 DuplicateElements: to add one more 0D element to a node or not
4207
4208         Returns:
4209             an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4210             IDs of new and/or found 0D elements. IDs of 0D elements
4211             can be retrieved from the returned object by
4212             calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4213         """
4214
4215         unRegister = genObjUnRegister()
4216         if isinstance( theObject, Mesh ):
4217             theObject = theObject.GetMesh()
4218         elif isinstance( theObject, list ):
4219             theObject = self.GetIDSource( theObject, SMESH.ALL )
4220             unRegister.set( theObject )
4221         return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4222
4223     def AddBall(self, IDOfNode, diameter):
4224         """
4225         Create a ball element on a node with given ID.
4226
4227         Parameters:
4228                 IDOfNode: the ID of node for creation of the element.
4229                 diameter: the bal diameter.
4230
4231         Returns:
4232             ID of the new ball element
4233         """
4234
4235         return self.editor.AddBall( IDOfNode, diameter )
4236
4237     def AddEdge(self, IDsOfNodes):
4238         """
4239         Create a linear or quadratic edge (this is determined
4240         by the number of given nodes).
4241
4242         Parameters:
4243                 IDsOfNodes: list of node IDs for creation of the element.
4244                         The order of nodes in this list should correspond to
4245                         the :ref:`connectivity convention <connectivity_page>`.
4246
4247         Returns:
4248             ID of the new edge
4249         """
4250
4251         return self.editor.AddEdge(IDsOfNodes)
4252
4253     def AddFace(self, IDsOfNodes):
4254         """
4255         Create a linear or quadratic face (this is determined
4256         by the number of given nodes).
4257
4258         Parameters:
4259                 IDsOfNodes: list of node IDs for creation of the element.
4260                         The order of nodes in this list should correspond to
4261                         the :ref:`connectivity convention <connectivity_page>`.
4262
4263         Returns:
4264             ID of the new face
4265         """
4266
4267         return self.editor.AddFace(IDsOfNodes)
4268
4269     def AddPolygonalFace(self, IdsOfNodes):
4270         """
4271         Add a polygonal face defined by a list of node IDs
4272
4273         Parameters:
4274                 IdsOfNodes: the list of node IDs for creation of the element.
4275
4276         Returns:
4277             ID of the new face
4278         """
4279
4280         return self.editor.AddPolygonalFace(IdsOfNodes)
4281
4282     def AddQuadPolygonalFace(self, IdsOfNodes):
4283         """
4284         Add a quadratic polygonal face defined by a list of node IDs
4285
4286         Parameters:
4287                 IdsOfNodes: the list of node IDs for creation of the element;
4288                         corner nodes follow first.
4289
4290         Returns:
4291             ID of the new face
4292         """
4293
4294         return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4295
4296     def AddVolume(self, IDsOfNodes):
4297         """
4298         Create both simple and quadratic volume (this is determined
4299         by the number of given nodes).
4300
4301         Parameters:
4302                 IDsOfNodes: list of node IDs for creation of the element.
4303                         The order of nodes in this list should correspond to
4304                         the :ref:`connectivity convention <connectivity_page>`.
4305
4306         Returns:
4307             ID of the new volumic element
4308         """
4309
4310         return self.editor.AddVolume(IDsOfNodes)
4311
4312     def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4313         """
4314         Create a volume of many faces, giving nodes for each face.
4315
4316         Parameters:
4317                 IdsOfNodes: list of node IDs for volume creation, face by face.
4318                 Quantities: list of integer values, Quantities[i]
4319                         gives the quantity of nodes in face number i.
4320
4321         Returns:
4322             ID of the new volumic element
4323         """
4324
4325         return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4326
4327     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4328         """
4329         Create a volume of many faces, giving the IDs of the existing faces.
4330
4331         Note:
4332                 The created volume will refer only to the nodes
4333                 of the given faces, not to the faces themselves.
4334
4335         Parameters:
4336                 IdsOfFaces: the list of face IDs for volume creation.
4337
4338         Returns:
4339             ID of the new volumic element
4340         """
4341
4342         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4343
4344
4345     def SetNodeOnVertex(self, NodeID, Vertex):
4346         """
4347         Bind a node to a vertex
4348
4349         Parameters:
4350                 NodeID: a node ID
4351                 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4352
4353         Returns:
4354             True if succeed else raises an exception
4355         """
4356
4357         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4358             VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4359         else:
4360             VertexID = Vertex
4361         try:
4362             self.editor.SetNodeOnVertex(NodeID, VertexID)
4363         except SALOME.SALOME_Exception as inst:
4364             raise ValueError(inst.details.text)
4365         return True
4366
4367
4368     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4369         """
4370         Store the node position on an edge
4371
4372         Parameters:
4373                 NodeID: a node ID
4374                 Edge: an edge (GEOM.GEOM_Object) or edge ID
4375                 paramOnEdge: a parameter on the edge where the node is located
4376
4377         Returns:
4378             True if succeed else raises an exception
4379         """
4380
4381         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4382             EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4383         else:
4384             EdgeID = Edge
4385         try:
4386             self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4387         except SALOME.SALOME_Exception as inst:
4388             raise ValueError(inst.details.text)
4389         return True
4390
4391     def SetNodeOnFace(self, NodeID, Face, u, v):
4392         """
4393         Store node position on a face
4394
4395         Parameters:
4396                 NodeID: a node ID
4397                 Face: a face (GEOM.GEOM_Object) or face ID
4398                 u: U parameter on the face where the node is located
4399                 v: V parameter on the face where the node is located
4400
4401         Returns:
4402             True if succeed else raises an exception
4403         """
4404
4405         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4406             FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4407         else:
4408             FaceID = Face
4409         try:
4410             self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4411         except SALOME.SALOME_Exception as inst:
4412             raise ValueError(inst.details.text)
4413         return True
4414
4415     def SetNodeInVolume(self, NodeID, Solid):
4416         """
4417         Bind a node to a solid
4418
4419         Parameters:
4420                 NodeID: a node ID
4421                 Solid:  a solid (GEOM.GEOM_Object) or solid ID
4422
4423         Returns:
4424             True if succeed else raises an exception
4425         """
4426
4427         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4428             SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4429         else:
4430             SolidID = Solid
4431         try:
4432             self.editor.SetNodeInVolume(NodeID, SolidID)
4433         except SALOME.SALOME_Exception as inst:
4434             raise ValueError(inst.details.text)
4435         return True
4436
4437     def SetMeshElementOnShape(self, ElementID, Shape):
4438         """
4439         Bind an element to a shape
4440
4441         Parameters:
4442                 ElementID: an element ID
4443                 Shape: a shape (GEOM.GEOM_Object) or shape ID
4444
4445         Returns:
4446             True if succeed else raises an exception
4447         """
4448
4449         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4450             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4451         else:
4452             ShapeID = Shape
4453         try:
4454             self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4455         except SALOME.SALOME_Exception as inst:
4456             raise ValueError(inst.details.text)
4457         return True
4458
4459
4460     def MoveNode(self, NodeID, x, y, z):
4461         """
4462         Move the node with the given id
4463
4464         Parameters:
4465                 NodeID: the id of the node
4466                 x:  a new X coordinate
4467                 y:  a new Y coordinate
4468                 z:  a new Z coordinate
4469
4470         Returns:
4471             True if succeed else False
4472         """
4473
4474         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4475         if hasVars: self.mesh.SetParameters(Parameters)
4476         return self.editor.MoveNode(NodeID, x, y, z)
4477
4478     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4479         """
4480         Find the node closest to a point and moves it to a point location
4481
4482         Parameters:
4483                 x:  the X coordinate of a point
4484                 y:  the Y coordinate of a point
4485                 z:  the Z coordinate of a point
4486                 NodeID: if specified (>0), the node with this ID is moved,
4487                         otherwise, the node closest to point (*x*, *y*, *z*) is moved
4488
4489         Returns:
4490             the ID of a moved node
4491         """
4492
4493         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4494         if hasVars: self.mesh.SetParameters(Parameters)
4495         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4496
4497     def FindNodeClosestTo(self, x, y, z):
4498         """
4499         Find the node closest to a point
4500
4501         Parameters:
4502                 x:  the X coordinate of a point
4503                 y:  the Y coordinate of a point
4504                 z:  the Z coordinate of a point
4505
4506         Returns:
4507             the ID of a node
4508         """
4509
4510         return self.editor.FindNodeClosestTo(x, y, z)
4511
4512     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4513         """
4514         Find the elements where a point lays IN or ON
4515
4516         Parameters:
4517                 x,y,z (float): coordinates of the point
4518                 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4519                         means elements of any type excluding nodes, discrete and 0D elements.
4520                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4521
4522         Returns:
4523             list of IDs of found elements
4524         """
4525         if meshPart:
4526             return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4527         else:
4528             return self.editor.FindElementsByPoint(x, y, z, elementType)
4529
4530     def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4531         """
4532         Project a point to a mesh object.
4533         Return ID of an element of given type where the given point is projected
4534         and coordinates of the projection point.
4535         In the case if nothing found, return -1 and []
4536         """
4537         if isinstance( meshObject, Mesh ):
4538             meshObject = meshObject.GetMesh()
4539         if not meshObject:
4540             meshObject = self.GetMesh()
4541         return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4542
4543     def GetPointState(self, x, y, z):
4544         """
4545         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4546         smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4547         UNKNOWN state means that either mesh is wrong or the analysis fails.
4548         """
4549
4550         return self.editor.GetPointState(x, y, z)
4551
4552     def IsManifold(self):
4553         """
4554         Check if a 2D mesh is manifold
4555         """
4556
4557         return self.editor.IsManifold()
4558
4559     def IsCoherentOrientation2D(self):
4560         """
4561         Check if orientation of 2D elements is coherent
4562         """
4563
4564         return self.editor.IsCoherentOrientation2D()
4565
4566     def Get1DBranches( self, edges, startNode = 0 ):
4567         """
4568         Partition given 1D elements into groups of contiguous edges.
4569         A node where number of meeting edges != 2 is a group end.
4570         An optional startNode is used to orient groups it belongs to.
4571
4572         Returns:
4573              A list of edge groups and a list of corresponding node groups,
4574              where the group is a list of IDs of edges or nodes, like follows
4575              [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4576              If a group is closed, the first and last nodes of the group are same.
4577         """
4578         if isinstance( edges, Mesh ):
4579             edges = edges.GetMesh()
4580         unRegister = genObjUnRegister()
4581         if isinstance( edges, list ):
4582             edges = self.GetIDSource( edges, SMESH.EDGE )
4583             unRegister.set( edges )
4584         return self.editor.Get1DBranches( edges, startNode )
4585
4586     def FindSharpEdges( self, angle, addExisting=False ):
4587         """
4588         Return sharp edges of faces and non-manifold ones.
4589         Optionally add existing edges.
4590
4591         Parameters:
4592                 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4593                 addExisting: to return existing edges (1D elements) as well
4594
4595         Returns:
4596             list of FaceEdge structures
4597         """
4598         angle = ParseParameters( angle )[0]
4599         return self.editor.FindSharpEdges( angle, addExisting )
4600
4601     def MeshToPassThroughAPoint(self, x, y, z):
4602         """
4603         Find the node closest to a point and moves it to a point location
4604
4605         Parameters:
4606                 x:  the X coordinate of a point
4607                 y:  the Y coordinate of a point
4608                 z:  the Z coordinate of a point
4609
4610         Returns:
4611             the ID of a moved node
4612         """
4613
4614         return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4615
4616     def InverseDiag(self, NodeID1, NodeID2):
4617         """
4618         Replace two neighbour triangles sharing Node1-Node2 link
4619         with the triangles built on the same 4 nodes but having other common link.
4620
4621         Parameters:
4622                 NodeID1:  the ID of the first node
4623                 NodeID2:  the ID of the second node
4624
4625         Returns:
4626             False if proper faces were not found
4627         """
4628         return self.editor.InverseDiag(NodeID1, NodeID2)
4629
4630     def DeleteDiag(self, NodeID1, NodeID2):
4631         """
4632         Replace two neighbour triangles sharing *Node1-Node2* link
4633         with a quadrangle built on the same 4 nodes.
4634
4635         Parameters:
4636                 NodeID1: ID of the first node
4637                 NodeID2: ID of the second node
4638
4639         Returns:
4640             False if proper faces were not found
4641
4642         Note:
4643                 This operation can create gaps in numeration of elements.
4644                 Call :meth:`RenumberElements` to remove the gaps.
4645         """
4646
4647         return self.editor.DeleteDiag(NodeID1, NodeID2)
4648
4649     def AddNodeOnSegment(self, Node1, Node2, position = 0.5):
4650         """
4651         Replace each triangle bound by Node1-Node2 segment with
4652         two triangles by connecting a node made on the link with a node
4653         opposite to the link.
4654
4655         Parameters:
4656                 Node1: ID of the first node
4657                 Node2: ID of the second node
4658                 position: location [0,1] of the new node on the segment
4659         """
4660         return self.editor.AddNodeOnSegment(Node1, Node2, position)
4661
4662     def AddNodeOnFace(self, face, x, y, z):
4663         """
4664         Split a face into triangles by adding a new node onto the face
4665         and connecting the new node with face nodes
4666
4667         Parameters:
4668                 face: ID of the face
4669                 x,y,z: coordinates of the new node
4670         """
4671         return self.editor.AddNodeOnFace(face, x, y, z)
4672
4673     def Reorient(self, IDsOfElements=None):
4674         """
4675         Reorient elements by ids
4676
4677         Parameters:
4678                 IDsOfElements: if undefined reorients all mesh elements
4679
4680         Returns:
4681             True if succeed else False
4682         """
4683
4684         if IDsOfElements == None:
4685             IDsOfElements = self.GetElementsId()
4686         return self.editor.Reorient(IDsOfElements)
4687
4688     def ReorientObject(self, theObject):
4689         """
4690         Reorient all elements of the object
4691
4692         Parameters:
4693                 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4694
4695         Returns:
4696             True if succeed else False
4697         """
4698
4699         if ( isinstance( theObject, Mesh )):
4700             theObject = theObject.GetMesh()
4701         return self.editor.ReorientObject(theObject)
4702
4703     def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4704         """
4705         Reorient faces contained in *the2DObject*.
4706
4707         Parameters:
4708                 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4709                 theDirection: a desired direction of normal of *theFace*.
4710                         It can be either a GEOM vector or a list of coordinates [x,y,z].
4711                 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4712                         compared with theDirection. It can be either ID of face or a point
4713                         by which the face will be found. The point can be given as either
4714                         a GEOM vertex or a list of point coordinates.
4715
4716         Returns:
4717             number of reoriented faces
4718         """
4719
4720         unRegister = genObjUnRegister()
4721         # check the2DObject
4722         if isinstance( the2DObject, Mesh ):
4723             the2DObject = the2DObject.GetMesh()
4724         if isinstance( the2DObject, list ):
4725             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4726             unRegister.set( the2DObject )
4727         # check theDirection
4728         if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4729             theDirection = self.smeshpyD.GetDirStruct( theDirection )
4730         if isinstance( theDirection, list ):
4731             theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
4732         # prepare theFace and thePoint
4733         theFace = theFaceOrPoint
4734         thePoint = PointStruct(0,0,0)
4735         if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4736             thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4737             theFace = -1
4738         if isinstance( theFaceOrPoint, list ):
4739             thePoint = PointStruct( *theFaceOrPoint )
4740             theFace = -1
4741         if isinstance( theFaceOrPoint, PointStruct ):
4742             thePoint = theFaceOrPoint
4743             theFace = -1
4744         return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4745
4746     def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
4747         """
4748         Reorient faces contained in a list of *objectFaces*
4749         equally to faces contained in a list of *referenceFaces*.
4750
4751         Parameters:
4752                  objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
4753                  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.
4754
4755         Returns:
4756                  number of reoriented faces.
4757         """
4758         if not isinstance( objectFaces, list ):
4759             objectFaces = [ objectFaces ]
4760         for i,obj2D in enumerate( objectFaces ):
4761             if isinstance( obj2D, Mesh ):
4762                 objectFaces[i] = obj2D.GetMesh()
4763         if not isinstance( referenceFaces, list ):
4764             referenceFaces = [ referenceFaces ]
4765
4766         return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
4767
4768
4769     def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4770         """
4771         Reorient faces according to adjacent volumes.
4772
4773         Parameters:
4774                 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4775                         either IDs of faces or face groups.
4776                 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4777                 theOutsideNormal: to orient faces to have their normals
4778                         pointing either *outside* or *inside* the adjacent volumes.
4779
4780         Returns:
4781             number of reoriented faces.
4782         """
4783
4784         unRegister = genObjUnRegister()
4785         # check the2DObject
4786         if not isinstance( the2DObject, list ):
4787             the2DObject = [ the2DObject ]
4788         elif the2DObject and isinstance( the2DObject[0], int ):
4789             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4790             unRegister.set( the2DObject )
4791             the2DObject = [ the2DObject ]
4792         for i,obj2D in enumerate( the2DObject ):
4793             if isinstance( obj2D, Mesh ):
4794                 the2DObject[i] = obj2D.GetMesh()
4795             if isinstance( obj2D, list ):
4796                 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4797                 unRegister.set( the2DObject[i] )
4798         # check the3DObject
4799         if isinstance( the3DObject, Mesh ):
4800             the3DObject = the3DObject.GetMesh()
4801         if isinstance( the3DObject, list ):
4802             the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4803             unRegister.set( the3DObject )
4804         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4805
4806     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4807         """
4808         Fuse the neighbouring triangles into quadrangles.
4809
4810         Parameters:
4811                 IDsOfElements: The triangles to be fused.
4812                 theCriterion:  a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4813                         applied to possible quadrangles to choose a neighbour to fuse with.
4814                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4815                         to numerical functors.
4816                 MaxAngle: is the maximum angle between element normals at which the fusion
4817                         is still performed; theMaxAngle is measured in radians.
4818                         Also it could be a name of variable which defines angle in degrees.
4819
4820         Returns:
4821             True in case of success, False otherwise.
4822
4823         Note:
4824                 This operation can create gaps in numeration of elements.
4825                 Call :meth:`RenumberElements` to remove the gaps.
4826         """
4827
4828         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4829         self.mesh.SetParameters(Parameters)
4830         if not IDsOfElements:
4831             IDsOfElements = self.GetElementsId()
4832         Functor = self.smeshpyD.GetFunctor(theCriterion)
4833         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4834
4835     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4836         """
4837         Fuse the neighbouring triangles of the object into quadrangles
4838
4839         Parameters:
4840                 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4841                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4842                         applied to possible quadrangles to choose a neighbour to fuse with.
4843                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4844                         to numerical functors.
4845                 MaxAngle: a max angle between element normals at which the fusion
4846                         is still performed; theMaxAngle is measured in radians.
4847
4848         Returns:
4849             True in case of success, False otherwise.
4850
4851         Note:
4852                 This operation can create gaps in numeration of elements.
4853                 Call :meth:`RenumberElements` to remove the gaps.
4854         """
4855
4856         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4857         self.mesh.SetParameters(Parameters)
4858         if isinstance( theObject, Mesh ):
4859             theObject = theObject.GetMesh()
4860         Functor = self.smeshpyD.GetFunctor(theCriterion)
4861         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4862
4863     def QuadToTri (self, IDsOfElements, theCriterion = None):
4864         """
4865         Split quadrangles into triangles.
4866
4867         Parameters:
4868                 IDsOfElements: the faces to be splitted.
4869                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4870                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4871                         value, then quadrangles will be split by the smallest diagonal.
4872                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4873                         to numerical functors.
4874
4875         Returns:
4876             True in case of success, False otherwise.
4877
4878         Note:
4879                 This operation can create gaps in numeration of elements.
4880                 Call :meth:`RenumberElements` to remove the gaps.
4881         """
4882         if IDsOfElements == []:
4883             IDsOfElements = self.GetElementsId()
4884         if theCriterion is None:
4885             theCriterion = FT_MaxElementLength2D
4886         Functor = self.smeshpyD.GetFunctor(theCriterion)
4887         return self.editor.QuadToTri(IDsOfElements, Functor)
4888
4889     def QuadToTriObject (self, theObject, theCriterion = None):
4890         """
4891         Split quadrangles into triangles.
4892
4893         Parameters:
4894                 theObject: the object from which the list of elements is taken,
4895                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4896                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4897                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4898                         value, then quadrangles will be split by the smallest diagonal.
4899                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4900                         to numerical functors.
4901
4902         Returns:
4903             True in case of success, False otherwise.
4904
4905         Note:
4906                 This operation can create gaps in numeration of elements.
4907                 Call :meth:`RenumberElements` to remove the gaps.
4908         """
4909         if ( isinstance( theObject, Mesh )):
4910             theObject = theObject.GetMesh()
4911         if theCriterion is None:
4912             theCriterion = FT_MaxElementLength2D
4913         Functor = self.smeshpyD.GetFunctor(theCriterion)
4914         return self.editor.QuadToTriObject(theObject, Functor)
4915
4916     def QuadTo4Tri (self, theElements=[]):
4917         """
4918         Split each of given quadrangles into 4 triangles. A node is added at the center of
4919         a quadrangle.
4920
4921         Parameters:
4922                 theElements: the faces to be splitted. This can be either
4923                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4924                         or a list of face IDs. By default all quadrangles are split
4925
4926         Note:
4927                 This operation can create gaps in numeration of elements.
4928                 Call :meth:`RenumberElements` to remove the gaps.
4929         """
4930         unRegister = genObjUnRegister()
4931         if isinstance( theElements, Mesh ):
4932             theElements = theElements.mesh
4933         elif not theElements:
4934             theElements = self.mesh
4935         elif isinstance( theElements, list ):
4936             theElements = self.GetIDSource( theElements, SMESH.FACE )
4937             unRegister.set( theElements )
4938         return self.editor.QuadTo4Tri( theElements )
4939
4940     def SplitQuad (self, IDsOfElements, Diag13):
4941         """
4942         Split quadrangles into triangles.
4943
4944         Parameters:
4945                 IDsOfElements: the faces to be splitted
4946                 Diag13 (boolean):        is used to choose a diagonal for splitting.
4947
4948         Returns:
4949             True in case of success, False otherwise.
4950
4951         Note:
4952                 This operation can create gaps in numeration of elements.
4953                 Call :meth:`RenumberElements` to remove the gaps.
4954         """
4955         if IDsOfElements == []:
4956             IDsOfElements = self.GetElementsId()
4957         return self.editor.SplitQuad(IDsOfElements, Diag13)
4958
4959     def SplitQuadObject (self, theObject, Diag13):
4960         """
4961         Split quadrangles into triangles.
4962
4963         Parameters:
4964                 theObject: the object from which the list of elements is taken,
4965                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4966                 Diag13 (boolean):    is used to choose a diagonal for splitting.
4967
4968         Returns:
4969             True in case of success, False otherwise.
4970
4971         Note:
4972                 This operation can create gaps in numeration of elements.
4973                 Call :meth:`RenumberElements` to remove the gaps.
4974         """
4975         if ( isinstance( theObject, Mesh )):
4976             theObject = theObject.GetMesh()
4977         return self.editor.SplitQuadObject(theObject, Diag13)
4978
4979     def BestSplit (self, IDOfQuad, theCriterion):
4980         """
4981         Find a better splitting of the given quadrangle.
4982
4983         Parameters:
4984                 IDOfQuad:   the ID of the quadrangle to be splitted.
4985                 theCriterion:  is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4986                         choose a diagonal for splitting.
4987                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4988                         to numerical functors.
4989
4990         Returns:
4991             * 1 if 1-3 diagonal is better,
4992             * 2 if 2-4 diagonal is better,
4993             * 0 if error occurs.
4994
4995         Note:
4996                 This operation can create gaps in numeration of elements.
4997                 Call :meth:`RenumberElements` to remove the gaps.
4998         """
4999         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
5000
5001     def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
5002         """
5003         Split volumic elements into tetrahedrons
5004
5005         Parameters:
5006                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5007                 method:  flags passing splitting method:
5008                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
5009                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
5010
5011         Note:
5012                 This operation can create gaps in numeration of elements.
5013                 Call :meth:`RenumberElements` to remove the gaps.
5014         """
5015         unRegister = genObjUnRegister()
5016         if isinstance( elems, Mesh ):
5017             elems = elems.GetMesh()
5018         if ( isinstance( elems, list )):
5019             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5020             unRegister.set( elems )
5021         self.editor.SplitVolumesIntoTetra(elems, method)
5022         return
5023
5024     def SplitBiQuadraticIntoLinear(self, elems=None):
5025         """
5026         Split bi-quadratic elements into linear ones without creation of additional nodes:
5027
5028             - bi-quadratic triangle will be split into 3 linear quadrangles;
5029             - bi-quadratic quadrangle will be split into 4 linear quadrangles;
5030             - tri-quadratic hexahedron will be split into 8 linear hexahedra.
5031
5032         Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
5033         will be split in order to keep the mesh conformal.
5034
5035         Parameters:
5036             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
5037                 if None (default), all bi-quadratic elements will be split
5038
5039         Note:
5040                 This operation can create gaps in numeration of elements.
5041                 Call :meth:`RenumberElements` to remove the gaps.
5042         """
5043         unRegister = genObjUnRegister()
5044         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
5045             elems = self.editor.MakeIDSource(elems, SMESH.ALL)
5046             unRegister.set( elems )
5047         if elems is None:
5048             elems = [ self.GetMesh() ]
5049         if isinstance( elems, Mesh ):
5050             elems = [ elems.GetMesh() ]
5051         if not isinstance( elems, list ):
5052             elems = [elems]
5053         self.editor.SplitBiQuadraticIntoLinear( elems )
5054
5055     def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
5056                                  method=smeshBuilder.Hex_2Prisms, allDomains=False ):
5057         """
5058         Split hexahedra into prisms
5059
5060         Parameters:
5061                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5062                 startHexPoint: a point used to find a hexahedron for which *facetNormal*
5063                         gives a normal vector defining facets to split into triangles.
5064                         *startHexPoint* can be either a triple of coordinates or a vertex.
5065                 facetNormal: a normal to a facet to split into triangles of a
5066                         hexahedron found by *startHexPoint*.
5067                         *facetNormal* can be either a triple of coordinates or an edge.
5068                 method:  flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
5069                         smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
5070                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
5071                         to *startHexPoint* are split, else *startHexPoint*
5072                         is used to find the facet to split in all domains present in *elems*.
5073
5074         Note:
5075                 This operation can create gaps in numeration of elements.
5076                 Call :meth:`RenumberElements` to remove the gaps.
5077         """
5078         # IDSource
5079         unRegister = genObjUnRegister()
5080         if isinstance( elems, Mesh ):
5081             elems = elems.GetMesh()
5082         if ( isinstance( elems, list )):
5083             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
5084             unRegister.set( elems )
5085             pass
5086         # axis
5087         if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
5088             startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
5089         elif isinstance( startHexPoint, list ):
5090             startHexPoint = SMESH.PointStruct( startHexPoint[0],
5091                                                startHexPoint[1],
5092                                                startHexPoint[2])
5093         if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5094             facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5095         elif isinstance( facetNormal, list ):
5096             facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5097                                                        facetNormal[1],
5098                                                        facetNormal[2])
5099         self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5100
5101         self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5102
5103     def SplitQuadsNearTriangularFacets(self):
5104         """
5105         Split quadrangle faces near triangular facets of volumes
5106
5107         Note:
5108                 This operation can create gaps in numeration of elements.
5109                 Call :meth:`RenumberElements` to remove the gaps.
5110         """
5111         faces_array = self.GetElementsByType(SMESH.FACE)
5112         for face_id in faces_array:
5113             if self.GetElemNbNodes(face_id) == 4: # quadrangle
5114                 quad_nodes = self.mesh.GetElemNodes(face_id)
5115                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5116                 isVolumeFound = False
5117                 for node1_elem in node1_elems:
5118                     if not isVolumeFound:
5119                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5120                             nb_nodes = self.GetElemNbNodes(node1_elem)
5121                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5122                                 volume_elem = node1_elem
5123                                 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5124                                 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5125                                     if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5126                                         isVolumeFound = True
5127                                         if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5128                                             self.SplitQuad([face_id], False) # diagonal 2-4
5129                                     elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5130                                         isVolumeFound = True
5131                                         self.SplitQuad([face_id], True) # diagonal 1-3
5132                                 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5133                                     if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5134                                         isVolumeFound = True
5135                                         self.SplitQuad([face_id], True) # diagonal 1-3
5136
5137     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5138         """
5139         Split hexahedrons into tetrahedrons.
5140
5141         This operation uses :doc:`pattern_mapping` functionality for splitting.
5142
5143         Parameters:
5144                 theObject: the object from which the list of hexahedrons is taken;
5145                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5146                 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5147                         pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5148                         will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5149                         key-point will be mapped into *theNode001*-th node of each volume.
5150                         The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5151
5152         Returns:
5153             True in case of success, False otherwise.
5154
5155         Note:
5156                 This operation can create gaps in numeration of elements.
5157                 Call :meth:`RenumberElements` to remove the gaps.
5158         """
5159 #    Pattern:
5160 #                     5.---------.6
5161 #                    /|#*      /|
5162 #                   / | #*    / |
5163 #                  /  |  # * /  |
5164 #                 /   |   # /*  |
5165 #       (0,0,1) 4.---------.7 * |
5166 #                |#*  |1   | # *|
5167 #                | # *.----|---#.2
5168 #                |  #/ *   |   /
5169 #                |  /#  *  |  /
5170 #                | /   # * | /
5171 #                |/      #*|/
5172 #        (0,0,0) 0.---------.3
5173         pattern_tetra = "!!! Nb of points: \n 8 \n\
5174         !!! Points: \n\
5175         0 0 0  !- 0 \n\
5176         0 1 0  !- 1 \n\
5177         1 1 0  !- 2 \n\
5178         1 0 0  !- 3 \n\
5179         0 0 1  !- 4 \n\
5180         0 1 1  !- 5 \n\
5181         1 1 1  !- 6 \n\
5182         1 0 1  !- 7 \n\
5183         !!! Indices of points of 6 tetras: \n\
5184         0 3 4 1 \n\
5185         7 4 3 1 \n\
5186         4 7 5 1 \n\
5187         6 2 5 7 \n\
5188         1 5 2 7 \n\
5189         2 3 1 7 \n"
5190
5191         pattern = self.smeshpyD.GetPattern()
5192         isDone  = pattern.LoadFromFile(pattern_tetra)
5193         if not isDone:
5194             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5195             return isDone
5196
5197         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5198         isDone = pattern.MakeMesh(self.mesh, False, False)
5199         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5200
5201         # split quafrangle faces near triangular facets of volumes
5202         self.SplitQuadsNearTriangularFacets()
5203
5204         return isDone
5205
5206     def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5207         """
5208         Split hexahedrons into prisms.
5209
5210         Uses the :doc:`pattern_mapping` functionality for splitting.
5211
5212         Parameters:
5213                 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5214                 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5215                         pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5216                         will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5217                         will be mapped into the *theNode001* -th node of each volume.
5218                         Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5219
5220         Returns:
5221             True in case of success, False otherwise.
5222
5223         Note:
5224                 This operation can create gaps in numeration of elements.
5225                 Call :meth:`RenumberElements` to remove the gaps.
5226         """
5227 #        Pattern:     5.---------.6
5228 #                     /|#       /|
5229 #                    / | #     / |
5230 #                   /  |  #   /  |
5231 #                  /   |   # /   |
5232 #        (0,0,1) 4.---------.7   |
5233 #                 |    |    |    |
5234 #                 |   1.----|----.2
5235 #                 |   / *   |   /
5236 #                 |  /   *  |  /
5237 #                 | /     * | /
5238 #                 |/       *|/
5239 #        (0,0,0) 0.---------.3
5240         pattern_prism = "!!! Nb of points: \n 8 \n\
5241         !!! Points: \n\
5242         0 0 0  !- 0 \n\
5243         0 1 0  !- 1 \n\
5244         1 1 0  !- 2 \n\
5245         1 0 0  !- 3 \n\
5246         0 0 1  !- 4 \n\
5247         0 1 1  !- 5 \n\
5248         1 1 1  !- 6 \n\
5249         1 0 1  !- 7 \n\
5250         !!! Indices of points of 2 prisms: \n\
5251         0 1 3 4 5 7 \n\
5252         2 3 1 6 7 5 \n"
5253
5254         pattern = self.smeshpyD.GetPattern()
5255         isDone  = pattern.LoadFromFile(pattern_prism)
5256         if not isDone:
5257             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5258             return isDone
5259
5260         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5261         isDone = pattern.MakeMesh(self.mesh, False, False)
5262         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5263
5264         # Split quafrangle faces near triangular facets of volumes
5265         self.SplitQuadsNearTriangularFacets()
5266
5267         return isDone
5268
5269     def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5270                MaxNbOfIterations, MaxAspectRatio, Method):
5271         """
5272         Smooth elements
5273
5274         Parameters:
5275                 IDsOfElements: the list if ids of elements to smooth
5276                 IDsOfFixedNodes: the list of ids of fixed nodes.
5277                         Note that nodes built on edges and boundary nodes are always fixed.
5278                 MaxNbOfIterations: the maximum number of iterations
5279                 MaxAspectRatio: varies in range [1.0, inf]
5280                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5281                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5282
5283         Returns:
5284             True in case of success, False otherwise.
5285         """
5286
5287         if IDsOfElements == []:
5288             IDsOfElements = self.GetElementsId()
5289         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5290         self.mesh.SetParameters(Parameters)
5291         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5292                                   MaxNbOfIterations, MaxAspectRatio, Method)
5293
5294     def SmoothObject(self, theObject, IDsOfFixedNodes,
5295                      MaxNbOfIterations, MaxAspectRatio, Method):
5296         """
5297         Smooth elements which belong to the given object
5298
5299         Parameters:
5300                 theObject: the object to smooth
5301                 IDsOfFixedNodes: the list of ids of fixed nodes.
5302                         Note that nodes built on edges and boundary nodes are always fixed.
5303                 MaxNbOfIterations: the maximum number of iterations
5304                 MaxAspectRatio: varies in range [1.0, inf]
5305                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5306                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5307
5308         Returns:
5309             True in case of success, False otherwise.
5310         """
5311
5312         if ( isinstance( theObject, Mesh )):
5313             theObject = theObject.GetMesh()
5314         return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5315                                         MaxNbOfIterations, MaxAspectRatio, Method)
5316
5317     def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5318                          MaxNbOfIterations, MaxAspectRatio, Method):
5319         """
5320         Parametrically smooth the given elements
5321
5322         Parameters:
5323                 IDsOfElements: the list if ids of elements to smooth
5324                 IDsOfFixedNodes: the list of ids of fixed nodes.
5325                         Note that nodes built on edges and boundary nodes are always fixed.
5326                 MaxNbOfIterations: the maximum number of iterations
5327                 MaxAspectRatio: varies in range [1.0, inf]
5328                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5329                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5330
5331         Returns:
5332             True in case of success, False otherwise.
5333         """
5334
5335         if IDsOfElements == []:
5336             IDsOfElements = self.GetElementsId()
5337         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5338         self.mesh.SetParameters(Parameters)
5339         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5340                                             MaxNbOfIterations, MaxAspectRatio, Method)
5341
5342     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5343                                MaxNbOfIterations, MaxAspectRatio, Method):
5344         """
5345         Parametrically smooth the elements which belong to the given object
5346
5347         Parameters:
5348                 theObject: the object to smooth
5349                 IDsOfFixedNodes: the list of ids of fixed nodes.
5350                         Note that nodes built on edges and boundary nodes are always fixed.
5351                 MaxNbOfIterations: the maximum number of iterations
5352                 MaxAspectRatio: varies in range [1.0, inf]
5353                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5354                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5355
5356         Returns:
5357             True in case of success, False otherwise.
5358         """
5359
5360         if ( isinstance( theObject, Mesh )):
5361             theObject = theObject.GetMesh()
5362         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5363                                                   MaxNbOfIterations, MaxAspectRatio, Method)
5364
5365     def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5366         """
5367         Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5368         them with quadratic with the same id.
5369
5370         Parameters:
5371                 theForce3d: method of new node creation:
5372
5373                   * False - the medium node lies at the geometrical entity from which the mesh element is built
5374                   * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5375                 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5376                 theToBiQuad: If True, converts the mesh to bi-quadratic
5377
5378         Returns:
5379             :class:`SMESH.ComputeError` which can hold a warning
5380
5381         Warning:
5382             If *theSubMesh* is provided, the mesh can become non-conformal
5383
5384         Note:
5385                 This operation can create gaps in numeration of nodes or elements.
5386                 Call :meth:`RenumberElements` to remove the gaps.
5387         """
5388
5389         if isinstance( theSubMesh, Mesh ):
5390             theSubMesh = theSubMesh.mesh
5391         if theToBiQuad:
5392             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5393         else:
5394             if theSubMesh:
5395                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5396             else:
5397                 self.editor.ConvertToQuadratic(theForce3d)
5398         error = self.editor.GetLastError()
5399         if error and error.comment:
5400             print(error.comment)
5401         return error
5402
5403     def ConvertFromQuadratic(self, theSubMesh=None):
5404         """
5405         Convert the mesh from quadratic to ordinary,
5406         deletes old quadratic elements,
5407         replacing them with ordinary mesh elements with the same id.
5408
5409         Parameters:
5410             theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5411
5412         Warning:
5413             If *theSubMesh* is provided, the mesh can become non-conformal
5414
5415         Note:
5416                 This operation can create gaps in numeration of nodes or elements.
5417                 Call :meth:`RenumberElements` to remove the gaps.
5418         """
5419
5420         if theSubMesh:
5421             self.editor.ConvertFromQuadraticObject(theSubMesh)
5422         else:
5423             return self.editor.ConvertFromQuadratic()
5424
5425     def Make2DMeshFrom3D(self):
5426         """
5427         Create 2D mesh as skin on boundary faces of a 3D mesh
5428
5429         Returns:
5430             True if operation has been completed successfully, False otherwise
5431         """
5432
5433         return self.editor.Make2DMeshFrom3D()
5434
5435     def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5436                          toCopyElements=False, toCopyExistingBondary=False):
5437         """
5438         Create missing boundary elements
5439
5440         Parameters:
5441                 elements: elements whose boundary is to be checked:
5442                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5443                         If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5444                 dimension: defines type of boundary elements to create, either of
5445                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5446                         SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5447                 groupName: a name of group to store created boundary elements in,
5448                         "" means not to create the group
5449                 meshName: a name of new mesh to store created boundary elements in,
5450                         "" means not to create the new mesh
5451                 toCopyElements: if True, the checked elements will be copied into
5452                         the new mesh else only boundary elements will be copied into the new mesh
5453                 toCopyExistingBondary: if True, not only new but also pre-existing
5454                         boundary elements will be copied into the new mesh
5455
5456         Returns:
5457             tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5458         """
5459
5460         unRegister = genObjUnRegister()
5461         if isinstance( elements, Mesh ):
5462             elements = elements.GetMesh()
5463         if ( isinstance( elements, list )):
5464             elemType = SMESH.ALL
5465             if elements: elemType = self.GetElementType( elements[0], iselem=True)
5466             elements = self.editor.MakeIDSource(elements, elemType)
5467             unRegister.set( elements )
5468         mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5469                                                    toCopyElements,toCopyExistingBondary)
5470         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5471         return mesh, group
5472
5473     def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5474                              toCopyAll=False, groups=[]):
5475         """
5476         Create missing boundary elements around either the whole mesh or
5477         groups of elements
5478
5479         Parameters:
5480                 dimension: defines type of boundary elements to create, either of
5481                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5482                 groupName: a name of group to store all boundary elements in,
5483                         "" means not to create the group
5484                 meshName: a name of a new mesh, which is a copy of the initial
5485                         mesh + created boundary elements; "" means not to create the new mesh
5486                 toCopyAll: if True, the whole initial mesh will be copied into
5487                         the new mesh else only boundary elements will be copied into the new mesh
5488                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5489
5490         Returns:
5491                 tuple( long, mesh, group )
5492                        - long - number of added boundary elements
5493                        - mesh - the :class:`Mesh` where elements were added to
5494                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5495         """
5496
5497         nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5498                                                            toCopyAll,groups)
5499         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5500         return nb, mesh, group
5501
5502     def RenumberNodes(self):
5503         """
5504         Renumber mesh nodes to remove unused node IDs
5505         """
5506         self.editor.RenumberNodes()
5507
5508     def RenumberElements(self):
5509         """
5510         Renumber mesh elements to remove unused element IDs
5511         """
5512         self.editor.RenumberElements()
5513
5514     def _getIdSourceList(self, arg, idType, unRegister):
5515         """
5516         Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5517         """
5518         if arg and isinstance( arg, list ):
5519             if isinstance( arg[0], int ):
5520                 arg = self.GetIDSource( arg, idType )
5521                 unRegister.set( arg )
5522             elif isinstance( arg[0], Mesh ):
5523                 arg[0] = arg[0].GetMesh()
5524         elif isinstance( arg, Mesh ):
5525             arg = arg.GetMesh()
5526         if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5527             arg = [arg]
5528         return arg
5529
5530     def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5531                              MakeGroups=False, TotalAngle=False):
5532         """
5533         Generate new elements by rotation of the given elements and nodes around the axis
5534
5535         Parameters:
5536                 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5537                 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5538                 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5539                 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5540                 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5541                         which defines angle in degrees
5542                 NbOfSteps: the number of steps
5543                 Tolerance: tolerance
5544                 MakeGroups: forces the generation of new groups from existing ones
5545                 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5546                         of all steps, else - size of each step
5547
5548         Returns:
5549             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5550         """
5551
5552         unRegister = genObjUnRegister()
5553         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5554         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5555         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5556
5557         if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5558             Axis = self.smeshpyD.GetAxisStruct( Axis )
5559         if isinstance( Axis, list ):
5560             Axis = SMESH.AxisStruct( *Axis )
5561
5562         AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5563         NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5564         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5565         self.mesh.SetParameters(Parameters)
5566         if TotalAngle and NbOfSteps:
5567             AngleInRadians /= NbOfSteps
5568         return self.editor.RotationSweepObjects( nodes, edges, faces,
5569                                                  Axis, AngleInRadians,
5570                                                  NbOfSteps, Tolerance, MakeGroups)
5571
5572     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5573                       MakeGroups=False, TotalAngle=False):
5574         """
5575         Generate new elements by rotation of the elements around the axis
5576
5577         Parameters:
5578             IDsOfElements: the list of ids of elements to sweep
5579             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5580             AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5581             NbOfSteps: the number of steps
5582             Tolerance: tolerance
5583             MakeGroups: forces the generation of new groups from existing ones
5584             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5585                 of all steps, else - size of each step
5586
5587         Returns:
5588             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5589         """
5590
5591         return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5592                                          AngleInRadians, NbOfSteps, Tolerance,
5593                                          MakeGroups, TotalAngle)
5594
5595     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5596                             MakeGroups=False, TotalAngle=False):
5597         """
5598         Generate new elements by rotation of the elements of object around the axis
5599         theObject object which elements should be sweeped.
5600         It can be a mesh, a sub mesh or a group.
5601
5602         Parameters:
5603             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5604             AngleInRadians: the angle of Rotation
5605             NbOfSteps: number of steps
5606             Tolerance: tolerance
5607             MakeGroups: forces the generation of new groups from existing ones
5608             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5609                 of all steps, else - size of each step
5610
5611         Returns:
5612             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5613         """
5614
5615         return self.RotationSweepObjects( [], theObject, theObject, Axis,
5616                                           AngleInRadians, NbOfSteps, Tolerance,
5617                                           MakeGroups, TotalAngle )
5618
5619     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5620                               MakeGroups=False, TotalAngle=False):
5621         """
5622         Generate new elements by rotation of the elements of object around the axis
5623         theObject object which elements should be sweeped.
5624         It can be a mesh, a sub mesh or a group.
5625
5626         Parameters:
5627             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5628             AngleInRadians: the angle of Rotation
5629             NbOfSteps: number of steps
5630             Tolerance: tolerance
5631             MakeGroups: forces the generation of new groups from existing ones
5632             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5633                 of all steps, else - size of each step
5634
5635         Returns:
5636             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5637             empty list otherwise
5638         """
5639
5640         return self.RotationSweepObjects([],theObject,[], Axis,
5641                                          AngleInRadians, NbOfSteps, Tolerance,
5642                                          MakeGroups, TotalAngle)
5643
5644     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5645                               MakeGroups=False, TotalAngle=False):
5646         """
5647         Generate new elements by rotation of the elements of object around the axis
5648         theObject object which elements should be sweeped.
5649         It can be a mesh, a sub mesh or a group.
5650
5651         Parameters:
5652             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5653             AngleInRadians: the angle of Rotation
5654             NbOfSteps: number of steps
5655             Tolerance: tolerance
5656             MakeGroups: forces the generation of new groups from existing ones
5657             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5658                 of all steps, else - size of each step
5659
5660         Returns:
5661             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5662         """
5663
5664         return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5665                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5666
5667     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5668                               scaleFactors=[], linearVariation=False, basePoint=[],
5669                               angles=[], anglesVariation=False):
5670         """
5671         Generate new elements by extrusion of the given elements and nodes
5672
5673         Parameters:
5674             nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5675             edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5676             faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5677             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5678                 the direction and value of extrusion for one step (the total extrusion
5679                 length will be NbOfSteps * ||StepVector||)
5680             NbOfSteps: the number of steps
5681             MakeGroups: forces the generation of new groups from existing ones
5682             scaleFactors: optional scale factors to apply during extrusion
5683             linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5684                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5685             basePoint: optional scaling and rotation center; if not provided, a gravity center of
5686                 nodes and elements being extruded is used as the scaling center.
5687                 It can be either
5688
5689                         - a list of tree components of the point or
5690                         - a node ID or
5691                         - a GEOM point
5692             angles: list of angles in radians. Nodes at each extrusion step are rotated
5693                 around *basePoint*, additionally to previous steps.
5694             anglesVariation: forces the computation of rotation angles as linear
5695                 variation of the given *angles* along path steps
5696         Returns:
5697             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5698
5699         Example: :ref:`tui_extrusion`
5700         """
5701         unRegister = genObjUnRegister()
5702         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5703         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5704         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5705
5706         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5707             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5708         if isinstance( StepVector, list ):
5709             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5710
5711         if isinstance( basePoint, int):
5712             xyz = self.GetNodeXYZ( basePoint )
5713             if not xyz:
5714                 raise RuntimeError("Invalid node ID: %s" % basePoint)
5715             basePoint = xyz
5716         if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5717             basePoint = self.geompyD.PointCoordinates( basePoint )
5718
5719         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5720         scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5721         angles,angleParameters,hasVars = ParseAngles(angles)
5722         Parameters = StepVector.PS.parameters + var_separator + \
5723                      Parameters + var_separator + \
5724                      scaleParameters + var_separator + angleParameters
5725         self.mesh.SetParameters(Parameters)
5726
5727         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5728                                                   StepVector, NbOfSteps, MakeGroups,
5729                                                   scaleFactors, linearVariation, basePoint,
5730                                                   angles, anglesVariation )
5731
5732
5733     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5734         """
5735         Generate new elements by extrusion of the elements with given ids
5736
5737         Parameters:
5738             IDsOfElements: the list of ids of elements or nodes for extrusion
5739             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5740                 the direction and value of extrusion for one step (the total extrusion
5741                 length will be NbOfSteps * ||StepVector||)
5742             NbOfSteps: the number of steps
5743             MakeGroups: forces the generation of new groups from existing ones
5744             IsNodes: is True if elements with given ids are nodes
5745
5746         Returns:
5747             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5748
5749         Example: :ref:`tui_extrusion`
5750         """
5751         n,e,f = [],[],[]
5752         if IsNodes: n = IDsOfElements
5753         else      : e,f, = IDsOfElements,IDsOfElements
5754         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5755
5756     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5757                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5758         """
5759         Generate new elements by extrusion along the normal to a discretized surface or wire
5760
5761         Parameters:
5762             Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5763                 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5764             StepSize: length of one extrusion step (the total extrusion
5765                 length will be *NbOfSteps* *StepSize*).
5766             NbOfSteps: number of extrusion steps.
5767             ByAverageNormal: if True each node is translated by *StepSize*
5768                 along the average of the normal vectors to the faces sharing the node;
5769                 else each node is translated along the same average normal till
5770                 intersection with the plane got by translation of the face sharing
5771                 the node along its own normal by *StepSize*.
5772             UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5773                 for every node of *Elements*.
5774             MakeGroups: forces generation of new groups from existing ones.
5775             Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5776                 is not yet implemented. This parameter is used if *Elements* contains
5777                 both faces and edges, i.e. *Elements* is a Mesh.
5778
5779         Returns:
5780             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5781             empty list otherwise.
5782         Example: :ref:`tui_extrusion`
5783         """
5784
5785         unRegister = genObjUnRegister()
5786         if isinstance( Elements, Mesh ):
5787             Elements = [ Elements.GetMesh() ]
5788         if isinstance( Elements, list ):
5789             if not Elements:
5790                 raise RuntimeError("Elements empty!")
5791             if isinstance( Elements[0], Mesh ):
5792                 Elements = [ Elements[0].GetMesh() ]
5793             if isinstance( Elements[0], int ):
5794                 Elements = self.GetIDSource( Elements, SMESH.ALL )
5795                 unRegister.set( Elements )
5796         if not isinstance( Elements, list ):
5797             Elements = [ Elements ]
5798         StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5799         self.mesh.SetParameters(Parameters)
5800         return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5801                                              ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5802
5803     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5804         """
5805         Generate new elements by extrusion of the elements or nodes which belong to the object
5806
5807         Parameters:
5808             theObject: the object whose elements or nodes should be processed.
5809                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5810             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5811                 the direction and value of extrusion for one step (the total extrusion
5812                 length will be NbOfSteps * ||StepVector||)
5813             NbOfSteps: the number of steps
5814             MakeGroups: forces the generation of new groups from existing ones
5815             IsNodes: is True if elements to extrude are nodes
5816
5817         Returns:
5818             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5819         Example: :ref:`tui_extrusion`
5820         """
5821
5822         n,e,f = [],[],[]
5823         if IsNodes: n    = theObject
5824         else      : e,f, = theObject,theObject
5825         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5826
5827     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5828         """
5829         Generate new elements by extrusion of edges which belong to the object
5830
5831         Parameters:
5832             theObject: object whose 1D elements should be processed.
5833                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5834             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5835                 the direction and value of extrusion for one step (the total extrusion
5836                 length will be NbOfSteps * ||StepVector||)
5837             NbOfSteps: the number of steps
5838             MakeGroups: to generate new groups from existing ones
5839
5840         Returns:
5841             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5842         Example: :ref:`tui_extrusion`
5843         """
5844
5845         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5846
5847     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5848         """
5849         Generate new elements by extrusion of faces which belong to the object
5850
5851         Parameters:
5852             theObject: object whose 2D elements should be processed.
5853                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5854             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5855                 the direction and value of extrusion for one step (the total extrusion
5856                 length will be NbOfSteps * ||StepVector||)
5857             NbOfSteps: the number of steps
5858             MakeGroups: forces the generation of new groups from existing ones
5859
5860         Returns:
5861             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5862         Example: :ref:`tui_extrusion`
5863         """
5864
5865         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5866
5867     def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5868                           ExtrFlags, SewTolerance, MakeGroups=False):
5869         """
5870         Generate new elements by extrusion of the elements with given ids
5871
5872         Parameters:
5873             IDsOfElements: is ids of elements
5874             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5875                 the direction and value of extrusion for one step (the total extrusion
5876                 length will be NbOfSteps * ||StepVector||)
5877             NbOfSteps: the number of steps
5878             ExtrFlags: sets flags for extrusion
5879             SewTolerance: uses for comparing locations of nodes if flag
5880                 EXTRUSION_FLAG_SEW is set
5881             MakeGroups: forces the generation of new groups from existing ones
5882
5883         Returns:
5884             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5885         """
5886
5887         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5888             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5889         if isinstance( StepVector, list ):
5890             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5891         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5892                                              ExtrFlags, SewTolerance, MakeGroups)
5893
5894     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5895                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5896                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5897                                   ScaleFactors=[], ScalesVariation=False):
5898         """
5899         Generate new elements by extrusion of the given elements and nodes along the path.
5900         The path of extrusion must be a meshed edge.
5901
5902         Parameters:
5903             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5904             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5905             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5906             PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5907             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
5908             NodeStart: the first or the last node on the path. Defines the direction of extrusion
5909             HasAngles: not used obsolete
5910             Angles: list of angles in radians. Nodes at each extrusion step are rotated
5911                 around *basePoint*, additionally to previous steps.
5912             LinearVariation: forces the computation of rotation angles as linear
5913                 variation of the given Angles along path steps
5914             HasRefPoint: allows using the reference point
5915             RefPoint: optional scaling and rotation center (mass center of the extruded
5916                 elements by default). The User can specify any point as the Reference Point.
5917                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5918             MakeGroups: forces the generation of new groups from existing ones
5919             ScaleFactors: optional scale factors to apply during extrusion
5920             ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5921                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5922
5923         Returns:
5924             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5925             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5926         Example: :ref:`tui_extrusion_along_path`
5927         """
5928
5929         unRegister = genObjUnRegister()
5930         Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5931         Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5932         Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5933
5934         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5935             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5936         if isinstance( RefPoint, list ):
5937             if not RefPoint: RefPoint = [0,0,0]
5938             RefPoint = SMESH.PointStruct( *RefPoint )
5939         if isinstance( PathObject, Mesh ):
5940             PathObject = PathObject.GetMesh()
5941         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5942         ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5943         Parameters = AnglesParameters + var_separator + \
5944                      RefPoint.parameters + var_separator + ScalesParameters
5945         self.mesh.SetParameters(Parameters)
5946         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5947                                                      PathObject, PathShape, NodeStart,
5948                                                      HasAngles, Angles, LinearVariation,
5949                                                      HasRefPoint, RefPoint, MakeGroups,
5950                                                      ScaleFactors, ScalesVariation)
5951
5952     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5953                             HasAngles=False, Angles=[], LinearVariation=False,
5954                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5955                             ElemType=SMESH.FACE):
5956         """
5957         Generate new elements by extrusion of the given elements.
5958         The path of extrusion must be a meshed edge.
5959
5960         Parameters:
5961             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5962             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5963             NodeStart: the start node from Path. Defines the direction of extrusion
5964             HasAngles: not used obsolete
5965             Angles: list of angles in radians. Nodes at each extrusion step are rotated
5966                 around *basePoint*, additionally to previous steps.
5967             LinearVariation: forces the computation of rotation angles as linear
5968                 variation of the given Angles along path steps
5969             HasRefPoint: allows using the reference point
5970             RefPoint: the reference point around which the elements are rotated (the mass
5971                 center of the elements by default).
5972                 The User can specify any point as the Reference Point.
5973                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5974             MakeGroups: forces the generation of new groups from existing ones
5975             ElemType: type of elements for extrusion (if param Base is a mesh)
5976
5977         Returns:
5978             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5979             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5980             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5981             otherwise
5982         Example: :ref:`tui_extrusion_along_path`
5983         """
5984
5985         n,e,f = [],[],[]
5986         if ElemType == SMESH.NODE: n = Base
5987         if ElemType == SMESH.EDGE: e = Base
5988         if ElemType == SMESH.FACE: f = Base
5989         gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5990                                                HasAngles, Angles, LinearVariation,
5991                                                HasRefPoint, RefPoint, MakeGroups)
5992         if MakeGroups: return gr,er
5993         return er
5994
5995     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5996                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5997                            MakeGroups=False, LinearVariation=False):
5998         """
5999         Generate new elements by extrusion of the given elements.
6000         The path of extrusion must be a meshed edge.
6001
6002         Parameters:
6003             IDsOfElements: ids of elements
6004             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
6005             PathShape: shape (edge) defines the sub-mesh for the path
6006             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6007             HasAngles: not used obsolete
6008             Angles: list of angles in radians. Nodes at each extrusion step are rotated
6009                 around *basePoint*, additionally to previous steps.
6010             HasRefPoint: allows using the reference point
6011             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6012                 The User can specify any point as the Reference Point.
6013                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6014             MakeGroups: forces the generation of new groups from existing ones
6015             LinearVariation: forces the computation of rotation angles as linear
6016                 variation of the given Angles along path steps
6017
6018         Returns:
6019             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6020             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
6021             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6022         Example: :ref:`tui_extrusion_along_path`
6023         """
6024
6025         if not IDsOfElements:
6026             IDsOfElements = [ self.GetMesh() ]
6027         n,e,f = [],IDsOfElements,IDsOfElements
6028         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
6029                                                NodeStart, HasAngles, Angles,
6030                                                LinearVariation,
6031                                                HasRefPoint, RefPoint, MakeGroups)
6032         if MakeGroups: return gr,er
6033         return er
6034
6035     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
6036                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6037                                  MakeGroups=False, LinearVariation=False):
6038         """
6039         Generate new elements by extrusion of the elements which belong to the object.
6040         The path of extrusion must be a meshed edge.
6041
6042         Parameters:
6043             theObject: the object whose elements should be processed.
6044                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6045             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6046             PathShape: shape (edge) defines the sub-mesh for the path
6047             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6048             HasAngles: not used obsolete
6049             Angles: list of angles in radians. Nodes at each extrusion step are rotated
6050                 around *basePoint*, additionally to previous steps.
6051             HasRefPoint: allows using the reference point
6052             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6053                 The User can specify any point as the Reference Point.
6054                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6055             MakeGroups: forces the generation of new groups from existing ones
6056             LinearVariation: forces the computation of rotation angles as linear
6057                 variation of the given Angles along path steps
6058
6059         Returns:
6060             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6061             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6062             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6063         Example: :ref:`tui_extrusion_along_path`
6064         """
6065
6066         n,e,f = [],theObject,theObject
6067         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6068                                                HasAngles, Angles, LinearVariation,
6069                                                HasRefPoint, RefPoint, MakeGroups)
6070         if MakeGroups: return gr,er
6071         return er
6072
6073     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
6074                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6075                                    MakeGroups=False, LinearVariation=False):
6076         """
6077         Generate new elements by extrusion of mesh segments which belong to the object.
6078         The path of extrusion must be a meshed edge.
6079
6080         Parameters:
6081             theObject: the object whose 1D elements should be processed.
6082                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6083             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6084             PathShape: shape (edge) defines the sub-mesh for the path
6085             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6086             HasAngles: not used obsolete
6087             Angles: list of angles in radians. Nodes at each extrusion step are rotated
6088                 around *basePoint*, additionally to previous steps.
6089             HasRefPoint: allows using the reference point
6090             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
6091                 The User can specify any point as the Reference Point.
6092                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6093             MakeGroups: forces the generation of new groups from existing ones
6094             LinearVariation: forces the computation of rotation angles as linear
6095                 variation of the given Angles along path steps
6096
6097         Returns:
6098             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6099             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6100             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6101         Example: :ref:`tui_extrusion_along_path`
6102         """
6103
6104         n,e,f = [],theObject,[]
6105         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6106                                                HasAngles, Angles, LinearVariation,
6107                                                HasRefPoint, RefPoint, MakeGroups)
6108         if MakeGroups: return gr,er
6109         return er
6110
6111     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6112                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6113                                    MakeGroups=False, LinearVariation=False):
6114         """
6115         Generate new elements by extrusion of faces which belong to the object.
6116         The path of extrusion must be a meshed edge.
6117
6118         Parameters:
6119             theObject: the object whose 2D elements should be processed.
6120                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6121             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6122             PathShape: shape (edge) defines the sub-mesh for the path
6123             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6124             HasAngles: not used obsolete
6125             Angles: list of angles in radians. Nodes at each extrusion step are rotated
6126                 around *basePoint*, additionally to previous steps.
6127             HasRefPoint: allows using the reference point
6128             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6129                 The User can specify any point as the Reference Point.
6130                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6131             MakeGroups: forces the generation of new groups from existing ones
6132             LinearVariation: forces the computation of rotation angles as linear
6133                 variation of the given Angles along path steps
6134
6135         Returns:
6136             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
6137             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6138             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6139         Example: :ref:`tui_extrusion_along_path`
6140         """
6141
6142         n,e,f = [],[],theObject
6143         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6144                                                HasAngles, Angles, LinearVariation,
6145                                                HasRefPoint, RefPoint, MakeGroups)
6146         if MakeGroups: return gr,er
6147         return er
6148
6149     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6150         """
6151         Create a symmetrical copy of mesh elements
6152
6153         Parameters:
6154             IDsOfElements: list of elements ids
6155             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6156             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6157                 If the *Mirror* is a geom object this parameter is unnecessary
6158             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6159             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6160
6161         Returns:
6162             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6163         """
6164
6165         if IDsOfElements == []:
6166             IDsOfElements = self.GetElementsId()
6167         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6168             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6169             theMirrorType = Mirror._mirrorType
6170         else:
6171             self.mesh.SetParameters(Mirror.parameters)
6172         if Copy and MakeGroups:
6173             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6174         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6175         return []
6176
6177     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6178         """
6179         Create a new mesh by a symmetrical copy of mesh elements
6180
6181         Parameters:
6182             IDsOfElements: the list of elements ids
6183             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6184             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6185                 If the *Mirror* is a geom object this parameter is unnecessary
6186             MakeGroups: to generate new groups from existing ones
6187             NewMeshName: a name of the new mesh to create
6188
6189         Returns:
6190             instance of class :class:`Mesh`
6191         """
6192
6193         if IDsOfElements == []:
6194             IDsOfElements = self.GetElementsId()
6195         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6196             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6197             theMirrorType = Mirror._mirrorType
6198         else:
6199             self.mesh.SetParameters(Mirror.parameters)
6200         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6201                                           MakeGroups, NewMeshName)
6202         return Mesh(self.smeshpyD,self.geompyD,mesh)
6203
6204     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6205         """
6206         Create a symmetrical copy of the object
6207
6208         Parameters:
6209             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6210             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6211             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6212                 If the *Mirror* is a geom object this parameter is unnecessary
6213             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6214             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6215
6216         Returns:
6217             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6218         """
6219
6220         if ( isinstance( theObject, Mesh )):
6221             theObject = theObject.GetMesh()
6222         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6223             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6224             theMirrorType = Mirror._mirrorType
6225         else:
6226             self.mesh.SetParameters(Mirror.parameters)
6227         if Copy and MakeGroups:
6228             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6229         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6230         return []
6231
6232     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6233         """
6234         Create a new mesh by a symmetrical copy of the object
6235
6236         Parameters:
6237             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6238             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6239             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6240                 If the *Mirror* is a geom object this parameter is unnecessary
6241             MakeGroups: forces the generation of new groups from existing ones
6242             NewMeshName: the name of the new mesh to create
6243
6244         Returns:
6245             instance of class :class:`Mesh`
6246         """
6247
6248         if ( isinstance( theObject, Mesh )):
6249             theObject = theObject.GetMesh()
6250         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6251             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6252             theMirrorType = Mirror._mirrorType
6253         else:
6254             self.mesh.SetParameters(Mirror.parameters)
6255         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6256                                                 MakeGroups, NewMeshName)
6257         return Mesh( self.smeshpyD,self.geompyD,mesh )
6258
6259     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6260         """
6261         Translate the elements
6262
6263         Parameters:
6264             IDsOfElements: list of elements ids
6265             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6266             Copy: allows copying the translated elements
6267             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6268
6269         Returns:
6270             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6271         """
6272
6273         if IDsOfElements == []:
6274             IDsOfElements = self.GetElementsId()
6275         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6276             Vector = self.smeshpyD.GetDirStruct(Vector)
6277         if isinstance( Vector, list ):
6278             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6279         self.mesh.SetParameters(Vector.PS.parameters)
6280         if Copy and MakeGroups:
6281             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6282         self.editor.Translate(IDsOfElements, Vector, Copy)
6283         return []
6284
6285     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6286         """
6287         Create a new mesh of translated elements
6288
6289         Parameters:
6290             IDsOfElements: list of elements ids
6291             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6292             MakeGroups: forces the generation of new groups from existing ones
6293             NewMeshName: the name of the newly created mesh
6294
6295         Returns:
6296             instance of class :class:`Mesh`
6297         """
6298
6299         if IDsOfElements == []:
6300             IDsOfElements = self.GetElementsId()
6301         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6302             Vector = self.smeshpyD.GetDirStruct(Vector)
6303         if isinstance( Vector, list ):
6304             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6305         self.mesh.SetParameters(Vector.PS.parameters)
6306         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6307         return Mesh ( self.smeshpyD, self.geompyD, mesh )
6308
6309     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6310         """
6311         Translate the object
6312
6313         Parameters:
6314             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6315             Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6316             Copy: allows copying the translated elements
6317             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6318
6319         Returns:
6320             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6321         """
6322
6323         if ( isinstance( theObject, Mesh )):
6324             theObject = theObject.GetMesh()
6325         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6326             Vector = self.smeshpyD.GetDirStruct(Vector)
6327         if isinstance( Vector, list ):
6328             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6329         self.mesh.SetParameters(Vector.PS.parameters)
6330         if Copy and MakeGroups:
6331             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6332         self.editor.TranslateObject(theObject, Vector, Copy)
6333         return []
6334
6335     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6336         """
6337         Create a new mesh from the translated object
6338
6339         Parameters:
6340             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6341             Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6342             MakeGroups: forces the generation of new groups from existing ones
6343             NewMeshName: the name of the newly created mesh
6344
6345         Returns:
6346             instance of class :class:`Mesh`
6347         """
6348
6349         if isinstance( theObject, Mesh ):
6350             theObject = theObject.GetMesh()
6351         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6352             Vector = self.smeshpyD.GetDirStruct(Vector)
6353         if isinstance( Vector, list ):
6354             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6355         self.mesh.SetParameters(Vector.PS.parameters)
6356         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6357         return Mesh( self.smeshpyD, self.geompyD, mesh )
6358
6359
6360
6361     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6362         """
6363         Scale the object
6364
6365         Parameters:
6366             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6367             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6368             theScaleFact: list of 1-3 scale factors for axises
6369             Copy: allows copying the translated elements
6370             MakeGroups: forces the generation of new groups from existing
6371                 ones (if Copy)
6372
6373         Returns:
6374             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6375             empty list otherwise
6376         """
6377         unRegister = genObjUnRegister()
6378         if ( isinstance( theObject, Mesh )):
6379             theObject = theObject.GetMesh()
6380         if ( isinstance( theObject, list )):
6381             theObject = self.GetIDSource(theObject, SMESH.ALL)
6382             unRegister.set( theObject )
6383         if ( isinstance( thePoint, list )):
6384             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6385         if ( isinstance( theScaleFact, float )):
6386             theScaleFact = [theScaleFact]
6387         if ( isinstance( theScaleFact, int )):
6388             theScaleFact = [ float(theScaleFact)]
6389
6390         self.mesh.SetParameters(thePoint.parameters)
6391
6392         if Copy and MakeGroups:
6393             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6394         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6395         return []
6396
6397     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6398         """
6399         Create a new mesh from the translated object
6400
6401         Parameters:
6402             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6403             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6404             theScaleFact: list of 1-3 scale factors for axises
6405             MakeGroups: forces the generation of new groups from existing ones
6406             NewMeshName: the name of the newly created mesh
6407
6408         Returns:
6409             instance of class :class:`Mesh`
6410         """
6411         unRegister = genObjUnRegister()
6412         if (isinstance(theObject, Mesh)):
6413             theObject = theObject.GetMesh()
6414         if ( isinstance( theObject, list )):
6415             theObject = self.GetIDSource(theObject,SMESH.ALL)
6416             unRegister.set( theObject )
6417         if ( isinstance( thePoint, list )):
6418             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6419         if ( isinstance( theScaleFact, float )):
6420             theScaleFact = [theScaleFact]
6421         if ( isinstance( theScaleFact, int )):
6422             theScaleFact = [ float(theScaleFact)]
6423
6424         self.mesh.SetParameters(thePoint.parameters)
6425         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6426                                          MakeGroups, NewMeshName)
6427         return Mesh( self.smeshpyD, self.geompyD, mesh )
6428
6429
6430
6431     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6432         """
6433         Rotate the elements
6434
6435         Parameters:
6436             IDsOfElements: list of elements ids
6437             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6438             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6439             Copy: allows copying the rotated elements
6440             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6441
6442         Returns:
6443             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6444         """
6445
6446
6447         if IDsOfElements == []:
6448             IDsOfElements = self.GetElementsId()
6449         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6450             Axis = self.smeshpyD.GetAxisStruct(Axis)
6451         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6452         Parameters = Axis.parameters + var_separator + Parameters
6453         self.mesh.SetParameters(Parameters)
6454         if Copy and MakeGroups:
6455             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6456         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6457         return []
6458
6459     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6460         """
6461         Create a new mesh of rotated elements
6462
6463         Parameters:
6464             IDsOfElements: list of element ids
6465             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6466             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6467             MakeGroups: forces the generation of new groups from existing ones
6468             NewMeshName: the name of the newly created mesh
6469
6470         Returns:
6471             instance of class :class:`Mesh`
6472         """
6473
6474         if IDsOfElements == []:
6475             IDsOfElements = self.GetElementsId()
6476         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6477             Axis = self.smeshpyD.GetAxisStruct(Axis)
6478         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6479         Parameters = Axis.parameters + var_separator + Parameters
6480         self.mesh.SetParameters(Parameters)
6481         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6482                                           MakeGroups, NewMeshName)
6483         return Mesh( self.smeshpyD, self.geompyD, mesh )
6484
6485     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6486         """
6487         Rotate the object
6488
6489         Parameters:
6490             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6491             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6492             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6493             Copy: allows copying the rotated elements
6494             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6495
6496         Returns:
6497             list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6498         """
6499
6500         if (isinstance(theObject, Mesh)):
6501             theObject = theObject.GetMesh()
6502         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6503             Axis = self.smeshpyD.GetAxisStruct(Axis)
6504         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6505         Parameters = Axis.parameters + ":" + Parameters
6506         self.mesh.SetParameters(Parameters)
6507         if Copy and MakeGroups:
6508             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6509         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6510         return []
6511
6512     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6513         """
6514         Create a new mesh from the rotated object
6515
6516         Parameters:
6517             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6518             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6519             AngleInRadians: the angle of rotation (in radians)  or a name of variable which defines angle in degrees
6520             MakeGroups: forces the generation of new groups from existing ones
6521             NewMeshName: the name of the newly created mesh
6522
6523         Returns:
6524             instance of class :class:`Mesh`
6525         """
6526
6527         if (isinstance( theObject, Mesh )):
6528             theObject = theObject.GetMesh()
6529         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6530             Axis = self.smeshpyD.GetAxisStruct(Axis)
6531         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6532         Parameters = Axis.parameters + ":" + Parameters
6533         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6534                                                        MakeGroups, NewMeshName)
6535         self.mesh.SetParameters(Parameters)
6536         return Mesh( self.smeshpyD, self.geompyD, mesh )
6537
6538     def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6539         """
6540         Create an offset mesh from the given 2D object
6541
6542         Parameters:
6543             theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6544             theValue (float): signed offset size
6545             MakeGroups (boolean): forces the generation of new groups from existing ones
6546             CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements,
6547                           False means to remove original elements.
6548             NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6549
6550         Returns:
6551             A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6552         """
6553
6554         if isinstance( theObject, Mesh ):
6555             theObject = theObject.GetMesh()
6556         theValue,Parameters,hasVars = ParseParameters(Value)
6557         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6558         self.mesh.SetParameters(Parameters)
6559         if mesh_groups[0]:
6560             return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6561         return mesh_groups
6562
6563     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6564         """
6565         Find groups of adjacent nodes within Tolerance.
6566
6567         Parameters:
6568             Tolerance (float): the value of tolerance
6569             SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6570                 corner and medium nodes in separate groups thus preventing
6571                 their further merge.
6572
6573         Returns:
6574             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6575         """
6576
6577         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6578
6579     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6580                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
6581         """
6582         Find groups of adjacent nodes within Tolerance.
6583
6584         Parameters:
6585             Tolerance: the value of tolerance
6586             SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6587             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6588             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6589                 corner and medium nodes in separate groups thus preventing
6590                 their further merge.
6591
6592         Returns:
6593             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6594         """
6595
6596         unRegister = genObjUnRegister()
6597         if not isinstance( SubMeshOrGroup, list ):
6598             SubMeshOrGroup = [ SubMeshOrGroup ]
6599         for i,obj in enumerate( SubMeshOrGroup ):
6600             if isinstance( obj, Mesh ):
6601                 SubMeshOrGroup = [ obj.GetMesh() ]
6602                 break
6603             if isinstance( obj, int ):
6604                 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6605                 unRegister.set( SubMeshOrGroup )
6606                 break
6607
6608         if not isinstance( exceptNodes, list ):
6609             exceptNodes = [ exceptNodes ]
6610         if exceptNodes and isinstance( exceptNodes[0], int ):
6611             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6612             unRegister.set( exceptNodes )
6613
6614         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6615                                                         exceptNodes, SeparateCornerAndMediumNodes)
6616
6617     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6618         """
6619         Merge nodes
6620
6621         Parameters:
6622             GroupsOfNodes: a list of groups of nodes IDs for merging.
6623                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6624                 in all elements and mesh groups by nodes 1 and 25 correspondingly
6625             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6626                 If *NodesToKeep* does not include a node to keep for some group to merge,
6627                 then the first node in the group is kept.
6628             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6629                 invalid
6630
6631         Note:
6632                 This operation can create gaps in numeration of nodes or elements.
6633                 Call :meth:`RenumberElements` to remove the gaps.
6634         """
6635         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6636
6637     def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6638         """
6639         Find the elements built on the same nodes.
6640
6641         Parameters:
6642             MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6643             exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6644
6645
6646         Returns:
6647             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6648         """
6649
6650         unRegister = genObjUnRegister()
6651         if MeshOrSubMeshOrGroup is None:
6652             MeshOrSubMeshOrGroup = [ self.mesh ]
6653         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6654             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6655         elif not isinstance( MeshOrSubMeshOrGroup, list ):
6656             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6657         if isinstance( MeshOrSubMeshOrGroup[0], int ):
6658             MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6659             unRegister.set( MeshOrSubMeshOrGroup )
6660         for item in MeshOrSubMeshOrGroup:
6661             if isinstance( item, Mesh ):
6662                 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6663
6664         if not isinstance( exceptElements, list ):
6665             exceptElements = [ exceptElements ]
6666         if exceptElements and isinstance( exceptElements[0], int ):
6667             exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6668             unRegister.set( exceptElements )
6669
6670         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6671
6672     def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6673         """
6674         Merge elements in each given group.
6675
6676         Parameters:
6677             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6678                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6679                 replaced in all mesh groups by elements 1 and 25)
6680             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6681                 If *ElementsToKeep* does not include an element to keep for some group to merge,
6682                 then the first element in the group is kept.
6683
6684         Note:
6685                 This operation can create gaps in numeration of elements.
6686                 Call :meth:`RenumberElements` to remove the gaps.
6687         """
6688
6689         unRegister = genObjUnRegister()
6690         if ElementsToKeep:
6691             if not isinstance( ElementsToKeep, list ):
6692                 ElementsToKeep = [ ElementsToKeep ]
6693             if isinstance( ElementsToKeep[0], int ):
6694                 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6695                 unRegister.set( ElementsToKeep )
6696
6697         self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6698
6699     def MergeEqualElements(self):
6700         """
6701         Leave one element and remove all other elements built on the same nodes.
6702
6703         Note:
6704                 This operation can create gaps in numeration of elements.
6705                 Call :meth:`RenumberElements` to remove the gaps.
6706         """
6707
6708         self.editor.MergeEqualElements()
6709
6710     def FindFreeBorders(self, ClosedOnly=True):
6711         """
6712         Returns all or only closed free borders
6713
6714         Returns:
6715             list of SMESH.FreeBorder's
6716         """
6717
6718         return self.editor.FindFreeBorders( ClosedOnly )
6719
6720     def FillHole(self, holeNodes, groupName=""):
6721         """
6722         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6723
6724         Parameters:
6725             holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6726                 must describe all sequential nodes of the hole border. The first and the last
6727                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6728             groupName (string): name of a group to add new faces
6729         Returns:
6730             a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6731         """
6732
6733
6734         if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6735             holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6736         if not isinstance( holeNodes, SMESH.FreeBorder ):
6737             raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6738         return self.editor.FillHole( holeNodes, groupName )
6739
6740     def FindCoincidentFreeBorders (self, tolerance=0.):
6741         """
6742         Return groups of FreeBorder's coincident within the given tolerance.
6743
6744         Parameters:
6745             tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6746                 size of elements adjacent to free borders being compared is used.
6747
6748         Returns:
6749             SMESH.CoincidentFreeBorders structure
6750         """
6751
6752         return self.editor.FindCoincidentFreeBorders( tolerance )
6753
6754     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6755         """
6756         Sew FreeBorder's of each group
6757
6758         Parameters:
6759             freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6760                 where each enclosed list contains node IDs of a group of coincident free
6761                 borders such that each consequent triple of IDs within a group describes
6762                 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6763                 last node of a border.
6764                 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6765                 groups of coincident free borders, each group including two borders.
6766             createPolygons: if :code:`True` faces adjacent to free borders are converted to
6767                 polygons if a node of opposite border falls on a face edge, else such
6768                 faces are split into several ones.
6769             createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6770                 polyhedra if a node of opposite border falls on a volume edge, else such
6771                 volumes, if any, remain intact and the mesh becomes non-conformal.
6772
6773         Returns:
6774             a number of successfully sewed groups
6775
6776         Note:
6777                 This operation can create gaps in numeration of nodes or elements.
6778                 Call :meth:`RenumberElements` to remove the gaps.
6779         """
6780
6781         if freeBorders and isinstance( freeBorders, list ):
6782             # construct SMESH.CoincidentFreeBorders
6783             if isinstance( freeBorders[0], int ):
6784                 freeBorders = [freeBorders]
6785             borders = []
6786             coincidentGroups = []
6787             for nodeList in freeBorders:
6788                 if not nodeList or len( nodeList ) % 3:
6789                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6790                 group = []
6791                 while nodeList:
6792                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6793                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
6794                     nodeList = nodeList[3:]
6795                     pass
6796                 coincidentGroups.append( group )
6797                 pass
6798             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6799
6800         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6801
6802     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6803                         FirstNodeID2, SecondNodeID2, LastNodeID2,
6804                         CreatePolygons, CreatePolyedrs):
6805         """
6806         Sew free borders
6807
6808         Returns:
6809             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6810
6811         Note:
6812                 This operation can create gaps in numeration of nodes or elements.
6813                 Call :meth:`RenumberElements` to remove the gaps.
6814         """
6815
6816         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6817                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
6818                                           CreatePolygons, CreatePolyedrs)
6819
6820     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6821                                FirstNodeID2, SecondNodeID2):
6822         """
6823         Sew conform free borders
6824
6825         Returns:
6826             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6827
6828         Note:
6829                 This operation can create gaps in numeration of elements.
6830                 Call :meth:`RenumberElements` to remove the gaps.
6831         """
6832
6833         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6834                                                  FirstNodeID2, SecondNodeID2)
6835
6836     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6837                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6838         """
6839         Sew border to side
6840
6841         Returns:
6842             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6843
6844         Note:
6845                 This operation can create gaps in numeration of elements.
6846                 Call :meth:`RenumberElements` to remove the gaps.
6847         """
6848
6849         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6850                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6851
6852     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6853                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6854                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6855         """
6856         Sew two sides of a mesh. The nodes belonging to Side1 are
6857         merged with the nodes of elements of Side2.
6858         The number of elements in theSide1 and in theSide2 must be
6859         equal and they should have similar nodal connectivity.
6860         The nodes to merge should belong to side borders and
6861         the first node should be linked to the second.
6862
6863         Returns:
6864             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6865
6866         Note:
6867                 This operation can create gaps in numeration of nodes.
6868                 Call :meth:`RenumberElements` to remove the gaps.
6869         """
6870
6871         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6872                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6873                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6874
6875     def ChangeElemNodes(self, ide, newIDs):
6876         """
6877         Set new nodes for the given element. Number of nodes should be kept.
6878
6879         Parameters:
6880             ide: the element ID
6881             newIDs: nodes IDs
6882
6883         Returns:
6884             False if the number of nodes does not correspond to the type of element
6885         """
6886
6887         return self.editor.ChangeElemNodes(ide, newIDs)
6888
6889     def GetLastCreatedNodes(self):
6890         """
6891         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6892         created, this method return the list of their IDs.
6893         If new nodes were not created - return empty list
6894
6895         Returns:
6896             the list of integer values (can be empty)
6897         """
6898
6899         return self.editor.GetLastCreatedNodes()
6900
6901     def GetLastCreatedElems(self):
6902         """
6903         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6904         created this method return the list of their IDs.
6905         If new elements were not created - return empty list
6906
6907         Returns:
6908             the list of integer values (can be empty)
6909         """
6910
6911         return self.editor.GetLastCreatedElems()
6912
6913     def ClearLastCreated(self):
6914         """
6915         Forget what nodes and elements were created by the last mesh edition operation
6916         """
6917
6918         self.editor.ClearLastCreated()
6919
6920     def DoubleElements(self, theElements, theGroupName=""):
6921         """
6922         Create duplicates of given elements, i.e. create new elements based on the
6923         same nodes as the given ones.
6924
6925         Parameters:
6926             theElements: container of elements to duplicate. It can be a
6927                 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
6928                 or a list of element IDs. If *theElements* is
6929                 a :class:`Mesh`, elements of highest dimension are duplicated
6930             theGroupName: a name of group to contain the generated elements.
6931                 If a group with such a name already exists, the new elements
6932                 are added to the existing group, else a new group is created.
6933                 If *theGroupName* is empty, new elements are not added
6934                 in any group.
6935
6936         Returns:
6937                 a :class:`group <SMESH.SMESH_Group>` where the new elements are added.
6938                 None if *theGroupName* == "".
6939         """
6940
6941         unRegister = genObjUnRegister()
6942         if isinstance( theElements, Mesh ):
6943             theElements = theElements.mesh
6944         elif isinstance( theElements, list ):
6945             theElements = self.GetIDSource( theElements, SMESH.ALL )
6946             unRegister.set( theElements )
6947         return self.editor.DoubleElements(theElements, theGroupName)
6948
6949     def DoubleNodes(self, theNodes, theModifiedElems):
6950         """
6951         Create a hole in a mesh by doubling the nodes of some particular elements
6952
6953         Parameters:
6954             theNodes: IDs of nodes to be doubled
6955             theModifiedElems: IDs of elements to be updated by the new (doubled)
6956                 nodes. If list of element identifiers is empty then nodes are doubled but
6957                 they not assigned to elements
6958
6959         Returns:
6960             True if operation has been completed successfully, False otherwise
6961         """
6962
6963         return self.editor.DoubleNodes(theNodes, theModifiedElems)
6964
6965     def DoubleNode(self, theNodeId, theModifiedElems):
6966         """
6967         Create a hole in a mesh by doubling the nodes of some particular elements.
6968         This method provided for convenience works as :meth:`DoubleNodes`.
6969
6970         Parameters:
6971             theNodeId: IDs of node to double
6972             theModifiedElems: IDs of elements to update
6973
6974         Returns:
6975             True if operation has been completed successfully, False otherwise
6976         """
6977
6978         return self.editor.DoubleNode(theNodeId, theModifiedElems)
6979
6980     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6981         """
6982         Create a hole in a mesh by doubling the nodes of some particular elements.
6983         This method provided for convenience works as :meth:`DoubleNodes`.
6984
6985         Parameters:
6986             theNodes: group of nodes to double.
6987             theModifiedElems: group of elements to update.
6988             theMakeGroup: forces the generation of a group containing new nodes.
6989
6990         Returns:
6991             True or a created group if operation has been completed successfully,
6992             False or None otherwise
6993         """
6994
6995         if theMakeGroup:
6996             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6997         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6998
6999     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
7000         """
7001         Create a hole in a mesh by doubling the nodes of some particular elements.
7002         This method provided for convenience works as :meth:`DoubleNodes`.
7003
7004         Parameters:
7005             theNodes: list of groups of nodes to double.
7006             theModifiedElems: list of groups of elements to update.
7007             theMakeGroup: forces the generation of a group containing new nodes.
7008
7009         Returns:
7010             True if operation has been completed successfully, False otherwise
7011         """
7012
7013         if theMakeGroup:
7014             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
7015         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
7016
7017     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
7018         """
7019         Create a hole in a mesh by doubling the nodes of some particular elements
7020
7021         Parameters:
7022             theElems: the list of elements (edges or faces) to replicate.
7023                 The nodes for duplication could be found from these elements
7024             theNodesNot: list of nodes NOT to replicate
7025             theAffectedElems: the list of elements (cells and edges) to which the
7026                 replicated nodes should be associated to
7027
7028         Returns:
7029             True if operation has been completed successfully, False otherwise
7030         """
7031
7032         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
7033
7034     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
7035         """
7036         Create a hole in a mesh by doubling the nodes of some particular elements
7037
7038         Parameters:
7039             theElems: the list of elements (edges or faces) to replicate.
7040                 The nodes for duplication could be found from these elements
7041             theNodesNot: list of nodes NOT to replicate
7042             theShape: shape to detect affected elements (element which geometric center
7043                 located on or inside shape).
7044                 The replicated nodes should be associated to affected elements.
7045
7046         Returns:
7047             True if operation has been completed successfully, False otherwise
7048         """
7049
7050         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
7051
7052     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
7053                              theMakeGroup=False, theMakeNodeGroup=False):
7054         """
7055         Create a hole in a mesh by doubling the nodes of some particular elements.
7056         This method provided for convenience works as :meth:`DoubleNodes`.
7057
7058         Parameters:
7059             theElems: group of of elements (edges or faces) to replicate.
7060             theNodesNot: group of nodes NOT to replicate.
7061             theAffectedElems: group of elements to which the replicated nodes
7062                 should be associated to.
7063             theMakeGroup: forces the generation of a group containing new elements.
7064             theMakeNodeGroup: forces the generation of a group containing new nodes.
7065
7066         Returns:
7067             True or created groups (one or two) if operation has been completed successfully,
7068             False or None otherwise
7069         """
7070
7071         if theMakeGroup or theMakeNodeGroup:
7072             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
7073                                                             theAffectedElems,
7074                                                             theMakeGroup, theMakeNodeGroup)
7075             if theMakeGroup and theMakeNodeGroup:
7076                 return twoGroups
7077             else:
7078                 return twoGroups[ int(theMakeNodeGroup) ]
7079         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
7080
7081     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
7082         """
7083         Create a hole in a mesh by doubling the nodes of some particular elements.
7084         This method provided for convenience works as :meth:`DoubleNodes`.
7085
7086         Parameters:
7087             theElems: group of of elements (edges or faces) to replicate
7088             theNodesNot: group of nodes not to replicate
7089             theShape: shape to detect affected elements (element which geometric center
7090                 located on or inside shape).
7091                 The replicated nodes should be associated to affected elements
7092         """
7093
7094         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7095
7096     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7097                              theMakeGroup=False, theMakeNodeGroup=False):
7098         """
7099         Create a hole in a mesh by doubling the nodes of some particular elements.
7100         This method provided for convenience works as :meth:`DoubleNodes`.
7101
7102         Parameters:
7103             theElems: list of groups of elements (edges or faces) to replicate
7104             theNodesNot: list of groups of nodes NOT to replicate
7105             theAffectedElems: group of elements to which the replicated nodes
7106                 should be associated to
7107             theMakeGroup: forces generation of a group containing new elements.
7108             theMakeNodeGroup: forces generation of a group containing new nodes
7109
7110         Returns:
7111             True or created groups (one or two) if operation has been completed successfully,
7112             False or None otherwise
7113         """
7114
7115         if theMakeGroup or theMakeNodeGroup:
7116             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7117                                                              theAffectedElems,
7118                                                              theMakeGroup, theMakeNodeGroup)
7119             if theMakeGroup and theMakeNodeGroup:
7120                 return twoGroups
7121             else:
7122                 return twoGroups[ int(theMakeNodeGroup) ]
7123         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7124
7125     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7126         """
7127         Create a hole in a mesh by doubling the nodes of some particular elements.
7128         This method provided for convenience works as :meth:`DoubleNodes`.
7129
7130         Parameters:
7131             theElems: list of groups of elements (edges or faces) to replicate
7132             theNodesNot: list of groups of nodes NOT to replicate
7133             theShape: shape to detect affected elements (element which geometric center
7134                 located on or inside shape).
7135                 The replicated nodes should be associated to affected elements
7136
7137         Returns:
7138             True if operation has been completed successfully, False otherwise
7139         """
7140
7141         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7142
7143     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7144         """
7145         Identify the elements that will be affected by node duplication (actual duplication is not performed).
7146         This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7147
7148         Parameters:
7149             theElems: list of groups of nodes or elements (edges or faces) to replicate
7150             theNodesNot: list of groups of nodes NOT to replicate
7151             theShape: shape to detect affected elements (element which geometric center
7152                 located on or inside shape).
7153                 The replicated nodes should be associated to affected elements
7154
7155         Returns:
7156             groups of affected elements in order: volumes, faces, edges
7157         """
7158
7159         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7160
7161     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7162
7163         """
7164         Double nodes on shared faces between groups of volumes and create flat elements on demand.
7165         The list of groups must describe a partition of the mesh volumes.
7166         The nodes of the internal faces at the boundaries of the groups are doubled.
7167         In option, the internal faces are replaced by flat elements.
7168         Triangles are transformed to prisms, and quadrangles to hexahedrons.
7169
7170         Parameters:
7171             theDomains: list of groups of volumes
7172             createJointElems: if True, create the elements
7173             onAllBoundaries: if True, the nodes and elements are also created on
7174                 the boundary between *theDomains* and the rest mesh
7175
7176         Returns:
7177             True if operation has been completed successfully, False otherwise
7178         """
7179
7180         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7181
7182     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7183         """
7184         Double nodes on some external faces and create flat elements.
7185         Flat elements are mainly used by some types of mechanic calculations.
7186
7187         Each group of the list must be constituted of faces.
7188         Triangles are transformed in prisms, and quadrangles in hexahedrons.
7189
7190         Parameters:
7191             theGroupsOfFaces: list of groups of faces
7192
7193         Returns:
7194             True if operation has been completed successfully, False otherwise
7195         """
7196
7197         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7198
7199     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7200         """
7201         Identify all the elements around a geom shape, get the faces delimiting the hole
7202         """
7203         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7204
7205     def MakePolyLine(self, segments, groupName='', isPreview=False ):
7206         """
7207         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7208         the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7209         plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7210         If there are several paths connecting a pair of points, the shortest path is
7211         selected by the module. Position of the cutting plane is defined by the two
7212         points and an optional vector lying on the plane specified by a PolySegment.
7213         By default the vector is defined by Mesh module as following. A middle point
7214         of the two given points is computed. The middle point is projected to the mesh.
7215         The vector goes from the middle point to the projection point. In case of planar
7216         mesh, the vector is normal to the mesh.
7217
7218         In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7219
7220         Parameters:
7221             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7222             groupName: optional name of a group where created mesh segments will be added.
7223
7224         """
7225         editor = self.editor
7226         if isPreview:
7227             editor = self.mesh.GetMeshEditPreviewer()
7228         segmentsRes = editor.MakePolyLine( segments, groupName )
7229         for i, seg in enumerate( segmentsRes ):
7230             segments[i].vector = seg.vector
7231         if isPreview:
7232             return editor.GetPreviewData()
7233         return None
7234
7235     def MakeSlot(self, segmentGroup, width ):
7236         """
7237         Create a slot of given width around given 1D elements lying on a triangle mesh.
7238         The slot is constructed by cutting faces by cylindrical surfaces made
7239         around each segment. Segments are expected to be created by MakePolyLine().
7240
7241         Returns:
7242                FaceEdge's located at the slot boundary
7243         """
7244         return self.editor.MakeSlot( segmentGroup, width )
7245
7246     def GetFunctor(self, funcType ):
7247         """
7248         Return a cached numerical functor by its type.
7249
7250         Parameters:
7251             funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7252                 Note that not all items correspond to numerical functors.
7253
7254         Returns:
7255             :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7256         """
7257
7258         fn = self.functors[ funcType._v ]
7259         if not fn:
7260             fn = self.smeshpyD.GetFunctor(funcType)
7261             fn.SetMesh(self.mesh)
7262             self.functors[ funcType._v ] = fn
7263         return fn
7264
7265     def FunctorValue(self, funcType, elemId, isElem=True):
7266         """
7267         Return value of a functor for a given element
7268
7269         Parameters:
7270             funcType: an item of :class:`SMESH.FunctorType` enum.
7271             elemId: element or node ID
7272             isElem: *elemId* is ID of element or node
7273
7274         Returns:
7275             the functor value or zero in case of invalid arguments
7276         """
7277
7278         fn = self.GetFunctor( funcType )
7279         if fn.GetElementType() == self.GetElementType(elemId, isElem):
7280             val = fn.GetValue(elemId)
7281         else:
7282             val = 0
7283         return val
7284
7285     def GetLength(self, elemId=None):
7286         """
7287         Get length of given 1D elements or of all 1D mesh elements
7288
7289         Parameters:
7290             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.
7291
7292         Returns:
7293             Sum of lengths of given elements
7294         """
7295
7296         length = 0
7297         if elemId == None:
7298             length = self.smeshpyD.GetLength(self)
7299         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7300             length = self.smeshpyD.GetLength(elemId)
7301         elif elemId == []:
7302             length = 0
7303         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7304             for obj in elemId:
7305                 length += self.smeshpyD.GetLength(obj)
7306         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7307             unRegister = genObjUnRegister()
7308             obj = self.GetIDSource( elemId )
7309             unRegister.set( obj )
7310             length = self.smeshpyD.GetLength( obj )
7311         else:
7312             length = self.FunctorValue(SMESH.FT_Length, elemId)
7313         return length
7314
7315     def GetArea(self, elemId=None):
7316         """
7317         Get area of given 2D elements or of all 2D mesh elements
7318
7319         Parameters:
7320             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.
7321
7322         Returns:
7323             Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7324         """
7325
7326         area = 0
7327         if elemId == None:
7328             area = self.smeshpyD.GetArea(self)
7329         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7330             area = self.smeshpyD.GetArea(elemId)
7331         elif elemId == []:
7332             area = 0
7333         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7334             for obj in elemId:
7335                 area += self.smeshpyD.GetArea(obj)
7336         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7337             unRegister = genObjUnRegister()
7338             obj = self.GetIDSource( elemId )
7339             unRegister.set( obj )
7340             area = self.smeshpyD.GetArea( obj )
7341         else:
7342             area = self.FunctorValue(SMESH.FT_Area, elemId)
7343         return area
7344
7345     def GetVolume(self, elemId=None):
7346         """
7347         Get volume of given 3D elements or of all 3D mesh elements
7348
7349         Parameters:
7350             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.
7351
7352         Returns:
7353             Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7354         """
7355
7356         volume = 0
7357         if elemId == None:
7358             volume= self.smeshpyD.GetVolume(self)
7359         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7360             volume= self.smeshpyD.GetVolume(elemId)
7361         elif elemId == []:
7362             volume = 0
7363         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7364             for obj in elemId:
7365                 volume+= self.smeshpyD.GetVolume(obj)
7366         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7367             unRegister = genObjUnRegister()
7368             obj = self.GetIDSource( elemId )
7369             unRegister.set( obj )
7370             volume= self.smeshpyD.GetVolume( obj )
7371         else:
7372             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7373         return volume
7374
7375     def GetAngle(self, node1, node2, node3 ):
7376         """
7377         Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7378
7379         Parameters:
7380                 node1,node2,node3: IDs of the three nodes
7381
7382         Returns:
7383             Angle in radians [0,PI]. -1 if failure case.
7384         """
7385         p1 = self.GetNodeXYZ( node1 )
7386         p2 = self.GetNodeXYZ( node2 )
7387         p3 = self.GetNodeXYZ( node3 )
7388         if p1 and p2 and p3:
7389             return self.smeshpyD.GetAngle( p1,p2,p3 )
7390         return -1.
7391
7392
7393     def GetMaxElementLength(self, elemId):
7394         """
7395         Get maximum element length.
7396
7397         Parameters:
7398             elemId: mesh element ID
7399
7400         Returns:
7401             element's maximum length value
7402         """
7403
7404         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7405             ftype = SMESH.FT_MaxElementLength3D
7406         else:
7407             ftype = SMESH.FT_MaxElementLength2D
7408         return self.FunctorValue(ftype, elemId)
7409
7410     def GetAspectRatio(self, elemId):
7411         """
7412         Get aspect ratio of 2D or 3D element.
7413
7414         Parameters:
7415             elemId: mesh element ID
7416
7417         Returns:
7418             element's aspect ratio value
7419         """
7420
7421         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7422             ftype = SMESH.FT_AspectRatio3D
7423         else:
7424             ftype = SMESH.FT_AspectRatio
7425         return self.FunctorValue(ftype, elemId)
7426
7427     def GetWarping(self, elemId):
7428         """
7429         Get warping angle of 2D element.
7430
7431         Parameters:
7432             elemId: mesh element ID
7433
7434         Returns:
7435             element's warping angle value
7436         """
7437
7438         return self.FunctorValue(SMESH.FT_Warping, elemId)
7439
7440     def GetMinimumAngle(self, elemId):
7441         """
7442         Get minimum angle of 2D element.
7443
7444         Parameters:
7445             elemId: mesh element ID
7446
7447         Returns:
7448             element's minimum angle value
7449         """
7450
7451         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7452
7453     def GetTaper(self, elemId):
7454         """
7455         Get taper of 2D element.
7456
7457         Parameters:
7458             elemId: mesh element ID
7459
7460         Returns:
7461             element's taper value
7462         """
7463
7464         return self.FunctorValue(SMESH.FT_Taper, elemId)
7465
7466     def GetSkew(self, elemId):
7467         """
7468         Get skew of 2D element.
7469
7470         Parameters:
7471             elemId: mesh element ID
7472
7473         Returns:
7474             element's skew value
7475         """
7476
7477         return self.FunctorValue(SMESH.FT_Skew, elemId)
7478
7479     def GetMinMax(self, funType, meshPart=None):
7480         """
7481         Return minimal and maximal value of a given functor.
7482
7483         Parameters:
7484             funType (SMESH.FunctorType): a functor type.
7485                   Note that not all items of :class:`SMESH.FunctorType` corresponds
7486                   to numerical functors.
7487             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7488
7489         Returns:
7490             tuple (min,max)
7491         """
7492
7493         unRegister = genObjUnRegister()
7494         if isinstance( meshPart, list ):
7495             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7496             unRegister.set( meshPart )
7497         if isinstance( meshPart, Mesh ):
7498             meshPart = meshPart.mesh
7499         fun = self.GetFunctor( funType )
7500         if fun:
7501             if meshPart:
7502                 if hasattr( meshPart, "SetMesh" ):
7503                     meshPart.SetMesh( self.mesh ) # set mesh to filter
7504                 hist = fun.GetLocalHistogram( 1, False, meshPart )
7505             else:
7506                 hist = fun.GetHistogram( 1, False )
7507             if hist:
7508                 return hist[0].min, hist[0].max
7509         return None
7510
7511     pass # end of Mesh class
7512
7513
7514 class meshProxy(SMESH._objref_SMESH_Mesh):
7515     """
7516     Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7517     with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7518     """
7519     def __init__(self,*args):
7520         SMESH._objref_SMESH_Mesh.__init__(self,*args)
7521     def __deepcopy__(self, memo=None):
7522         new = self.__class__(self)
7523         return new
7524     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7525         if len( args ) == 3:
7526             args += SMESH.ALL_NODES, True
7527         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7528     def ExportToMEDX(self, *args): # function removed
7529         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7530         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7531         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7532     def ExportToMED(self, *args): # function removed
7533         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7534         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7535         args2 = list(args)
7536         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7537             args2.append(True)
7538         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7539     def ExportPartToMED(self, *args): # 'version' parameter removed
7540         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7541         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7542     def ExportMED(self, *args): # signature of method changed
7543         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7544         args2 = list(args)
7545         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7546             args2.append(True)
7547         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7548     def ExportUNV(self, *args): # renumber arg added
7549         if len( args ) == 1:
7550             args += True,
7551         return SMESH._objref_SMESH_Mesh.ExportUNV(self, *args)
7552     def ExportDAT(self, *args): # renumber arg added
7553         if len( args ) == 1:
7554             args += True,
7555         return SMESH._objref_SMESH_Mesh.ExportDAT(self, *args)
7556     pass
7557 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7558
7559
7560 class submeshProxy(SMESH._objref_SMESH_subMesh):
7561
7562     """
7563     Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7564     """
7565     def __init__(self,*args):
7566         SMESH._objref_SMESH_subMesh.__init__(self,*args)
7567         self.mesh = None
7568     def __deepcopy__(self, memo=None):
7569         new = self.__class__(self)
7570         return new
7571
7572     def Compute(self,refresh=False):
7573         """
7574         Compute the sub-mesh and return the status of the computation
7575
7576         Parameters:
7577             refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7578
7579         Returns:
7580             True or False
7581
7582         This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7583         :meth:`smeshBuilder.Mesh.GetSubMesh`.
7584         """
7585
7586         if not self.mesh:
7587             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7588
7589         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7590
7591         if salome.sg.hasDesktop():
7592             if refresh: salome.sg.updateObjBrowser()
7593             pass
7594
7595         return ok
7596     pass
7597 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7598
7599
7600 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7601     """
7602     Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7603     compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7604     smeshBuilder.Mesh
7605     """
7606     def __init__(self,*args):
7607         SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7608         self.mesh = None
7609     def __getattr__(self, name ): # method called if an attribute not found
7610         if not self.mesh:         # look for name() method in Mesh class
7611             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7612         if hasattr( self.mesh, name ):
7613             return getattr( self.mesh, name )
7614         if name == "ExtrusionAlongPathObjX":
7615             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7616         print("meshEditor: attribute '%s' NOT FOUND" % name)
7617         return None
7618     def __deepcopy__(self, memo=None):
7619         new = self.__class__(self)
7620         return new
7621     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7622         if len( args ) == 1: args += False,
7623         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7624     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7625         if len( args ) == 2: args += False,
7626         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7627     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7628         if len( args ) == 1:
7629             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7630         NodesToKeep = args[1]
7631         AvoidMakingHoles = args[2] if len( args ) == 3 else False
7632         unRegister  = genObjUnRegister()
7633         if NodesToKeep:
7634             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7635                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7636             if not isinstance( NodesToKeep, list ):
7637                 NodesToKeep = [ NodesToKeep ]
7638         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7639     pass
7640 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7641
7642 class Pattern(SMESH._objref_SMESH_Pattern):
7643     """
7644     Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7645     variables in some methods
7646     """
7647
7648     def LoadFromFile(self, patternTextOrFile ):
7649         text = patternTextOrFile
7650         if os.path.exists( text ):
7651             text = open( patternTextOrFile ).read()
7652             pass
7653         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7654
7655     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7656         decrFun = lambda i: i-1
7657         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7658         theMesh.SetParameters(Parameters)
7659         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7660
7661     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7662         decrFun = lambda i: i-1
7663         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7664         theMesh.SetParameters(Parameters)
7665         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7666
7667     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7668         if isinstance( mesh, Mesh ):
7669             mesh = mesh.GetMesh()
7670         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7671
7672 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7673 """
7674 Registering the new proxy for Pattern
7675 """
7676
7677 class algoCreator:
7678     """
7679     Private class used to bind methods creating algorithms to the class Mesh
7680     """
7681
7682     def __init__(self, method):
7683         self.mesh = None
7684         self.defaultAlgoType = ""
7685         self.algoTypeToClass = {}
7686         self.method = method
7687
7688     def add(self, algoClass):
7689         """
7690         Store a python class of algorithm
7691         """
7692         if inspect.isclass(algoClass) and \
7693            hasattr( algoClass, "algoType"):
7694             self.algoTypeToClass[ algoClass.algoType ] = algoClass
7695             if not self.defaultAlgoType and \
7696                hasattr( algoClass, "isDefault") and algoClass.isDefault:
7697                 self.defaultAlgoType = algoClass.algoType
7698             #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7699
7700     def copy(self, mesh):
7701         """
7702         Create a copy of self and assign mesh to the copy
7703         """
7704
7705         other = algoCreator( self.method )
7706         other.defaultAlgoType = self.defaultAlgoType
7707         other.algoTypeToClass = self.algoTypeToClass
7708         other.mesh = mesh
7709         return other
7710
7711     def __call__(self,algo="",geom=0,*args):
7712         """
7713         Create an instance of algorithm
7714         """
7715         algoType = ""
7716         shape = 0
7717         if isinstance( algo, str ):
7718             algoType = algo
7719         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7720                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7721             shape = algo
7722         elif algo:
7723             args += (algo,)
7724
7725         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7726             shape = geom
7727         elif not algoType and isinstance( geom, str ):
7728             algoType = geom
7729         elif geom:
7730             args += (geom,)
7731         for arg in args:
7732             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7733                 shape = arg
7734             elif isinstance( arg, str ) and not algoType:
7735                 algoType = arg
7736             else:
7737                 import traceback, sys
7738                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
7739                 sys.stderr.write( msg + '\n' )
7740                 tb = traceback.extract_stack(None,2)
7741                 traceback.print_list( [tb[0]] )
7742         if not algoType:
7743             algoType = self.defaultAlgoType
7744         if not algoType and self.algoTypeToClass:
7745             algoType = sorted( self.algoTypeToClass.keys() )[0]
7746         if algoType in self.algoTypeToClass:
7747             #print("Create algo",algoType)
7748             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7749         raise RuntimeError( "No class found for algo type %s" % algoType)
7750         return None
7751
7752 class hypMethodWrapper:
7753     """
7754     Private class used to substitute and store variable parameters of hypotheses.
7755     """
7756
7757     def __init__(self, hyp, method):
7758         self.hyp    = hyp
7759         self.method = method
7760         #print("REBIND:", method.__name__)
7761         return
7762
7763     def __call__(self,*args):
7764         """
7765         call a method of hypothesis with calling SetVarParameter() before
7766         """
7767
7768         if not args:
7769             return self.method( self.hyp, *args ) # hypothesis method with no args
7770
7771         #print("MethWrapper.__call__", self.method.__name__, args)
7772         try:
7773             parsed = ParseParameters(*args)     # replace variables with their values
7774             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7775             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7776         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7777             # maybe there is a replaced string arg which is not variable
7778             result = self.method( self.hyp, *args )
7779         except ValueError as detail: # raised by ParseParameters()
7780             try:
7781                 result = self.method( self.hyp, *args )
7782             except omniORB.CORBA.BAD_PARAM:
7783                 raise ValueError(detail) # wrong variable name
7784
7785         return result
7786     pass
7787
7788 class genObjUnRegister:
7789     """
7790     A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7791     """
7792
7793     def __init__(self, genObj=None):
7794         self.genObjList = []
7795         self.set( genObj )
7796         return
7797
7798     def set(self, genObj):
7799         "Store one or a list of of SALOME.GenericObj'es"
7800         if isinstance( genObj, list ):
7801             self.genObjList.extend( genObj )
7802         else:
7803             self.genObjList.append( genObj )
7804         return
7805
7806     def __del__(self):
7807         for genObj in self.genObjList:
7808             if genObj and hasattr( genObj, "UnRegister" ):
7809                 genObj.UnRegister()
7810
7811 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7812     """
7813     Bind methods creating mesher plug-ins to the Mesh class
7814     """
7815
7816     # print("pluginName: ", pluginName)
7817     pluginBuilderName = pluginName + "Builder"
7818     try:
7819         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7820     except Exception as e:
7821         from salome_utils import verbose
7822         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7823         continue
7824     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7825     plugin = eval( pluginBuilderName )
7826     # print("  plugin:" , str(plugin))
7827
7828     # add methods creating algorithms to Mesh
7829     for k in dir( plugin ):
7830         if k[0] == '_': continue
7831         algo = getattr( plugin, k )
7832         #print("             algo:", str(algo))
7833         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7834             #print("                     meshMethod:" , str(algo.meshMethod))
7835             if not hasattr( Mesh, algo.meshMethod ):
7836                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7837                 pass
7838             _mmethod = getattr( Mesh, algo.meshMethod )
7839             if hasattr(  _mmethod, "add" ):
7840                 _mmethod.add(algo)
7841             pass
7842         pass
7843     pass
7844 del pluginName