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