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