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