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