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