Salome HOME
#17636 [CEA 17369] Extrusion by normal: along average normal option issue
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2019  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
44 import SALOME
45 import SALOMEDS
46 import os
47 import inspect
48
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
51 # defined
52 #
53 try:
54     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
55 except TypeError:
56     def enumitem_eq(self, other):
57         try:
58             if isinstance(other, omniORB.EnumItem):
59                 if other._parent_id == self._parent_id:
60                     return self._v == other._v
61                 else:
62                     return self._parent_id == other._parent_id
63             else:
64                 return id(self) == id(other)
65         except:
66             return id(self) == id(other)
67
68     def enumitem_lt(self, other):
69         try:
70             if isinstance(other, omniORB.EnumItem):
71                 if other._parent_id == self._parent_id:
72                     return self._v < other._v
73                 else:
74                     return self._parent_id < other._parent_id
75             else:
76                 return id(self) < id(other)
77         except:
78             return id(self) < id(other)
79
80     def enumitem_le(self, other):
81         try:
82             if isinstance(other, omniORB.EnumItem):
83                 if other._parent_id == self._parent_id:
84                     return self._v <= other._v
85                 else:
86                     return self._parent_id <= other._parent_id
87             else:
88                 return id(self) <= id(other)
89         except:
90             return id(self) <= id(other)
91
92     def enumitem_gt(self, other):
93         try:
94             if isinstance(other, omniORB.EnumItem):
95                 if other._parent_id == self._parent_id:
96                     return self._v > other._v
97                 else:
98                     return self._parent_id > other._parent_id
99             else:
100                 return id(self) > id(other)
101         except:
102             return id(self) > id(other)
103
104     def enumitem_ge(self, other):
105         try:
106             if isinstance(other, omniORB.EnumItem):
107                 if other._parent_id == self._parent_id:
108                     return self._v >= other._v
109                 else:
110                     return self._parent_id >= other._parent_id
111             else:
112                 return id(self) >= id(other)
113         except:
114             return id(self) >= id(other)
115
116     omniORB.EnumItem.__eq__ = enumitem_eq
117     omniORB.EnumItem.__lt__ = enumitem_lt
118     omniORB.EnumItem.__le__ = enumitem_le
119     omniORB.EnumItem.__gt__ = enumitem_gt
120     omniORB.EnumItem.__ge__ = enumitem_ge
121
122
123 class MeshMeta(type):
124     """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
125     """
126     def __instancecheck__(cls, inst):
127         """Implement isinstance(inst, cls)."""
128         return any(cls.__subclasscheck__(c)
129                    for c in {type(inst), inst.__class__})
130
131     def __subclasscheck__(cls, sub):
132         """Implement issubclass(sub, cls)."""
133         return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
134
135 def DegreesToRadians(AngleInDegrees):
136     """Convert an angle from degrees to radians
137     """
138     from math import pi
139     return AngleInDegrees * pi / 180.0
140
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
144 var_separator = ":"
145
146 def ParseParameters(*args):
147     """
148     Return list of variable values from salome notebook.
149     The last argument, if is callable, is used to modify values got from notebook
150     """
151     Result = []
152     Parameters = ""
153     hasVariables = False
154     varModifFun=None
155     if args and callable(args[-1]):
156         args, varModifFun = args[:-1], args[-1]
157     for parameter in args:
158
159         Parameters += str(parameter) + var_separator
160
161         if isinstance(parameter,str):
162             # check if there is an inexistent variable name
163             if not notebook.isVariable(parameter):
164                 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165             parameter = notebook.get(parameter)
166             hasVariables = True
167             if varModifFun:
168                 parameter = varModifFun(parameter)
169                 pass
170             pass
171         Result.append(parameter)
172
173         pass
174     Parameters = Parameters[:-1]
175     Result.append( Parameters )
176     Result.append( hasVariables )
177     return Result
178
179 def ParseAngles(*args):
180     """
181     Parse parameters while converting variables to radians
182     """
183     return ParseParameters( *( args + (DegreesToRadians, )))
184
185 def __initPointStruct(point,*args):
186     """
187     Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188     Parameters are stored in PointStruct.parameters attribute
189     """
190     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
191     pass
192 SMESH.PointStruct.__init__ = __initPointStruct
193
194 def __initAxisStruct(ax,*args):
195     """
196     Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197     Parameters are stored in AxisStruct.parameters attribute
198     """
199     if len( args ) != 6:
200         raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
202     pass
203 SMESH.AxisStruct.__init__ = __initAxisStruct
204
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207     """Compare real values using smeshPrecisionConfusion as tolerance
208     """
209     if abs(val1 - val2) < tol:
210         return True
211     return False
212
213 NO_NAME = "NoName"
214
215 def GetName(obj):
216     """
217     Return a name of an object
218     
219     Returns:
220         object name
221     """
222     if obj:
223         # object not null
224         if isinstance(obj, SALOMEDS._objref_SObject):
225             # study object
226             return obj.GetName()
227         try:
228             ior  = salome.orb.object_to_string(obj)
229         except:
230             ior = None
231         if ior:
232             sobj = salome.myStudy.FindObjectIOR(ior)
233             if sobj:
234                 return sobj.GetName()
235             if hasattr(obj, "GetName"):
236                 # unknown CORBA object, having GetName() method
237                 return obj.GetName()
238             else:
239                 # unknown CORBA object, no GetName() method
240                 return NO_NAME
241             pass
242         if hasattr(obj, "GetName"):
243             # unknown non-CORBA object, having GetName() method
244             return obj.GetName()
245         pass
246     raise RuntimeError("Null or invalid object")
247
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
249     """
250     Print error message if a hypothesis was not assigned.
251     """
252     if isAlgo:
253         hypType = "algorithm"
254     else:
255         hypType = "hypothesis"
256         pass
257     reason = ""
258     if hasattr( status, "__getitem__" ):
259         status, reason = status[0], status[1]
260     if status == HYP_UNKNOWN_FATAL:
261         reason = "for unknown reason"
262     elif status == HYP_INCOMPATIBLE:
263         reason = "this hypothesis mismatches the algorithm"
264     elif status == HYP_NOTCONFORM:
265         reason = "a non-conform mesh would be built"
266     elif status == HYP_ALREADY_EXIST:
267         if isAlgo: return # it does not influence anything
268         reason = hypType + " of the same dimension is already assigned to this shape"
269     elif status == HYP_BAD_DIM:
270         reason = hypType + " mismatches the shape"
271     elif status == HYP_CONCURRENT :
272         reason = "there are concurrent hypotheses on sub-shapes"
273     elif status == HYP_BAD_SUBSHAPE:
274         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275     elif status == HYP_BAD_GEOMETRY:
276         reason = "the algorithm is not applicable to this geometry"
277     elif status == HYP_HIDDEN_ALGO:
278         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279     elif status == HYP_HIDING_ALGO:
280         reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281     elif status == HYP_NEED_SHAPE:
282         reason = "algorithm can't work without shape"
283     elif status == HYP_INCOMPAT_HYPS:
284         pass
285     else:
286         return
287     where = geomName
288     if where:
289         where = '"%s"' % geomName
290         if mesh:
291             meshName = GetName( mesh )
292             if meshName and meshName != NO_NAME:
293                 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294     if status < HYP_UNKNOWN_FATAL and where:
295         print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
296     elif where:
297         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
298     else:
299         print('"%s" was not assigned : %s' %( hypName, reason ))
300         pass
301
302 def AssureGeomPublished(mesh, geom, name=''):
303     """
304     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
305     """
306     if not mesh.smeshpyD.IsEnablePublish():
307         return
308     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
309         return
310     if not geom.GetStudyEntry():
311         ## get a name
312         if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313             # for all groups SubShapeName() return "Compound_-1"
314             name = mesh.geompyD.SubShapeName(geom, mesh.geom)
315         if not name:
316             name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
317         ## publish
318         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
319     return
320
321 def FirstVertexOnCurve(mesh, edge):
322     """
323     Returns:
324         the first vertex of a geometrical edge by ignoring orientation
325     """
326     vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
327     if not vv:
328         raise TypeError("Given object has no vertices")
329     if len( vv ) == 1: return vv[0]
330     v0   = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331     xyz  = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332     xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333     xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
334     dist1, dist2 = 0,0
335     for i in range(3):
336         dist1 += abs( xyz[i] - xyz1[i] )
337         dist2 += abs( xyz[i] - xyz2[i] )
338     if dist1 < dist2:
339         return vv[0]
340     else:
341         return vv[1]
342
343 smeshInst = None
344 """
345 Warning:
346     smeshInst is a singleton
347 """
348 engine = None
349 doLcc = False
350 created = False
351
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
353     """
354     This class allows to create, load or manipulate meshes.
355     It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356     It also has methods to get infos and measure meshes.
357     """
358
359     # MirrorType enumeration
360     POINT = SMESH_MeshEditor.POINT
361     AXIS =  SMESH_MeshEditor.AXIS
362     PLANE = SMESH_MeshEditor.PLANE
363
364     # Smooth_Method enumeration
365     LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366     CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
367
368     PrecisionConfusion = smeshPrecisionConfusion
369
370     # TopAbs_State enumeration
371     [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
372
373     # Methods of splitting a hexahedron into tetrahedra
374     Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
375
376     def __new__(cls, *args):
377         global engine
378         global smeshInst
379         global doLcc
380         #print("==== __new__", engine, smeshInst, doLcc)
381
382         if smeshInst is None:
383             # smesh engine is either retrieved from engine, or created
384             smeshInst = engine
385             # Following test avoids a recursive loop
386             if doLcc:
387                 if smeshInst is not None:
388                     # smesh engine not created: existing engine found
389                     doLcc = False
390                 if doLcc:
391                     doLcc = False
392                     # FindOrLoadComponent called:
393                     # 1. CORBA resolution of server
394                     # 2. the __new__ method is called again
395                     #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396                     smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
397             else:
398                 # FindOrLoadComponent not called
399                 if smeshInst is None:
400                     # smeshBuilder instance is created from lcc.FindOrLoadComponent
401                     #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402                     smeshInst = super(smeshBuilder,cls).__new__(cls)
403                 else:
404                     # smesh engine not created: existing engine found
405                     #print("==== existing ", engine, smeshInst, doLcc)
406                     pass
407             #print("====1 ", smeshInst)
408             return smeshInst
409
410         #print("====2 ", smeshInst)
411         return smeshInst
412
413     def __init__(self, *args):
414         global created
415         #print("--------------- smeshbuilder __init__ ---", created)
416         if not created:
417             created = True
418             SMESH._objref_SMESH_Gen.__init__(self, *args)
419
420
421     def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
422         """
423         Dump component to the Python script.
424         This method overrides IDL function to allow default values for the parameters.
425         """
426
427         return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
428
429     def SetDumpPythonHistorical(self, isHistorical):
430         """
431         Set mode of DumpPython(), *historical* or *snapshot*.
432         In the *historical* mode, the Python Dump script includes all commands
433         performed by SMESH engine. In the *snapshot* mode, commands
434         relating to objects removed from the Study are excluded from the script
435         as well as commands not influencing the current state of meshes
436         """
437
438         if isHistorical: val = "true"
439         else:            val = "false"
440         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
441
442     def init_smesh(self,geompyD = None):
443         """
444         Set Geometry component
445         """    
446         #print("init_smesh")
447         self.UpdateStudy(geompyD)
448         notebook.myStudy = salome.myStudy
449
450     def Mesh(self, obj=0, name=0):
451         """
452         Create a mesh. This mesh can be either 
453
454         * an empty mesh not bound to geometry, if *obj* == 0
455         * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456         * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
457
458         Parameters:
459             obj: either 
460
461                    1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
462                       ::
463
464                         salome.myStudy.FindObjectID("0:1:2:3").GetObject() 
465
466                    2. a geometrical object for meshing
467                    3. none.
468             name: the name for the new mesh.
469
470         Returns:
471             an instance of class :class:`Mesh`.
472         """
473
474         if isinstance(obj,str):
475             obj,name = name,obj
476         return Mesh(self, self.geompyD, obj, name)
477
478     def RemoveMesh( self, mesh ):
479         """
480         Delete a mesh
481         """
482         if isinstance( mesh, Mesh ):
483             mesh = mesh.GetMesh()
484             pass
485         if not isinstance( mesh, SMESH._objref_SMESH_Mesh ):
486             raise TypeError("%s is not a mesh" % mesh )
487         so = salome.ObjectToSObject( mesh )
488         if so:
489             sb = salome.myStudy.NewBuilder()
490             sb.RemoveObjectWithChildren( so )
491         else:
492             mesh.UnRegister()
493             pass
494         return
495
496     def EnumToLong(self,theItem):
497         """
498         Return a long value from enumeration
499         """
500
501         return theItem._v
502
503     def ColorToString(self,c):
504         """
505         Convert SALOMEDS.Color to string.
506         To be used with filters.
507
508         Parameters:
509             c: color value (SALOMEDS.Color)
510
511         Returns:
512             a string representation of the color.
513         """
514
515         val = ""
516         if isinstance(c, SALOMEDS.Color):
517             val = "%s;%s;%s" % (c.R, c.G, c.B)
518         elif isinstance(c, str):
519             val = c
520         else:
521             raise ValueError("Color value should be of string or SALOMEDS.Color type")
522         return val
523
524     def GetPointStruct(self,theVertex):
525         """
526         Get :class:`SMESH.PointStruct` from vertex
527
528         Parameters:
529                 theVertex (GEOM.GEOM_Object): vertex
530
531         Returns:
532                 :class:`SMESH.PointStruct`
533         """
534
535         [x, y, z] = self.geompyD.PointCoordinates(theVertex)
536         return PointStruct(x,y,z)
537
538     def GetDirStruct(self,theVector):
539         """
540         Get :class:`SMESH.DirStruct` from vector
541
542         Parameters:
543                 theVector (GEOM.GEOM_Object): vector
544
545         Returns:
546                 :class:`SMESH.DirStruct`
547         """
548
549         vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
550         if(len(vertices) != 2):
551             print("Error: vector object is incorrect.")
552             return None
553         p1 = self.geompyD.PointCoordinates(vertices[0])
554         p2 = self.geompyD.PointCoordinates(vertices[1])
555         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
556         dirst = DirStruct(pnt)
557         return dirst
558
559     def MakeDirStruct(self,x,y,z):
560         """
561         Make :class:`SMESH.DirStruct` from a triplet of floats
562
563         Parameters:
564                 x,y,z (float): vector components
565
566         Returns:
567                 :class:`SMESH.DirStruct`
568         """
569
570         pnt = PointStruct(x,y,z)
571         return DirStruct(pnt)
572
573     def GetAxisStruct(self,theObj):
574         """
575         Get :class:`SMESH.AxisStruct` from a geometrical object
576
577         Parameters:
578             theObj (GEOM.GEOM_Object): line or plane
579
580         Returns:
581             :class:`SMESH.AxisStruct`
582         """
583         import GEOM
584         edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
585         axis = None
586         if len(edges) > 1:
587             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
588             vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
589             vertex1 = self.geompyD.PointCoordinates(vertex1)
590             vertex2 = self.geompyD.PointCoordinates(vertex2)
591             vertex3 = self.geompyD.PointCoordinates(vertex3)
592             vertex4 = self.geompyD.PointCoordinates(vertex4)
593             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
594             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
595             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] ]
596             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
597             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
598         elif len(edges) == 1:
599             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
600             p1 = self.geompyD.PointCoordinates( vertex1 )
601             p2 = self.geompyD.PointCoordinates( vertex2 )
602             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
603             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
604         elif theObj.GetShapeType() == GEOM.VERTEX:
605             x,y,z = self.geompyD.PointCoordinates( theObj )
606             axis = AxisStruct( x,y,z, 1,0,0,)
607             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
608         return axis
609
610     # From SMESH_Gen interface:
611     # ------------------------
612
613     def SetName(self, obj, name):
614         """
615         Set the given name to an object
616
617         Parameters:
618                 obj: the object to rename
619                 name: a new object name
620         """
621
622         if isinstance( obj, Mesh ):
623             obj = obj.GetMesh()
624         elif isinstance( obj, Mesh_Algorithm ):
625             obj = obj.GetAlgorithm()
626         ior  = salome.orb.object_to_string(obj)
627         SMESH._objref_SMESH_Gen.SetName(self, ior, name)
628
629     def SetEmbeddedMode( self,theMode ):
630         """
631         Set the current mode
632         """
633
634         SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
635
636     def IsEmbeddedMode(self):
637         """
638         Get the current mode
639         """
640
641         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
642
643     def UpdateStudy( self, geompyD = None  ):
644         """
645         Update the current study. Calling UpdateStudy() allows to
646         update meshes at switching GEOM->SMESH
647         """
648         #self.UpdateStudy()
649         if not geompyD:
650             from salome.geom import geomBuilder
651             geompyD = geomBuilder.geom
652             if not geompyD:
653                 geompyD = geomBuilder.New()
654             pass
655         self.geompyD=geompyD
656         self.SetGeomEngine(geompyD)
657         SMESH._objref_SMESH_Gen.UpdateStudy(self)
658         sb = salome.myStudy.NewBuilder()
659         sc = salome.myStudy.FindComponent("SMESH")
660         if sc:
661             sb.LoadWith(sc, self)
662         pass
663     
664     def SetEnablePublish( self, theIsEnablePublish ):
665         """
666         Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
667         switch **off** publishing in the Study of mesh objects.
668         """
669        #self.SetEnablePublish(theIsEnablePublish)
670         SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
671         global notebook
672         notebook = salome_notebook.NoteBook( theIsEnablePublish )
673
674
675     def CreateMeshesFromUNV( self,theFileName ):
676         """
677         Create a Mesh object importing data from the given UNV file
678
679         Returns:
680                 an instance of class :class:`Mesh`
681         """
682
683         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
684         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
685         return aMesh
686
687     def CreateMeshesFromMED( self,theFileName ):
688         """
689         Create a Mesh object(s) importing data from the given MED file
690
691         Returns:
692                 a tuple ( list of class :class:`Mesh` instances, 
693                 :class:`SMESH.DriverMED_ReadStatus` )
694         """
695
696         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
697         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
698         return aMeshes, aStatus
699
700     def CreateMeshesFromSAUV( self,theFileName ):
701         """
702         Create a Mesh object(s) importing data from the given SAUV file
703
704         Returns:
705                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
706         """
707
708         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
709         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
710         return aMeshes, aStatus
711
712     def CreateMeshesFromSTL( self, theFileName ):
713         """
714         Create a Mesh object importing data from the given STL file
715
716         Returns:
717                 an instance of class :class:`Mesh`
718         """
719
720         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
721         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
722         return aMesh
723
724     def CreateMeshesFromCGNS( self, theFileName ):
725         """
726         Create Mesh objects importing data from the given CGNS file
727
728         Returns:
729                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
730         """
731
732         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
733         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
734         return aMeshes, aStatus
735
736     def CreateMeshesFromGMF( self, theFileName ):
737         """
738         Create a Mesh object importing data from the given GMF file.
739         GMF files must have .mesh extension for the ASCII format and .meshb for
740         the binary format.
741
742         Returns:
743                 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
744         """
745
746         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
747                                                                         theFileName,
748                                                                         True)
749         if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
750         return Mesh(self, self.geompyD, aSmeshMesh), error
751
752     def Concatenate( self, meshes, uniteIdenticalGroups,
753                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
754                      name = "", meshToAppendTo = None):
755         """
756         Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
757         All groups of input meshes will be present in the new mesh.
758
759         Parameters:
760                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
761                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
762                 mergeNodesAndElements: if True, equal nodes and elements are merged
763                 mergeTolerance: tolerance for merging nodes
764                 allGroups: forces creation of groups corresponding to every input mesh
765                 name: name of a new mesh
766                 meshToAppendTo: a mesh to append all given meshes
767
768         Returns:
769                 an instance of class :class:`Mesh`
770
771         See also: 
772                 :meth:`Mesh.Append`
773         """
774
775         if not meshes: return None
776         if not isinstance( meshes, list ):
777             meshes = [ meshes ]
778         for i,m in enumerate( meshes ):
779             if isinstance( m, Mesh ):
780                 meshes[i] = m.GetMesh()
781         mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
782         if hasattr(meshes[0], "SetParameters"):
783             meshes[0].SetParameters( Parameters )
784         else:
785             meshes[0].GetMesh().SetParameters( Parameters )
786         if isinstance( meshToAppendTo, Mesh ):
787             meshToAppendTo = meshToAppendTo.GetMesh()
788         if allGroups:
789             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
790                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
791                 mergeTolerance,meshToAppendTo )
792         else:
793             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
794                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
795                 mergeTolerance,meshToAppendTo )
796
797         aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
798         return aMesh
799
800     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
801         """
802         Create a mesh by copying a part of another mesh.
803
804         Parameters:
805                 meshPart: a part of mesh to copy, either 
806                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
807                         To copy nodes or elements not forming any mesh object,
808                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
809                 meshName: a name of the new mesh
810                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
811                 toKeepIDs: to preserve order of the copied elements or not
812
813         Returns:
814                 an instance of class :class:`Mesh`
815         """
816
817         if isinstance( meshPart, Mesh ):
818             meshPart = meshPart.GetMesh()
819         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
820         return Mesh(self, self.geompyD, mesh)
821
822     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
823                           toReuseHypotheses=True, toCopyElements=True):
824         """
825         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
826         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
827         To facilitate and speed up the operation, consider using
828         "Set presentation parameters and sub-shapes from arguments" option in
829         a dialog of geometrical operation used to create the new geometry.
830
831         Parameters:
832                 sourceMesh: the mesh to copy definition of.
833                 newGeom: the new geometry.
834                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
835                 toCopyGroups: to create groups in the new mesh.
836                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
837                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
838                                 *sourceMesh*.
839         Returns:
840                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
841                 *invalidEntries* are study entries of objects whose
842                 counterparts are not found in the *newGeom*, followed by entries
843                 of mesh sub-objects that are invalid because they depend on a not found
844                 preceding sub-shape
845         """
846         if isinstance( sourceMesh, Mesh ):
847             sourceMesh = sourceMesh.GetMesh()
848
849         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
850            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
851                                                      toCopyGroups,
852                                                      toReuseHypotheses,
853                                                      toCopyElements)
854         return ( ok, Mesh(self, self.geompyD, newMesh),
855                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
856
857     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
858         """
859         Return IDs of sub-shapes
860
861         Parameters:
862                 theMainObject (GEOM.GEOM_Object): a shape
863                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
864         Returns:
865                 the list of integer values
866         """
867
868         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
869
870     def GetPattern(self):
871         """
872         Create a pattern mapper.
873
874         Returns:
875                 an instance of :class:`SMESH.SMESH_Pattern`
876
877         :ref:`Example of Patterns usage <tui_pattern_mapping>`
878         """
879
880         return SMESH._objref_SMESH_Gen.GetPattern(self)
881
882     def SetBoundaryBoxSegmentation(self, nbSegments):
883         """
884         Set number of segments per diagonal of boundary box of geometry, by which
885         default segment length of appropriate 1D hypotheses is defined in GUI.
886         Default value is 10.
887         """
888
889         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
890
891     # Filtering. Auxiliary functions:
892     # ------------------------------
893
894     def GetEmptyCriterion(self):
895         """
896         Create an empty criterion
897
898         Returns:
899                 :class:`SMESH.Filter.Criterion`
900         """
901
902         Type = self.EnumToLong(FT_Undefined)
903         Compare = self.EnumToLong(FT_Undefined)
904         Threshold = 0
905         ThresholdStr = ""
906         ThresholdID = ""
907         UnaryOp = self.EnumToLong(FT_Undefined)
908         BinaryOp = self.EnumToLong(FT_Undefined)
909         Tolerance = 1e-07
910         TypeOfElement = ALL
911         Precision = -1 ##@1e-07
912         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
913                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
914
915     def GetCriterion(self,elementType,
916                      CritType,
917                      Compare = FT_EqualTo,
918                      Threshold="",
919                      UnaryOp=FT_Undefined,
920                      BinaryOp=FT_Undefined,
921                      Tolerance=1e-07):
922         """
923         Create a criterion by the given parameters
924         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
925
926         Parameters:
927                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
928                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
929                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
930                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
931                 Threshold: the threshold value (range of ids as string, shape, numeric)
932                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
933                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
934                         SMESH.FT_Undefined
935                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
936                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
937
938         Returns:
939                 :class:`SMESH.Filter.Criterion`
940
941         Example: :ref:`combining_filters`
942         """
943
944         if not CritType in SMESH.FunctorType._items:
945             raise TypeError("CritType should be of SMESH.FunctorType")
946         aCriterion               = self.GetEmptyCriterion()
947         aCriterion.TypeOfElement = elementType
948         aCriterion.Type          = self.EnumToLong(CritType)
949         aCriterion.Tolerance     = Tolerance
950
951         aThreshold = Threshold
952
953         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
954             aCriterion.Compare = self.EnumToLong(Compare)
955         elif Compare == "=" or Compare == "==":
956             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
957         elif Compare == "<":
958             aCriterion.Compare = self.EnumToLong(FT_LessThan)
959         elif Compare == ">":
960             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
961         elif Compare != FT_Undefined:
962             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
963             aThreshold = Compare
964
965         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
966                         FT_BelongToCylinder, FT_LyingOnGeom]:
967             # Check that Threshold is GEOM object
968             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
969                 aCriterion.ThresholdStr = GetName(aThreshold)
970                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
971                 if not aCriterion.ThresholdID:
972                     name = aCriterion.ThresholdStr
973                     if not name:
974                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
975                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
976             # or a name of GEOM object
977             elif isinstance( aThreshold, str ):
978                 aCriterion.ThresholdStr = aThreshold
979             else:
980                 raise TypeError("The Threshold should be a shape.")
981             if isinstance(UnaryOp,float):
982                 aCriterion.Tolerance = UnaryOp
983                 UnaryOp = FT_Undefined
984                 pass
985         elif CritType == FT_BelongToMeshGroup:
986             # Check that Threshold is a group
987             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
988                 if aThreshold.GetType() != elementType:
989                     raise ValueError("Group type mismatches Element type")
990                 aCriterion.ThresholdStr = aThreshold.GetName()
991                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
992                 study = salome.myStudy
993                 if study:
994                     so = study.FindObjectIOR( aCriterion.ThresholdID )
995                     if so:
996                         entry = so.GetID()
997                         if entry:
998                             aCriterion.ThresholdID = entry
999             else:
1000                 raise TypeError("The Threshold should be a Mesh Group")
1001         elif CritType == FT_RangeOfIds:
1002             # Check that Threshold is string
1003             if isinstance(aThreshold, str):
1004                 aCriterion.ThresholdStr = aThreshold
1005             else:
1006                 raise TypeError("The Threshold should be a string.")
1007         elif CritType == FT_CoplanarFaces:
1008             # Check the Threshold
1009             if isinstance(aThreshold, int):
1010                 aCriterion.ThresholdID = str(aThreshold)
1011             elif isinstance(aThreshold, str):
1012                 ID = int(aThreshold)
1013                 if ID < 1:
1014                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
1015                 aCriterion.ThresholdID = aThreshold
1016             else:
1017                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1018         elif CritType == FT_ConnectedElements:
1019             # Check the Threshold
1020             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1021                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1022                 if not aCriterion.ThresholdID:
1023                     name = aThreshold.GetName()
1024                     if not name:
1025                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1026                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1027             elif isinstance(aThreshold, int): # node id
1028                 aCriterion.Threshold = aThreshold
1029             elif isinstance(aThreshold, list): # 3 point coordinates
1030                 if len( aThreshold ) < 3:
1031                     raise ValueError("too few point coordinates, must be 3")
1032                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1033             elif isinstance(aThreshold, str):
1034                 if aThreshold.isdigit():
1035                     aCriterion.Threshold = aThreshold # node id
1036                 else:
1037                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1038             else:
1039                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1040                       "or a list of point coordinates and not '%s'"%aThreshold)
1041         elif CritType == FT_ElemGeomType:
1042             # Check the Threshold
1043             try:
1044                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1045                 assert( aThreshold in SMESH.GeometryType._items )
1046             except:
1047                 if isinstance(aThreshold, int):
1048                     aCriterion.Threshold = aThreshold
1049                 else:
1050                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1051                 pass
1052             pass
1053         elif CritType == FT_EntityType:
1054             # Check the Threshold
1055             try:
1056                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1057                 assert( aThreshold in SMESH.EntityType._items )
1058             except:
1059                 if isinstance(aThreshold, int):
1060                     aCriterion.Threshold = aThreshold
1061                 else:
1062                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1063                 pass
1064             pass
1065
1066         elif CritType == FT_GroupColor:
1067             # Check the Threshold
1068             try:
1069                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1070             except:
1071                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1072             pass
1073         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1074                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1075                           FT_BareBorderFace, FT_BareBorderVolume,
1076                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1077                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1078             # At this point the Threshold is unnecessary
1079             if aThreshold ==  FT_LogicalNOT:
1080                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1081             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1082                 aCriterion.BinaryOp = aThreshold
1083         else:
1084             # Check Threshold
1085             try:
1086                 aThreshold = float(aThreshold)
1087                 aCriterion.Threshold = aThreshold
1088             except:
1089                 raise TypeError("The Threshold should be a number.")
1090                 return None
1091
1092         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1093             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1094
1095         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1096             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1097
1098         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1099             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1100
1101         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1102             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1103
1104         return aCriterion
1105
1106     def GetFilter(self,elementType,
1107                   CritType=FT_Undefined,
1108                   Compare=FT_EqualTo,
1109                   Threshold="",
1110                   UnaryOp=FT_Undefined,
1111                   Tolerance=1e-07,
1112                   mesh=None):
1113         """
1114         Create a filter with the given parameters
1115
1116         Parameters:
1117                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1118                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1119                         Note that the items starting from FT_LessThan are not suitable for CritType.
1120                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1121                 Threshold: the threshold value (range of ids as string, shape, numeric)
1122                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1123                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1124                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1125                 mesh: the mesh to initialize the filter with
1126
1127         Returns:
1128                 :class:`SMESH.Filter`
1129
1130         Examples:
1131                See :doc:`Filters usage examples <tui_filters>`
1132         """
1133
1134         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1135         aFilterMgr = self.CreateFilterManager()
1136         aFilter = aFilterMgr.CreateFilter()
1137         aCriteria = []
1138         aCriteria.append(aCriterion)
1139         aFilter.SetCriteria(aCriteria)
1140         if mesh:
1141             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1142             else                       : aFilter.SetMesh( mesh )
1143         aFilterMgr.UnRegister()
1144         return aFilter
1145
1146     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1147         """
1148         Create a filter from criteria
1149
1150         Parameters:
1151                 criteria: a list of :class:`SMESH.Filter.Criterion`
1152                 binOp: binary operator used when binary operator of criteria is undefined
1153
1154         Returns:
1155                 :class:`SMESH.Filter`
1156
1157         Examples:
1158                See :doc:`Filters usage examples <tui_filters>`
1159         """
1160
1161         for i in range( len( criteria ) - 1 ):
1162             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1163                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1164         aFilterMgr = self.CreateFilterManager()
1165         aFilter = aFilterMgr.CreateFilter()
1166         aFilter.SetCriteria(criteria)
1167         aFilterMgr.UnRegister()
1168         return aFilter
1169
1170     def GetFunctor(self,theCriterion):
1171         """
1172         Create a numerical functor by its type
1173
1174         Parameters:
1175                 theCriterion (SMESH.FunctorType): functor type.
1176                         Note that not all items correspond to numerical functors.
1177
1178         Returns:
1179                 :class:`SMESH.NumericalFunctor`
1180         """
1181
1182         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1183             return theCriterion
1184         aFilterMgr = self.CreateFilterManager()
1185         functor = None
1186         if theCriterion == FT_AspectRatio:
1187             functor = aFilterMgr.CreateAspectRatio()
1188         elif theCriterion == FT_AspectRatio3D:
1189             functor = aFilterMgr.CreateAspectRatio3D()
1190         elif theCriterion == FT_Warping:
1191             functor = aFilterMgr.CreateWarping()
1192         elif theCriterion == FT_MinimumAngle:
1193             functor = aFilterMgr.CreateMinimumAngle()
1194         elif theCriterion == FT_Taper:
1195             functor = aFilterMgr.CreateTaper()
1196         elif theCriterion == FT_Skew:
1197             functor = aFilterMgr.CreateSkew()
1198         elif theCriterion == FT_Area:
1199             functor = aFilterMgr.CreateArea()
1200         elif theCriterion == FT_Volume3D:
1201             functor = aFilterMgr.CreateVolume3D()
1202         elif theCriterion == FT_MaxElementLength2D:
1203             functor = aFilterMgr.CreateMaxElementLength2D()
1204         elif theCriterion == FT_MaxElementLength3D:
1205             functor = aFilterMgr.CreateMaxElementLength3D()
1206         elif theCriterion == FT_MultiConnection:
1207             functor = aFilterMgr.CreateMultiConnection()
1208         elif theCriterion == FT_MultiConnection2D:
1209             functor = aFilterMgr.CreateMultiConnection2D()
1210         elif theCriterion == FT_Length:
1211             functor = aFilterMgr.CreateLength()
1212         elif theCriterion == FT_Length2D:
1213             functor = aFilterMgr.CreateLength2D()
1214         elif theCriterion == FT_Length3D:
1215             functor = aFilterMgr.CreateLength3D()
1216         elif theCriterion == FT_Deflection2D:
1217             functor = aFilterMgr.CreateDeflection2D()
1218         elif theCriterion == FT_NodeConnectivityNumber:
1219             functor = aFilterMgr.CreateNodeConnectivityNumber()
1220         elif theCriterion == FT_BallDiameter:
1221             functor = aFilterMgr.CreateBallDiameter()
1222         else:
1223             print("Error: given parameter is not numerical functor type.")
1224         aFilterMgr.UnRegister()
1225         return functor
1226
1227     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1228         """
1229         Create hypothesis
1230
1231         Parameters:
1232                 theHType (string): mesh hypothesis type
1233                 theLibName (string): mesh plug-in library name
1234
1235         Returns:
1236                 created hypothesis instance
1237         """
1238         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1239
1240         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1241             return hyp
1242
1243         # wrap hypothesis methods
1244         for meth_name in dir( hyp.__class__ ):
1245             if not meth_name.startswith("Get") and \
1246                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1247                 method = getattr ( hyp.__class__, meth_name )
1248                 if callable(method):
1249                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1250
1251         return hyp
1252
1253     def GetMeshInfo(self, obj):
1254         """
1255         Get the mesh statistic.
1256
1257         Returns:
1258                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1259         """
1260
1261         if isinstance( obj, Mesh ):
1262             obj = obj.GetMesh()
1263         d = {}
1264         if hasattr(obj, "GetMeshInfo"):
1265             values = obj.GetMeshInfo()
1266             for i in range(SMESH.Entity_Last._v):
1267                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1268             pass
1269         return d
1270
1271     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1272         """
1273         Get minimum distance between two objects
1274
1275         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1276         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1277
1278         Parameters:
1279                 src1 (SMESH.SMESH_IDSource): first source object
1280                 src2 (SMESH.SMESH_IDSource): second source object
1281                 id1 (int): node/element id from the first source
1282                 id2 (int): node/element id from the second (or first) source
1283                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1284                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1285
1286         Returns:
1287                 minimum distance value
1288
1289         See also: 
1290                 :meth:`GetMinDistance`
1291         """
1292
1293         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1294         if result is None:
1295             result = 0.0
1296         else:
1297             result = result.value
1298         return result
1299
1300     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1301         """
1302         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1303
1304         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1305         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1306
1307         Parameters:
1308                 src1 (SMESH.SMESH_IDSource): first source object
1309                 src2 (SMESH.SMESH_IDSource): second source object
1310                 id1 (int): node/element id from the first source
1311                 id2 (int): node/element id from the second (or first) source
1312                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1313                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1314
1315         Returns:
1316                 :class:`SMESH.Measure` structure or None if input data is invalid
1317         See also: 
1318                 :meth:`MinDistance`
1319         """
1320
1321         if isinstance(src1, Mesh): src1 = src1.mesh
1322         if isinstance(src2, Mesh): src2 = src2.mesh
1323         if src2 is None and id2 != 0: src2 = src1
1324         if not hasattr(src1, "_narrow"): return None
1325         src1 = src1._narrow(SMESH.SMESH_IDSource)
1326         if not src1: return None
1327         unRegister = genObjUnRegister()
1328         if id1 != 0:
1329             m = src1.GetMesh()
1330             e = m.GetMeshEditor()
1331             if isElem1:
1332                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1333             else:
1334                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1335             unRegister.set( src1 )
1336             pass
1337         if hasattr(src2, "_narrow"):
1338             src2 = src2._narrow(SMESH.SMESH_IDSource)
1339             if src2 and id2 != 0:
1340                 m = src2.GetMesh()
1341                 e = m.GetMeshEditor()
1342                 if isElem2:
1343                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1344                 else:
1345                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1346                 unRegister.set( src2 )
1347                 pass
1348             pass
1349         aMeasurements = self.CreateMeasurements()
1350         unRegister.set( aMeasurements )
1351         result = aMeasurements.MinDistance(src1, src2)
1352         return result
1353
1354     def BoundingBox(self, objects):
1355         """
1356         Get bounding box of the specified object(s)
1357
1358         Parameters:
1359                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1360
1361         Returns:
1362                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1363
1364         See also: 
1365                :meth:`GetBoundingBox`
1366         """
1367
1368         result = self.GetBoundingBox(objects)
1369         if result is None:
1370             result = (0.0,)*6
1371         else:
1372             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1373         return result
1374
1375     def GetBoundingBox(self, objects):
1376         """
1377         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1378
1379         Parameters:
1380                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1381
1382         Returns:
1383                 :class:`SMESH.Measure` structure
1384
1385         See also: 
1386                 :meth:`BoundingBox`
1387         """
1388
1389         if isinstance(objects, tuple):
1390             objects = list(objects)
1391         if not isinstance(objects, list):
1392             objects = [objects]
1393         srclist = []
1394         for o in objects:
1395             if isinstance(o, Mesh):
1396                 srclist.append(o.mesh)
1397             elif hasattr(o, "_narrow"):
1398                 src = o._narrow(SMESH.SMESH_IDSource)
1399                 if src: srclist.append(src)
1400                 pass
1401             pass
1402         aMeasurements = self.CreateMeasurements()
1403         result = aMeasurements.BoundingBox(srclist)
1404         aMeasurements.UnRegister()
1405         return result
1406
1407     def GetLength(self, obj):
1408         """
1409         Get sum of lengths of all 1D elements in the mesh object.
1410
1411         Parameters:
1412                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1413
1414         Returns:
1415                 sum of lengths of all 1D elements
1416         """
1417
1418         if isinstance(obj, Mesh): obj = obj.mesh
1419         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1420         aMeasurements = self.CreateMeasurements()
1421         value = aMeasurements.Length(obj)
1422         aMeasurements.UnRegister()
1423         return value
1424
1425     def GetArea(self, obj):
1426         """
1427         Get sum of areas of all 2D elements in the mesh object.
1428
1429         Parameters:
1430                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1431
1432         Returns:
1433                 sum of areas of all 2D elements
1434         """
1435
1436         if isinstance(obj, Mesh): obj = obj.mesh
1437         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438         aMeasurements = self.CreateMeasurements()
1439         value = aMeasurements.Area(obj)
1440         aMeasurements.UnRegister()
1441         return value
1442
1443     def GetVolume(self, obj):
1444         """
1445         Get sum of volumes of all 3D elements in the mesh object.
1446
1447         Parameters:
1448                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1449
1450         Returns:
1451                 sum of volumes of all 3D elements
1452         """
1453
1454         if isinstance(obj, Mesh): obj = obj.mesh
1455         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1456         aMeasurements = self.CreateMeasurements()
1457         value = aMeasurements.Volume(obj)
1458         aMeasurements.UnRegister()
1459         return value
1460
1461     def GetGravityCenter(self, obj):
1462         """
1463         Get gravity center of all nodes of a mesh object.
1464         
1465         Parameters:            
1466                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1467
1468         Returns:        
1469                 Three components of the gravity center (x,y,z)
1470
1471         See also: 
1472                 :meth:`Mesh.BaryCenter`
1473         """
1474         if isinstance(obj, Mesh): obj = obj.mesh
1475         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1476         aMeasurements = self.CreateMeasurements()
1477         pointStruct = aMeasurements.GravityCenter(obj)
1478         aMeasurements.UnRegister()
1479         return pointStruct.x, pointStruct.y, pointStruct.z
1480
1481     def GetAngle(self, p1, p2, p3 ):
1482         """
1483         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1484
1485         Parameters:            
1486                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
1487                           or list [x,y,z]
1488
1489         Returns:        
1490             Angle in radians
1491         """
1492         if isinstance( p1, list ): p1 = PointStruct(*p1)
1493         if isinstance( p2, list ): p2 = PointStruct(*p2)
1494         if isinstance( p3, list ): p3 = PointStruct(*p3)
1495
1496         aMeasurements = self.CreateMeasurements()
1497         angle = aMeasurements.Angle(p1,p2,p3)
1498         aMeasurements.UnRegister()
1499
1500         return angle
1501
1502
1503     pass # end of class smeshBuilder
1504
1505 import omniORB
1506 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1507 """Registering the new proxy for SMESH.SMESH_Gen"""
1508
1509
1510 def New( instance=None, instanceGeom=None):
1511     """
1512     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1513     interface to create or load meshes.
1514
1515     Typical use is::
1516
1517         import salome
1518         salome.salome_init()
1519         from salome.smesh import smeshBuilder
1520         smesh = smeshBuilder.New()
1521
1522     Parameters:
1523         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1524         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1525     Returns:
1526         :class:`smeshBuilder` instance
1527     """
1528     global engine
1529     global smeshInst
1530     global doLcc
1531     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1532         import sys
1533         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1534         instance = None
1535     engine = instance
1536     if engine is None:
1537         doLcc = True
1538     smeshInst = smeshBuilder()
1539     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1540     smeshInst.init_smesh(instanceGeom)
1541     return smeshInst
1542
1543
1544 # Public class: Mesh
1545 # ==================
1546
1547
1548 class Mesh(metaclass = MeshMeta):
1549     """
1550     This class allows defining and managing a mesh.
1551     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1552     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1553     new nodes and elements and by changing the existing entities), to get information
1554     about a mesh and to export a mesh in different formats.
1555     """    
1556
1557     geom = 0
1558     mesh = 0
1559     editor = 0
1560
1561     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1562
1563         """
1564         Constructor
1565
1566         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1567         sets the GUI name of this mesh to *name*.
1568
1569         Parameters:
1570                 smeshpyD: an instance of smeshBuilder class
1571                 geompyD: an instance of geomBuilder class
1572                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1573                 name: Study name of the mesh
1574         """
1575
1576         self.smeshpyD = smeshpyD
1577         self.geompyD = geompyD
1578         if obj is None:
1579             obj = 0
1580         objHasName = False
1581         if obj != 0:
1582             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1583                 self.geom = obj
1584                 objHasName = True
1585                 # publish geom of mesh (issue 0021122)
1586                 if not self.geom.GetStudyEntry():
1587                     objHasName = False
1588                     geompyD.init_geom()
1589                     if name:
1590                         geo_name = name + " shape"
1591                     else:
1592                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1593                     geompyD.addToStudy( self.geom, geo_name )
1594                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1595
1596             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1597                 self.SetMesh(obj)
1598         else:
1599             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1600         if name:
1601             self.smeshpyD.SetName(self.mesh, name)
1602         elif objHasName:
1603             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1604
1605         if not self.geom:
1606             self.geom = self.mesh.GetShapeToMesh()
1607
1608         self.editor   = self.mesh.GetMeshEditor()
1609         self.functors = [None] * SMESH.FT_Undefined._v
1610
1611         # set self to algoCreator's
1612         for attrName in dir(self):
1613             attr = getattr( self, attrName )
1614             if isinstance( attr, algoCreator ):
1615                 setattr( self, attrName, attr.copy( self ))
1616                 pass
1617             pass
1618         pass
1619
1620     def __del__(self):
1621         """
1622         Destructor. Clean-up resources
1623         """
1624         if self.mesh:
1625             #self.mesh.UnRegister()
1626             pass
1627         pass
1628
1629     def SetMesh(self, theMesh):
1630         """
1631         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1632
1633         Parameters:
1634                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1635         """
1636
1637
1638         # do not call Register() as this prevents mesh servant deletion at closing study
1639         #if self.mesh: self.mesh.UnRegister()
1640         self.mesh = theMesh
1641         if self.mesh:
1642             #self.mesh.Register()
1643             self.geom = self.mesh.GetShapeToMesh()
1644         pass
1645
1646     def GetMesh(self):
1647         """
1648         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1649
1650         Returns:
1651                 a :class:`SMESH.SMESH_Mesh` object
1652         """
1653
1654         return self.mesh
1655
1656     def GetEngine(self):
1657         """
1658         Return a smeshBuilder instance created this mesh
1659         """
1660         return self.smeshpyD
1661
1662     def GetGeomEngine(self):
1663         """
1664         Return a geomBuilder instance
1665         """
1666         return self.geompyD
1667
1668     def GetName(self):
1669         """
1670         Get the name of the mesh
1671
1672         Returns:
1673                 the name of the mesh as a string
1674         """
1675
1676         name = GetName(self.GetMesh())
1677         return name
1678
1679     def SetName(self, name):
1680         """
1681         Set a name to the mesh
1682
1683         Parameters:
1684                 name: a new name of the mesh
1685         """
1686
1687         self.smeshpyD.SetName(self.GetMesh(), name)
1688
1689     def GetSubMesh(self, geom, name):
1690         """
1691         Get a sub-mesh object associated to a *geom* geometrical object.
1692
1693         Parameters:
1694                 geom: a geometrical object (shape)
1695                 name: a name for the sub-mesh in the Object Browser
1696
1697         Returns:
1698                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1699                 which lies on the given shape
1700
1701         Note:
1702                 A sub-mesh is implicitly created when a sub-shape is specified at
1703                 creating an algorithm, for example::
1704
1705                    algo1D = mesh.Segment(geom=Edge_1)
1706
1707                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1708                 The created sub-mesh can be retrieved from the algorithm::
1709
1710                    submesh = algo1D.GetSubMesh()
1711         """
1712
1713         AssureGeomPublished( self, geom, name )
1714         submesh = self.mesh.GetSubMesh( geom, name )
1715         return submesh
1716
1717     def GetShape(self):
1718         """
1719         Return the shape associated to the mesh
1720
1721         Returns:
1722                 a GEOM_Object
1723         """
1724
1725         return self.geom
1726
1727     def SetShape(self, geom):
1728         """
1729         Associate the given shape to the mesh (entails the recreation of the mesh)
1730
1731         Parameters:
1732                 geom: the shape to be meshed (GEOM_Object)
1733         """
1734
1735         self.mesh = self.smeshpyD.CreateMesh(geom)
1736
1737     def HasShapeToMesh(self):
1738         """
1739         Return ``True`` if this mesh is based on geometry
1740         """
1741         return self.mesh.HasShapeToMesh()
1742
1743     def Load(self):
1744         """
1745         Load mesh from the study after opening the study
1746         """
1747         self.mesh.Load()
1748
1749     def IsReadyToCompute(self, theSubObject):
1750         """
1751         Return true if the hypotheses are defined well
1752
1753         Parameters:
1754                 theSubObject: a sub-shape of a mesh shape
1755
1756         Returns:
1757                 True or False
1758         """
1759
1760         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1761
1762     def GetAlgoState(self, theSubObject):
1763         """
1764         Return errors of hypotheses definition.
1765         The list of errors is empty if everything is OK.
1766
1767         Parameters:
1768                 theSubObject: a sub-shape of a mesh shape
1769
1770         Returns:
1771                 a list of errors
1772         """
1773
1774         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1775
1776     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1777         """
1778         Return a geometrical object on which the given element was built.
1779         The returned geometrical object, if not nil, is either found in the
1780         study or published by this method with the given name
1781
1782         Parameters:
1783             theElementID: the id of the mesh element
1784             theGeomName: the user-defined name of the geometrical object
1785
1786         Returns:
1787             GEOM.GEOM_Object instance
1788         """
1789
1790         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1791
1792     def MeshDimension(self):
1793         """
1794         Return the mesh dimension depending on the dimension of the underlying shape
1795         or, if the mesh is not based on any shape, basing on deimension of elements
1796
1797         Returns:
1798                 mesh dimension as an integer value [0,3]
1799         """
1800
1801         if self.mesh.HasShapeToMesh():
1802             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1803             if len( shells ) > 0 :
1804                 return 3
1805             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1806                 return 2
1807             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1808                 return 1
1809             else:
1810                 return 0;
1811         else:
1812             if self.NbVolumes() > 0: return 3
1813             if self.NbFaces()   > 0: return 2
1814             if self.NbEdges()   > 0: return 1
1815         return 0
1816
1817     def Evaluate(self, geom=0):
1818         """
1819         Evaluate size of prospective mesh on a shape
1820
1821         Returns:
1822                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1823                 To know predicted number of e.g. edges, inquire it this way::
1824
1825                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1826         """
1827
1828         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1829             if self.geom == 0:
1830                 geom = self.mesh.GetShapeToMesh()
1831             else:
1832                 geom = self.geom
1833         return self.smeshpyD.Evaluate(self.mesh, geom)
1834
1835
1836     def Compute(self, geom=0, discardModifs=False, refresh=False):
1837         """
1838         Compute the mesh and return the status of the computation
1839
1840         Parameters:
1841                 geom: geomtrical shape on which mesh data should be computed
1842                 discardModifs: if True and the mesh has been edited since
1843                         a last total re-compute and that may prevent successful partial re-compute,
1844                         then the mesh is cleaned before Compute()
1845                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1846
1847         Returns:
1848                 True or False
1849         """
1850
1851         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1852             if self.geom == 0:
1853                 geom = self.mesh.GetShapeToMesh()
1854             else:
1855                 geom = self.geom
1856         ok = False
1857         try:
1858             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1859                 self.mesh.Clear()
1860             ok = self.smeshpyD.Compute(self.mesh, geom)
1861         except SALOME.SALOME_Exception as ex:
1862             print("Mesh computation failed, exception caught:")
1863             print("    ", ex.details.text)
1864         except:
1865             import traceback
1866             print("Mesh computation failed, exception caught:")
1867             traceback.print_exc()
1868         if True:#not ok:
1869             allReasons = ""
1870
1871             # Treat compute errors
1872             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1873             shapeText = ""
1874             for err in computeErrors:
1875                 if self.mesh.HasShapeToMesh():
1876                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1877                 errText = ""
1878                 stdErrors = ["OK",                   #COMPERR_OK
1879                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1880                              "std::exception",       #COMPERR_STD_EXCEPTION
1881                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1882                              "..",                   #COMPERR_SLM_EXCEPTION
1883                              "Unknown exception",    #COMPERR_EXCEPTION
1884                              "Memory allocation problem", #COMPERR_MEMORY_PB
1885                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1886                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1887                              "Warning",              #COMPERR_WARNING
1888                              "Computation cancelled",#COMPERR_CANCELED
1889                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1890                 if err.code > 0:
1891                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1892                 else:
1893                     errText = "code %s" % -err.code
1894                 if errText: errText += ". "
1895                 errText += err.comment
1896                 if allReasons: allReasons += "\n"
1897                 if ok:
1898                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1899                 else:
1900                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1901                 pass
1902
1903             # Treat hyp errors
1904             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1905             for err in errors:
1906                 if err.isGlobalAlgo:
1907                     glob = "global"
1908                 else:
1909                     glob = "local"
1910                     pass
1911                 dim = err.algoDim
1912                 name = err.algoName
1913                 if len(name) == 0:
1914                     reason = '%s %sD algorithm is missing' % (glob, dim)
1915                 elif err.state == HYP_MISSING:
1916                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1917                               % (glob, dim, name, dim))
1918                 elif err.state == HYP_NOTCONFORM:
1919                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1920                 elif err.state == HYP_BAD_PARAMETER:
1921                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1922                               % ( glob, dim, name ))
1923                 elif err.state == HYP_BAD_GEOMETRY:
1924                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1925                               'geometry' % ( glob, dim, name ))
1926                 elif err.state == HYP_HIDDEN_ALGO:
1927                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1928                               'algorithm of upper dimension generating %sD mesh'
1929                               % ( glob, dim, name, glob, dim ))
1930                 else:
1931                     reason = ("For unknown reason. "
1932                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1933                     pass
1934                 if allReasons: allReasons += "\n"
1935                 allReasons += "-  " + reason
1936                 pass
1937             if not ok or allReasons != "":
1938                 msg = '"' + GetName(self.mesh) + '"'
1939                 if ok: msg += " has been computed with warnings"
1940                 else:  msg += " has not been computed"
1941                 if allReasons != "": msg += ":"
1942                 else:                msg += "."
1943                 print(msg)
1944                 print(allReasons)
1945             pass
1946         if salome.sg.hasDesktop():
1947             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1948                 if refresh: salome.sg.updateObjBrowser()
1949
1950         return ok
1951
1952     def GetComputeErrors(self, shape=0 ):
1953         """
1954         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1955         """
1956
1957         if shape == 0:
1958             shape = self.mesh.GetShapeToMesh()
1959         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1960
1961     def GetSubShapeName(self, subShapeID ):
1962         """
1963         Return a name of a sub-shape by its ID.
1964         Possible variants (for *subShapeID* == 3):
1965
1966                 - **"Face_12"** - published sub-shape
1967                 - **FACE #3** - not published sub-shape
1968                 - **sub-shape #3** - invalid sub-shape ID
1969                 - **#3** - error in this function
1970
1971         Parameters:
1972                 subShapeID: a unique ID of a sub-shape
1973
1974         Returns:
1975                 a string describing the sub-shape
1976
1977         """
1978
1979         if not self.mesh.HasShapeToMesh():
1980             return ""
1981         try:
1982             shapeText = ""
1983             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1984             s = salome.myStudy
1985             mainSO = s.FindObjectIOR(mainIOR)
1986             if mainSO:
1987                 if subShapeID == 1:
1988                     shapeText = '"%s"' % mainSO.GetName()
1989                 subIt = s.NewChildIterator(mainSO)
1990                 while subIt.More():
1991                     subSO = subIt.Value()
1992                     subIt.Next()
1993                     obj = subSO.GetObject()
1994                     if not obj: continue
1995                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1996                     if not go: continue
1997                     try:
1998                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1999                     except:
2000                         continue
2001                     if ids == subShapeID:
2002                         shapeText = '"%s"' % subSO.GetName()
2003                         break
2004             if not shapeText:
2005                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2006                 if shape:
2007                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2008                 else:
2009                     shapeText = 'sub-shape #%s' % (subShapeID)
2010         except:
2011             shapeText = "#%s" % (subShapeID)
2012         return shapeText
2013
2014     def GetFailedShapes(self, publish=False):
2015         """
2016         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2017         error of an algorithm
2018
2019         Parameters:
2020                 publish: if *True*, the returned groups will be published in the study
2021
2022         Returns:
2023                 a list of GEOM groups each named after a failed algorithm
2024         """
2025
2026
2027         algo2shapes = {}
2028         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2029         for err in computeErrors:
2030             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2031             if not shape: continue
2032             if err.algoName in algo2shapes:
2033                 algo2shapes[ err.algoName ].append( shape )
2034             else:
2035                 algo2shapes[ err.algoName ] = [ shape ]
2036             pass
2037
2038         groups = []
2039         for algoName, shapes in list(algo2shapes.items()):
2040             while shapes:
2041                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2042                 otherTypeShapes = []
2043                 sameTypeShapes  = []
2044                 group = self.geompyD.CreateGroup( self.geom, groupType )
2045                 for shape in shapes:
2046                     if shape.GetShapeType() == shapes[0].GetShapeType():
2047                         sameTypeShapes.append( shape )
2048                     else:
2049                         otherTypeShapes.append( shape )
2050                 self.geompyD.UnionList( group, sameTypeShapes )
2051                 if otherTypeShapes:
2052                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2053                 else:
2054                     group.SetName( algoName )
2055                 groups.append( group )
2056                 shapes = otherTypeShapes
2057             pass
2058         if publish:
2059             for group in groups:
2060                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2061         return groups
2062
2063     def GetMeshOrder(self):
2064         """
2065         Return sub-mesh objects list in meshing order
2066
2067         Returns:
2068                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2069         """
2070
2071         return self.mesh.GetMeshOrder()
2072
2073     def SetMeshOrder(self, submeshes):
2074         """
2075         Set priority of sub-meshes. It works in two ways:
2076         
2077         * For sub-meshes with assigned algorithms of same dimension generating mesh of
2078           *several dimensions*, it sets the order in which the sub-meshes are computed.
2079         * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2080           when looking for meshing parameters to apply to a sub-shape. To impose the 
2081           order in which sub-meshes with uni-dimensional algorithms are computed, 
2082           call **submesh.Compute()** in a desired order.
2083
2084         Parameters:
2085                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2086         """
2087
2088         return self.mesh.SetMeshOrder(submeshes)
2089
2090     def Clear(self, refresh=False):
2091         """
2092         Remove all nodes and elements generated on geometry. Imported elements remain.
2093
2094         Parameters:
2095                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2096         """
2097
2098         self.mesh.Clear()
2099         if ( salome.sg.hasDesktop() ):
2100             if refresh: salome.sg.updateObjBrowser()
2101
2102     def ClearSubMesh(self, geomId, refresh=False):
2103         """
2104         Remove all nodes and elements of indicated shape
2105
2106         Parameters:
2107                 geomId: the ID of a sub-shape to remove elements on
2108                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2109         """
2110
2111         self.mesh.ClearSubMesh(geomId)
2112         if salome.sg.hasDesktop():
2113             if refresh: salome.sg.updateObjBrowser()
2114
2115     def AutomaticTetrahedralization(self, fineness=0):
2116         """
2117         Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2118
2119         Parameters:
2120                 fineness: [0.0,1.0] defines mesh fineness
2121
2122         Returns:
2123                 True or False
2124         """
2125
2126         dim = self.MeshDimension()
2127         # assign hypotheses
2128         self.RemoveGlobalHypotheses()
2129         self.Segment().AutomaticLength(fineness)
2130         if dim > 1 :
2131             self.Triangle().LengthFromEdges()
2132             pass
2133         if dim > 2 :
2134             self.Tetrahedron()
2135             pass
2136         return self.Compute()
2137
2138     def AutomaticHexahedralization(self, fineness=0):
2139         """
2140         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2141
2142         Parameters:
2143                 fineness: [0.0, 1.0] defines mesh fineness
2144
2145         Returns:
2146                 True or False
2147         """
2148
2149         dim = self.MeshDimension()
2150         # assign the hypotheses
2151         self.RemoveGlobalHypotheses()
2152         self.Segment().AutomaticLength(fineness)
2153         if dim > 1 :
2154             self.Quadrangle()
2155             pass
2156         if dim > 2 :
2157             self.Hexahedron()
2158             pass
2159         return self.Compute()
2160
2161     def AddHypothesis(self, hyp, geom=0):
2162         """
2163         Assign a hypothesis
2164
2165         Parameters:
2166                 hyp: a hypothesis to assign
2167                 geom: a subhape of mesh geometry
2168
2169         Returns:
2170                 :class:`SMESH.Hypothesis_Status`
2171         """
2172
2173         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2174             hyp, geom = geom, hyp
2175         if isinstance( hyp, Mesh_Algorithm ):
2176             hyp = hyp.GetAlgorithm()
2177             pass
2178         if not geom:
2179             geom = self.geom
2180             if not geom:
2181                 geom = self.mesh.GetShapeToMesh()
2182             pass
2183         isApplicable = True
2184         if self.mesh.HasShapeToMesh():
2185             hyp_type     = hyp.GetName()
2186             lib_name     = hyp.GetLibName()
2187             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2188             # if checkAll and geom:
2189             #     checkAll = geom.GetType() == 37
2190             checkAll     = False
2191             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2192         if isApplicable:
2193             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2194             status = self.mesh.AddHypothesis(geom, hyp)
2195         else:
2196             status = HYP_BAD_GEOMETRY, ""
2197         hyp_name = GetName( hyp )
2198         geom_name = ""
2199         if geom:
2200             geom_name = geom.GetName()
2201         isAlgo = hyp._narrow( SMESH_Algo )
2202         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2203         return status
2204
2205     def IsUsedHypothesis(self, hyp, geom):
2206         """
2207         Return True if an algorithm or hypothesis is assigned to a given shape
2208
2209         Parameters:
2210                 hyp: an algorithm or hypothesis to check
2211                 geom: a subhape of mesh geometry
2212
2213         Returns:
2214                 True of False
2215         """
2216
2217         if not hyp: # or not geom
2218             return False
2219         if isinstance( hyp, Mesh_Algorithm ):
2220             hyp = hyp.GetAlgorithm()
2221             pass
2222         hyps = self.GetHypothesisList(geom)
2223         for h in hyps:
2224             if h.GetId() == hyp.GetId():
2225                 return True
2226         return False
2227
2228     def RemoveHypothesis(self, hyp, geom=0):
2229         """
2230         Unassign a hypothesis
2231
2232         Parameters:
2233                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2234                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2235
2236         Returns:
2237                 :class:`SMESH.Hypothesis_Status`
2238         """
2239
2240         if not hyp:
2241             return None
2242         if isinstance( hyp, Mesh_Algorithm ):
2243             hyp = hyp.GetAlgorithm()
2244             pass
2245         shape = geom
2246         if not shape:
2247             shape = self.geom
2248             pass
2249         if self.IsUsedHypothesis( hyp, shape ):
2250             return self.mesh.RemoveHypothesis( shape, hyp )
2251         hypName = GetName( hyp )
2252         geoName = GetName( shape )
2253         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2254         return None
2255
2256     def GetHypothesisList(self, geom):
2257         """
2258         Get the list of hypotheses added on a geometry
2259
2260         Parameters:
2261                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2262
2263         Returns:
2264                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2265         """
2266
2267         return self.mesh.GetHypothesisList( geom )
2268
2269     def RemoveGlobalHypotheses(self):
2270         """
2271         Remove all global hypotheses
2272         """
2273
2274         current_hyps = self.mesh.GetHypothesisList( self.geom )
2275         for hyp in current_hyps:
2276             self.mesh.RemoveHypothesis( self.geom, hyp )
2277             pass
2278         pass
2279     def ExportMED(self, *args, **kwargs):
2280         """
2281         Export the mesh in a file in MED format
2282         allowing to overwrite the file if it exists or add the exported data to its contents
2283
2284         Parameters:
2285                 fileName: is the file name
2286                 auto_groups (boolean): parameter for creating/not creating
2287                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2288                         the typical use is auto_groups=False.
2289                 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2290                         The minor must be between 0 and the current minor version of MED file library.
2291                         If minor is equal to -1, the minor version is not changed (default).
2292                         The major version (x, where version is x.y.z) cannot be changed.
2293                 overwrite (boolean): parameter for overwriting/not overwriting the file
2294                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2295                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2296
2297                         - 1D if all mesh nodes lie on OX coordinate axis, or
2298                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2299                         - 3D in the rest cases.
2300
2301                         If *autoDimension* is *False*, the space dimension is always 3.
2302                 fields: list of GEOM fields defined on the shape to mesh.
2303                 geomAssocFields: each character of this string means a need to export a 
2304                         corresponding field; correspondence between fields and characters 
2305                         is following:
2306
2307                         - 'v' stands for "_vertices_" field;
2308                         - 'e' stands for "_edges_" field;
2309                         - 'f' stands for "_faces_" field;
2310                         - 's' stands for "_solids_" field.
2311
2312                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2313                              close to zero within a given tolerance, the coordinate is set to zero.
2314                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2315         """
2316         # process positional arguments
2317         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2318         fileName        = args[0]
2319         auto_groups     = args[1] if len(args) > 1 else False
2320         minor           = args[2] if len(args) > 2 else -1
2321         overwrite       = args[3] if len(args) > 3 else True
2322         meshPart        = args[4] if len(args) > 4 else None
2323         autoDimension   = args[5] if len(args) > 5 else True
2324         fields          = args[6] if len(args) > 6 else []
2325         geomAssocFields = args[7] if len(args) > 7 else ''
2326         z_tolerance     = args[8] if len(args) > 8 else -1.
2327         # process keywords arguments
2328         auto_groups     = kwargs.get("auto_groups", auto_groups)
2329         minor           = kwargs.get("minor", minor)
2330         overwrite       = kwargs.get("overwrite", overwrite)
2331         meshPart        = kwargs.get("meshPart", meshPart)
2332         autoDimension   = kwargs.get("autoDimension", autoDimension)
2333         fields          = kwargs.get("fields", fields)
2334         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2335         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2336
2337         # invoke engine's function
2338         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2339             unRegister = genObjUnRegister()
2340             if isinstance( meshPart, list ):
2341                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2342                 unRegister.set( meshPart )
2343
2344             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2345             self.mesh.SetParameters(Parameters)
2346
2347             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2348                                        fields, geomAssocFields, z_tolerance)
2349         else:
2350             self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2351
2352     def ExportSAUV(self, f, auto_groups=0):
2353         """
2354         Export the mesh in a file in SAUV format
2355
2356
2357         Parameters:
2358                 f: is the file name
2359                 auto_groups: boolean parameter for creating/not creating
2360                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2361                         the typical use is auto_groups=False.
2362         """
2363
2364         self.mesh.ExportSAUV(f, auto_groups)
2365
2366     def ExportDAT(self, f, meshPart=None):
2367         """
2368         Export the mesh in a file in DAT format
2369
2370         Parameters:
2371                 f: the file name
2372                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2373         """
2374
2375         if meshPart:
2376             unRegister = genObjUnRegister()
2377             if isinstance( meshPart, list ):
2378                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2379                 unRegister.set( meshPart )
2380             self.mesh.ExportPartToDAT( meshPart, f )
2381         else:
2382             self.mesh.ExportDAT(f)
2383
2384     def ExportUNV(self, f, meshPart=None):
2385         """
2386         Export the mesh in a file in UNV format
2387
2388         Parameters:
2389                 f: the file name
2390                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2391         """
2392
2393         if meshPart:
2394             unRegister = genObjUnRegister()
2395             if isinstance( meshPart, list ):
2396                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2397                 unRegister.set( meshPart )
2398             self.mesh.ExportPartToUNV( meshPart, f )
2399         else:
2400             self.mesh.ExportUNV(f)
2401
2402     def ExportSTL(self, f, ascii=1, meshPart=None):
2403         """
2404         Export the mesh in a file in STL format
2405
2406         Parameters:
2407                 f: the file name
2408                 ascii: defines the file encoding
2409                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2410         """
2411
2412         if meshPart:
2413             unRegister = genObjUnRegister()
2414             if isinstance( meshPart, list ):
2415                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2416                 unRegister.set( meshPart )
2417             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2418         else:
2419             self.mesh.ExportSTL(f, ascii)
2420
2421     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2422         """
2423         Export the mesh in a file in CGNS format
2424
2425         Parameters:
2426                 f: is the file name
2427                 overwrite: boolean parameter for overwriting/not overwriting the file
2428                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2429                 groupElemsByType: if True all elements of same entity type are exported at ones,
2430                         else elements are exported in order of their IDs which can cause creation
2431                         of multiple cgns sections
2432         """
2433
2434         unRegister = genObjUnRegister()
2435         if isinstance( meshPart, list ):
2436             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2437             unRegister.set( meshPart )
2438         if isinstance( meshPart, Mesh ):
2439             meshPart = meshPart.mesh
2440         elif not meshPart:
2441             meshPart = self.mesh
2442         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2443
2444     def ExportGMF(self, f, meshPart=None):
2445         """
2446         Export the mesh in a file in GMF format.
2447         GMF files must have .mesh extension for the ASCII format and .meshb for
2448         the bynary format. Other extensions are not allowed.
2449
2450         Parameters:
2451                 f: is the file name
2452                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2453         """
2454
2455         unRegister = genObjUnRegister()
2456         if isinstance( meshPart, list ):
2457             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2458             unRegister.set( meshPart )
2459         if isinstance( meshPart, Mesh ):
2460             meshPart = meshPart.mesh
2461         elif not meshPart:
2462             meshPart = self.mesh
2463         self.mesh.ExportGMF(meshPart, f, True)
2464
2465     def ExportToMED(self, *args, **kwargs):
2466         """
2467         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2468         Export the mesh in a file in MED format
2469         allowing to overwrite the file if it exists or add the exported data to its contents
2470
2471         Parameters:
2472                 fileName: the file name
2473                 opt (boolean): parameter for creating/not creating
2474                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2475                 overwrite: boolean parameter for overwriting/not overwriting the file
2476                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2477
2478                         - 1D if all mesh nodes lie on OX coordinate axis, or
2479                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2480                         - 3D in the rest cases.
2481
2482                         If **autoDimension** is *False*, the space dimension is always 3.
2483         """
2484     
2485         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2486         # process positional arguments
2487         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2488         fileName      = args[0]
2489         auto_groups   = args[1] if len(args) > 1 else False
2490         overwrite     = args[2] if len(args) > 2 else True
2491         autoDimension = args[3] if len(args) > 3 else True
2492         # process keywords arguments
2493         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2494         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2495         overwrite     = kwargs.get("overwrite", overwrite)
2496         autoDimension = kwargs.get("autoDimension", autoDimension)
2497         minor = -1
2498         # invoke engine's function
2499         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2500
2501     def ExportToMEDX(self, *args, **kwargs):
2502         """
2503         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2504         Export the mesh in a file in MED format
2505
2506         Parameters:
2507                 fileName: the file name
2508                 opt (boolean): parameter for creating/not creating
2509                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2510                 overwrite: boolean parameter for overwriting/not overwriting the file
2511                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2512
2513                         - 1D if all mesh nodes lie on OX coordinate axis, or
2514                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2515                         - 3D in the rest cases.
2516
2517                         If **autoDimension** is *False*, the space dimension is always 3.
2518                 """
2519
2520         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2521         # process positional arguments
2522         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2523         fileName      = args[0]
2524         auto_groups   = args[1] if len(args) > 1 else False
2525         overwrite     = args[2] if len(args) > 2 else True
2526         autoDimension = args[3] if len(args) > 3 else True
2527         # process keywords arguments
2528         auto_groups   = kwargs.get("auto_groups", auto_groups)
2529         overwrite     = kwargs.get("overwrite", overwrite)
2530         autoDimension = kwargs.get("autoDimension", autoDimension)
2531         minor = -1
2532         # invoke engine's function
2533         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2534         return
2535
2536
2537     def Append(self, meshes, uniteIdenticalGroups = True,
2538                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2539         """
2540         Append given meshes into this mesh.
2541         All groups of input meshes will be created in this mesh.
2542
2543         Parameters:
2544                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2545                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2546                 mergeNodesAndElements: if True, equal nodes and elements are merged
2547                 mergeTolerance: tolerance for merging nodes
2548                 allGroups: forces creation of groups corresponding to every input mesh
2549         """
2550         self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2551                                    mergeNodesAndElements, mergeTolerance, allGroups,
2552                                    meshToAppendTo = self.GetMesh() )
2553
2554     # Operations with groups:
2555     # ----------------------
2556     def CreateEmptyGroup(self, elementType, name):
2557         """
2558         Create an empty standalone mesh group
2559
2560         Parameters:
2561                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2562                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2563                 name: the name of the mesh group
2564
2565         Returns:
2566                 :class:`SMESH.SMESH_Group`
2567         """
2568
2569         return self.mesh.CreateGroup(elementType, name)
2570
2571     def Group(self, grp, name=""):
2572         """
2573         Create a mesh group based on the geometric object *grp*
2574         and give it a *name*.
2575         If *name* is not defined the name of the geometric group is used
2576
2577         Note:
2578                 Works like :meth:`GroupOnGeom`.
2579
2580         Parameters:
2581                 grp:  a geometric group, a vertex, an edge, a face or a solid
2582                 name: the name of the mesh group
2583
2584         Returns:
2585                 :class:`SMESH.SMESH_GroupOnGeom`
2586         """
2587
2588         return self.GroupOnGeom(grp, name)
2589
2590     def GroupOnGeom(self, grp, name="", typ=None):
2591         """
2592         Create a mesh group based on the geometrical object *grp*
2593         and give it a *name*.
2594         if *name* is not defined the name of the geometric group is used
2595
2596         Parameters:
2597                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2598                 name: the name of the mesh group
2599                 typ:  the type of elements in the group; either of
2600                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2601                         automatically detected by the type of the geometry
2602
2603         Returns:
2604                 :class:`SMESH.SMESH_GroupOnGeom`
2605         """
2606
2607         AssureGeomPublished( self, grp, name )
2608         if name == "":
2609             name = grp.GetName()
2610         if not typ:
2611             typ = self._groupTypeFromShape( grp )
2612         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2613
2614     def _groupTypeFromShape( self, shape ):
2615         """
2616         Pivate method to get a type of group on geometry
2617         """
2618         tgeo = str(shape.GetShapeType())
2619         if tgeo == "VERTEX":
2620             typ = NODE
2621         elif tgeo == "EDGE":
2622             typ = EDGE
2623         elif tgeo == "FACE" or tgeo == "SHELL":
2624             typ = FACE
2625         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2626             typ = VOLUME
2627         elif tgeo == "COMPOUND":
2628             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2629             if not sub:
2630                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2631             return self._groupTypeFromShape( sub[0] )
2632         else:
2633             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2634         return typ
2635
2636     def GroupOnFilter(self, typ, name, filter):
2637         """
2638         Create a mesh group with given *name* based on the *filter*.
2639         It is a special type of group dynamically updating it's contents during
2640         mesh modification
2641
2642         Parameters:
2643                 typ: the type of elements in the group; either of
2644                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2645                 name: the name of the mesh group
2646                 filter (SMESH.Filter): the filter defining group contents
2647
2648         Returns:
2649                 :class:`SMESH.SMESH_GroupOnFilter`
2650         """
2651
2652         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2653
2654     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2655         """
2656         Create a mesh group by the given ids of elements
2657
2658         Parameters:
2659                 groupName: the name of the mesh group
2660                 elementType: the type of elements in the group; either of
2661                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2662                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2663
2664         Returns:
2665                 :class:`SMESH.SMESH_Group`
2666         """
2667
2668         group = self.mesh.CreateGroup(elementType, groupName)
2669         if isinstance( elemIDs, Mesh ):
2670             elemIDs = elemIDs.GetMesh()
2671         if hasattr( elemIDs, "GetIDs" ):
2672             if hasattr( elemIDs, "SetMesh" ):
2673                 elemIDs.SetMesh( self.GetMesh() )
2674             group.AddFrom( elemIDs )
2675         else:
2676             group.Add(elemIDs)
2677         return group
2678
2679     def MakeGroup(self,
2680                   groupName,
2681                   elementType,
2682                   CritType=FT_Undefined,
2683                   Compare=FT_EqualTo,
2684                   Threshold="",
2685                   UnaryOp=FT_Undefined,
2686                   Tolerance=1e-07):
2687         """
2688         Create a mesh group by the given conditions
2689
2690         Parameters:
2691                 groupName: the name of the mesh group
2692                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2693                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2694                         Note that the items starting from FT_LessThan are not suitable for CritType.
2695                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2696                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2697                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2698                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2699                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2700
2701         Returns:
2702                 :class:`SMESH.SMESH_GroupOnFilter`
2703         """
2704
2705         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2706         group = self.MakeGroupByCriterion(groupName, aCriterion)
2707         return group
2708
2709     def MakeGroupByCriterion(self, groupName, Criterion):
2710         """
2711         Create a mesh group by the given criterion
2712
2713         Parameters:
2714                 groupName: the name of the mesh group
2715                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2716
2717         Returns:
2718                 :class:`SMESH.SMESH_GroupOnFilter`
2719
2720         See Also:
2721                 :meth:`smeshBuilder.GetCriterion`
2722         """
2723
2724         return self.MakeGroupByCriteria( groupName, [Criterion] )
2725
2726     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2727         """
2728         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2729
2730         Parameters:
2731                 groupName: the name of the mesh group
2732                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2733                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2734
2735         Returns:
2736                 :class:`SMESH.SMESH_GroupOnFilter`
2737
2738         See Also:
2739                 :meth:`smeshBuilder.GetCriterion`
2740         """
2741
2742         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2743         group = self.MakeGroupByFilter(groupName, aFilter)
2744         return group
2745
2746     def MakeGroupByFilter(self, groupName, theFilter):
2747         """
2748         Create a mesh group by the given filter
2749
2750         Parameters:
2751                 groupName (string): the name of the mesh group
2752                 theFilter (SMESH.Filter): the filter
2753
2754         Returns:
2755                 :class:`SMESH.SMESH_GroupOnFilter`
2756
2757         See Also:
2758                 :meth:`smeshBuilder.GetFilter`
2759         """
2760
2761         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2762         #theFilter.SetMesh( self.mesh )
2763         #group.AddFrom( theFilter )
2764         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2765         return group
2766
2767     def RemoveGroup(self, group):
2768         """
2769         Remove a group
2770
2771         Parameters:
2772                 group (SMESH.SMESH_GroupBase): group to remove
2773         """
2774
2775         self.mesh.RemoveGroup(group)
2776
2777     def RemoveGroupWithContents(self, group):
2778         """
2779         Remove a group with its contents
2780
2781         Parameters:
2782                 group (SMESH.SMESH_GroupBase): group to remove
2783
2784         Note:
2785                 This operation can create gaps in numeration of nodes or elements.
2786                 Call :meth:`RenumberElements` to remove the gaps.
2787         """
2788
2789         self.mesh.RemoveGroupWithContents(group)
2790
2791     def GetGroups(self, elemType = SMESH.ALL):
2792         """
2793         Get the list of groups existing in the mesh in the order of creation 
2794         (starting from the oldest one)
2795
2796         Parameters:
2797                 elemType (SMESH.ElementType): type of elements the groups contain;
2798                         by default groups of elements of all types are returned
2799
2800         Returns:
2801                 a list of :class:`SMESH.SMESH_GroupBase`
2802         """
2803
2804         groups = self.mesh.GetGroups()
2805         if elemType == SMESH.ALL:
2806             return groups
2807         typedGroups = []
2808         for g in groups:
2809             if g.GetType() == elemType:
2810                 typedGroups.append( g )
2811                 pass
2812             pass
2813         return typedGroups
2814
2815     def NbGroups(self):
2816         """
2817         Get the number of groups existing in the mesh
2818
2819         Returns:
2820                 the quantity of groups as an integer value
2821         """
2822
2823         return self.mesh.NbGroups()
2824
2825     def GetGroupNames(self):
2826         """
2827         Get the list of names of groups existing in the mesh
2828
2829         Returns:
2830                 list of strings
2831         """
2832
2833         groups = self.GetGroups()
2834         names = []
2835         for group in groups:
2836             names.append(group.GetName())
2837         return names
2838
2839     def GetGroupByName(self, name, elemType = None):
2840         """
2841         Find groups by name and type
2842
2843         Parameters:
2844                 name (string): name of the group of interest
2845                 elemType (SMESH.ElementType): type of elements the groups contain;
2846                         by default one group of any type is returned;
2847                         if elemType == SMESH.ALL then all groups of any type are returned
2848
2849         Returns:
2850                 a list of :class:`SMESH.SMESH_GroupBase`
2851         """
2852
2853         groups = []
2854         for group in self.GetGroups():
2855             if group.GetName() == name:
2856                 if elemType is None:
2857                     return [group]
2858                 if ( elemType == SMESH.ALL or
2859                      group.GetType() == elemType ):
2860                     groups.append( group )
2861         return groups
2862
2863     def UnionGroups(self, group1, group2, name):
2864         """
2865         Produce a union of two groups.
2866         A new group is created. All mesh elements that are
2867         present in the initial groups are added to the new one
2868
2869         Parameters:
2870            group1 (SMESH.SMESH_GroupBase): a group
2871            group2 (SMESH.SMESH_GroupBase): another group
2872
2873         Returns:
2874                 instance of :class:`SMESH.SMESH_Group`
2875         """
2876
2877         return self.mesh.UnionGroups(group1, group2, name)
2878
2879     def UnionListOfGroups(self, groups, name):
2880         """
2881         Produce a union list of groups.
2882         New group is created. All mesh elements that are present in
2883         initial groups are added to the new one
2884
2885         Parameters:
2886            groups: list of :class:`SMESH.SMESH_GroupBase`
2887
2888         Returns:
2889                 instance of :class:`SMESH.SMESH_Group`
2890         """
2891         return self.mesh.UnionListOfGroups(groups, name)
2892
2893     def IntersectGroups(self, group1, group2, name):
2894         """
2895         Prodice an intersection of two groups.
2896         A new group is created. All mesh elements that are common
2897         for the two initial groups are added to the new one.
2898
2899         Parameters:
2900            group1 (SMESH.SMESH_GroupBase): a group
2901            group2 (SMESH.SMESH_GroupBase):&nb