Salome HOME
d2b35d10465a221c7606b6ecba51703762449158
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 #  File   : smeshBuilder.py
20 #  Author : Francis KLOSS, OCC
21 #  Module : SMESH
22
23 import salome
24 from salome.geom import geomBuilder
25
26 import SMESH # This is necessary for back compatibility
27 import omniORB                                       # back compatibility
28 SMESH.MED_V2_1    = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2    = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
40
41 from   SMESH import *
42 from   salome.smesh.smesh_algorithm import Mesh_Algorithm
43
44 import SALOME
45 import SALOMEDS
46 import os
47 import inspect
48
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
51 # defined
52 #
53 try:
54     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
55 except TypeError:
56     def enumitem_eq(self, other):
57         try:
58             if isinstance(other, omniORB.EnumItem):
59                 if other._parent_id == self._parent_id:
60                     return self._v == other._v
61                 else:
62                     return self._parent_id == other._parent_id
63             else:
64                 return id(self) == id(other)
65         except:
66             return id(self) == id(other)
67
68     def enumitem_lt(self, other):
69         try:
70             if isinstance(other, omniORB.EnumItem):
71                 if other._parent_id == self._parent_id:
72                     return self._v < other._v
73                 else:
74                     return self._parent_id < other._parent_id
75             else:
76                 return id(self) < id(other)
77         except:
78             return id(self) < id(other)
79
80     def enumitem_le(self, other):
81         try:
82             if isinstance(other, omniORB.EnumItem):
83                 if other._parent_id == self._parent_id:
84                     return self._v <= other._v
85                 else:
86                     return self._parent_id <= other._parent_id
87             else:
88                 return id(self) <= id(other)
89         except:
90             return id(self) <= id(other)
91
92     def enumitem_gt(self, other):
93         try:
94             if isinstance(other, omniORB.EnumItem):
95                 if other._parent_id == self._parent_id:
96                     return self._v > other._v
97                 else:
98                     return self._parent_id > other._parent_id
99             else:
100                 return id(self) > id(other)
101         except:
102             return id(self) > id(other)
103
104     def enumitem_ge(self, other):
105         try:
106             if isinstance(other, omniORB.EnumItem):
107                 if other._parent_id == self._parent_id:
108                     return self._v >= other._v
109                 else:
110                     return self._parent_id >= other._parent_id
111             else:
112                 return id(self) >= id(other)
113         except:
114             return id(self) >= id(other)
115
116     omniORB.EnumItem.__eq__ = enumitem_eq
117     omniORB.EnumItem.__lt__ = enumitem_lt
118     omniORB.EnumItem.__le__ = enumitem_le
119     omniORB.EnumItem.__gt__ = enumitem_gt
120     omniORB.EnumItem.__ge__ = enumitem_ge
121
122
123 class MeshMeta(type):
124     """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
125     """
126     def __instancecheck__(cls, inst):
127         """Implement isinstance(inst, cls)."""
128         return any(cls.__subclasscheck__(c)
129                    for c in {type(inst), inst.__class__})
130
131     def __subclasscheck__(cls, sub):
132         """Implement issubclass(sub, cls)."""
133         return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
134
135 def DegreesToRadians(AngleInDegrees):
136     """Convert an angle from degrees to radians
137     """
138     from math import pi
139     return AngleInDegrees * pi / 180.0
140
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
144 var_separator = ":"
145
146 def ParseParameters(*args):
147     """
148     Return list of variable values from salome notebook.
149     The last argument, if is callable, is used to modify values got from notebook
150     """
151     Result = []
152     Parameters = ""
153     hasVariables = False
154     varModifFun=None
155     if args and callable(args[-1]):
156         args, varModifFun = args[:-1], args[-1]
157     for parameter in args:
158
159         Parameters += str(parameter) + var_separator
160
161         if isinstance(parameter,str):
162             # check if there is an inexistent variable name
163             if not notebook.isVariable(parameter):
164                 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165             parameter = notebook.get(parameter)
166             hasVariables = True
167             if varModifFun:
168                 parameter = varModifFun(parameter)
169                 pass
170             pass
171         Result.append(parameter)
172
173         pass
174     Parameters = Parameters[:-1]
175     Result.append( Parameters )
176     Result.append( hasVariables )
177     return Result
178
179 def ParseAngles(*args):
180     """
181     Parse parameters while converting variables to radians
182     """
183     return ParseParameters( *( args + (DegreesToRadians, )))
184
185 def __initPointStruct(point,*args):
186     """
187     Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188     Parameters are stored in PointStruct.parameters attribute
189     """
190     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
191     pass
192 SMESH.PointStruct.__init__ = __initPointStruct
193
194 def __initAxisStruct(ax,*args):
195     """
196     Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197     Parameters are stored in AxisStruct.parameters attribute
198     """
199     if len( args ) != 6:
200         raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
202     pass
203 SMESH.AxisStruct.__init__ = __initAxisStruct
204
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207     """Compare real values using smeshPrecisionConfusion as tolerance
208     """
209     if abs(val1 - val2) < tol:
210         return True
211     return False
212
213 NO_NAME = "NoName"
214
215 def GetName(obj):
216     """
217     Return a name of an object
218     
219     Returns:
220         object name
221     """
222     if obj:
223         # object not null
224         if isinstance(obj, SALOMEDS._objref_SObject):
225             # study object
226             return obj.GetName()
227         try:
228             ior  = salome.orb.object_to_string(obj)
229         except:
230             ior = None
231         if ior:
232             sobj = salome.myStudy.FindObjectIOR(ior)
233             if sobj:
234                 return sobj.GetName()
235             if hasattr(obj, "GetName"):
236                 # unknown CORBA object, having GetName() method
237                 return obj.GetName()
238             else:
239                 # unknown CORBA object, no GetName() method
240                 return NO_NAME
241             pass
242         if hasattr(obj, "GetName"):
243             # unknown non-CORBA object, having GetName() method
244             return obj.GetName()
245         pass
246     raise RuntimeError("Null or invalid object")
247
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
249     """
250     Print error message if a hypothesis was not assigned.
251     """
252     if isAlgo:
253         hypType = "algorithm"
254     else:
255         hypType = "hypothesis"
256         pass
257     reason = ""
258     if hasattr( status, "__getitem__" ):
259         status, reason = status[0], status[1]
260     if status == HYP_UNKNOWN_FATAL:
261         reason = "for unknown reason"
262     elif status == HYP_INCOMPATIBLE:
263         reason = "this hypothesis mismatches the algorithm"
264     elif status == HYP_NOTCONFORM:
265         reason = "a non-conform mesh would be built"
266     elif status == HYP_ALREADY_EXIST:
267         if isAlgo: return # it does not influence anything
268         reason = hypType + " of the same dimension is already assigned to this shape"
269     elif status == HYP_BAD_DIM:
270         reason = hypType + " mismatches the shape"
271     elif status == HYP_CONCURRENT :
272         reason = "there are concurrent hypotheses on sub-shapes"
273     elif status == HYP_BAD_SUBSHAPE:
274         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275     elif status == HYP_BAD_GEOMETRY:
276         reason = "the algorithm is not applicable to this geometry"
277     elif status == HYP_HIDDEN_ALGO:
278         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279     elif status == HYP_HIDING_ALGO:
280         reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281     elif status == HYP_NEED_SHAPE:
282         reason = "algorithm can't work without shape"
283     elif status == HYP_INCOMPAT_HYPS:
284         pass
285     else:
286         return
287     where = geomName
288     if where:
289         where = '"%s"' % geomName
290         if mesh:
291             meshName = GetName( mesh )
292             if meshName and meshName != NO_NAME:
293                 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294     if status < HYP_UNKNOWN_FATAL and where:
295         print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
296     elif where:
297         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
298     else:
299         print('"%s" was not assigned : %s' %( hypName, reason ))
300         pass
301
302 def AssureGeomPublished(mesh, geom, name=''):
303     """
304     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
305     """
306     if not mesh.smeshpyD.IsEnablePublish():
307         return
308     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
309         return
310     if not geom.GetStudyEntry():
311         ## get a name
312         if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313             # for all groups SubShapeName() return "Compound_-1"
314             name = mesh.geompyD.SubShapeName(geom, mesh.geom)
315         if not name:
316             name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
317         ## publish
318         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
319     return
320
321 def FirstVertexOnCurve(mesh, edge):
322     """
323     Returns:
324         the first vertex of a geometrical edge by ignoring orientation
325     """
326     vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
327     if not vv:
328         raise TypeError("Given object has no vertices")
329     if len( vv ) == 1: return vv[0]
330     v0   = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331     xyz  = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332     xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333     xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
334     dist1, dist2 = 0,0
335     for i in range(3):
336         dist1 += abs( xyz[i] - xyz1[i] )
337         dist2 += abs( xyz[i] - xyz2[i] )
338     if dist1 < dist2:
339         return vv[0]
340     else:
341         return vv[1]
342
343 smeshInst = None
344 """
345 Warning:
346     smeshInst is a singleton
347 """
348 engine = None
349 doLcc = False
350 created = False
351
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
353     """
354     This class allows to create, load or manipulate meshes.
355     It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356     It also has methods to get infos and measure meshes.
357     """
358
359     # MirrorType enumeration
360     POINT = SMESH_MeshEditor.POINT
361     AXIS =  SMESH_MeshEditor.AXIS
362     PLANE = SMESH_MeshEditor.PLANE
363
364     # Smooth_Method enumeration
365     LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366     CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
367
368     PrecisionConfusion = smeshPrecisionConfusion
369
370     # TopAbs_State enumeration
371     [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
372
373     # Methods of splitting a hexahedron into tetrahedra
374     Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
375
376     def __new__(cls, *args):
377         global engine
378         global smeshInst
379         global doLcc
380         #print("==== __new__", engine, smeshInst, doLcc)
381
382         if smeshInst is None:
383             # smesh engine is either retrieved from engine, or created
384             smeshInst = engine
385             # Following test avoids a recursive loop
386             if doLcc:
387                 if smeshInst is not None:
388                     # smesh engine not created: existing engine found
389                     doLcc = False
390                 if doLcc:
391                     doLcc = False
392                     # FindOrLoadComponent called:
393                     # 1. CORBA resolution of server
394                     # 2. the __new__ method is called again
395                     #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396                     smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
397             else:
398                 # FindOrLoadComponent not called
399                 if smeshInst is None:
400                     # smeshBuilder instance is created from lcc.FindOrLoadComponent
401                     #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402                     smeshInst = super(smeshBuilder,cls).__new__(cls)
403                 else:
404                     # smesh engine not created: existing engine found
405                     #print("==== existing ", engine, smeshInst, doLcc)
406                     pass
407             #print("====1 ", smeshInst)
408             return smeshInst
409
410         #print("====2 ", smeshInst)
411         return smeshInst
412
413     def __init__(self, *args):
414         global created
415         #print("--------------- smeshbuilder __init__ ---", created)
416         if not created:
417             created = True
418             SMESH._objref_SMESH_Gen.__init__(self, *args)
419
420
421     def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
422         """
423         Dump component to the Python script.
424         This method overrides IDL function to allow default values for the parameters.
425         """
426
427         return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
428
429     def SetDumpPythonHistorical(self, isHistorical):
430         """
431         Set mode of DumpPython(), *historical* or *snapshot*.
432         In the *historical* mode, the Python Dump script includes all commands
433         performed by SMESH engine. In the *snapshot* mode, commands
434         relating to objects removed from the Study are excluded from the script
435         as well as commands not influencing the current state of meshes
436         """
437
438         if isHistorical: val = "true"
439         else:            val = "false"
440         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
441
442     def init_smesh(self,geompyD = None):
443         """
444         Set Geometry component
445         """    
446         #print("init_smesh")
447         self.UpdateStudy(geompyD)
448         notebook.myStudy = salome.myStudy
449
450     def Mesh(self, obj=0, name=0):
451         """
452         Create a mesh. This mesh can be either 
453
454         * an empty mesh not bound to geometry, if *obj* == 0
455         * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456         * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
457
458         Parameters:
459             obj: either 
460
461                    1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
462                       ::
463
464                         salome.myStudy.FindObjectID("0:1:2:3").GetObject() 
465
466                    2. a geometrical object for meshing
467                    3. none.
468             name: the name for the new mesh.
469
470         Returns:
471             an instance of class :class:`Mesh`.
472         """
473
474         if isinstance(obj,str):
475             obj,name = name,obj
476         return Mesh(self, self.geompyD, obj, name)
477
478     def 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 = "", meshToAppendTo = None):
737         """
738         Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
739         All groups of input meshes will be 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                 meshToAppendTo: a mesh to append all given meshes
749
750         Returns:
751                 an instance of class :class:`Mesh`
752
753         See also: 
754                 :meth:`Mesh.Append`
755         """
756
757         if not meshes: return None
758         if not isinstance( meshes, list ):
759             meshes = [ meshes ]
760         for i,m in enumerate( meshes ):
761             if isinstance( m, Mesh ):
762                 meshes[i] = m.GetMesh()
763         mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
764         if hasattr(meshes[0], "SetParameters"):
765             meshes[0].SetParameters( Parameters )
766         else:
767             meshes[0].GetMesh().SetParameters( Parameters )
768         if isinstance( meshToAppendTo, Mesh ):
769             meshToAppendTo = meshToAppendTo.GetMesh()
770         if allGroups:
771             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
772                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
773                 mergeTolerance,meshToAppendTo )
774         else:
775             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
776                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
777                 mergeTolerance,meshToAppendTo )
778
779         aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
780         return aMesh
781
782     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
783         """
784         Create a mesh by copying a part of another mesh.
785
786         Parameters:
787                 meshPart: a part of mesh to copy, either 
788                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
789                         To copy nodes or elements not forming any mesh object,
790                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
791                 meshName: a name of the new mesh
792                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
793                 toKeepIDs: to preserve order of the copied elements or not
794
795         Returns:
796                 an instance of class :class:`Mesh`
797         """
798
799         if isinstance( meshPart, Mesh ):
800             meshPart = meshPart.GetMesh()
801         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
802         return Mesh(self, self.geompyD, mesh)
803
804     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
805                           toReuseHypotheses=True, toCopyElements=True):
806         """
807         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
808         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
809         To facilitate and speed up the operation, consider using
810         "Set presentation parameters and sub-shapes from arguments" option in
811         a dialog of geometrical operation used to create the new geometry.
812
813         Parameters:
814                 sourceMesh: the mesh to copy definition of.
815                 newGeom: the new geomtry.
816                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
817                 toCopyGroups: to create groups in the new mesh.
818                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
819                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
820                                 *sourceMesh*.
821         Returns:
822                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
823                 *invalidEntries* are study entries of objects whose
824                 counterparts are not found in the *newGeom*, followed by entries
825                 of mesh sub-objects that are invalid because they depend on a not found
826                 preceeding sub-shape
827         """
828         if isinstance( sourceMesh, Mesh ):
829             sourceMesh = sourceMesh.GetMesh()
830
831         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
832            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
833                                                      toCopyGroups,
834                                                      toReuseHypotheses,
835                                                      toCopyElements)
836         return ( ok, Mesh(self, self.geompyD, newMesh),
837                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
838
839     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
840         """
841         Return IDs of sub-shapes
842
843         Parameters:
844                 theMainObject (GEOM.GEOM_Object): a shape
845                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
846         Returns:
847                 the list of integer values
848         """
849
850         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
851
852     def GetPattern(self):
853         """
854         Create a pattern mapper.
855
856         Returns:
857                 an instance of :class:`SMESH.SMESH_Pattern`
858
859         :ref:`Example of Patterns usage <tui_pattern_mapping>`
860         """
861
862         return SMESH._objref_SMESH_Gen.GetPattern(self)
863
864     def SetBoundaryBoxSegmentation(self, nbSegments):
865         """
866         Set number of segments per diagonal of boundary box of geometry, by which
867         default segment length of appropriate 1D hypotheses is defined in GUI.
868         Default value is 10.
869         """
870
871         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
872
873     # Filtering. Auxiliary functions:
874     # ------------------------------
875
876     def GetEmptyCriterion(self):
877         """
878         Create an empty criterion
879
880         Returns:
881                 :class:`SMESH.Filter.Criterion`
882         """
883
884         Type = self.EnumToLong(FT_Undefined)
885         Compare = self.EnumToLong(FT_Undefined)
886         Threshold = 0
887         ThresholdStr = ""
888         ThresholdID = ""
889         UnaryOp = self.EnumToLong(FT_Undefined)
890         BinaryOp = self.EnumToLong(FT_Undefined)
891         Tolerance = 1e-07
892         TypeOfElement = ALL
893         Precision = -1 ##@1e-07
894         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
895                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
896
897     def GetCriterion(self,elementType,
898                      CritType,
899                      Compare = FT_EqualTo,
900                      Threshold="",
901                      UnaryOp=FT_Undefined,
902                      BinaryOp=FT_Undefined,
903                      Tolerance=1e-07):
904         """
905         Create a criterion by the given parameters
906         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
907
908         Parameters:
909                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
910                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
911                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
912                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
913                 Threshold: the threshold value (range of ids as string, shape, numeric)
914                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
915                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
916                         SMESH.FT_Undefined
917                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
918                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
919
920         Returns:
921                 :class:`SMESH.Filter.Criterion`
922
923         Example: :ref:`combining_filters`
924         """
925
926         if not CritType in SMESH.FunctorType._items:
927             raise TypeError("CritType should be of SMESH.FunctorType")
928         aCriterion               = self.GetEmptyCriterion()
929         aCriterion.TypeOfElement = elementType
930         aCriterion.Type          = self.EnumToLong(CritType)
931         aCriterion.Tolerance     = Tolerance
932
933         aThreshold = Threshold
934
935         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
936             aCriterion.Compare = self.EnumToLong(Compare)
937         elif Compare == "=" or Compare == "==":
938             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
939         elif Compare == "<":
940             aCriterion.Compare = self.EnumToLong(FT_LessThan)
941         elif Compare == ">":
942             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
943         elif Compare != FT_Undefined:
944             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
945             aThreshold = Compare
946
947         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
948                         FT_BelongToCylinder, FT_LyingOnGeom]:
949             # Check that Threshold is GEOM object
950             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
951                 aCriterion.ThresholdStr = GetName(aThreshold)
952                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
953                 if not aCriterion.ThresholdID:
954                     name = aCriterion.ThresholdStr
955                     if not name:
956                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
957                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
958             # or a name of GEOM object
959             elif isinstance( aThreshold, str ):
960                 aCriterion.ThresholdStr = aThreshold
961             else:
962                 raise TypeError("The Threshold should be a shape.")
963             if isinstance(UnaryOp,float):
964                 aCriterion.Tolerance = UnaryOp
965                 UnaryOp = FT_Undefined
966                 pass
967         elif CritType == FT_BelongToMeshGroup:
968             # Check that Threshold is a group
969             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
970                 if aThreshold.GetType() != elementType:
971                     raise ValueError("Group type mismatches Element type")
972                 aCriterion.ThresholdStr = aThreshold.GetName()
973                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
974                 study = salome.myStudy
975                 if study:
976                     so = study.FindObjectIOR( aCriterion.ThresholdID )
977                     if so:
978                         entry = so.GetID()
979                         if entry:
980                             aCriterion.ThresholdID = entry
981             else:
982                 raise TypeError("The Threshold should be a Mesh Group")
983         elif CritType == FT_RangeOfIds:
984             # Check that Threshold is string
985             if isinstance(aThreshold, str):
986                 aCriterion.ThresholdStr = aThreshold
987             else:
988                 raise TypeError("The Threshold should be a string.")
989         elif CritType == FT_CoplanarFaces:
990             # Check the Threshold
991             if isinstance(aThreshold, int):
992                 aCriterion.ThresholdID = str(aThreshold)
993             elif isinstance(aThreshold, str):
994                 ID = int(aThreshold)
995                 if ID < 1:
996                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
997                 aCriterion.ThresholdID = aThreshold
998             else:
999                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
1000         elif CritType == FT_ConnectedElements:
1001             # Check the Threshold
1002             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1003                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1004                 if not aCriterion.ThresholdID:
1005                     name = aThreshold.GetName()
1006                     if not name:
1007                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1008                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1009             elif isinstance(aThreshold, int): # node id
1010                 aCriterion.Threshold = aThreshold
1011             elif isinstance(aThreshold, list): # 3 point coordinates
1012                 if len( aThreshold ) < 3:
1013                     raise ValueError("too few point coordinates, must be 3")
1014                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1015             elif isinstance(aThreshold, str):
1016                 if aThreshold.isdigit():
1017                     aCriterion.Threshold = aThreshold # node id
1018                 else:
1019                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1020             else:
1021                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1022                       "or a list of point coordinates and not '%s'"%aThreshold)
1023         elif CritType == FT_ElemGeomType:
1024             # Check the Threshold
1025             try:
1026                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1027                 assert( aThreshold in SMESH.GeometryType._items )
1028             except:
1029                 if isinstance(aThreshold, int):
1030                     aCriterion.Threshold = aThreshold
1031                 else:
1032                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1033                 pass
1034             pass
1035         elif CritType == FT_EntityType:
1036             # Check the Threshold
1037             try:
1038                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1039                 assert( aThreshold in SMESH.EntityType._items )
1040             except:
1041                 if isinstance(aThreshold, int):
1042                     aCriterion.Threshold = aThreshold
1043                 else:
1044                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1045                 pass
1046             pass
1047
1048         elif CritType == FT_GroupColor:
1049             # Check the Threshold
1050             try:
1051                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1052             except:
1053                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1054             pass
1055         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1056                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1057                           FT_BareBorderFace, FT_BareBorderVolume,
1058                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1059                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1060             # At this point the Threshold is unnecessary
1061             if aThreshold ==  FT_LogicalNOT:
1062                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1063             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1064                 aCriterion.BinaryOp = aThreshold
1065         else:
1066             # Check Threshold
1067             try:
1068                 aThreshold = float(aThreshold)
1069                 aCriterion.Threshold = aThreshold
1070             except:
1071                 raise TypeError("The Threshold should be a number.")
1072                 return None
1073
1074         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1075             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1076
1077         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1078             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1079
1080         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1081             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1082
1083         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1084             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1085
1086         return aCriterion
1087
1088     def GetFilter(self,elementType,
1089                   CritType=FT_Undefined,
1090                   Compare=FT_EqualTo,
1091                   Threshold="",
1092                   UnaryOp=FT_Undefined,
1093                   Tolerance=1e-07,
1094                   mesh=None):
1095         """
1096         Create a filter with the given parameters
1097
1098         Parameters:
1099                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1100                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1101                         Note that the items starting from FT_LessThan are not suitable for CritType.
1102                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1103                 Threshold: the threshold value (range of ids as string, shape, numeric)
1104                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1105                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1106                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1107                 mesh: the mesh to initialize the filter with
1108
1109         Returns:
1110                 :class:`SMESH.Filter`
1111
1112         Examples:
1113                See :doc:`Filters usage examples <tui_filters>`
1114         """
1115
1116         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1117         aFilterMgr = self.CreateFilterManager()
1118         aFilter = aFilterMgr.CreateFilter()
1119         aCriteria = []
1120         aCriteria.append(aCriterion)
1121         aFilter.SetCriteria(aCriteria)
1122         if mesh:
1123             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1124             else                       : aFilter.SetMesh( mesh )
1125         aFilterMgr.UnRegister()
1126         return aFilter
1127
1128     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1129         """
1130         Create a filter from criteria
1131
1132         Parameters:
1133                 criteria: a list of :class:`SMESH.Filter.Criterion`
1134                 binOp: binary operator used when binary operator of criteria is undefined
1135
1136         Returns:
1137                 :class:`SMESH.Filter`
1138
1139         Examples:
1140                See :doc:`Filters usage examples <tui_filters>`
1141         """
1142
1143         for i in range( len( criteria ) - 1 ):
1144             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1145                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1146         aFilterMgr = self.CreateFilterManager()
1147         aFilter = aFilterMgr.CreateFilter()
1148         aFilter.SetCriteria(criteria)
1149         aFilterMgr.UnRegister()
1150         return aFilter
1151
1152     def GetFunctor(self,theCriterion):
1153         """
1154         Create a numerical functor by its type
1155
1156         Parameters:
1157                 theCriterion (SMESH.FunctorType): functor type.
1158                         Note that not all items correspond to numerical functors.
1159
1160         Returns:
1161                 :class:`SMESH.NumericalFunctor`
1162         """
1163
1164         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1165             return theCriterion
1166         aFilterMgr = self.CreateFilterManager()
1167         functor = None
1168         if theCriterion == FT_AspectRatio:
1169             functor = aFilterMgr.CreateAspectRatio()
1170         elif theCriterion == FT_AspectRatio3D:
1171             functor = aFilterMgr.CreateAspectRatio3D()
1172         elif theCriterion == FT_Warping:
1173             functor = aFilterMgr.CreateWarping()
1174         elif theCriterion == FT_MinimumAngle:
1175             functor = aFilterMgr.CreateMinimumAngle()
1176         elif theCriterion == FT_Taper:
1177             functor = aFilterMgr.CreateTaper()
1178         elif theCriterion == FT_Skew:
1179             functor = aFilterMgr.CreateSkew()
1180         elif theCriterion == FT_Area:
1181             functor = aFilterMgr.CreateArea()
1182         elif theCriterion == FT_Volume3D:
1183             functor = aFilterMgr.CreateVolume3D()
1184         elif theCriterion == FT_MaxElementLength2D:
1185             functor = aFilterMgr.CreateMaxElementLength2D()
1186         elif theCriterion == FT_MaxElementLength3D:
1187             functor = aFilterMgr.CreateMaxElementLength3D()
1188         elif theCriterion == FT_MultiConnection:
1189             functor = aFilterMgr.CreateMultiConnection()
1190         elif theCriterion == FT_MultiConnection2D:
1191             functor = aFilterMgr.CreateMultiConnection2D()
1192         elif theCriterion == FT_Length:
1193             functor = aFilterMgr.CreateLength()
1194         elif theCriterion == FT_Length2D:
1195             functor = aFilterMgr.CreateLength2D()
1196         elif theCriterion == FT_Length3D:
1197             functor = aFilterMgr.CreateLength3D()
1198         elif theCriterion == FT_Deflection2D:
1199             functor = aFilterMgr.CreateDeflection2D()
1200         elif theCriterion == FT_NodeConnectivityNumber:
1201             functor = aFilterMgr.CreateNodeConnectivityNumber()
1202         elif theCriterion == FT_BallDiameter:
1203             functor = aFilterMgr.CreateBallDiameter()
1204         else:
1205             print("Error: given parameter is not numerical functor type.")
1206         aFilterMgr.UnRegister()
1207         return functor
1208
1209     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1210         """
1211         Create hypothesis
1212
1213         Parameters:
1214                 theHType (string): mesh hypothesis type
1215                 theLibName (string): mesh plug-in library name
1216
1217         Returns:
1218                 created hypothesis instance
1219         """
1220         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1221
1222         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1223             return hyp
1224
1225         # wrap hypothesis methods
1226         for meth_name in dir( hyp.__class__ ):
1227             if not meth_name.startswith("Get") and \
1228                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1229                 method = getattr ( hyp.__class__, meth_name )
1230                 if callable(method):
1231                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1232
1233         return hyp
1234
1235     def GetMeshInfo(self, obj):
1236         """
1237         Get the mesh statistic.
1238
1239         Returns:
1240                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1241         """
1242
1243         if isinstance( obj, Mesh ):
1244             obj = obj.GetMesh()
1245         d = {}
1246         if hasattr(obj, "GetMeshInfo"):
1247             values = obj.GetMeshInfo()
1248             for i in range(SMESH.Entity_Last._v):
1249                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1250             pass
1251         return d
1252
1253     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1254         """
1255         Get minimum distance between two objects
1256
1257         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1258         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1259
1260         Parameters:
1261                 src1 (SMESH.SMESH_IDSource): first source object
1262                 src2 (SMESH.SMESH_IDSource): second source object
1263                 id1 (int): node/element id from the first source
1264                 id2 (int): node/element id from the second (or first) source
1265                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1266                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1267
1268         Returns:
1269                 minimum distance value
1270
1271         See also: 
1272                 :meth:`GetMinDistance`
1273         """
1274
1275         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1276         if result is None:
1277             result = 0.0
1278         else:
1279             result = result.value
1280         return result
1281
1282     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1283         """
1284         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1285
1286         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1287         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1288
1289         Parameters:
1290                 src1 (SMESH.SMESH_IDSource): first source object
1291                 src2 (SMESH.SMESH_IDSource): second source object
1292                 id1 (int): node/element id from the first source
1293                 id2 (int): node/element id from the second (or first) source
1294                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1295                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1296
1297         Returns:
1298                 :class:`SMESH.Measure` structure or None if input data is invalid
1299         See also: 
1300                 :meth:`MinDistance`
1301         """
1302
1303         if isinstance(src1, Mesh): src1 = src1.mesh
1304         if isinstance(src2, Mesh): src2 = src2.mesh
1305         if src2 is None and id2 != 0: src2 = src1
1306         if not hasattr(src1, "_narrow"): return None
1307         src1 = src1._narrow(SMESH.SMESH_IDSource)
1308         if not src1: return None
1309         unRegister = genObjUnRegister()
1310         if id1 != 0:
1311             m = src1.GetMesh()
1312             e = m.GetMeshEditor()
1313             if isElem1:
1314                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1315             else:
1316                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1317             unRegister.set( src1 )
1318             pass
1319         if hasattr(src2, "_narrow"):
1320             src2 = src2._narrow(SMESH.SMESH_IDSource)
1321             if src2 and id2 != 0:
1322                 m = src2.GetMesh()
1323                 e = m.GetMeshEditor()
1324                 if isElem2:
1325                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1326                 else:
1327                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1328                 unRegister.set( src2 )
1329                 pass
1330             pass
1331         aMeasurements = self.CreateMeasurements()
1332         unRegister.set( aMeasurements )
1333         result = aMeasurements.MinDistance(src1, src2)
1334         return result
1335
1336     def BoundingBox(self, objects):
1337         """
1338         Get bounding box of the specified object(s)
1339
1340         Parameters:
1341                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1342
1343         Returns:
1344                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1345
1346         See also: 
1347                :meth:`GetBoundingBox`
1348         """
1349
1350         result = self.GetBoundingBox(objects)
1351         if result is None:
1352             result = (0.0,)*6
1353         else:
1354             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1355         return result
1356
1357     def GetBoundingBox(self, objects):
1358         """
1359         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1360
1361         Parameters:
1362                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1363
1364         Returns:
1365                 :class:`SMESH.Measure` structure
1366
1367         See also: 
1368                 :meth:`BoundingBox`
1369         """
1370
1371         if isinstance(objects, tuple):
1372             objects = list(objects)
1373         if not isinstance(objects, list):
1374             objects = [objects]
1375         srclist = []
1376         for o in objects:
1377             if isinstance(o, Mesh):
1378                 srclist.append(o.mesh)
1379             elif hasattr(o, "_narrow"):
1380                 src = o._narrow(SMESH.SMESH_IDSource)
1381                 if src: srclist.append(src)
1382                 pass
1383             pass
1384         aMeasurements = self.CreateMeasurements()
1385         result = aMeasurements.BoundingBox(srclist)
1386         aMeasurements.UnRegister()
1387         return result
1388
1389     def GetLength(self, obj):
1390         """
1391         Get sum of lengths of all 1D elements in the mesh object.
1392
1393         Parameters:
1394                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1395
1396         Returns:
1397                 sum of lengths of all 1D elements
1398         """
1399
1400         if isinstance(obj, Mesh): obj = obj.mesh
1401         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1402         aMeasurements = self.CreateMeasurements()
1403         value = aMeasurements.Length(obj)
1404         aMeasurements.UnRegister()
1405         return value
1406
1407     def GetArea(self, obj):
1408         """
1409         Get sum of areas of all 2D elements in the mesh object.
1410
1411         Parameters:
1412                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1413
1414         Returns:
1415                 sum of areas of all 2D elements
1416         """
1417
1418         if isinstance(obj, Mesh): obj = obj.mesh
1419         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1420         aMeasurements = self.CreateMeasurements()
1421         value = aMeasurements.Area(obj)
1422         aMeasurements.UnRegister()
1423         return value
1424
1425     def GetVolume(self, obj):
1426         """
1427         Get sum of volumes of all 3D elements in the mesh object.
1428
1429         Parameters:
1430                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1431
1432         Returns:
1433                 sum of volumes of all 3D elements
1434         """
1435
1436         if isinstance(obj, Mesh): obj = obj.mesh
1437         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1438         aMeasurements = self.CreateMeasurements()
1439         value = aMeasurements.Volume(obj)
1440         aMeasurements.UnRegister()
1441         return value
1442
1443     def GetGravityCenter(self, obj):
1444         """
1445         Get gravity center of all nodes of a mesh object.
1446         
1447         Parameters:            
1448                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1449
1450         Returns:        
1451                 Three components of the gravity center (x,y,z)
1452
1453         See also: 
1454                 :meth:`Mesh.BaryCenter`
1455         """
1456         if isinstance(obj, Mesh): obj = obj.mesh
1457         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1458         aMeasurements = self.CreateMeasurements()
1459         pointStruct = aMeasurements.GravityCenter(obj)
1460         aMeasurements.UnRegister()
1461         return pointStruct.x, pointStruct.y, pointStruct.z
1462
1463     def GetAngle(self, p1, p2, p3 ):
1464         """
1465         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1466
1467         Parameters:            
1468                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
1469                           or list [x,y,z]
1470
1471         Returns:        
1472             Angle in radians
1473         """
1474         if isinstance( p1, list ): p1 = PointStruct(*p1)
1475         if isinstance( p2, list ): p2 = PointStruct(*p2)
1476         if isinstance( p3, list ): p3 = PointStruct(*p3)
1477
1478         aMeasurements = self.CreateMeasurements()
1479         angle = aMeasurements.Angle(p1,p2,p3)
1480         aMeasurements.UnRegister()
1481
1482         return angle
1483
1484
1485     pass # end of class smeshBuilder
1486
1487 import omniORB
1488 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1489 """Registering the new proxy for SMESH.SMESH_Gen"""
1490
1491
1492 def New( instance=None, instanceGeom=None):
1493     """
1494     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1495     interface to create or load meshes.
1496
1497     Typical use is::
1498
1499         import salome
1500         salome.salome_init()
1501         from salome.smesh import smeshBuilder
1502         smesh = smeshBuilder.New()
1503
1504     Parameters:
1505         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1506         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1507     Returns:
1508         :class:`smeshBuilder` instance
1509     """
1510     global engine
1511     global smeshInst
1512     global doLcc
1513     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1514         import sys
1515         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1516         instance = None
1517     engine = instance
1518     if engine is None:
1519         doLcc = True
1520     smeshInst = smeshBuilder()
1521     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1522     smeshInst.init_smesh(instanceGeom)
1523     return smeshInst
1524
1525
1526 # Public class: Mesh
1527 # ==================
1528
1529
1530 class Mesh(metaclass = MeshMeta):
1531     """
1532     This class allows defining and managing a mesh.
1533     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1534     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1535     new nodes and elements and by changing the existing entities), to get information
1536     about a mesh and to export a mesh in different formats.
1537     """    
1538
1539     geom = 0
1540     mesh = 0
1541     editor = 0
1542
1543     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1544
1545         """
1546         Constructor
1547
1548         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1549         sets the GUI name of this mesh to *name*.
1550
1551         Parameters:
1552                 smeshpyD: an instance of smeshBuilder class
1553                 geompyD: an instance of geomBuilder class
1554                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1555                 name: Study name of the mesh
1556         """
1557
1558         self.smeshpyD = smeshpyD
1559         self.geompyD = geompyD
1560         if obj is None:
1561             obj = 0
1562         objHasName = False
1563         if obj != 0:
1564             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1565                 self.geom = obj
1566                 objHasName = True
1567                 # publish geom of mesh (issue 0021122)
1568                 if not self.geom.GetStudyEntry():
1569                     objHasName = False
1570                     geompyD.init_geom()
1571                     if name:
1572                         geo_name = name + " shape"
1573                     else:
1574                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1575                     geompyD.addToStudy( self.geom, geo_name )
1576                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1577
1578             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1579                 self.SetMesh(obj)
1580         else:
1581             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1582         if name:
1583             self.smeshpyD.SetName(self.mesh, name)
1584         elif objHasName:
1585             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1586
1587         if not self.geom:
1588             self.geom = self.mesh.GetShapeToMesh()
1589
1590         self.editor   = self.mesh.GetMeshEditor()
1591         self.functors = [None] * SMESH.FT_Undefined._v
1592
1593         # set self to algoCreator's
1594         for attrName in dir(self):
1595             attr = getattr( self, attrName )
1596             if isinstance( attr, algoCreator ):
1597                 setattr( self, attrName, attr.copy( self ))
1598                 pass
1599             pass
1600         pass
1601
1602     def __del__(self):
1603         """
1604         Destructor. Clean-up resources
1605         """
1606         if self.mesh:
1607             #self.mesh.UnRegister()
1608             pass
1609         pass
1610
1611     def SetMesh(self, theMesh):
1612         """
1613         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1614
1615         Parameters:
1616                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1617         """
1618
1619
1620         # do not call Register() as this prevents mesh servant deletion at closing study
1621         #if self.mesh: self.mesh.UnRegister()
1622         self.mesh = theMesh
1623         if self.mesh:
1624             #self.mesh.Register()
1625             self.geom = self.mesh.GetShapeToMesh()
1626         pass
1627
1628     def GetMesh(self):
1629         """
1630         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1631
1632         Returns:
1633                 a :class:`SMESH.SMESH_Mesh` object
1634         """
1635
1636         return self.mesh
1637
1638     def GetEngine(self):
1639         """
1640         Return a smeshBuilder instance created this mesh
1641         """
1642         return self.smeshpyD
1643
1644     def GetGeomEngine(self):
1645         """
1646         Return a geomBuilder instance
1647         """
1648         return self.geompyD
1649
1650     def GetName(self):
1651         """
1652         Get the name of the mesh
1653
1654         Returns:
1655                 the name of the mesh as a string
1656         """
1657
1658         name = GetName(self.GetMesh())
1659         return name
1660
1661     def SetName(self, name):
1662         """
1663         Set a name to the mesh
1664
1665         Parameters:
1666                 name: a new name of the mesh
1667         """
1668
1669         self.smeshpyD.SetName(self.GetMesh(), name)
1670
1671     def GetSubMesh(self, geom, name):
1672         """
1673         Get a sub-mesh object associated to a *geom* geometrical object.
1674
1675         Parameters:
1676                 geom: a geometrical object (shape)
1677                 name: a name for the sub-mesh in the Object Browser
1678
1679         Returns:
1680                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1681                 which lies on the given shape
1682
1683         Note:
1684                 A sub-mesh is implicitly created when a sub-shape is specified at
1685                 creating an algorithm, for example::
1686
1687                    algo1D = mesh.Segment(geom=Edge_1)
1688
1689                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1690                 The created sub-mesh can be retrieved from the algorithm::
1691
1692                    submesh = algo1D.GetSubMesh()
1693         """
1694
1695         AssureGeomPublished( self, geom, name )
1696         submesh = self.mesh.GetSubMesh( geom, name )
1697         return submesh
1698
1699     def GetShape(self):
1700         """
1701         Return the shape associated to the mesh
1702
1703         Returns:
1704                 a GEOM_Object
1705         """
1706
1707         return self.geom
1708
1709     def SetShape(self, geom):
1710         """
1711         Associate the given shape to the mesh (entails the recreation of the mesh)
1712
1713         Parameters:
1714                 geom: the shape to be meshed (GEOM_Object)
1715         """
1716
1717         self.mesh = self.smeshpyD.CreateMesh(geom)
1718
1719     def HasShapeToMesh(self):
1720         """
1721         Return ``True`` if this mesh is based on geometry
1722         """
1723         return self.mesh.HasShapeToMesh()
1724
1725     def Load(self):
1726         """
1727         Load mesh from the study after opening the study
1728         """
1729         self.mesh.Load()
1730
1731     def IsReadyToCompute(self, theSubObject):
1732         """
1733         Return true if the hypotheses are defined well
1734
1735         Parameters:
1736                 theSubObject: a sub-shape of a mesh shape
1737
1738         Returns:
1739                 True or False
1740         """
1741
1742         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1743
1744     def GetAlgoState(self, theSubObject):
1745         """
1746         Return errors of hypotheses definition.
1747         The list of errors is empty if everything is OK.
1748
1749         Parameters:
1750                 theSubObject: a sub-shape of a mesh shape
1751
1752         Returns:
1753                 a list of errors
1754         """
1755
1756         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1757
1758     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1759         """
1760         Return a geometrical object on which the given element was built.
1761         The returned geometrical object, if not nil, is either found in the
1762         study or published by this method with the given name
1763
1764         Parameters:
1765             theElementID: the id of the mesh element
1766             theGeomName: the user-defined name of the geometrical object
1767
1768         Returns:
1769             GEOM.GEOM_Object instance
1770         """
1771
1772         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1773
1774     def MeshDimension(self):
1775         """
1776         Return the mesh dimension depending on the dimension of the underlying shape
1777         or, if the mesh is not based on any shape, basing on deimension of elements
1778
1779         Returns:
1780                 mesh dimension as an integer value [0,3]
1781         """
1782
1783         if self.mesh.HasShapeToMesh():
1784             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1785             if len( shells ) > 0 :
1786                 return 3
1787             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1788                 return 2
1789             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1790                 return 1
1791             else:
1792                 return 0;
1793         else:
1794             if self.NbVolumes() > 0: return 3
1795             if self.NbFaces()   > 0: return 2
1796             if self.NbEdges()   > 0: return 1
1797         return 0
1798
1799     def Evaluate(self, geom=0):
1800         """
1801         Evaluate size of prospective mesh on a shape
1802
1803         Returns:
1804                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1805                 To know predicted number of e.g. edges, inquire it this way::
1806
1807                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1808         """
1809
1810         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1811             if self.geom == 0:
1812                 geom = self.mesh.GetShapeToMesh()
1813             else:
1814                 geom = self.geom
1815         return self.smeshpyD.Evaluate(self.mesh, geom)
1816
1817
1818     def Compute(self, geom=0, discardModifs=False, refresh=False):
1819         """
1820         Compute the mesh and return the status of the computation
1821
1822         Parameters:
1823                 geom: geomtrical shape on which mesh data should be computed
1824                 discardModifs: if True and the mesh has been edited since
1825                         a last total re-compute and that may prevent successful partial re-compute,
1826                         then the mesh is cleaned before Compute()
1827                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1828
1829         Returns:
1830                 True or False
1831         """
1832
1833         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1834             if self.geom == 0:
1835                 geom = self.mesh.GetShapeToMesh()
1836             else:
1837                 geom = self.geom
1838         ok = False
1839         try:
1840             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1841                 self.mesh.Clear()
1842             ok = self.smeshpyD.Compute(self.mesh, geom)
1843         except SALOME.SALOME_Exception as ex:
1844             print("Mesh computation failed, exception caught:")
1845             print("    ", ex.details.text)
1846         except:
1847             import traceback
1848             print("Mesh computation failed, exception caught:")
1849             traceback.print_exc()
1850         if True:#not ok:
1851             allReasons = ""
1852
1853             # Treat compute errors
1854             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1855             shapeText = ""
1856             for err in computeErrors:
1857                 if self.mesh.HasShapeToMesh():
1858                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1859                 errText = ""
1860                 stdErrors = ["OK",                   #COMPERR_OK
1861                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1862                              "std::exception",       #COMPERR_STD_EXCEPTION
1863                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1864                              "..",                   #COMPERR_SLM_EXCEPTION
1865                              "Unknown exception",    #COMPERR_EXCEPTION
1866                              "Memory allocation problem", #COMPERR_MEMORY_PB
1867                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1868                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1869                              "Warning",              #COMPERR_WARNING
1870                              "Computation cancelled",#COMPERR_CANCELED
1871                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1872                 if err.code > 0:
1873                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1874                 else:
1875                     errText = "code %s" % -err.code
1876                 if errText: errText += ". "
1877                 errText += err.comment
1878                 if allReasons: allReasons += "\n"
1879                 if ok:
1880                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1881                 else:
1882                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1883                 pass
1884
1885             # Treat hyp errors
1886             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1887             for err in errors:
1888                 if err.isGlobalAlgo:
1889                     glob = "global"
1890                 else:
1891                     glob = "local"
1892                     pass
1893                 dim = err.algoDim
1894                 name = err.algoName
1895                 if len(name) == 0:
1896                     reason = '%s %sD algorithm is missing' % (glob, dim)
1897                 elif err.state == HYP_MISSING:
1898                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1899                               % (glob, dim, name, dim))
1900                 elif err.state == HYP_NOTCONFORM:
1901                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1902                 elif err.state == HYP_BAD_PARAMETER:
1903                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1904                               % ( glob, dim, name ))
1905                 elif err.state == HYP_BAD_GEOMETRY:
1906                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1907                               'geometry' % ( glob, dim, name ))
1908                 elif err.state == HYP_HIDDEN_ALGO:
1909                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1910                               'algorithm of upper dimension generating %sD mesh'
1911                               % ( glob, dim, name, glob, dim ))
1912                 else:
1913                     reason = ("For unknown reason. "
1914                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1915                     pass
1916                 if allReasons: allReasons += "\n"
1917                 allReasons += "-  " + reason
1918                 pass
1919             if not ok or allReasons != "":
1920                 msg = '"' + GetName(self.mesh) + '"'
1921                 if ok: msg += " has been computed with warnings"
1922                 else:  msg += " has not been computed"
1923                 if allReasons != "": msg += ":"
1924                 else:                msg += "."
1925                 print(msg)
1926                 print(allReasons)
1927             pass
1928         if salome.sg.hasDesktop():
1929             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1930                 if refresh: salome.sg.updateObjBrowser()
1931
1932         return ok
1933
1934     def GetComputeErrors(self, shape=0 ):
1935         """
1936         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1937         """
1938
1939         if shape == 0:
1940             shape = self.mesh.GetShapeToMesh()
1941         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1942
1943     def GetSubShapeName(self, subShapeID ):
1944         """
1945         Return a name of a sub-shape by its ID.
1946         Possible variants (for *subShapeID* == 3):
1947
1948                 - **"Face_12"** - published sub-shape
1949                 - **FACE #3** - not published sub-shape
1950                 - **sub-shape #3** - invalid sub-shape ID
1951                 - **#3** - error in this function
1952
1953         Parameters:
1954                 subShapeID: a unique ID of a sub-shape
1955
1956         Returns:
1957                 a string describing the sub-shape
1958
1959         """
1960
1961         if not self.mesh.HasShapeToMesh():
1962             return ""
1963         try:
1964             shapeText = ""
1965             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1966             s = salome.myStudy
1967             mainSO = s.FindObjectIOR(mainIOR)
1968             if mainSO:
1969                 if subShapeID == 1:
1970                     shapeText = '"%s"' % mainSO.GetName()
1971                 subIt = s.NewChildIterator(mainSO)
1972                 while subIt.More():
1973                     subSO = subIt.Value()
1974                     subIt.Next()
1975                     obj = subSO.GetObject()
1976                     if not obj: continue
1977                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1978                     if not go: continue
1979                     try:
1980                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1981                     except:
1982                         continue
1983                     if ids == subShapeID:
1984                         shapeText = '"%s"' % subSO.GetName()
1985                         break
1986             if not shapeText:
1987                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1988                 if shape:
1989                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1990                 else:
1991                     shapeText = 'sub-shape #%s' % (subShapeID)
1992         except:
1993             shapeText = "#%s" % (subShapeID)
1994         return shapeText
1995
1996     def GetFailedShapes(self, publish=False):
1997         """
1998         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1999         error of an algorithm
2000
2001         Parameters:
2002                 publish: if *True*, the returned groups will be published in the study
2003
2004         Returns:
2005                 a list of GEOM groups each named after a failed algorithm
2006         """
2007
2008
2009         algo2shapes = {}
2010         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2011         for err in computeErrors:
2012             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2013             if not shape: continue
2014             if err.algoName in algo2shapes:
2015                 algo2shapes[ err.algoName ].append( shape )
2016             else:
2017                 algo2shapes[ err.algoName ] = [ shape ]
2018             pass
2019
2020         groups = []
2021         for algoName, shapes in list(algo2shapes.items()):
2022             while shapes:
2023                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2024                 otherTypeShapes = []
2025                 sameTypeShapes  = []
2026                 group = self.geompyD.CreateGroup( self.geom, groupType )
2027                 for shape in shapes:
2028                     if shape.GetShapeType() == shapes[0].GetShapeType():
2029                         sameTypeShapes.append( shape )
2030                     else:
2031                         otherTypeShapes.append( shape )
2032                 self.geompyD.UnionList( group, sameTypeShapes )
2033                 if otherTypeShapes:
2034                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2035                 else:
2036                     group.SetName( algoName )
2037                 groups.append( group )
2038                 shapes = otherTypeShapes
2039             pass
2040         if publish:
2041             for group in groups:
2042                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2043         return groups
2044
2045     def GetMeshOrder(self):
2046         """
2047         Return sub-mesh objects list in meshing order
2048
2049         Returns:
2050                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2051         """
2052
2053         return self.mesh.GetMeshOrder()
2054
2055     def SetMeshOrder(self, submeshes):
2056         """
2057         Set order in which concurrent sub-meshes should be meshed
2058
2059         Parameters:
2060                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2061         """
2062
2063         return self.mesh.SetMeshOrder(submeshes)
2064
2065     def Clear(self, refresh=False):
2066         """
2067         Remove all nodes and elements generated on geometry. Imported elements remain.
2068
2069         Parameters:
2070                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2071         """
2072
2073         self.mesh.Clear()
2074         if ( salome.sg.hasDesktop() ):
2075             if refresh: salome.sg.updateObjBrowser()
2076
2077     def ClearSubMesh(self, geomId, refresh=False):
2078         """
2079         Remove all nodes and elements of indicated shape
2080
2081         Parameters:
2082                 geomId: the ID of a sub-shape to remove elements on
2083                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2084         """
2085
2086         self.mesh.ClearSubMesh(geomId)
2087         if salome.sg.hasDesktop():
2088             if refresh: salome.sg.updateObjBrowser()
2089
2090     def AutomaticTetrahedralization(self, fineness=0):
2091         """
2092         Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2093
2094         Parameters:
2095                 fineness: [0.0,1.0] defines mesh fineness
2096
2097         Returns:
2098                 True or False
2099         """
2100
2101         dim = self.MeshDimension()
2102         # assign hypotheses
2103         self.RemoveGlobalHypotheses()
2104         self.Segment().AutomaticLength(fineness)
2105         if dim > 1 :
2106             self.Triangle().LengthFromEdges()
2107             pass
2108         if dim > 2 :
2109             self.Tetrahedron()
2110             pass
2111         return self.Compute()
2112
2113     def AutomaticHexahedralization(self, fineness=0):
2114         """
2115         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2116
2117         Parameters:
2118                 fineness: [0.0, 1.0] defines mesh fineness
2119
2120         Returns:
2121                 True or False
2122         """
2123
2124         dim = self.MeshDimension()
2125         # assign the hypotheses
2126         self.RemoveGlobalHypotheses()
2127         self.Segment().AutomaticLength(fineness)
2128         if dim > 1 :
2129             self.Quadrangle()
2130             pass
2131         if dim > 2 :
2132             self.Hexahedron()
2133             pass
2134         return self.Compute()
2135
2136     def AddHypothesis(self, hyp, geom=0):
2137         """
2138         Assign a hypothesis
2139
2140         Parameters:
2141                 hyp: a hypothesis to assign
2142                 geom: a subhape of mesh geometry
2143
2144         Returns:
2145                 :class:`SMESH.Hypothesis_Status`
2146         """
2147
2148         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2149             hyp, geom = geom, hyp
2150         if isinstance( hyp, Mesh_Algorithm ):
2151             hyp = hyp.GetAlgorithm()
2152             pass
2153         if not geom:
2154             geom = self.geom
2155             if not geom:
2156                 geom = self.mesh.GetShapeToMesh()
2157             pass
2158         isApplicable = True
2159         if self.mesh.HasShapeToMesh():
2160             hyp_type     = hyp.GetName()
2161             lib_name     = hyp.GetLibName()
2162             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2163             # if checkAll and geom:
2164             #     checkAll = geom.GetType() == 37
2165             checkAll     = False
2166             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2167         if isApplicable:
2168             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2169             status = self.mesh.AddHypothesis(geom, hyp)
2170         else:
2171             status = HYP_BAD_GEOMETRY, ""
2172         hyp_name = GetName( hyp )
2173         geom_name = ""
2174         if geom:
2175             geom_name = geom.GetName()
2176         isAlgo = hyp._narrow( SMESH_Algo )
2177         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2178         return status
2179
2180     def IsUsedHypothesis(self, hyp, geom):
2181         """
2182         Return True if an algorithm or hypothesis is assigned to a given shape
2183
2184         Parameters:
2185                 hyp: an algorithm or hypothesis to check
2186                 geom: a subhape of mesh geometry
2187
2188         Returns:
2189                 True of False
2190         """
2191
2192         if not hyp: # or not geom
2193             return False
2194         if isinstance( hyp, Mesh_Algorithm ):
2195             hyp = hyp.GetAlgorithm()
2196             pass
2197         hyps = self.GetHypothesisList(geom)
2198         for h in hyps:
2199             if h.GetId() == hyp.GetId():
2200                 return True
2201         return False
2202
2203     def RemoveHypothesis(self, hyp, geom=0):
2204         """
2205         Unassign a hypothesis
2206
2207         Parameters:
2208                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2209                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2210
2211         Returns:
2212                 :class:`SMESH.Hypothesis_Status`
2213         """
2214
2215         if not hyp:
2216             return None
2217         if isinstance( hyp, Mesh_Algorithm ):
2218             hyp = hyp.GetAlgorithm()
2219             pass
2220         shape = geom
2221         if not shape:
2222             shape = self.geom
2223             pass
2224         if self.IsUsedHypothesis( hyp, shape ):
2225             return self.mesh.RemoveHypothesis( shape, hyp )
2226         hypName = GetName( hyp )
2227         geoName = GetName( shape )
2228         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2229         return None
2230
2231     def GetHypothesisList(self, geom):
2232         """
2233         Get the list of hypotheses added on a geometry
2234
2235         Parameters:
2236                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2237
2238         Returns:
2239                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2240         """
2241
2242         return self.mesh.GetHypothesisList( geom )
2243
2244     def RemoveGlobalHypotheses(self):
2245         """
2246         Remove all global hypotheses
2247         """
2248
2249         current_hyps = self.mesh.GetHypothesisList( self.geom )
2250         for hyp in current_hyps:
2251             self.mesh.RemoveHypothesis( self.geom, hyp )
2252             pass
2253         pass
2254     def ExportMED(self, *args, **kwargs):
2255         """
2256         Export the mesh in a file in MED format
2257         allowing to overwrite the file if it exists or add the exported data to its contents
2258
2259         Parameters:
2260                 fileName: is the file name
2261                 auto_groups (boolean): parameter for creating/not creating
2262                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2263                         the typical use is auto_groups=False.
2264                 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2265                         The minor must be between 0 and the current minor version of MED file library.
2266                         If minor is equal to -1, the minor version is not changed (default).
2267                         The major version (x, where version is x.y.z) cannot be changed.
2268                 overwrite (boolean): parameter for overwriting/not overwriting the file
2269                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2270                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2271
2272                         - 1D if all mesh nodes lie on OX coordinate axis, or
2273                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2274                         - 3D in the rest cases.
2275
2276                         If *autoDimension* is *False*, the space dimension is always 3.
2277                 fields: list of GEOM fields defined on the shape to mesh.
2278                 geomAssocFields: each character of this string means a need to export a 
2279                         corresponding field; correspondence between fields and characters 
2280                         is following:
2281
2282                         - 'v' stands for "_vertices_" field;
2283                         - 'e' stands for "_edges_" field;
2284                         - 'f' stands for "_faces_" field;
2285                         - 's' stands for "_solids_" field.
2286
2287                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2288                              close to zero within a given tolerance, the coordinate is set to zero.
2289                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2290         """
2291         # process positional arguments
2292         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2293         fileName        = args[0]
2294         auto_groups     = args[1] if len(args) > 1 else False
2295         minor           = args[2] if len(args) > 2 else -1
2296         overwrite       = args[3] if len(args) > 3 else True
2297         meshPart        = args[4] if len(args) > 4 else None
2298         autoDimension   = args[5] if len(args) > 5 else True
2299         fields          = args[6] if len(args) > 6 else []
2300         geomAssocFields = args[7] if len(args) > 7 else ''
2301         z_tolerance     = args[8] if len(args) > 8 else -1.
2302         # process keywords arguments
2303         auto_groups     = kwargs.get("auto_groups", auto_groups)
2304         minor           = kwargs.get("minor", minor)
2305         overwrite       = kwargs.get("overwrite", overwrite)
2306         meshPart        = kwargs.get("meshPart", meshPart)
2307         autoDimension   = kwargs.get("autoDimension", autoDimension)
2308         fields          = kwargs.get("fields", fields)
2309         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2310         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2311
2312         # invoke engine's function
2313         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2314             unRegister = genObjUnRegister()
2315             if isinstance( meshPart, list ):
2316                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2317                 unRegister.set( meshPart )
2318
2319             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2320             self.mesh.SetParameters(Parameters)
2321
2322             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2323                                        fields, geomAssocFields, z_tolerance)
2324         else:
2325             self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2326
2327     def ExportSAUV(self, f, auto_groups=0):
2328         """
2329         Export the mesh in a file in SAUV format
2330
2331
2332         Parameters:
2333                 f: is the file name
2334                 auto_groups: boolean parameter for creating/not creating
2335                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2336                         the typical use is auto_groups=False.
2337         """
2338
2339         self.mesh.ExportSAUV(f, auto_groups)
2340
2341     def ExportDAT(self, f, meshPart=None):
2342         """
2343         Export the mesh in a file in DAT format
2344
2345         Parameters:
2346                 f: the file name
2347                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2348         """
2349
2350         if meshPart:
2351             unRegister = genObjUnRegister()
2352             if isinstance( meshPart, list ):
2353                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2354                 unRegister.set( meshPart )
2355             self.mesh.ExportPartToDAT( meshPart, f )
2356         else:
2357             self.mesh.ExportDAT(f)
2358
2359     def ExportUNV(self, f, meshPart=None):
2360         """
2361         Export the mesh in a file in UNV format
2362
2363         Parameters:
2364                 f: the file name
2365                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2366         """
2367
2368         if meshPart:
2369             unRegister = genObjUnRegister()
2370             if isinstance( meshPart, list ):
2371                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2372                 unRegister.set( meshPart )
2373             self.mesh.ExportPartToUNV( meshPart, f )
2374         else:
2375             self.mesh.ExportUNV(f)
2376
2377     def ExportSTL(self, f, ascii=1, meshPart=None):
2378         """
2379         Export the mesh in a file in STL format
2380
2381         Parameters:
2382                 f: the file name
2383                 ascii: defines the file encoding
2384                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2385         """
2386
2387         if meshPart:
2388             unRegister = genObjUnRegister()
2389             if isinstance( meshPart, list ):
2390                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2391                 unRegister.set( meshPart )
2392             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2393         else:
2394             self.mesh.ExportSTL(f, ascii)
2395
2396     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2397         """
2398         Export the mesh in a file in CGNS format
2399
2400         Parameters:
2401                 f: is the file name
2402                 overwrite: boolean parameter for overwriting/not overwriting the file
2403                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2404                 groupElemsByType: if True all elements of same entity type are exported at ones,
2405                         else elements are exported in order of their IDs which can cause creation
2406                         of multiple cgns sections
2407         """
2408
2409         unRegister = genObjUnRegister()
2410         if isinstance( meshPart, list ):
2411             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2412             unRegister.set( meshPart )
2413         if isinstance( meshPart, Mesh ):
2414             meshPart = meshPart.mesh
2415         elif not meshPart:
2416             meshPart = self.mesh
2417         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2418
2419     def ExportGMF(self, f, meshPart=None):
2420         """
2421         Export the mesh in a file in GMF format.
2422         GMF files must have .mesh extension for the ASCII format and .meshb for
2423         the bynary format. Other extensions are not allowed.
2424
2425         Parameters:
2426                 f: is the file name
2427                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2428         """
2429
2430         unRegister = genObjUnRegister()
2431         if isinstance( meshPart, list ):
2432             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2433             unRegister.set( meshPart )
2434         if isinstance( meshPart, Mesh ):
2435             meshPart = meshPart.mesh
2436         elif not meshPart:
2437             meshPart = self.mesh
2438         self.mesh.ExportGMF(meshPart, f, True)
2439
2440     def ExportToMED(self, *args, **kwargs):
2441         """
2442         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2443         Export the mesh in a file in MED format
2444         allowing to overwrite the file if it exists or add the exported data to its contents
2445
2446         Parameters:
2447                 fileName: the file name
2448                 opt (boolean): parameter for creating/not creating
2449                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2450                 overwrite: boolean parameter for overwriting/not overwriting the file
2451                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2452
2453                         - 1D if all mesh nodes lie on OX coordinate axis, or
2454                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2455                         - 3D in the rest cases.
2456
2457                         If **autoDimension** is *False*, the space dimension is always 3.
2458         """
2459     
2460         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2461         # process positional arguments
2462         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2463         fileName      = args[0]
2464         auto_groups   = args[1] if len(args) > 1 else False
2465         overwrite     = args[2] if len(args) > 2 else True
2466         autoDimension = args[3] if len(args) > 3 else True
2467         # process keywords arguments
2468         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2469         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2470         overwrite     = kwargs.get("overwrite", overwrite)
2471         autoDimension = kwargs.get("autoDimension", autoDimension)
2472         minor = -1
2473         # invoke engine's function
2474         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2475
2476     def ExportToMEDX(self, *args, **kwargs):
2477         """
2478         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2479         Export the mesh in a file in MED format
2480
2481         Parameters:
2482                 fileName: the file name
2483                 opt (boolean): parameter for creating/not creating
2484                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2485                 overwrite: boolean parameter for overwriting/not overwriting the file
2486                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2487
2488                         - 1D if all mesh nodes lie on OX coordinate axis, or
2489                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2490                         - 3D in the rest cases.
2491
2492                         If **autoDimension** is *False*, the space dimension is always 3.
2493                 """
2494
2495         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2496         # process positional arguments
2497         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2498         fileName      = args[0]
2499         auto_groups   = args[1] if len(args) > 1 else False
2500         overwrite     = args[2] if len(args) > 2 else True
2501         autoDimension = args[3] if len(args) > 3 else True
2502         # process keywords arguments
2503         auto_groups   = kwargs.get("auto_groups", auto_groups)
2504         overwrite     = kwargs.get("overwrite", overwrite)
2505         autoDimension = kwargs.get("autoDimension", autoDimension)
2506         minor = -1
2507         # invoke engine's function
2508         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2509         return
2510
2511
2512     def Append(self, meshes, uniteIdenticalGroups = True,
2513                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2514         """
2515         Append given meshes into this mesh.
2516         All groups of input meshes will be created in this mesh.
2517
2518         Parameters:
2519                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2520                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2521                 mergeNodesAndElements: if True, equal nodes and elements are merged
2522                 mergeTolerance: tolerance for merging nodes
2523                 allGroups: forces creation of groups corresponding to every input mesh
2524         """
2525         self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2526                                    mergeNodesAndElements, mergeTolerance, allGroups,
2527                                    meshToAppendTo = self.GetMesh() )
2528
2529     # Operations with groups:
2530     # ----------------------
2531     def CreateEmptyGroup(self, elementType, name):
2532         """
2533         Create an empty standalone mesh group
2534
2535         Parameters:
2536                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2537                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2538                 name: the name of the mesh group
2539
2540         Returns:
2541                 :class:`SMESH.SMESH_Group`
2542         """
2543
2544         return self.mesh.CreateGroup(elementType, name)
2545
2546     def Group(self, grp, name=""):
2547         """
2548         Create a mesh group based on the geometric object *grp*
2549         and give it a *name*.
2550         If *name* is not defined the name of the geometric group is used
2551
2552         Note:
2553                 Works like :meth:`GroupOnGeom`.
2554
2555         Parameters:
2556                 grp:  a geometric group, a vertex, an edge, a face or a solid
2557                 name: the name of the mesh group
2558
2559         Returns:
2560                 :class:`SMESH.SMESH_GroupOnGeom`
2561         """
2562
2563         return self.GroupOnGeom(grp, name)
2564
2565     def GroupOnGeom(self, grp, name="", typ=None):
2566         """
2567         Create a mesh group based on the geometrical object *grp*
2568         and give it a *name*.
2569         if *name* is not defined the name of the geometric group is used
2570
2571         Parameters:
2572                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2573                 name: the name of the mesh group
2574                 typ:  the type of elements in the group; either of
2575                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2576                         automatically detected by the type of the geometry
2577
2578         Returns:
2579                 :class:`SMESH.SMESH_GroupOnGeom`
2580         """
2581
2582         AssureGeomPublished( self, grp, name )
2583         if name == "":
2584             name = grp.GetName()
2585         if not typ:
2586             typ = self._groupTypeFromShape( grp )
2587         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2588
2589     def _groupTypeFromShape( self, shape ):
2590         """
2591         Pivate method to get a type of group on geometry
2592         """
2593         tgeo = str(shape.GetShapeType())
2594         if tgeo == "VERTEX":
2595             typ = NODE
2596         elif tgeo == "EDGE":
2597             typ = EDGE
2598         elif tgeo == "FACE" or tgeo == "SHELL":
2599             typ = FACE
2600         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2601             typ = VOLUME
2602         elif tgeo == "COMPOUND":
2603             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2604             if not sub:
2605                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2606             return self._groupTypeFromShape( sub[0] )
2607         else:
2608             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2609         return typ
2610
2611     def GroupOnFilter(self, typ, name, filter):
2612         """
2613         Create a mesh group with given *name* based on the *filter*.
2614         It is a special type of group dynamically updating it's contents during
2615         mesh modification
2616
2617         Parameters:
2618                 typ: the type of elements in the group; either of
2619                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2620                 name: the name of the mesh group
2621                 filter (SMESH.Filter): the filter defining group contents
2622
2623         Returns:
2624                 :class:`SMESH.SMESH_GroupOnFilter`
2625         """
2626
2627         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2628
2629     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2630         """
2631         Create a mesh group by the given ids of elements
2632
2633         Parameters:
2634                 groupName: the name of the mesh group
2635                 elementType: the type of elements in the group; either of
2636                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2637                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2638
2639         Returns:
2640                 :class:`SMESH.SMESH_Group`
2641         """
2642
2643         group = self.mesh.CreateGroup(elementType, groupName)
2644         if isinstance( elemIDs, Mesh ):
2645             elemIDs = elemIDs.GetMesh()
2646         if hasattr( elemIDs, "GetIDs" ):
2647             if hasattr( elemIDs, "SetMesh" ):
2648                 elemIDs.SetMesh( self.GetMesh() )
2649             group.AddFrom( elemIDs )
2650         else:
2651             group.Add(elemIDs)
2652         return group
2653
2654     def MakeGroup(self,
2655                   groupName,
2656                   elementType,
2657                   CritType=FT_Undefined,
2658                   Compare=FT_EqualTo,
2659                   Threshold="",
2660                   UnaryOp=FT_Undefined,
2661                   Tolerance=1e-07):
2662         """
2663         Create a mesh group by the given conditions
2664
2665         Parameters:
2666                 groupName: the name of the mesh group
2667                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2668                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2669                         Note that the items starting from FT_LessThan are not suitable for CritType.
2670                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2671                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2672                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2673                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2674                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2675
2676         Returns:
2677                 :class:`SMESH.SMESH_GroupOnFilter`
2678         """
2679
2680         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2681         group = self.MakeGroupByCriterion(groupName, aCriterion)
2682         return group
2683
2684     def MakeGroupByCriterion(self, groupName, Criterion):
2685         """
2686         Create a mesh group by the given criterion
2687
2688         Parameters:
2689                 groupName: the name of the mesh group
2690                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2691
2692         Returns:
2693                 :class:`SMESH.SMESH_GroupOnFilter`
2694
2695         See Also:
2696                 :meth:`smeshBuilder.GetCriterion`
2697         """
2698
2699         return self.MakeGroupByCriteria( groupName, [Criterion] )
2700
2701     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2702         """
2703         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2704
2705         Parameters:
2706                 groupName: the name of the mesh group
2707                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2708                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2709
2710         Returns:
2711                 :class:`SMESH.SMESH_GroupOnFilter`
2712
2713         See Also:
2714                 :meth:`smeshBuilder.GetCriterion`
2715         """
2716
2717         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2718         group = self.MakeGroupByFilter(groupName, aFilter)
2719         return group
2720
2721     def MakeGroupByFilter(self, groupName, theFilter):
2722         """
2723         Create a mesh group by the given filter
2724
2725         Parameters:
2726                 groupName (string): the name of the mesh group
2727                 theFilter (SMESH.Filter): the filter
2728
2729         Returns:
2730                 :class:`SMESH.SMESH_GroupOnFilter`
2731
2732         See Also:
2733                 :meth:`smeshBuilder.GetFilter`
2734         """
2735
2736         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2737         #theFilter.SetMesh( self.mesh )
2738         #group.AddFrom( theFilter )
2739         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2740         return group
2741
2742     def RemoveGroup(self, group):
2743         """
2744         Remove a group
2745
2746         Parameters:
2747                 group (SMESH.SMESH_GroupBase): group to remove
2748         """
2749
2750         self.mesh.RemoveGroup(group)
2751
2752     def RemoveGroupWithContents(self, group):
2753         """
2754         Remove a group with its contents
2755
2756         Parameters:
2757                 group (SMESH.SMESH_GroupBase): group to remove
2758         """
2759
2760         self.mesh.RemoveGroupWithContents(group)
2761
2762     def GetGroups(self, elemType = SMESH.ALL):
2763         """
2764         Get the list of groups existing in the mesh in the order of creation 
2765         (starting from the oldest one)
2766
2767         Parameters:
2768                 elemType (SMESH.ElementType): type of elements the groups contain;
2769                         by default groups of elements of all types are returned
2770
2771         Returns:
2772                 a list of :class:`SMESH.SMESH_GroupBase`
2773         """
2774
2775         groups = self.mesh.GetGroups()
2776         if elemType == SMESH.ALL:
2777             return groups
2778         typedGroups = []
2779         for g in groups:
2780             if g.GetType() == elemType:
2781                 typedGroups.append( g )
2782                 pass
2783             pass
2784         return typedGroups
2785
2786     def NbGroups(self):
2787         """
2788         Get the number of groups existing in the mesh
2789
2790         Returns:
2791                 the quantity of groups as an integer value
2792         """
2793
2794         return self.mesh.NbGroups()
2795
2796     def GetGroupNames(self):
2797         """
2798         Get the list of names of groups existing in the mesh
2799
2800         Returns:
2801                 list of strings
2802         """
2803
2804         groups = self.GetGroups()
2805         names = []
2806         for group in groups:
2807             names.append(group.GetName())
2808         return names
2809
2810     def GetGroupByName(self, name, elemType = None):
2811         """
2812         Find groups by name and type
2813
2814         Parameters:
2815                 name (string): name of the group of interest
2816                 elemType (SMESH.ElementType): type of elements the groups contain;
2817                         by default one group of any type is returned;
2818                         if elemType == SMESH.ALL then all groups of any type are returned
2819
2820         Returns:
2821                 a list of :class:`SMESH.SMESH_GroupBase`
2822         """
2823
2824         groups = []
2825         for group in self.GetGroups():
2826             if group.GetName() == name:
2827                 if elemType is None:
2828                     return [group]
2829                 if ( elemType == SMESH.ALL or
2830                      group.GetType() == elemType ):
2831                     groups.append( group )
2832         return groups
2833
2834     def UnionGroups(self, group1, group2, name):
2835         """
2836         Produce a union of two groups.
2837         A new group is created. All mesh elements that are
2838         present in the initial groups are added to the new one
2839
2840         Parameters:
2841            group1 (SMESH.SMESH_GroupBase): a group
2842            group2 (SMESH.SMESH_GroupBase): another group
2843
2844         Returns:
2845                 instance of :class:`SMESH.SMESH_Group`
2846         """
2847
2848         return self.mesh.UnionGroups(group1, group2, name)
2849
2850     def UnionListOfGroups(self, groups, name):
2851         """
2852         Produce a union list of groups.
2853         New group is created. All mesh elements that are present in
2854         initial groups are added to the new one
2855
2856         Parameters:
2857            groups: list of :class:`SMESH.SMESH_GroupBase`
2858
2859         Returns:
2860                 instance of :class:`SMESH.SMESH_Group`
2861         """
2862         return self.mesh.UnionListOfGroups(groups, name)
2863
2864     def IntersectGroups(self, group1, group2, name):
2865         """
2866         Prodice an intersection of two groups.
2867         A new group is created. All mesh elements that are common
2868         for the two initial groups are added to the new one.
2869
2870         Parameters:
2871            group1 (SMESH.SMESH_GroupBase): a group
2872            group2 (SMESH.SMESH_GroupBase): another group
2873
2874         Returns:
2875                 instance of :class:`SMESH.SMESH_Group`
2876         """
2877
2878         return self.mesh.IntersectGroups(group1, group2, name)
2879
2880     def IntersectListOfGroups(self, groups, name):
2881         """
2882         Produce an intersection of groups.
2883         New group is created. All mesh elements that are present in all
2884         initial groups simultaneously are added to the new one
2885
2886         Parameters:
2887            groups: a list of :class:`SMESH.SMESH_GroupBase`
2888
2889         Returns:
2890                 instance of :class:`SMESH.SMESH_Group`
2891         """
2892         return self.mesh.IntersectListOfGroups(groups, name)
2893
2894     def CutGroups(self, main_group, tool_group, name):
2895         """
2896         Produce a cut of two groups.
2897         A new group is created. All mesh elements that are present in
2898         the main group but are not present in the tool group are added to the new one
2899
2900         Parameters:
2901            main_group (SMESH.SMESH_GroupBase): a group to cut from
2902            tool_group (SMESH.SMESH_GroupBase): a group to cut by
2903
2904         Returns:
2905                 an instance of :class:`SMESH.SMESH_Group`
2906         """
2907
2908         return self.mesh.CutGroups(main_group, tool_group, name)
2909
2910     def CutListOfGroups(self, main_groups, tool_groups, name):
2911         """
2912         Produce a cut of groups.
2913         A new group is created. All mesh elements that are present in main groups
2914         but do not present in tool groups are added to the new one
2915
2916         Parameters:
2917            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
2918            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
2919
2920         Returns:
2921                 an instance of :class:`SMESH.SMESH_Group`
2922         """
2923
2924         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2925
2926     def CreateDimGroup(self, groups, elemType, name,
2927                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2928         """
2929         Create a standalone group of entities basing on nodes of other groups.
2930
2931         Parameters:
2932                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2933                 elemType: a type of elements to include to the new group; either of
2934                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2935                 name: a name of the new group.
2936                 nbCommonNodes: a criterion of inclusion of an element to the new group
2937                         basing on number of element nodes common with reference *groups*.
2938                         Meaning of possible values are:
2939
2940                                 - SMESH.ALL_NODES - include if all nodes are common,
2941                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2942                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2943                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
2944                 underlyingOnly: if *True* (default), an element is included to the
2945                         new group provided that it is based on nodes of an element of *groups*;
2946                         in this case the reference *groups* are supposed to be of higher dimension
2947                         than *elemType*, which can be useful for example to get all faces lying on
2948                         volumes of the reference *groups*.
2949
2950         Returns:
2951                 an instance of :class:`SMESH.SMESH_Group`
2952         """
2953
2954         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2955             groups = [groups]
2956         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2957
2958     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2959         """
2960         Distribute all faces of the mesh among groups using sharp edges and optionally
2961         existing 1D elements as group boundaries.
2962
2963         Parameters:
2964                 sharpAngle: edge is considered sharp if an angle between normals of
2965                             adjacent faces is more than \a sharpAngle in degrees.
2966                 createEdges (boolean): to create 1D elements for detected sharp edges.
2967                 useExistingEdges (boolean): to use existing edges as group boundaries
2968         Returns:
2969                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2970         """
2971         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2972         self.mesh.SetParameters(Parameters)
2973         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2974
2975     def ConvertToStandalone(self, group):
2976         """
2977         Convert group on geom into standalone group
2978         """
2979
2980         return self.mesh.ConvertToStandalone(group)
2981
2982     # Get some info about mesh:
2983     # ------------------------
2984
2985     def GetLog(self, clearAfterGet):
2986         """
2987         Return the log of nodes and elements added or removed
2988         since the previous clear of the log.
2989
2990         Parameters:
2991                 clearAfterGet: log is emptied after Get (safe if concurrents access)
2992
2993         Returns:
2994                 list of SMESH.log_block structures { commandType, number, coords, indexes }
2995         """
2996
2997         return self.mesh.GetLog(clearAfterGet)
2998
2999     def ClearLog(self):
3000         """
3001         Clear the log of nodes and elements added or removed since the previous
3002         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3003         """
3004
3005         self.mesh.ClearLog()
3006
3007     def SetAutoColor(self, theAutoColor):
3008         """
3009         Toggle auto color mode on the object.
3010         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3011
3012         Parameters:
3013                 theAutoColor (boolean): the flag which toggles auto color mode.
3014         """
3015
3016         self.mesh.SetAutoColor(theAutoColor)
3017
3018     def GetAutoColor(self):
3019         """
3020         Get flag of object auto color mode.
3021
3022         Returns:
3023                 True or False
3024         """
3025
3026         return self.mesh.GetAutoColor()
3027
3028     def GetId(self):
3029         """
3030         Get the internal ID
3031
3032         Returns:
3033             integer value, which is the internal Id of the mesh
3034         """
3035
3036         return self.mesh.GetId()
3037
3038     def HasDuplicatedGroupNamesMED(self):
3039         """
3040         Check the group names for duplications.
3041         Consider the maximum group name length stored in MED file.
3042
3043         Returns:
3044             True or False
3045         """
3046
3047         return self.mesh.HasDuplicatedGroupNamesMED()
3048
3049     def GetMeshEditor(self):
3050         """
3051         Obtain the mesh editor tool
3052
3053         Returns:
3054             an instance of :class:`SMESH.SMESH_MeshEditor`
3055         """
3056
3057         return self.editor
3058
3059     def GetIDSource(self, ids, elemType = SMESH.ALL):
3060         """
3061         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3062         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3063
3064         Parameters:
3065                 ids: list of IDs
3066                 elemType: type of elements; this parameter is used to distinguish
3067                         IDs of nodes from IDs of elements; by default ids are treated as
3068                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3069
3070         Returns:
3071             an instance of :class:`SMESH.SMESH_IDSource`
3072
3073         Warning:
3074                 call UnRegister() for the returned object as soon as it is no more useful::
3075
3076                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3077                         mesh.DoSomething( idSrc )
3078                         idSrc.UnRegister()
3079         """
3080
3081         if isinstance( ids, int ):
3082             ids = [ids]
3083         return self.editor.MakeIDSource(ids, elemType)
3084
3085
3086     # Get information about mesh contents:
3087     # ------------------------------------
3088
3089     def GetMeshInfo(self, obj = None):
3090         """
3091         Get the mesh statistic.
3092
3093         Returns:
3094                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3095         """
3096
3097         if not obj: obj = self.mesh
3098         return self.smeshpyD.GetMeshInfo(obj)
3099
3100     def NbNodes(self):
3101         """
3102         Return the number of nodes in the mesh
3103
3104         Returns:
3105             an integer value
3106         """
3107
3108         return self.mesh.NbNodes()
3109
3110     def NbElements(self):
3111         """
3112         Return the number of elements in the mesh
3113
3114         Returns:
3115             an integer value
3116         """
3117
3118         return self.mesh.NbElements()
3119
3120     def Nb0DElements(self):
3121         """
3122         Return the number of 0d elements in the mesh
3123
3124         Returns:
3125             an integer value
3126         """
3127
3128         return self.mesh.Nb0DElements()
3129
3130     def NbBalls(self):
3131         """
3132         Return the number of ball discrete elements in the mesh
3133
3134         Returns:
3135             an integer value
3136         """
3137
3138         return self.mesh.NbBalls()
3139
3140     def NbEdges(self):
3141         """
3142         Return the number of edges in the mesh
3143
3144         Returns:
3145             an integer value
3146         """
3147
3148         return self.mesh.NbEdges()
3149
3150     def NbEdgesOfOrder(self, elementOrder):
3151         """
3152         Return the number of edges with the given order in the mesh
3153
3154         Parameters:
3155                 elementOrder: the order of elements
3156                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3157
3158         Returns:
3159             an integer value
3160         """
3161
3162         return self.mesh.NbEdgesOfOrder(elementOrder)
3163
3164     def NbFaces(self):
3165         """
3166         Return the number of faces in the mesh
3167
3168         Returns:
3169             an integer value
3170         """
3171
3172         return self.mesh.NbFaces()
3173
3174     def NbFacesOfOrder(self, elementOrder):
3175         """
3176         Return the number of faces with the given order in the mesh
3177
3178         Parameters:
3179                 elementOrder: the order of elements
3180                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3181
3182         Returns:
3183             an integer value
3184         """
3185
3186         return self.mesh.NbFacesOfOrder(elementOrder)
3187
3188     def NbTriangles(self):
3189         """
3190         Return the number of triangles in the mesh
3191
3192         Returns:
3193             an integer value
3194         """
3195
3196         return self.mesh.NbTriangles()
3197
3198     def NbTrianglesOfOrder(self, elementOrder):
3199         """
3200         Return the number of triangles with the given order in the mesh
3201
3202         Parameters:
3203                 elementOrder: is the order of elements
3204                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3205
3206         Returns:
3207             an integer value
3208         """
3209
3210         return self.mesh.NbTrianglesOfOrder(elementOrder)
3211
3212     def NbBiQuadTriangles(self):
3213         """
3214         Return the number of biquadratic triangles in the mesh
3215
3216         Returns:
3217             an integer value
3218         """
3219
3220         return self.mesh.NbBiQuadTriangles()
3221
3222     def NbQuadrangles(self):
3223         """
3224         Return the number of quadrangles in the mesh
3225
3226         Returns:
3227             an integer value
3228         """
3229
3230         return self.mesh.NbQuadrangles()
3231
3232     def NbQuadranglesOfOrder(self, elementOrder):
3233         """
3234         Return the number of quadrangles with the given order in the mesh
3235
3236         Parameters:
3237                 elementOrder: the order of elements
3238                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3239
3240         Returns:
3241             an integer value
3242         """
3243
3244         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3245
3246     def NbBiQuadQuadrangles(self):
3247         """
3248         Return the number of biquadratic quadrangles in the mesh
3249
3250         Returns:
3251             an integer value
3252         """
3253
3254         return self.mesh.NbBiQuadQuadrangles()
3255
3256     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3257         """
3258         Return the number of polygons of given order in the mesh
3259
3260         Parameters:
3261                 elementOrder: the order of elements
3262                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3263
3264         Returns:
3265             an integer value
3266         """
3267
3268         return self.mesh.NbPolygonsOfOrder(elementOrder)
3269
3270     def NbVolumes(self):
3271         """
3272         Return the number of volumes in the mesh
3273
3274         Returns:
3275             an integer value
3276         """
3277
3278         return self.mesh.NbVolumes()
3279
3280
3281     def NbVolumesOfOrder(self, elementOrder):
3282         """
3283         Return the number of volumes with the given order in the mesh
3284
3285         Parameters:
3286                 elementOrder:  the order of elements
3287                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3288
3289         Returns:
3290             an integer value
3291         """
3292
3293         return self.mesh.NbVolumesOfOrder(elementOrder)
3294
3295     def NbTetras(self):
3296         """
3297         Return the number of tetrahedrons in the mesh
3298
3299         Returns:
3300             an integer value
3301         """
3302
3303         return self.mesh.NbTetras()
3304
3305     def NbTetrasOfOrder(self, elementOrder):
3306         """
3307         Return the number of tetrahedrons with the given order in the mesh
3308
3309         Parameters:
3310                 elementOrder:  the order of elements
3311                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3312
3313         Returns:
3314             an integer value
3315         """
3316
3317         return self.mesh.NbTetrasOfOrder(elementOrder)
3318
3319     def NbHexas(self):
3320         """
3321         Return the number of hexahedrons in the mesh
3322
3323         Returns:
3324             an integer value
3325         """
3326
3327         return self.mesh.NbHexas()
3328
3329     def NbHexasOfOrder(self, elementOrder):
3330         """
3331         Return the number of hexahedrons with the given order in the mesh
3332
3333         Parameters:
3334                 elementOrder:  the order of elements
3335                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3336
3337         Returns:
3338             an integer value
3339         """
3340