Salome HOME
35198fe5982de2249dd3d1d675afb30775877e74
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2016  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 EnumToLong(self,theItem):
479         """
480         Return a long value from enumeration
481         """
482
483         return theItem._v
484
485     def ColorToString(self,c):
486         """
487         Convert SALOMEDS.Color to string.
488         To be used with filters.
489
490         Parameters:
491             c: color value (SALOMEDS.Color)
492
493         Returns:
494             a string representation of the color.
495         """
496
497         val = ""
498         if isinstance(c, SALOMEDS.Color):
499             val = "%s;%s;%s" % (c.R, c.G, c.B)
500         elif isinstance(c, str):
501             val = c
502         else:
503             raise ValueError("Color value should be of string or SALOMEDS.Color type")
504         return val
505
506     def GetPointStruct(self,theVertex):
507         """
508         Get :class:`SMESH.PointStruct` from vertex
509
510         Parameters:
511                 theVertex (GEOM.GEOM_Object): vertex
512
513         Returns:
514                 :class:`SMESH.PointStruct`
515         """
516
517         [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518         return PointStruct(x,y,z)
519
520     def GetDirStruct(self,theVector):
521         """
522         Get :class:`SMESH.DirStruct` from vector
523
524         Parameters:
525                 theVector (GEOM.GEOM_Object): vector
526
527         Returns:
528                 :class:`SMESH.DirStruct`
529         """
530
531         vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532         if(len(vertices) != 2):
533             print("Error: vector object is incorrect.")
534             return None
535         p1 = self.geompyD.PointCoordinates(vertices[0])
536         p2 = self.geompyD.PointCoordinates(vertices[1])
537         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538         dirst = DirStruct(pnt)
539         return dirst
540
541     def MakeDirStruct(self,x,y,z):
542         """
543         Make :class:`SMESH.DirStruct` from a triplet of floats
544
545         Parameters:
546                 x,y,z (float): vector components
547
548         Returns:
549                 :class:`SMESH.DirStruct`
550         """
551
552         pnt = PointStruct(x,y,z)
553         return DirStruct(pnt)
554
555     def GetAxisStruct(self,theObj):
556         """
557         Get :class:`SMESH.AxisStruct` from a geometrical object
558
559         Parameters:
560             theObj (GEOM.GEOM_Object): line or plane
561
562         Returns:
563             :class:`SMESH.AxisStruct`
564         """
565         import GEOM
566         edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
567         axis = None
568         if len(edges) > 1:
569             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570             vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571             vertex1 = self.geompyD.PointCoordinates(vertex1)
572             vertex2 = self.geompyD.PointCoordinates(vertex2)
573             vertex3 = self.geompyD.PointCoordinates(vertex3)
574             vertex4 = self.geompyD.PointCoordinates(vertex4)
575             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577             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] ]
578             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580         elif len(edges) == 1:
581             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582             p1 = self.geompyD.PointCoordinates( vertex1 )
583             p2 = self.geompyD.PointCoordinates( vertex2 )
584             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586         elif theObj.GetShapeType() == GEOM.VERTEX:
587             x,y,z = self.geompyD.PointCoordinates( theObj )
588             axis = AxisStruct( x,y,z, 1,0,0,)
589             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
590         return axis
591
592     # From SMESH_Gen interface:
593     # ------------------------
594
595     def SetName(self, obj, name):
596         """
597         Set the given name to an object
598
599         Parameters:
600                 obj: the object to rename
601                 name: a new object name
602         """
603
604         if isinstance( obj, Mesh ):
605             obj = obj.GetMesh()
606         elif isinstance( obj, Mesh_Algorithm ):
607             obj = obj.GetAlgorithm()
608         ior  = salome.orb.object_to_string(obj)
609         SMESH._objref_SMESH_Gen.SetName(self, ior, name)
610
611     def SetEmbeddedMode( self,theMode ):
612         """
613         Set the current mode
614         """
615
616         SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
617
618     def IsEmbeddedMode(self):
619         """
620         Get the current mode
621         """
622
623         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
624
625     def UpdateStudy( self, geompyD = None  ):
626         """
627         Update the current study. Calling UpdateStudy() allows to
628         update meshes at switching GEOM->SMESH
629         """
630         #self.UpdateStudy()
631         if not geompyD:
632             from salome.geom import geomBuilder
633             geompyD = geomBuilder.geom
634             if not geompyD:
635                 geompyD = geomBuilder.New()
636             pass
637         self.geompyD=geompyD
638         self.SetGeomEngine(geompyD)
639         SMESH._objref_SMESH_Gen.UpdateStudy(self)
640         sb = salome.myStudy.NewBuilder()
641         sc = salome.myStudy.FindComponent("SMESH")
642         if sc:
643             sb.LoadWith(sc, self)
644         pass
645     
646     def SetEnablePublish( self, theIsEnablePublish ):
647         """
648         Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649         switch **off** publishing in the Study of mesh objects.
650         """
651        #self.SetEnablePublish(theIsEnablePublish)
652         SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
653         global notebook
654         notebook = salome_notebook.NoteBook( theIsEnablePublish )
655
656
657     def CreateMeshesFromUNV( self,theFileName ):
658         """
659         Create a Mesh object importing data from the given UNV file
660
661         Returns:
662                 an instance of class :class:`Mesh`
663         """
664
665         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
667         return aMesh
668
669     def CreateMeshesFromMED( self,theFileName ):
670         """
671         Create a Mesh object(s) importing data from the given MED file
672
673         Returns:
674                 a tuple ( list of class :class:`Mesh` instances, 
675                 :class:`SMESH.DriverMED_ReadStatus` )
676         """
677
678         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680         return aMeshes, aStatus
681
682     def CreateMeshesFromSAUV( self,theFileName ):
683         """
684         Create a Mesh object(s) importing data from the given SAUV file
685
686         Returns:
687                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
688         """
689
690         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692         return aMeshes, aStatus
693
694     def CreateMeshesFromSTL( self, theFileName ):
695         """
696         Create a Mesh object importing data from the given STL file
697
698         Returns:
699                 an instance of class :class:`Mesh`
700         """
701
702         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
704         return aMesh
705
706     def CreateMeshesFromCGNS( self, theFileName ):
707         """
708         Create Mesh objects importing data from the given CGNS file
709
710         Returns:
711                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
712         """
713
714         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716         return aMeshes, aStatus
717
718     def CreateMeshesFromGMF( self, theFileName ):
719         """
720         Create a Mesh object importing data from the given GMF file.
721         GMF files must have .mesh extension for the ASCII format and .meshb for
722         the binary format.
723
724         Returns:
725                 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
726         """
727
728         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
729                                                                         theFileName,
730                                                                         True)
731         if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732         return Mesh(self, self.geompyD, aSmeshMesh), error
733
734     def Concatenate( self, meshes, uniteIdenticalGroups,
735                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736                      name = ""):
737         """
738         Concatenate the given meshes into one mesh. All groups of input meshes will be
739         present in the new mesh.
740
741         Parameters:
742                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744                 mergeNodesAndElements: if True, equal nodes and elements are merged
745                 mergeTolerance: tolerance for merging nodes
746                 allGroups: forces creation of groups corresponding to every input mesh
747                 name: name of a new mesh
748
749         Returns:
750                 an instance of class :class:`Mesh`
751         """
752
753         if not meshes: return None
754         for i,m in enumerate(meshes):
755             if isinstance(m, Mesh):
756                 meshes[i] = m.GetMesh()
757         mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
758         meshes[0].SetParameters(Parameters)
759         if allGroups:
760             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
761                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
762         else:
763             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
764                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
765         aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
766         return aMesh
767
768     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
769         """
770         Create a mesh by copying a part of another mesh.
771
772         Parameters:
773                 meshPart: a part of mesh to copy, either 
774                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
775                         To copy nodes or elements not forming any mesh object,
776                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
777                 meshName: a name of the new mesh
778                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
779                 toKeepIDs: to preserve order of the copied elements or not
780
781         Returns:
782                 an instance of class :class:`Mesh`
783         """
784
785         if isinstance( meshPart, Mesh ):
786             meshPart = meshPart.GetMesh()
787         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
788         return Mesh(self, self.geompyD, mesh)
789
790     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
791                           toReuseHypotheses=True, toCopyElements=True):
792         """
793         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
794         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
795         To facilitate and speed up the operation, consider using
796         "Set presentation parameters and sub-shapes from arguments" option in
797         a dialog of geometrical operation used to create the new geometry.
798
799         Parameters:
800                 sourceMesh: the mesh to copy definition of.
801                 newGeom: the new geomtry.
802                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
803                 toCopyGroups: to create groups in the new mesh.
804                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
805                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
806                                 *sourceMesh*.
807         Returns:
808                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
809                 *invalidEntries* are study entries of objects whose
810                 counterparts are not found in the *newGeom*, followed by entries
811                 of mesh sub-objects that are invalid because they depend on a not found
812                 preceeding sub-shape
813         """
814         if isinstance( sourceMesh, Mesh ):
815             sourceMesh = sourceMesh.GetMesh()
816
817         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
818            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
819                                                      toCopyGroups,
820                                                      toReuseHypotheses,
821                                                      toCopyElements)
822         return ( ok, Mesh(self, self.geompyD, newMesh),
823                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
824
825     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
826         """
827         Return IDs of sub-shapes
828
829         Parameters:
830                 theMainObject (GEOM.GEOM_Object): a shape
831                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
832         Returns:
833                 the list of integer values
834         """
835
836         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
837
838     def GetPattern(self):
839         """
840         Create a pattern mapper.
841
842         Returns:
843                 an instance of :class:`SMESH.SMESH_Pattern`
844
845         :ref:`Example of Patterns usage <tui_pattern_mapping>`
846         """
847
848         return SMESH._objref_SMESH_Gen.GetPattern(self)
849
850     def SetBoundaryBoxSegmentation(self, nbSegments):
851         """
852         Set number of segments per diagonal of boundary box of geometry, by which
853         default segment length of appropriate 1D hypotheses is defined in GUI.
854         Default value is 10.
855         """
856
857         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
858
859     # Filtering. Auxiliary functions:
860     # ------------------------------
861
862     def GetEmptyCriterion(self):
863         """
864         Create an empty criterion
865
866         Returns:
867                 :class:`SMESH.Filter.Criterion`
868         """
869
870         Type = self.EnumToLong(FT_Undefined)
871         Compare = self.EnumToLong(FT_Undefined)
872         Threshold = 0
873         ThresholdStr = ""
874         ThresholdID = ""
875         UnaryOp = self.EnumToLong(FT_Undefined)
876         BinaryOp = self.EnumToLong(FT_Undefined)
877         Tolerance = 1e-07
878         TypeOfElement = ALL
879         Precision = -1 ##@1e-07
880         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
881                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
882
883     def GetCriterion(self,elementType,
884                      CritType,
885                      Compare = FT_EqualTo,
886                      Threshold="",
887                      UnaryOp=FT_Undefined,
888                      BinaryOp=FT_Undefined,
889                      Tolerance=1e-07):
890         """
891         Create a criterion by the given parameters
892         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
893
894         Parameters:
895                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
896                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
897                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
898                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
899                 Threshold: the threshold value (range of ids as string, shape, numeric)
900                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
901                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
902                         SMESH.FT_Undefined
903                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
904                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
905
906         Returns:
907                 :class:`SMESH.Filter.Criterion`
908
909         Example: :ref:`combining_filters`
910         """
911
912         if not CritType in SMESH.FunctorType._items:
913             raise TypeError("CritType should be of SMESH.FunctorType")
914         aCriterion               = self.GetEmptyCriterion()
915         aCriterion.TypeOfElement = elementType
916         aCriterion.Type          = self.EnumToLong(CritType)
917         aCriterion.Tolerance     = Tolerance
918
919         aThreshold = Threshold
920
921         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
922             aCriterion.Compare = self.EnumToLong(Compare)
923         elif Compare == "=" or Compare == "==":
924             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
925         elif Compare == "<":
926             aCriterion.Compare = self.EnumToLong(FT_LessThan)
927         elif Compare == ">":
928             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
929         elif Compare != FT_Undefined:
930             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
931             aThreshold = Compare
932
933         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
934                         FT_BelongToCylinder, FT_LyingOnGeom]:
935             # Check that Threshold is GEOM object
936             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
937                 aCriterion.ThresholdStr = GetName(aThreshold)
938                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
939                 if not aCriterion.ThresholdID:
940                     name = aCriterion.ThresholdStr
941                     if not name:
942                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
943                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
944             # or a name of GEOM object
945             elif isinstance( aThreshold, str ):
946                 aCriterion.ThresholdStr = aThreshold
947             else:
948                 raise TypeError("The Threshold should be a shape.")
949             if isinstance(UnaryOp,float):
950                 aCriterion.Tolerance = UnaryOp
951                 UnaryOp = FT_Undefined
952                 pass
953         elif CritType == FT_BelongToMeshGroup:
954             # Check that Threshold is a group
955             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
956                 if aThreshold.GetType() != elementType:
957                     raise ValueError("Group type mismatches Element type")
958                 aCriterion.ThresholdStr = aThreshold.GetName()
959                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
960                 study = salome.myStudy
961                 if study:
962                     so = study.FindObjectIOR( aCriterion.ThresholdID )
963                     if so:
964                         entry = so.GetID()
965                         if entry:
966                             aCriterion.ThresholdID = entry
967             else:
968                 raise TypeError("The Threshold should be a Mesh Group")
969         elif CritType == FT_RangeOfIds:
970             # Check that Threshold is string
971             if isinstance(aThreshold, str):
972                 aCriterion.ThresholdStr = aThreshold
973             else:
974                 raise TypeError("The Threshold should be a string.")
975         elif CritType == FT_CoplanarFaces:
976             # Check the Threshold
977             if isinstance(aThreshold, int):
978                 aCriterion.ThresholdID = str(aThreshold)
979             elif isinstance(aThreshold, str):
980                 ID = int(aThreshold)
981                 if ID < 1:
982                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
983                 aCriterion.ThresholdID = aThreshold
984             else:
985                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
986         elif CritType == FT_ConnectedElements:
987             # Check the Threshold
988             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
989                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
990                 if not aCriterion.ThresholdID:
991                     name = aThreshold.GetName()
992                     if not name:
993                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
994                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
995             elif isinstance(aThreshold, int): # node id
996                 aCriterion.Threshold = aThreshold
997             elif isinstance(aThreshold, list): # 3 point coordinates
998                 if len( aThreshold ) < 3:
999                     raise ValueError("too few point coordinates, must be 3")
1000                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1001             elif isinstance(aThreshold, str):
1002                 if aThreshold.isdigit():
1003                     aCriterion.Threshold = aThreshold # node id
1004                 else:
1005                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1006             else:
1007                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1008                       "or a list of point coordinates and not '%s'"%aThreshold)
1009         elif CritType == FT_ElemGeomType:
1010             # Check the Threshold
1011             try:
1012                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1013                 assert( aThreshold in SMESH.GeometryType._items )
1014             except:
1015                 if isinstance(aThreshold, int):
1016                     aCriterion.Threshold = aThreshold
1017                 else:
1018                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1019                 pass
1020             pass
1021         elif CritType == FT_EntityType:
1022             # Check the Threshold
1023             try:
1024                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1025                 assert( aThreshold in SMESH.EntityType._items )
1026             except:
1027                 if isinstance(aThreshold, int):
1028                     aCriterion.Threshold = aThreshold
1029                 else:
1030                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1031                 pass
1032             pass
1033
1034         elif CritType == FT_GroupColor:
1035             # Check the Threshold
1036             try:
1037                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1038             except:
1039                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1040             pass
1041         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1042                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1043                           FT_BareBorderFace, FT_BareBorderVolume,
1044                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1045                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1046             # At this point the Threshold is unnecessary
1047             if aThreshold ==  FT_LogicalNOT:
1048                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1049             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1050                 aCriterion.BinaryOp = aThreshold
1051         else:
1052             # Check Threshold
1053             try:
1054                 aThreshold = float(aThreshold)
1055                 aCriterion.Threshold = aThreshold
1056             except:
1057                 raise TypeError("The Threshold should be a number.")
1058                 return None
1059
1060         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1061             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1062
1063         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1064             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1065
1066         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1067             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1068
1069         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1070             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1071
1072         return aCriterion
1073
1074     def GetFilter(self,elementType,
1075                   CritType=FT_Undefined,
1076                   Compare=FT_EqualTo,
1077                   Threshold="",
1078                   UnaryOp=FT_Undefined,
1079                   Tolerance=1e-07,
1080                   mesh=None):
1081         """
1082         Create a filter with the given parameters
1083
1084         Parameters:
1085                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1086                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1087                         Note that the items starting from FT_LessThan are not suitable for CritType.
1088                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1089                 Threshold: the threshold value (range of ids as string, shape, numeric)
1090                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1091                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1092                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1093                 mesh: the mesh to initialize the filter with
1094
1095         Returns:
1096                 :class:`SMESH.Filter`
1097
1098         Examples:
1099                See :doc:`Filters usage examples <tui_filters>`
1100         """
1101
1102         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1103         aFilterMgr = self.CreateFilterManager()
1104         aFilter = aFilterMgr.CreateFilter()
1105         aCriteria = []
1106         aCriteria.append(aCriterion)
1107         aFilter.SetCriteria(aCriteria)
1108         if mesh:
1109             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1110             else                       : aFilter.SetMesh( mesh )
1111         aFilterMgr.UnRegister()
1112         return aFilter
1113
1114     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1115         """
1116         Create a filter from criteria
1117
1118         Parameters:
1119                 criteria: a list of :class:`SMESH.Filter.Criterion`
1120                 binOp: binary operator used when binary operator of criteria is undefined
1121
1122         Returns:
1123                 :class:`SMESH.Filter`
1124
1125         Examples:
1126                See :doc:`Filters usage examples <tui_filters>`
1127         """
1128
1129         for i in range( len( criteria ) - 1 ):
1130             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1131                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1132         aFilterMgr = self.CreateFilterManager()
1133         aFilter = aFilterMgr.CreateFilter()
1134         aFilter.SetCriteria(criteria)
1135         aFilterMgr.UnRegister()
1136         return aFilter
1137
1138     def GetFunctor(self,theCriterion):
1139         """
1140         Create a numerical functor by its type
1141
1142         Parameters:
1143                 theCriterion (SMESH.FunctorType): functor type.
1144                         Note that not all items correspond to numerical functors.
1145
1146         Returns:
1147                 :class:`SMESH.NumericalFunctor`
1148         """
1149
1150         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1151             return theCriterion
1152         aFilterMgr = self.CreateFilterManager()
1153         functor = None
1154         if theCriterion == FT_AspectRatio:
1155             functor = aFilterMgr.CreateAspectRatio()
1156         elif theCriterion == FT_AspectRatio3D:
1157             functor = aFilterMgr.CreateAspectRatio3D()
1158         elif theCriterion == FT_Warping:
1159             functor = aFilterMgr.CreateWarping()
1160         elif theCriterion == FT_MinimumAngle:
1161             functor = aFilterMgr.CreateMinimumAngle()
1162         elif theCriterion == FT_Taper:
1163             functor = aFilterMgr.CreateTaper()
1164         elif theCriterion == FT_Skew:
1165             functor = aFilterMgr.CreateSkew()
1166         elif theCriterion == FT_Area:
1167             functor = aFilterMgr.CreateArea()
1168         elif theCriterion == FT_Volume3D:
1169             functor = aFilterMgr.CreateVolume3D()
1170         elif theCriterion == FT_MaxElementLength2D:
1171             functor = aFilterMgr.CreateMaxElementLength2D()
1172         elif theCriterion == FT_MaxElementLength3D:
1173             functor = aFilterMgr.CreateMaxElementLength3D()
1174         elif theCriterion == FT_MultiConnection:
1175             functor = aFilterMgr.CreateMultiConnection()
1176         elif theCriterion == FT_MultiConnection2D:
1177             functor = aFilterMgr.CreateMultiConnection2D()
1178         elif theCriterion == FT_Length:
1179             functor = aFilterMgr.CreateLength()
1180         elif theCriterion == FT_Length2D:
1181             functor = aFilterMgr.CreateLength2D()
1182         elif theCriterion == FT_Deflection2D:
1183             functor = aFilterMgr.CreateDeflection2D()
1184         elif theCriterion == FT_NodeConnectivityNumber:
1185             functor = aFilterMgr.CreateNodeConnectivityNumber()
1186         elif theCriterion == FT_BallDiameter:
1187             functor = aFilterMgr.CreateBallDiameter()
1188         else:
1189             print("Error: given parameter is not numerical functor type.")
1190         aFilterMgr.UnRegister()
1191         return functor
1192
1193     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1194         """
1195         Create hypothesis
1196
1197         Parameters:
1198                 theHType (string): mesh hypothesis type
1199                 theLibName (string): mesh plug-in library name
1200
1201         Returns:
1202                 created hypothesis instance
1203         """
1204         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1205
1206         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1207             return hyp
1208
1209         # wrap hypothesis methods
1210         for meth_name in dir( hyp.__class__ ):
1211             if not meth_name.startswith("Get") and \
1212                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1213                 method = getattr ( hyp.__class__, meth_name )
1214                 if callable(method):
1215                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1216
1217         return hyp
1218
1219     def GetMeshInfo(self, obj):
1220         """
1221         Get the mesh statistic.
1222         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
1223         an item of :class:`SMESH.EntityType`.
1224
1225         Returns:
1226                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1227         """
1228
1229         if isinstance( obj, Mesh ):
1230             obj = obj.GetMesh()
1231         d = {}
1232         if hasattr(obj, "GetMeshInfo"):
1233             values = obj.GetMeshInfo()
1234             for i in range(SMESH.Entity_Last._v):
1235                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1236             pass
1237         return d
1238
1239     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1240         """
1241         Get minimum distance between two objects
1242
1243         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1244         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1245
1246         Parameters:
1247                 src1 (SMESH.SMESH_IDSource): first source object
1248                 src2 (SMESH.SMESH_IDSource): second source object
1249                 id1 (int): node/element id from the first source
1250                 id2 (int): node/element id from the second (or first) source
1251                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1252                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1253
1254         Returns:
1255                 minimum distance value
1256
1257         See also: 
1258                 :meth:`GetMinDistance`
1259         """
1260
1261         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1262         if result is None:
1263             result = 0.0
1264         else:
1265             result = result.value
1266         return result
1267
1268     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1269         """
1270         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1271
1272         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1273         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1274
1275         Parameters:
1276                 src1 (SMESH.SMESH_IDSource): first source object
1277                 src2 (SMESH.SMESH_IDSource): second source object
1278                 id1 (int): node/element id from the first source
1279                 id2 (int): node/element id from the second (or first) source
1280                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1281                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1282
1283         Returns:
1284                 :class:`SMESH.Measure` structure or None if input data is invalid
1285         See also: 
1286                 :meth:`MinDistance`
1287         """
1288
1289         if isinstance(src1, Mesh): src1 = src1.mesh
1290         if isinstance(src2, Mesh): src2 = src2.mesh
1291         if src2 is None and id2 != 0: src2 = src1
1292         if not hasattr(src1, "_narrow"): return None
1293         src1 = src1._narrow(SMESH.SMESH_IDSource)
1294         if not src1: return None
1295         unRegister = genObjUnRegister()
1296         if id1 != 0:
1297             m = src1.GetMesh()
1298             e = m.GetMeshEditor()
1299             if isElem1:
1300                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1301             else:
1302                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1303             unRegister.set( src1 )
1304             pass
1305         if hasattr(src2, "_narrow"):
1306             src2 = src2._narrow(SMESH.SMESH_IDSource)
1307             if src2 and id2 != 0:
1308                 m = src2.GetMesh()
1309                 e = m.GetMeshEditor()
1310                 if isElem2:
1311                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1312                 else:
1313                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1314                 unRegister.set( src2 )
1315                 pass
1316             pass
1317         aMeasurements = self.CreateMeasurements()
1318         unRegister.set( aMeasurements )
1319         result = aMeasurements.MinDistance(src1, src2)
1320         return result
1321
1322     def BoundingBox(self, objects):
1323         """
1324         Get bounding box of the specified object(s)
1325
1326         Parameters:
1327                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1328
1329         Returns:
1330                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1331
1332         See also: 
1333                :meth:`GetBoundingBox`
1334         """
1335
1336         result = self.GetBoundingBox(objects)
1337         if result is None:
1338             result = (0.0,)*6
1339         else:
1340             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1341         return result
1342
1343     def GetBoundingBox(self, objects):
1344         """
1345         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1346
1347         Parameters:
1348                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1349
1350         Returns:
1351                 :class:`SMESH.Measure` structure
1352
1353         See also: 
1354                 :meth:`BoundingBox`
1355         """
1356
1357         if isinstance(objects, tuple):
1358             objects = list(objects)
1359         if not isinstance(objects, list):
1360             objects = [objects]
1361         srclist = []
1362         for o in objects:
1363             if isinstance(o, Mesh):
1364                 srclist.append(o.mesh)
1365             elif hasattr(o, "_narrow"):
1366                 src = o._narrow(SMESH.SMESH_IDSource)
1367                 if src: srclist.append(src)
1368                 pass
1369             pass
1370         aMeasurements = self.CreateMeasurements()
1371         result = aMeasurements.BoundingBox(srclist)
1372         aMeasurements.UnRegister()
1373         return result
1374
1375     def GetLength(self, obj):
1376         """
1377         Get sum of lengths of all 1D elements in the mesh object.
1378
1379         Parameters:
1380                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1381
1382         Returns:
1383                 sum of lengths of all 1D elements
1384         """
1385
1386         if isinstance(obj, Mesh): obj = obj.mesh
1387         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1388         aMeasurements = self.CreateMeasurements()
1389         value = aMeasurements.Length(obj)
1390         aMeasurements.UnRegister()
1391         return value
1392
1393     def GetArea(self, obj):
1394         """
1395         Get sum of areas of all 2D elements in the mesh object.
1396
1397         Parameters:
1398                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1399
1400         Returns:
1401                 sum of areas of all 2D elements
1402         """
1403
1404         if isinstance(obj, Mesh): obj = obj.mesh
1405         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1406         aMeasurements = self.CreateMeasurements()
1407         value = aMeasurements.Area(obj)
1408         aMeasurements.UnRegister()
1409         return value
1410
1411     def GetVolume(self, obj):
1412         """
1413         Get sum of volumes of all 3D elements in the mesh object.
1414
1415         Parameters:
1416                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1417
1418         Returns:
1419                 sum of volumes of all 3D elements
1420         """
1421
1422         if isinstance(obj, Mesh): obj = obj.mesh
1423         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1424         aMeasurements = self.CreateMeasurements()
1425         value = aMeasurements.Volume(obj)
1426         aMeasurements.UnRegister()
1427         return value
1428
1429     def GetGravityCenter(self, obj):
1430         """
1431         Get gravity center of all nodes of the mesh object.
1432         
1433         Parameters:            
1434                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1435
1436         Returns:        
1437             Three components of the gravity center (x,y,z)
1438         """
1439         if isinstance(obj, Mesh): obj = obj.mesh
1440         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1441         aMeasurements = self.CreateMeasurements()
1442         pointStruct = aMeasurements.GravityCenter(obj)
1443         aMeasurements.UnRegister()
1444         return pointStruct.x, pointStruct.y, pointStruct.z
1445
1446     def GetAngle(self, p1, p2, p3 ):
1447         """
1448         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1449
1450         Parameters:            
1451                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
1452                           or list [x,y,z]
1453
1454         Returns:        
1455             Angle in radians
1456         """
1457         if isinstance( p1, list ): p1 = PointStruct(*p1)
1458         if isinstance( p2, list ): p2 = PointStruct(*p2)
1459         if isinstance( p3, list ): p3 = PointStruct(*p3)
1460
1461         aMeasurements = self.CreateMeasurements()
1462         angle = aMeasurements.Angle(p1,p2,p3)
1463         aMeasurements.UnRegister()
1464
1465         return angle
1466
1467
1468     pass # end of class smeshBuilder
1469
1470 import omniORB
1471 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1472 """Registering the new proxy for SMESH.SMESH_Gen"""
1473
1474
1475 def New( instance=None, instanceGeom=None):
1476     """
1477     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1478     interface to create or load meshes.
1479
1480     Typical use is::
1481
1482         import salome
1483         salome.salome_init()
1484         from salome.smesh import smeshBuilder
1485         smesh = smeshBuilder.New()
1486
1487     Parameters:
1488         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1489         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1490     Returns:
1491         :class:`smeshBuilder` instance
1492     """
1493     global engine
1494     global smeshInst
1495     global doLcc
1496     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1497         import sys
1498         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1499         instance = None
1500     engine = instance
1501     if engine is None:
1502         doLcc = True
1503     smeshInst = smeshBuilder()
1504     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1505     smeshInst.init_smesh(instanceGeom)
1506     return smeshInst
1507
1508
1509 # Public class: Mesh
1510 # ==================
1511
1512
1513 class Mesh(metaclass = MeshMeta):
1514     """
1515     This class allows defining and managing a mesh.
1516     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1517     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1518     new nodes and elements and by changing the existing entities), to get information
1519     about a mesh and to export a mesh in different formats.
1520     """    
1521
1522     geom = 0
1523     mesh = 0
1524     editor = 0
1525
1526     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1527
1528         """
1529         Constructor
1530
1531         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1532         sets the GUI name of this mesh to *name*.
1533
1534         Parameters:
1535                 smeshpyD: an instance of smeshBuilder class
1536                 geompyD: an instance of geomBuilder class
1537                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1538                 name: Study name of the mesh
1539         """
1540
1541         self.smeshpyD = smeshpyD
1542         self.geompyD = geompyD
1543         if obj is None:
1544             obj = 0
1545         objHasName = False
1546         if obj != 0:
1547             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1548                 self.geom = obj
1549                 objHasName = True
1550                 # publish geom of mesh (issue 0021122)
1551                 if not self.geom.GetStudyEntry():
1552                     objHasName = False
1553                     geompyD.init_geom()
1554                     if name:
1555                         geo_name = name + " shape"
1556                     else:
1557                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1558                     geompyD.addToStudy( self.geom, geo_name )
1559                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1560
1561             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1562                 self.SetMesh(obj)
1563         else:
1564             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1565         if name:
1566             self.smeshpyD.SetName(self.mesh, name)
1567         elif objHasName:
1568             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1569
1570         if not self.geom:
1571             self.geom = self.mesh.GetShapeToMesh()
1572
1573         self.editor   = self.mesh.GetMeshEditor()
1574         self.functors = [None] * SMESH.FT_Undefined._v
1575
1576         # set self to algoCreator's
1577         for attrName in dir(self):
1578             attr = getattr( self, attrName )
1579             if isinstance( attr, algoCreator ):
1580                 setattr( self, attrName, attr.copy( self ))
1581                 pass
1582             pass
1583         pass
1584
1585     def __del__(self):
1586         """
1587         Destructor. Clean-up resources
1588         """
1589         if self.mesh:
1590             #self.mesh.UnRegister()
1591             pass
1592         pass
1593
1594     def SetMesh(self, theMesh):
1595         """
1596         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1597
1598         Parameters:
1599                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1600         """
1601
1602
1603         # do not call Register() as this prevents mesh servant deletion at closing study
1604         #if self.mesh: self.mesh.UnRegister()
1605         self.mesh = theMesh
1606         if self.mesh:
1607             #self.mesh.Register()
1608             self.geom = self.mesh.GetShapeToMesh()
1609         pass
1610
1611     def GetMesh(self):
1612         """
1613         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1614
1615         Returns:
1616                 a :class:`SMESH.SMESH_Mesh` object
1617         """
1618
1619         return self.mesh
1620
1621     def GetName(self):
1622         """
1623         Get the name of the mesh
1624
1625         Returns:
1626                 the name of the mesh as a string
1627         """
1628
1629         name = GetName(self.GetMesh())
1630         return name
1631
1632     def SetName(self, name):
1633         """
1634         Set a name to the mesh
1635
1636         Parameters:
1637                 name: a new name of the mesh
1638         """
1639
1640         self.smeshpyD.SetName(self.GetMesh(), name)
1641
1642     def GetSubMesh(self, geom, name):
1643         """
1644         Get a sub-mesh object associated to a *geom* geometrical object.
1645
1646         Parameters:
1647                 geom: a geometrical object (shape)
1648                 name: a name for the sub-mesh in the Object Browser
1649
1650         Returns:
1651                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1652                 which lies on the given shape
1653
1654         Note:
1655                 A sub-mesh is implicitly created when a sub-shape is specified at
1656                 creating an algorithm, for example::
1657
1658                    algo1D = mesh.Segment(geom=Edge_1)
1659
1660                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1661                 The created sub-mesh can be retrieved from the algorithm::
1662
1663                    submesh = algo1D.GetSubMesh()
1664         """
1665
1666         AssureGeomPublished( self, geom, name )
1667         submesh = self.mesh.GetSubMesh( geom, name )
1668         return submesh
1669
1670     def GetShape(self):
1671         """
1672         Return the shape associated to the mesh
1673
1674         Returns:
1675                 a GEOM_Object
1676         """
1677
1678         return self.geom
1679
1680     def SetShape(self, geom):
1681         """
1682         Associate the given shape to the mesh (entails the recreation of the mesh)
1683
1684         Parameters:
1685                 geom: the shape to be meshed (GEOM_Object)
1686         """
1687
1688         self.mesh = self.smeshpyD.CreateMesh(geom)
1689
1690     def HasShapeToMesh(self):
1691         """
1692         Return ``True`` if this mesh is based on geometry
1693         """
1694         return self.mesh.HasShapeToMesh()
1695
1696     def Load(self):
1697         """
1698         Load mesh from the study after opening the study
1699         """
1700         self.mesh.Load()
1701
1702     def IsReadyToCompute(self, theSubObject):
1703         """
1704         Return true if the hypotheses are defined well
1705
1706         Parameters:
1707                 theSubObject: a sub-shape of a mesh shape
1708
1709         Returns:
1710                 True or False
1711         """
1712
1713         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1714
1715     def GetAlgoState(self, theSubObject):
1716         """
1717         Return errors of hypotheses definition.
1718         The list of errors is empty if everything is OK.
1719
1720         Parameters:
1721                 theSubObject: a sub-shape of a mesh shape
1722
1723         Returns:
1724                 a list of errors
1725         """
1726
1727         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1728
1729     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1730         """
1731         Return a geometrical object on which the given element was built.
1732         The returned geometrical object, if not nil, is either found in the
1733         study or published by this method with the given name
1734
1735         Parameters:
1736             theElementID: the id of the mesh element
1737             theGeomName: the user-defined name of the geometrical object
1738
1739         Returns:
1740             GEOM.GEOM_Object instance
1741         """
1742
1743         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1744
1745     def MeshDimension(self):
1746         """
1747         Return the mesh dimension depending on the dimension of the underlying shape
1748         or, if the mesh is not based on any shape, basing on deimension of elements
1749
1750         Returns:
1751                 mesh dimension as an integer value [0,3]
1752         """
1753
1754         if self.mesh.HasShapeToMesh():
1755             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1756             if len( shells ) > 0 :
1757                 return 3
1758             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1759                 return 2
1760             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1761                 return 1
1762             else:
1763                 return 0;
1764         else:
1765             if self.NbVolumes() > 0: return 3
1766             if self.NbFaces()   > 0: return 2
1767             if self.NbEdges()   > 0: return 1
1768         return 0
1769
1770     def Evaluate(self, geom=0):
1771         """
1772         Evaluate size of prospective mesh on a shape
1773
1774         Returns:
1775                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1776                 To know predicted number of e.g. edges, inquire it this way::
1777
1778                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1779         """
1780
1781         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1782             if self.geom == 0:
1783                 geom = self.mesh.GetShapeToMesh()
1784             else:
1785                 geom = self.geom
1786         return self.smeshpyD.Evaluate(self.mesh, geom)
1787
1788
1789     def Compute(self, geom=0, discardModifs=False, refresh=False):
1790         """
1791         Compute the mesh and return the status of the computation
1792
1793         Parameters:
1794                 geom: geomtrical shape on which mesh data should be computed
1795                 discardModifs: if True and the mesh has been edited since
1796                         a last total re-compute and that may prevent successful partial re-compute,
1797                         then the mesh is cleaned before Compute()
1798                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1799
1800         Returns:
1801                 True or False
1802         """
1803
1804         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1805             if self.geom == 0:
1806                 geom = self.mesh.GetShapeToMesh()
1807             else:
1808                 geom = self.geom
1809         ok = False
1810         try:
1811             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1812                 self.mesh.Clear()
1813             ok = self.smeshpyD.Compute(self.mesh, geom)
1814         except SALOME.SALOME_Exception as ex:
1815             print("Mesh computation failed, exception caught:")
1816             print("    ", ex.details.text)
1817         except:
1818             import traceback
1819             print("Mesh computation failed, exception caught:")
1820             traceback.print_exc()
1821         if True:#not ok:
1822             allReasons = ""
1823
1824             # Treat compute errors
1825             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1826             shapeText = ""
1827             for err in computeErrors:
1828                 if self.mesh.HasShapeToMesh():
1829                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1830                 errText = ""
1831                 stdErrors = ["OK",                   #COMPERR_OK
1832                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1833                              "std::exception",       #COMPERR_STD_EXCEPTION
1834                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1835                              "..",                   #COMPERR_SLM_EXCEPTION
1836                              "Unknown exception",    #COMPERR_EXCEPTION
1837                              "Memory allocation problem", #COMPERR_MEMORY_PB
1838                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1839                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1840                              "Warning",              #COMPERR_WARNING
1841                              "Computation cancelled",#COMPERR_CANCELED
1842                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1843                 if err.code > 0:
1844                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1845                 else:
1846                     errText = "code %s" % -err.code
1847                 if errText: errText += ". "
1848                 errText += err.comment
1849                 if allReasons: allReasons += "\n"
1850                 if ok:
1851                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1852                 else:
1853                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1854                 pass
1855
1856             # Treat hyp errors
1857             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1858             for err in errors:
1859                 if err.isGlobalAlgo:
1860                     glob = "global"
1861                 else:
1862                     glob = "local"
1863                     pass
1864                 dim = err.algoDim
1865                 name = err.algoName
1866                 if len(name) == 0:
1867                     reason = '%s %sD algorithm is missing' % (glob, dim)
1868                 elif err.state == HYP_MISSING:
1869                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1870                               % (glob, dim, name, dim))
1871                 elif err.state == HYP_NOTCONFORM:
1872                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1873                 elif err.state == HYP_BAD_PARAMETER:
1874                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1875                               % ( glob, dim, name ))
1876                 elif err.state == HYP_BAD_GEOMETRY:
1877                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1878                               'geometry' % ( glob, dim, name ))
1879                 elif err.state == HYP_HIDDEN_ALGO:
1880                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1881                               'algorithm of upper dimension generating %sD mesh'
1882                               % ( glob, dim, name, glob, dim ))
1883                 else:
1884                     reason = ("For unknown reason. "
1885                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1886                     pass
1887                 if allReasons: allReasons += "\n"
1888                 allReasons += "-  " + reason
1889                 pass
1890             if not ok or allReasons != "":
1891                 msg = '"' + GetName(self.mesh) + '"'
1892                 if ok: msg += " has been computed with warnings"
1893                 else:  msg += " has not been computed"
1894                 if allReasons != "": msg += ":"
1895                 else:                msg += "."
1896                 print(msg)
1897                 print(allReasons)
1898             pass
1899         if salome.sg.hasDesktop():
1900             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1901                 if refresh: salome.sg.updateObjBrowser()
1902
1903         return ok
1904
1905     def GetComputeErrors(self, shape=0 ):
1906         """
1907         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1908         """
1909
1910         if shape == 0:
1911             shape = self.mesh.GetShapeToMesh()
1912         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1913
1914     def GetSubShapeName(self, subShapeID ):
1915         """
1916         Return a name of a sub-shape by its ID.
1917         Possible variants (for *subShapeID* == 3):
1918
1919                 - **"Face_12"** - published sub-shape
1920                 - **FACE #3** - not published sub-shape
1921                 - **sub-shape #3** - invalid sub-shape ID
1922                 - **#3** - error in this function
1923
1924         Parameters:
1925                 subShapeID: a unique ID of a sub-shape
1926
1927         Returns:
1928                 a string describing the sub-shape
1929
1930         """
1931
1932         if not self.mesh.HasShapeToMesh():
1933             return ""
1934         try:
1935             shapeText = ""
1936             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1937             s = salome.myStudy
1938             mainSO = s.FindObjectIOR(mainIOR)
1939             if mainSO:
1940                 if subShapeID == 1:
1941                     shapeText = '"%s"' % mainSO.GetName()
1942                 subIt = s.NewChildIterator(mainSO)
1943                 while subIt.More():
1944                     subSO = subIt.Value()
1945                     subIt.Next()
1946                     obj = subSO.GetObject()
1947                     if not obj: continue
1948                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1949                     if not go: continue
1950                     try:
1951                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1952                     except:
1953                         continue
1954                     if ids == subShapeID:
1955                         shapeText = '"%s"' % subSO.GetName()
1956                         break
1957             if not shapeText:
1958                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1959                 if shape:
1960                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1961                 else:
1962                     shapeText = 'sub-shape #%s' % (subShapeID)
1963         except:
1964             shapeText = "#%s" % (subShapeID)
1965         return shapeText
1966
1967     def GetFailedShapes(self, publish=False):
1968         """
1969         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1970         error of an algorithm
1971
1972         Parameters:
1973                 publish: if *True*, the returned groups will be published in the study
1974
1975         Returns:
1976                 a list of GEOM groups each named after a failed algorithm
1977         """
1978
1979
1980         algo2shapes = {}
1981         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1982         for err in computeErrors:
1983             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1984             if not shape: continue
1985             if err.algoName in algo2shapes:
1986                 algo2shapes[ err.algoName ].append( shape )
1987             else:
1988                 algo2shapes[ err.algoName ] = [ shape ]
1989             pass
1990
1991         groups = []
1992         for algoName, shapes in list(algo2shapes.items()):
1993             while shapes:
1994                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1995                 otherTypeShapes = []
1996                 sameTypeShapes  = []
1997                 group = self.geompyD.CreateGroup( self.geom, groupType )
1998                 for shape in shapes:
1999                     if shape.GetShapeType() == shapes[0].GetShapeType():
2000                         sameTypeShapes.append( shape )
2001                     else:
2002                         otherTypeShapes.append( shape )
2003                 self.geompyD.UnionList( group, sameTypeShapes )
2004                 if otherTypeShapes:
2005                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2006                 else:
2007                     group.SetName( algoName )
2008                 groups.append( group )
2009                 shapes = otherTypeShapes
2010             pass
2011         if publish:
2012             for group in groups:
2013                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2014         return groups
2015
2016     def GetMeshOrder(self):
2017         """
2018         Return sub-mesh objects list in meshing order
2019
2020         Returns:
2021                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2022         """
2023
2024         return self.mesh.GetMeshOrder()
2025
2026     def SetMeshOrder(self, submeshes):
2027         """
2028         Set order in which concurrent sub-meshes should be meshed
2029
2030         Parameters:
2031                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2032         """
2033
2034         return self.mesh.SetMeshOrder(submeshes)
2035
2036     def Clear(self, refresh=False):
2037         """
2038         Remove all nodes and elements generated on geometry. Imported elements remain.
2039
2040         Parameters:
2041                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2042         """
2043
2044         self.mesh.Clear()
2045         if ( salome.sg.hasDesktop() ):
2046             if refresh: salome.sg.updateObjBrowser()
2047
2048     def ClearSubMesh(self, geomId, refresh=False):
2049         """
2050         Remove all nodes and elements of indicated shape
2051
2052         Parameters:
2053                 geomId: the ID of a sub-shape to remove elements on
2054                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2055         """
2056
2057         self.mesh.ClearSubMesh(geomId)
2058         if salome.sg.hasDesktop():
2059             if refresh: salome.sg.updateObjBrowser()
2060
2061     def AutomaticTetrahedralization(self, fineness=0):
2062         """
2063         Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2064
2065         Parameters:
2066                 fineness: [0.0,1.0] defines mesh fineness
2067
2068         Returns:
2069                 True or False
2070         """
2071
2072         dim = self.MeshDimension()
2073         # assign hypotheses
2074         self.RemoveGlobalHypotheses()
2075         self.Segment().AutomaticLength(fineness)
2076         if dim > 1 :
2077             self.Triangle().LengthFromEdges()
2078             pass
2079         if dim > 2 :
2080             self.Tetrahedron()
2081             pass
2082         return self.Compute()
2083
2084     def AutomaticHexahedralization(self, fineness=0):
2085         """
2086         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2087
2088         Parameters:
2089                 fineness: [0.0, 1.0] defines mesh fineness
2090
2091         Returns:
2092                 True or False
2093         """
2094
2095         dim = self.MeshDimension()
2096         # assign the hypotheses
2097         self.RemoveGlobalHypotheses()
2098         self.Segment().AutomaticLength(fineness)
2099         if dim > 1 :
2100             self.Quadrangle()
2101             pass
2102         if dim > 2 :
2103             self.Hexahedron()
2104             pass
2105         return self.Compute()
2106
2107     def AddHypothesis(self, hyp, geom=0):
2108         """
2109         Assign a hypothesis
2110
2111         Parameters:
2112                 hyp: a hypothesis to assign
2113                 geom: a subhape of mesh geometry
2114
2115         Returns:
2116                 :class:`SMESH.Hypothesis_Status`
2117         """
2118
2119         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2120             hyp, geom = geom, hyp
2121         if isinstance( hyp, Mesh_Algorithm ):
2122             hyp = hyp.GetAlgorithm()
2123             pass
2124         if not geom:
2125             geom = self.geom
2126             if not geom:
2127                 geom = self.mesh.GetShapeToMesh()
2128             pass
2129         isApplicable = True
2130         if self.mesh.HasShapeToMesh():
2131             hyp_type     = hyp.GetName()
2132             lib_name     = hyp.GetLibName()
2133             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2134             # if checkAll and geom:
2135             #     checkAll = geom.GetType() == 37
2136             checkAll     = False
2137             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2138         if isApplicable:
2139             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2140             status = self.mesh.AddHypothesis(geom, hyp)
2141         else:
2142             status = HYP_BAD_GEOMETRY, ""
2143         hyp_name = GetName( hyp )
2144         geom_name = ""
2145         if geom:
2146             geom_name = geom.GetName()
2147         isAlgo = hyp._narrow( SMESH_Algo )
2148         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2149         return status
2150
2151     def IsUsedHypothesis(self, hyp, geom):
2152         """
2153         Return True if an algorithm or hypothesis is assigned to a given shape
2154
2155         Parameters:
2156                 hyp: an algorithm or hypothesis to check
2157                 geom: a subhape of mesh geometry
2158
2159         Returns:
2160                 True of False
2161         """
2162
2163         if not hyp: # or not geom
2164             return False
2165         if isinstance( hyp, Mesh_Algorithm ):
2166             hyp = hyp.GetAlgorithm()
2167             pass
2168         hyps = self.GetHypothesisList(geom)
2169         for h in hyps:
2170             if h.GetId() == hyp.GetId():
2171                 return True
2172         return False
2173
2174     def RemoveHypothesis(self, hyp, geom=0):
2175         """
2176         Unassign a hypothesis
2177
2178         Parameters:
2179                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2180                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2181
2182         Returns:
2183                 :class:`SMESH.Hypothesis_Status`
2184         """
2185
2186         if not hyp:
2187             return None
2188         if isinstance( hyp, Mesh_Algorithm ):
2189             hyp = hyp.GetAlgorithm()
2190             pass
2191         shape = geom
2192         if not shape:
2193             shape = self.geom
2194             pass
2195         if self.IsUsedHypothesis( hyp, shape ):
2196             return self.mesh.RemoveHypothesis( shape, hyp )
2197         hypName = GetName( hyp )
2198         geoName = GetName( shape )
2199         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2200         return None
2201
2202     def GetHypothesisList(self, geom):
2203         """
2204         Get the list of hypotheses added on a geometry
2205
2206         Parameters:
2207                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2208
2209         Returns:
2210                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2211         """
2212
2213         return self.mesh.GetHypothesisList( geom )
2214
2215     def RemoveGlobalHypotheses(self):
2216         """
2217         Remove all global hypotheses
2218         """
2219
2220         current_hyps = self.mesh.GetHypothesisList( self.geom )
2221         for hyp in current_hyps:
2222             self.mesh.RemoveHypothesis( self.geom, hyp )
2223             pass
2224         pass
2225     def ExportMED(self, *args, **kwargs):
2226         """
2227         Export the mesh in a file in MED format
2228         allowing to overwrite the file if it exists or add the exported data to its contents
2229
2230         Parameters:
2231                 fileName: is the file name
2232                 auto_groups (boolean): parameter for creating/not creating
2233                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2234                         the typical use is auto_groups=False.
2235                 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2236                         The minor must be between 0 and the current minor version of MED file library.
2237                         If minor is equal to -1, the minor version is not changed (default).
2238                         The major version (x, where version is x.y.z) cannot be changed.
2239                 overwrite (boolean): parameter for overwriting/not overwriting the file
2240                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2241                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2242
2243                         - 1D if all mesh nodes lie on OX coordinate axis, or
2244                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2245                         - 3D in the rest cases.
2246
2247                         If *autoDimension* is *False*, the space dimension is always 3.
2248                 fields: list of GEOM fields defined on the shape to mesh.
2249                 geomAssocFields: each character of this string means a need to export a 
2250                         corresponding field; correspondence between fields and characters 
2251                         is following:
2252
2253                         - 'v' stands for "_vertices_" field;
2254                         - 'e' stands for "_edges_" field;
2255                         - 'f' stands for "_faces_" field;
2256                         - 's' stands for "_solids_" field.
2257
2258                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2259                              close to zero within a given tolerance, the coordinate is set to zero.
2260                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2261         """
2262         # process positional arguments
2263         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2264         fileName        = args[0]
2265         auto_groups     = args[1] if len(args) > 1 else False
2266         minor           = args[2] if len(args) > 2 else -1
2267         overwrite       = args[3] if len(args) > 3 else True
2268         meshPart        = args[4] if len(args) > 4 else None
2269         autoDimension   = args[5] if len(args) > 5 else True
2270         fields          = args[6] if len(args) > 6 else []
2271         geomAssocFields = args[7] if len(args) > 7 else ''
2272         z_tolerance     = args[8] if len(args) > 8 else -1.
2273         # process keywords arguments
2274         auto_groups     = kwargs.get("auto_groups", auto_groups)
2275         minor           = kwargs.get("minor", minor)
2276         overwrite       = kwargs.get("overwrite", overwrite)
2277         meshPart        = kwargs.get("meshPart", meshPart)
2278         autoDimension   = kwargs.get("autoDimension", autoDimension)
2279         fields          = kwargs.get("fields", fields)
2280         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2281         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2282
2283         # invoke engine's function
2284         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2285             unRegister = genObjUnRegister()
2286             if isinstance( meshPart, list ):
2287                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2288                 unRegister.set( meshPart )
2289
2290             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2291             self.mesh.SetParameters(Parameters)
2292
2293             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2294                                        fields, geomAssocFields, z_tolerance)
2295         else:
2296             self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2297
2298     def ExportSAUV(self, f, auto_groups=0):
2299         """
2300         Export the mesh in a file in SAUV format
2301
2302
2303         Parameters:
2304                 f: is the file name
2305                 auto_groups: boolean parameter for creating/not creating
2306                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2307                         the typical use is auto_groups=False.
2308         """
2309
2310         self.mesh.ExportSAUV(f, auto_groups)
2311
2312     def ExportDAT(self, f, meshPart=None):
2313         """
2314         Export the mesh in a file in DAT format
2315
2316         Parameters:
2317                 f: the file name
2318                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2319         """
2320
2321         if meshPart:
2322             unRegister = genObjUnRegister()
2323             if isinstance( meshPart, list ):
2324                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2325                 unRegister.set( meshPart )
2326             self.mesh.ExportPartToDAT( meshPart, f )
2327         else:
2328             self.mesh.ExportDAT(f)
2329
2330     def ExportUNV(self, f, meshPart=None):
2331         """
2332         Export the mesh in a file in UNV format
2333
2334         Parameters:
2335                 f: the file name
2336                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2337         """
2338
2339         if meshPart:
2340             unRegister = genObjUnRegister()
2341             if isinstance( meshPart, list ):
2342                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2343                 unRegister.set( meshPart )
2344             self.mesh.ExportPartToUNV( meshPart, f )
2345         else:
2346             self.mesh.ExportUNV(f)
2347
2348     def ExportSTL(self, f, ascii=1, meshPart=None):
2349         """
2350         Export the mesh in a file in STL format
2351
2352         Parameters:
2353                 f: the file name
2354                 ascii: defines the file encoding
2355                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2356         """
2357
2358         if meshPart:
2359             unRegister = genObjUnRegister()
2360             if isinstance( meshPart, list ):
2361                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2362                 unRegister.set( meshPart )
2363             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2364         else:
2365             self.mesh.ExportSTL(f, ascii)
2366
2367     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2368         """
2369         Export the mesh in a file in CGNS format
2370
2371         Parameters:
2372                 f: is the file name
2373                 overwrite: boolean parameter for overwriting/not overwriting the file
2374                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2375                 groupElemsByType: if True all elements of same entity type are exported at ones,
2376                         else elements are exported in order of their IDs which can cause creation
2377                         of multiple cgns sections
2378         """
2379
2380         unRegister = genObjUnRegister()
2381         if isinstance( meshPart, list ):
2382             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2383             unRegister.set( meshPart )
2384         if isinstance( meshPart, Mesh ):
2385             meshPart = meshPart.mesh
2386         elif not meshPart:
2387             meshPart = self.mesh
2388         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2389
2390     def ExportGMF(self, f, meshPart=None):
2391         """
2392         Export the mesh in a file in GMF format.
2393         GMF files must have .mesh extension for the ASCII format and .meshb for
2394         the bynary format. Other extensions are not allowed.
2395
2396         Parameters:
2397                 f: is the file name
2398                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2399         """
2400
2401         unRegister = genObjUnRegister()
2402         if isinstance( meshPart, list ):
2403             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2404             unRegister.set( meshPart )
2405         if isinstance( meshPart, Mesh ):
2406             meshPart = meshPart.mesh
2407         elif not meshPart:
2408             meshPart = self.mesh
2409         self.mesh.ExportGMF(meshPart, f, True)
2410
2411     def ExportToMED(self, *args, **kwargs):
2412         """
2413         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2414         Export the mesh in a file in MED format
2415         allowing to overwrite the file if it exists or add the exported data to its contents
2416
2417         Parameters:
2418                 fileName: the file name
2419                 opt (boolean): parameter for creating/not creating
2420                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2421                 overwrite: boolean parameter for overwriting/not overwriting the file
2422                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2423
2424                         - 1D if all mesh nodes lie on OX coordinate axis, or
2425                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2426                         - 3D in the rest cases.
2427
2428                         If **autoDimension** is *False*, the space dimension is always 3.
2429         """
2430     
2431         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2432         # process positional arguments
2433         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2434         fileName      = args[0]
2435         auto_groups   = args[1] if len(args) > 1 else False
2436         overwrite     = args[2] if len(args) > 2 else True
2437         autoDimension = args[3] if len(args) > 3 else True
2438         # process keywords arguments
2439         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2440         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2441         overwrite     = kwargs.get("overwrite", overwrite)
2442         autoDimension = kwargs.get("autoDimension", autoDimension)
2443         minor = -1
2444         # invoke engine's function
2445         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2446
2447     def ExportToMEDX(self, *args, **kwargs):
2448         """
2449         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2450         Export the mesh in a file in MED format
2451
2452         Parameters:
2453                 fileName: the file name
2454                 opt (boolean): parameter for creating/not creating
2455                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2456                 overwrite: boolean parameter for overwriting/not overwriting the file
2457                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2458
2459                         - 1D if all mesh nodes lie on OX coordinate axis, or
2460                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2461                         - 3D in the rest cases.
2462
2463                         If **autoDimension** is *False*, the space dimension is always 3.
2464                 """
2465
2466         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2467         # process positional arguments
2468         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2469         fileName      = args[0]
2470         auto_groups   = args[1] if len(args) > 1 else False
2471         overwrite     = args[2] if len(args) > 2 else True
2472         autoDimension = args[3] if len(args) > 3 else True
2473         # process keywords arguments
2474         auto_groups   = kwargs.get("auto_groups", auto_groups)
2475         overwrite     = kwargs.get("overwrite", overwrite)
2476         autoDimension = kwargs.get("autoDimension", autoDimension)
2477         minor = -1
2478         # invoke engine's function
2479         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2480
2481     # Operations with groups:
2482     # ----------------------
2483     def CreateEmptyGroup(self, elementType, name):
2484         """
2485         Create an empty standalone mesh group
2486
2487         Parameters:
2488                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2489                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2490                 name: the name of the mesh group
2491
2492         Returns:
2493                 :class:`SMESH.SMESH_Group`
2494         """
2495
2496         return self.mesh.CreateGroup(elementType, name)
2497
2498     def Group(self, grp, name=""):
2499         """
2500         Create a mesh group based on the geometric object *grp*
2501         and give it a *name*.
2502         If *name* is not defined the name of the geometric group is used
2503
2504         Note:
2505                 Works like :meth:`GroupOnGeom`.
2506
2507         Parameters:
2508                 grp:  a geometric group, a vertex, an edge, a face or a solid
2509                 name: the name of the mesh group
2510
2511         Returns:
2512                 :class:`SMESH.SMESH_GroupOnGeom`
2513         """
2514
2515         return self.GroupOnGeom(grp, name)
2516
2517     def GroupOnGeom(self, grp, name="", typ=None):
2518         """
2519         Create a mesh group based on the geometrical object *grp*
2520         and give it a *name*.
2521         if *name* is not defined the name of the geometric group is used
2522
2523         Parameters:
2524                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2525                 name: the name of the mesh group
2526                 typ:  the type of elements in the group; either of
2527                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2528                         automatically detected by the type of the geometry
2529
2530         Returns:
2531                 :class:`SMESH.SMESH_GroupOnGeom`
2532         """
2533
2534         AssureGeomPublished( self, grp, name )
2535         if name == "":
2536             name = grp.GetName()
2537         if not typ:
2538             typ = self._groupTypeFromShape( grp )
2539         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2540
2541     def _groupTypeFromShape( self, shape ):
2542         """
2543         Pivate method to get a type of group on geometry
2544         """
2545         tgeo = str(shape.GetShapeType())
2546         if tgeo == "VERTEX":
2547             typ = NODE
2548         elif tgeo == "EDGE":
2549             typ = EDGE
2550         elif tgeo == "FACE" or tgeo == "SHELL":
2551             typ = FACE
2552         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2553             typ = VOLUME
2554         elif tgeo == "COMPOUND":
2555             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2556             if not sub:
2557                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2558             return self._groupTypeFromShape( sub[0] )
2559         else:
2560             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2561         return typ
2562
2563     def GroupOnFilter(self, typ, name, filter):
2564         """
2565         Create a mesh group with given *name* based on the *filter*.
2566         It is a special type of group dynamically updating it's contents during
2567         mesh modification
2568
2569         Parameters:
2570                 typ: the type of elements in the group; either of
2571                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2572                 name: the name of the mesh group
2573                 filter (SMESH.Filter): the filter defining group contents
2574
2575         Returns:
2576                 :class:`SMESH.SMESH_GroupOnFilter`
2577         """
2578
2579         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2580
2581     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2582         """
2583         Create a mesh group by the given ids of elements
2584
2585         Parameters:
2586                 groupName: the name of the mesh group
2587                 elementType: the type of elements in the group; either of
2588                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2589                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2590
2591         Returns:
2592                 :class:`SMESH.SMESH_Group`
2593         """
2594
2595         group = self.mesh.CreateGroup(elementType, groupName)
2596         if isinstance( elemIDs, Mesh ):
2597             elemIDs = elemIDs.GetMesh()
2598         if hasattr( elemIDs, "GetIDs" ):
2599             if hasattr( elemIDs, "SetMesh" ):
2600                 elemIDs.SetMesh( self.GetMesh() )
2601             group.AddFrom( elemIDs )
2602         else:
2603             group.Add(elemIDs)
2604         return group
2605
2606     def MakeGroup(self,
2607                   groupName,
2608                   elementType,
2609                   CritType=FT_Undefined,
2610                   Compare=FT_EqualTo,
2611                   Threshold="",
2612                   UnaryOp=FT_Undefined,
2613                   Tolerance=1e-07):
2614         """
2615         Create a mesh group by the given conditions
2616
2617         Parameters:
2618                 groupName: the name of the mesh group
2619                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2620                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2621                         Note that the items starting from FT_LessThan are not suitable for CritType.
2622                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2623                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2624                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2625                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2626                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2627
2628         Returns:
2629                 :class:`SMESH.SMESH_GroupOnFilter`
2630         """
2631
2632         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2633         group = self.MakeGroupByCriterion(groupName, aCriterion)
2634         return group
2635
2636     def MakeGroupByCriterion(self, groupName, Criterion):
2637         """
2638         Create a mesh group by the given criterion
2639
2640         Parameters:
2641                 groupName: the name of the mesh group
2642                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2643
2644         Returns:
2645                 :class:`SMESH.SMESH_GroupOnFilter`
2646
2647         See Also:
2648                 :meth:`smeshBuilder.GetCriterion`
2649         """
2650
2651         return self.MakeGroupByCriteria( groupName, [Criterion] )
2652
2653     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2654         """
2655         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2656
2657         Parameters:
2658                 groupName: the name of the mesh group
2659                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2660                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2661
2662         Returns:
2663                 :class:`SMESH.SMESH_GroupOnFilter`
2664
2665         See Also:
2666                 :meth:`smeshBuilder.GetCriterion`
2667         """
2668
2669         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2670         group = self.MakeGroupByFilter(groupName, aFilter)
2671         return group
2672
2673     def MakeGroupByFilter(self, groupName, theFilter):
2674         """
2675         Create a mesh group by the given filter
2676
2677         Parameters:
2678                 groupName (string): the name of the mesh group
2679                 theFilter (SMESH.Filter): the filter
2680
2681         Returns:
2682                 :class:`SMESH.SMESH_GroupOnFilter`
2683
2684         See Also:
2685                 :meth:`smeshBuilder.GetFilter`
2686         """
2687
2688         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2689         #theFilter.SetMesh( self.mesh )
2690         #group.AddFrom( theFilter )
2691         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2692         return group
2693
2694     def RemoveGroup(self, group):
2695         """
2696         Remove a group
2697
2698         Parameters:
2699                 group (SMESH.SMESH_GroupBase): group to remove
2700         """
2701
2702         self.mesh.RemoveGroup(group)
2703
2704     def RemoveGroupWithContents(self, group):
2705         """
2706         Remove a group with its contents
2707
2708         Parameters:
2709                 group (SMESH.SMESH_GroupBase): group to remove
2710         """
2711
2712         self.mesh.RemoveGroupWithContents(group)
2713
2714     def GetGroups(self, elemType = SMESH.ALL):
2715         """
2716         Get the list of groups existing in the mesh in the order of creation 
2717         (starting from the oldest one)
2718
2719         Parameters:
2720                 elemType (SMESH.ElementType): type of elements the groups contain;
2721                         by default groups of elements of all types are returned
2722
2723         Returns:
2724                 a list of :class:`SMESH.SMESH_GroupBase`
2725         """
2726
2727         groups = self.mesh.GetGroups()
2728         if elemType == SMESH.ALL:
2729             return groups
2730         typedGroups = []
2731         for g in groups:
2732             if g.GetType() == elemType:
2733                 typedGroups.append( g )
2734                 pass
2735             pass
2736         return typedGroups
2737
2738     def NbGroups(self):
2739         """
2740         Get the number of groups existing in the mesh
2741
2742         Returns:
2743                 the quantity of groups as an integer value
2744         """
2745
2746         return self.mesh.NbGroups()
2747
2748     def GetGroupNames(self):
2749         """
2750         Get the list of names of groups existing in the mesh
2751
2752         Returns:
2753                 list of strings
2754         """
2755
2756         groups = self.GetGroups()
2757         names = []
2758         for group in groups:
2759             names.append(group.GetName())
2760         return names
2761
2762     def GetGroupByName(self, name, elemType = None):
2763         """
2764         Find groups by name and type
2765
2766         Parameters:
2767                 name (string): name of the group of interest
2768                 elemType (SMESH.ElementType): type of elements the groups contain;
2769                         by default one group of any type is returned;
2770                         if elemType == SMESH.ALL then all groups of any type are returned
2771
2772         Returns:
2773                 a list of :class:`SMESH.SMESH_GroupBase`
2774         """
2775
2776         groups = []
2777         for group in self.GetGroups():
2778             if group.GetName() == name:
2779                 if elemType is None:
2780                     return [group]
2781                 if ( elemType == SMESH.ALL or
2782                      group.GetType() == elemType ):
2783                     groups.append( group )
2784         return groups
2785
2786     def UnionGroups(self, group1, group2, name):
2787         """
2788         Produce a union of two groups.
2789         A new group is created. All mesh elements that are
2790         present in the initial groups are added to the new one
2791
2792         Parameters:
2793            group1 (SMESH.SMESH_GroupBase): a group
2794            group2 (SMESH.SMESH_GroupBase): another group
2795
2796         Returns:
2797                 instance of :class:`SMESH.SMESH_Group`
2798         """
2799
2800         return self.mesh.UnionGroups(group1, group2, name)
2801
2802     def UnionListOfGroups(self, groups, name):
2803         """
2804         Produce a union list of groups.
2805         New group is created. All mesh elements that are present in
2806         initial groups are added to the new one
2807
2808         Parameters:
2809            groups: list of :class:`SMESH.SMESH_GroupBase`
2810
2811         Returns:
2812                 instance of :class:`SMESH.SMESH_Group`
2813         """
2814         return self.mesh.UnionListOfGroups(groups, name)
2815
2816     def IntersectGroups(self, group1, group2, name):
2817         """
2818         Prodice an intersection of two groups.
2819         A new group is created. All mesh elements that are common
2820         for the two initial groups are added to the new one.
2821
2822         Parameters:
2823            group1 (SMESH.SMESH_GroupBase): a group
2824            group2 (SMESH.SMESH_GroupBase): another group
2825
2826         Returns:
2827                 instance of :class:`SMESH.SMESH_Group`
2828         """
2829
2830         return self.mesh.IntersectGroups(group1, group2, name)
2831
2832     def IntersectListOfGroups(self, groups, name):
2833         """
2834         Produce an intersection of groups.
2835         New group is created. All mesh elements that are present in all
2836         initial groups simultaneously are added to the new one
2837
2838         Parameters:
2839            groups: a list of :class:`SMESH.SMESH_GroupBase`
2840
2841         Returns:
2842                 instance of :class:`SMESH.SMESH_Group`
2843         """
2844         return self.mesh.IntersectListOfGroups(groups, name)
2845
2846     def CutGroups(self, main_group, tool_group, name):
2847         """
2848         Produce a cut of two groups.
2849         A new group is created. All mesh elements that are present in
2850         the main group but are not present in the tool group are added to the new one
2851
2852         Parameters:
2853            main_group (SMESH.SMESH_GroupBase): a group to cut from
2854            tool_group (SMESH.SMESH_GroupBase): a group to cut by
2855
2856         Returns:
2857                 an instance of :class:`SMESH.SMESH_Group`
2858         """
2859
2860         return self.mesh.CutGroups(main_group, tool_group, name)
2861
2862     def CutListOfGroups(self, main_groups, tool_groups, name):
2863         """
2864         Produce a cut of groups.
2865         A new group is created. All mesh elements that are present in main groups
2866         but do not present in tool groups are added to the new one
2867
2868         Parameters:
2869            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
2870            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
2871
2872         Returns:
2873                 an instance of :class:`SMESH.SMESH_Group`
2874         """
2875
2876         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2877
2878     def CreateDimGroup(self, groups, elemType, name,
2879                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2880         """
2881         Create a standalone group of entities basing on nodes of other groups.
2882
2883         Parameters:
2884                 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2885                 elemType: a type of elements to include to the new group; either of
2886                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2887                 name: a name of the new group.
2888                 nbCommonNodes: a criterion of inclusion of an element to the new group
2889                         basing on number of element nodes common with reference *groups*.
2890                         Meaning of possible values are:
2891
2892                                 - SMESH.ALL_NODES - include if all nodes are common,
2893                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2894                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2895                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
2896                 underlyingOnly: if *True* (default), an element is included to the
2897                         new group provided that it is based on nodes of an element of *groups*;
2898                         in this case the reference *groups* are supposed to be of higher dimension
2899                         than *elemType*, which can be useful for example to get all faces lying on
2900                         volumes of the reference *groups*.
2901
2902         Returns:
2903                 an instance of :class:`SMESH.SMESH_Group`
2904         """
2905
2906         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2907             groups = [groups]
2908         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2909
2910     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2911         """
2912         Distribute all faces of the mesh among groups using sharp edges and optionally
2913         existing 1D elements as group boundaries.
2914
2915         Parameters:
2916                 sharpAngle: edge is considered sharp if an angle between normals of
2917                             adjacent faces is more than \a sharpAngle in degrees.
2918                 createEdges (boolean): to create 1D elements for detected sharp edges.
2919                 useExistingEdges (boolean): to use existing edges as group boundaries
2920         Returns:
2921                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2922         """
2923         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2924         self.mesh.SetParameters(Parameters)
2925         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2926
2927     def ConvertToStandalone(self, group):
2928         """
2929         Convert group on geom into standalone group
2930         """
2931
2932         return self.mesh.ConvertToStandalone(group)
2933
2934     # Get some info about mesh:
2935     # ------------------------
2936
2937     def GetLog(self, clearAfterGet):
2938         """
2939         Return the log of nodes and elements added or removed
2940         since the previous clear of the log.
2941
2942         Parameters:
2943                 clearAfterGet: log is emptied after Get (safe if concurrents access)
2944
2945         Returns:
2946                 list of SMESH.log_block structures { commandType, number, coords, indexes }
2947         """
2948
2949         return self.mesh.GetLog(clearAfterGet)
2950
2951     def ClearLog(self):
2952         """
2953         Clear the log of nodes and elements added or removed since the previous
2954         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2955         """
2956
2957         self.mesh.ClearLog()
2958
2959     def SetAutoColor(self, theAutoColor):
2960         """
2961         Toggle auto color mode on the object.
2962         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2963
2964         Parameters:
2965                 theAutoColor (boolean): the flag which toggles auto color mode.
2966         """
2967
2968         self.mesh.SetAutoColor(theAutoColor)
2969
2970     def GetAutoColor(self):
2971         """
2972         Get flag of object auto color mode.
2973
2974         Returns:
2975                 True or False
2976         """
2977
2978         return self.mesh.GetAutoColor()
2979
2980     def GetId(self):
2981         """
2982         Get the internal ID
2983
2984         Returns:
2985             integer value, which is the internal Id of the mesh
2986         """
2987
2988         return self.mesh.GetId()
2989
2990     def HasDuplicatedGroupNamesMED(self):
2991         """
2992         Check the group names for duplications.
2993         Consider the maximum group name length stored in MED file.
2994
2995         Returns:
2996             True or False
2997         """
2998
2999         return self.mesh.HasDuplicatedGroupNamesMED()
3000
3001     def GetMeshEditor(self):
3002         """
3003         Obtain the mesh editor tool
3004
3005         Returns:
3006             an instance of :class:`SMESH.SMESH_MeshEditor`
3007         """
3008
3009         return self.editor
3010
3011     def GetIDSource(self, ids, elemType = SMESH.ALL):
3012         """
3013         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3014         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3015
3016         Parameters:
3017                 ids: list of IDs
3018                 elemType: type of elements; this parameter is used to distinguish
3019                         IDs of nodes from IDs of elements; by default ids are treated as
3020                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3021
3022         Returns:
3023             an instance of :class:`SMESH.SMESH_IDSource`
3024
3025         Warning:
3026                 call UnRegister() for the returned object as soon as it is no more useful::
3027
3028                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3029                         mesh.DoSomething( idSrc )
3030                         idSrc.UnRegister()
3031         """
3032
3033         if isinstance( ids, int ):
3034             ids = [ids]
3035         return self.editor.MakeIDSource(ids, elemType)
3036
3037
3038     # Get information about mesh contents:
3039     # ------------------------------------
3040
3041     def GetMeshInfo(self, obj = None):
3042         """
3043         Get the mesh statistic.
3044         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
3045         an item of :class:`SMESH.EntityType`.
3046
3047         Returns:
3048                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3049         """
3050
3051         if not obj: obj = self.mesh
3052         return self.smeshpyD.GetMeshInfo(obj)
3053
3054     def NbNodes(self):
3055         """
3056         Return the number of nodes in the mesh
3057
3058         Returns:
3059             an integer value
3060         """
3061
3062         return self.mesh.NbNodes()
3063
3064     def NbElements(self):
3065         """
3066         Return the number of elements in the mesh
3067
3068         Returns:
3069             an integer value
3070         """
3071
3072         return self.mesh.NbElements()
3073
3074     def Nb0DElements(self):
3075         """
3076         Return the number of 0d elements in the mesh
3077
3078         Returns:
3079             an integer value
3080         """
3081
3082         return self.mesh.Nb0DElements()
3083
3084     def NbBalls(self):
3085         """
3086         Return the number of ball discrete elements in the mesh
3087
3088         Returns:
3089             an integer value
3090         """
3091
3092         return self.mesh.NbBalls()
3093
3094     def NbEdges(self):
3095         """
3096         Return the number of edges in the mesh
3097
3098         Returns:
3099             an integer value
3100         """
3101
3102         return self.mesh.NbEdges()
3103
3104     def NbEdgesOfOrder(self, elementOrder):
3105         """
3106         Return the number of edges with the given order in the mesh
3107
3108         Parameters:
3109                 elementOrder: the order of elements
3110                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3111
3112         Returns:
3113             an integer value
3114         """
3115
3116         return self.mesh.NbEdgesOfOrder(elementOrder)
3117
3118     def NbFaces(self):
3119         """
3120         Return the number of faces in the mesh
3121
3122         Returns:
3123             an integer value
3124         """
3125
3126         return self.mesh.NbFaces()
3127
3128     def NbFacesOfOrder(self, elementOrder):
3129         """
3130         Return the number of faces with the given order in the mesh
3131
3132         Parameters:
3133                 elementOrder: the order of elements
3134                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3135
3136         Returns:
3137             an integer value
3138         """
3139
3140         return self.mesh.NbFacesOfOrder(elementOrder)
3141
3142     def NbTriangles(self):
3143         """
3144         Return the number of triangles in the mesh
3145
3146         Returns:
3147             an integer value
3148         """
3149
3150         return self.mesh.NbTriangles()
3151
3152     def NbTrianglesOfOrder(self, elementOrder):
3153         """
3154         Return the number of triangles with the given order in the mesh
3155
3156         Parameters:
3157                 elementOrder: is the order of elements
3158                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3159
3160         Returns:
3161             an integer value
3162         """
3163
3164         return self.mesh.NbTrianglesOfOrder(elementOrder)
3165
3166     def NbBiQuadTriangles(self):
3167         """
3168         Return the number of biquadratic triangles in the mesh
3169
3170         Returns:
3171             an integer value
3172         """
3173
3174         return self.mesh.NbBiQuadTriangles()
3175
3176     def NbQuadrangles(self):
3177         """
3178         Return the number of quadrangles in the mesh
3179
3180         Returns:
3181             an integer value
3182         """
3183
3184         return self.mesh.NbQuadrangles()
3185
3186     def NbQuadranglesOfOrder(self, elementOrder):
3187         """
3188         Return the number of quadrangles with the given order in the mesh
3189
3190         Parameters:
3191                 elementOrder: the order of elements
3192                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3193
3194         Returns:
3195             an integer value
3196         """
3197
3198         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3199
3200     def NbBiQuadQuadrangles(self):
3201         """
3202         Return the number of biquadratic quadrangles in the mesh
3203
3204         Returns:
3205             an integer value
3206         """
3207
3208         return self.mesh.NbBiQuadQuadrangles()
3209
3210     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3211         """
3212         Return the number of polygons of given order in the mesh
3213
3214         Parameters:
3215                 elementOrder: the order of elements
3216                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3217
3218         Returns:
3219             an integer value
3220         """
3221
3222         return self.mesh.NbPolygonsOfOrder(elementOrder)
3223
3224     def NbVolumes(self):
3225         """
3226         Return the number of volumes in the mesh
3227
3228         Returns:
3229             an integer value
3230         """
3231
3232         return self.mesh.NbVolumes()
3233
3234
3235     def NbVolumesOfOrder(self, elementOrder):
3236         """
3237         Return the number of volumes with the given order in the mesh
3238
3239         Parameters:
3240                 elementOrder:  the order of elements
3241                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3242
3243         Returns:
3244             an integer value
3245         """
3246
3247         return self.mesh.NbVolumesOfOrder(elementOrder)
3248
3249     def NbTetras(self):
3250         """
3251         Return the number of tetrahedrons in the mesh
3252
3253         Returns:
3254             an integer value
3255         """
3256
3257         return self.mesh.NbTetras()
3258
3259     def NbTetrasOfOrder(self, elementOrder):
3260         """
3261         Return the number of tetrahedrons with the given order in the mesh
3262
3263         Parameters:
3264                 elementOrder:  the order of elements
3265                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3266
3267         Returns:
3268             an integer value
3269         """
3270
3271         return self.mesh.NbTetrasOfOrder(elementOrder)
3272
3273     def NbHexas(self):
3274         """
3275         Return the number of hexahedrons in the mesh
3276
3277         Returns:
3278             an integer value
3279         """
3280
3281         return self.mesh.NbHexas()
3282
3283     def NbHexasOfOrder(self, elementOrder):
3284         """
3285         Return the number of hexahedrons with the given order in the mesh
3286
3287         Parameters:
3288                 elementOrder:  the order of elements
3289                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3290
3291         Returns:
3292             an integer value
3293         """
3294
3295         return self.mesh.NbHexasOfOrder(elementOrder)
3296
3297     def NbTriQuadraticHexas(self):
3298         """
3299         Return the number of triquadratic hexahedrons in the mesh
3300
3301         Returns:
3302             an integer value
3303         """
3304
3305         return self.mesh.NbTriQuadraticHexas()
3306
3307     def NbPyramids(self):
3308         """
3309         Return the number of pyramids in the mesh
3310
3311         Returns:
3312             an integer value
3313         """
3314
3315         return self.mesh.NbPyramids()
3316
3317     def NbPyramidsOfOrder(self, elementOrder):
3318         """
3319         Return the number of pyramids with the given order in the mesh
3320
3321         Parameters:
3322                 elementOrder:  the order of elements
3323                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3324
3325         Returns:
3326             an integer value
3327         """
3328
3329         return self.mesh.NbPyramidsOfOrder(elementOrder)
3330
3331     def NbPrisms(self):
3332         """
3333         Return the number of prisms in the mesh
3334
3335         Returns:
3336             an integer value
3337         """
3338
3339         return self.mesh.NbPrisms()
3340
3341     def NbPrismsOfOrder(self, elementOrder):
3342         """
3343         Return the number of prisms with the given order in the mesh
3344
3345         Parameters:
3346                 elementOrder:  the order of elements