Salome HOME
35198fe5982de2249dd3d1d675afb30775877e74
[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 = ""):
737         """
738         Concatenate the given meshes into one mesh. All groups of input meshes will be
739         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
749         Returns:
750                 an instance of class :class:`Mesh`
751         """
752
753         if not meshes: return None
754         for i,m in enumerate(meshes):
755             if isinstance(m, Mesh):
756                 meshes[i] = m.GetMesh()
757         mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
758         meshes[0].SetParameters(Parameters)
759         if allGroups:
760             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
761                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
762         else:
763             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
764                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
765         aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
766         return aMesh
767
768     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
769         """
770         Create a mesh by copying a part of another mesh.
771
772         Parameters:
773                 meshPart: a part of mesh to copy, either 
774                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
775                         To copy nodes or elements not forming any mesh object,
776                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
777                 meshName: a name of the new mesh
778                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
779                 toKeepIDs: to preserve order of the copied elements or not
780
781         Returns:
782                 an instance of class :class:`Mesh`
783         """
784
785         if isinstance( meshPart, Mesh ):
786             meshPart = meshPart.GetMesh()
787         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
788         return Mesh(self, self.geompyD, mesh)
789
790     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
791                           toReuseHypotheses=True, toCopyElements=True):
792         """
793         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
794         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
795         To facilitate and speed up the operation, consider using
796         "Set presentation parameters and sub-shapes from arguments" option in
797         a dialog of geometrical operation used to create the new geometry.
798
799         Parameters:
800                 sourceMesh: the mesh to copy definition of.
801                 newGeom: the new geomtry.
802                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
803                 toCopyGroups: to create groups in the new mesh.
804                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
805                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
806                                 *sourceMesh*.
807         Returns:
808                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
809                 *invalidEntries* are study entries of objects whose
810                 counterparts are not found in the *newGeom*, followed by entries
811                 of mesh sub-objects that are invalid because they depend on a not found
812                 preceeding sub-shape
813         """
814         if isinstance( sourceMesh, Mesh ):
815             sourceMesh = sourceMesh.GetMesh()
816
817         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
818            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
819                                                      toCopyGroups,
820                                                      toReuseHypotheses,
821                                                      toCopyElements)
822         return ( ok, Mesh(self, self.geompyD, newMesh),
823                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
824
825     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
826         """
827         Return IDs of sub-shapes
828
829         Parameters:
830                 theMainObject (GEOM.GEOM_Object): a shape
831                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
832         Returns:
833                 the list of integer values
834         """
835
836         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
837
838     def GetPattern(self):
839         """
840         Create a pattern mapper.
841
842         Returns:
843                 an instance of :class:`SMESH.SMESH_Pattern`
844
845         :ref:`Example of Patterns usage <tui_pattern_mapping>`
846         """
847
848         return SMESH._objref_SMESH_Gen.GetPattern(self)
849
850     def SetBoundaryBoxSegmentation(self, nbSegments):
851         """
852         Set number of segments per diagonal of boundary box of geometry, by which
853         default segment length of appropriate 1D hypotheses is defined in GUI.
854         Default value is 10.
855         """
856
857         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
858
859     # Filtering. Auxiliary functions:
860     # ------------------------------
861
862     def GetEmptyCriterion(self):
863         """
864         Create an empty criterion
865
866         Returns:
867                 :class:`SMESH.Filter.Criterion`
868         """
869
870         Type = self.EnumToLong(FT_Undefined)
871         Compare = self.EnumToLong(FT_Undefined)
872         Threshold = 0
873         ThresholdStr = ""
874         ThresholdID = ""
875         UnaryOp = self.EnumToLong(FT_Undefined)
876         BinaryOp = self.EnumToLong(FT_Undefined)
877         Tolerance = 1e-07
878         TypeOfElement = ALL
879         Precision = -1 ##@1e-07
880         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
881                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
882
883     def GetCriterion(self,elementType,
884                      CritType,
885                      Compare = FT_EqualTo,
886                      Threshold="",
887                      UnaryOp=FT_Undefined,
888                      BinaryOp=FT_Undefined,
889                      Tolerance=1e-07):
890         """
891         Create a criterion by the given parameters
892         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
893
894         Parameters:
895                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
896                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
897                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
898                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
899                 Threshold: the threshold value (range of ids as string, shape, numeric)
900                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
901                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
902                         SMESH.FT_Undefined
903                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
904                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
905
906         Returns:
907                 :class:`SMESH.Filter.Criterion`
908
909         Example: :ref:`combining_filters`
910         """
911
912         if not CritType in SMESH.FunctorType._items:
913             raise TypeError("CritType should be of SMESH.FunctorType")
914         aCriterion               = self.GetEmptyCriterion()
915         aCriterion.TypeOfElement = elementType
916         aCriterion.Type          = self.EnumToLong(CritType)
917         aCriterion.Tolerance     = Tolerance
918
919         aThreshold = Threshold
920
921         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
922             aCriterion.Compare = self.EnumToLong(Compare)
923         elif Compare == "=" or Compare == "==":
924             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
925         elif Compare == "<":
926             aCriterion.Compare = self.EnumToLong(FT_LessThan)
927         elif Compare == ">":
928             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
929         elif Compare != FT_Undefined:
930             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
931             aThreshold = Compare
932
933         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
934                         FT_BelongToCylinder, FT_LyingOnGeom]:
935             # Check that Threshold is GEOM object
936             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
937                 aCriterion.ThresholdStr = GetName(aThreshold)
938                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
939                 if not aCriterion.ThresholdID:
940                     name = aCriterion.ThresholdStr
941                     if not name:
942                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
943                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
944             # or a name of GEOM object
945             elif isinstance( aThreshold, str ):
946                 aCriterion.ThresholdStr = aThreshold
947             else:
948                 raise TypeError("The Threshold should be a shape.")
949             if isinstance(UnaryOp,float):
950                 aCriterion.Tolerance = UnaryOp
951                 UnaryOp = FT_Undefined
952                 pass
953         elif CritType == FT_BelongToMeshGroup:
954             # Check that Threshold is a group
955             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
956                 if aThreshold.GetType() != elementType:
957                     raise ValueError("Group type mismatches Element type")
958                 aCriterion.ThresholdStr = aThreshold.GetName()
959                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
960                 study = salome.myStudy
961                 if study:
962                     so = study.FindObjectIOR( aCriterion.ThresholdID )
963                     if so:
964                         entry = so.GetID()
965                         if entry:
966                             aCriterion.ThresholdID = entry
967             else:
968                 raise TypeError("The Threshold should be a Mesh Group")
969         elif CritType == FT_RangeOfIds:
970             # Check that Threshold is string
971             if isinstance(aThreshold, str):
972                 aCriterion.ThresholdStr = aThreshold
973             else:
974                 raise TypeError("The Threshold should be a string.")
975         elif CritType == FT_CoplanarFaces:
976             # Check the Threshold
977             if isinstance(aThreshold, int):
978                 aCriterion.ThresholdID = str(aThreshold)
979             elif isinstance(aThreshold, str):
980                 ID = int(aThreshold)
981                 if ID < 1:
982                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
983                 aCriterion.ThresholdID = aThreshold
984             else:
985                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
986         elif CritType == FT_ConnectedElements:
987             # Check the Threshold
988             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
989                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
990                 if not aCriterion.ThresholdID:
991                     name = aThreshold.GetName()
992                     if not name:
993                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
994                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
995             elif isinstance(aThreshold, int): # node id
996                 aCriterion.Threshold = aThreshold
997             elif isinstance(aThreshold, list): # 3 point coordinates
998                 if len( aThreshold ) < 3:
999                     raise ValueError("too few point coordinates, must be 3")
1000                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1001             elif isinstance(aThreshold, str):
1002                 if aThreshold.isdigit():
1003                     aCriterion.Threshold = aThreshold # node id
1004                 else:
1005                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1006             else:
1007                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1008                       "or a list of point coordinates and not '%s'"%aThreshold)
1009         elif CritType == FT_ElemGeomType:
1010             # Check the Threshold
1011             try:
1012                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1013                 assert( aThreshold in SMESH.GeometryType._items )
1014             except:
1015                 if isinstance(aThreshold, int):
1016                     aCriterion.Threshold = aThreshold
1017                 else:
1018                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1019                 pass
1020             pass
1021         elif CritType == FT_EntityType:
1022             # Check the Threshold
1023             try:
1024                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1025                 assert( aThreshold in SMESH.EntityType._items )
1026             except:
1027                 if isinstance(aThreshold, int):
1028                     aCriterion.Threshold = aThreshold
1029                 else:
1030                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1031                 pass
1032             pass
1033
1034         elif CritType == FT_GroupColor:
1035             # Check the Threshold
1036             try:
1037                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1038             except:
1039                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1040             pass
1041         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1042                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1043                           FT_BareBorderFace, FT_BareBorderVolume,
1044                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1045                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1046             # At this point the Threshold is unnecessary
1047             if aThreshold ==  FT_LogicalNOT:
1048                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1049             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1050                 aCriterion.BinaryOp = aThreshold
1051         else:
1052             # Check Threshold
1053             try:
1054                 aThreshold = float(aThreshold)
1055                 aCriterion.Threshold = aThreshold
1056             except:
1057                 raise TypeError("The Threshold should be a number.")
1058                 return None
1059
1060         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1061             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1062
1063         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1064             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1065
1066         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1067             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1068
1069         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1070             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1071
1072         return aCriterion
1073
1074     def GetFilter(self,elementType,
1075                   CritType=FT_Undefined,
1076                   Compare=FT_EqualTo,
1077                   Threshold="",
1078                   UnaryOp=FT_Undefined,
1079                   Tolerance=1e-07,
1080                   mesh=None):
1081         """
1082         Create a filter with the given parameters
1083
1084         Parameters:
1085                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1086                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1087                         Note that the items starting from FT_LessThan are not suitable for CritType.
1088                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1089                 Threshold: the threshold value (range of ids as string, shape, numeric)
1090                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1091                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1092                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1093                 mesh: the mesh to initialize the filter with
1094
1095         Returns:
1096                 :class:`SMESH.Filter`
1097
1098         Examples:
1099                See :doc:`Filters usage examples <tui_filters>`
1100         """
1101
1102         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1103         aFilterMgr = self.CreateFilterManager()
1104         aFilter = aFilterMgr.CreateFilter()
1105         aCriteria = []
1106         aCriteria.append(aCriterion)
1107         aFilter.SetCriteria(aCriteria)
1108         if mesh:
1109             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1110             else                       : aFilter.SetMesh( mesh )
1111         aFilterMgr.UnRegister()
1112         return aFilter
1113
1114     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1115         """
1116         Create a filter from criteria
1117
1118         Parameters:
1119                 criteria: a list of :class:`SMESH.Filter.Criterion`
1120                 binOp: binary operator used when binary operator of criteria is undefined
1121
1122         Returns:
1123                 :class:`SMESH.Filter`
1124
1125         Examples:
1126                See :doc:`Filters usage examples <tui_filters>`
1127         """
1128
1129         for i in range( len( criteria ) - 1 ):
1130             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1131                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1132         aFilterMgr = self.CreateFilterManager()
1133         aFilter = aFilterMgr.CreateFilter()
1134         aFilter.SetCriteria(criteria)
1135         aFilterMgr.UnRegister()
1136         return aFilter
1137
1138     def GetFunctor(self,theCriterion):
1139         """
1140         Create a numerical functor by its type
1141
1142         Parameters:
1143                 theCriterion (SMESH.FunctorType): functor type.
1144                         Note that not all items correspond to numerical functors.
1145
1146         Returns:
1147                 :class:`SMESH.NumericalFunctor`
1148         """
1149
1150         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1151             return theCriterion
1152         aFilterMgr = self.CreateFilterManager()
1153         functor = None
1154         if theCriterion == FT_AspectRatio:
1155             functor = aFilterMgr.CreateAspectRatio()
1156         elif theCriterion == FT_AspectRatio3D:
1157             functor = aFilterMgr.CreateAspectRatio3D()
1158         elif theCriterion == FT_Warping:
1159             functor = aFilterMgr.CreateWarping()
1160         elif theCriterion == FT_MinimumAngle:
1161             functor = aFilterMgr.CreateMinimumAngle()
1162         elif theCriterion == FT_Taper:
1163             functor = aFilterMgr.CreateTaper()
1164         elif theCriterion == FT_Skew:
1165             functor = aFilterMgr.CreateSkew()
1166         elif theCriterion == FT_Area:
1167             functor = aFilterMgr.CreateArea()
1168         elif theCriterion == FT_Volume3D:
1169             functor = aFilterMgr.CreateVolume3D()
1170         elif theCriterion == FT_MaxElementLength2D:
1171             functor = aFilterMgr.CreateMaxElementLength2D()
1172         elif theCriterion == FT_MaxElementLength3D:
1173             functor = aFilterMgr.CreateMaxElementLength3D()
1174         elif theCriterion == FT_MultiConnection:
1175             functor = aFilterMgr.CreateMultiConnection()
1176         elif theCriterion == FT_MultiConnection2D:
1177             functor = aFilterMgr.CreateMultiConnection2D()
1178         elif theCriterion == FT_Length:
1179             functor = aFilterMgr.CreateLength()
1180         elif theCriterion == FT_Length2D:
1181             functor = aFilterMgr.CreateLength2D()
1182         elif theCriterion == FT_Deflection2D:
1183             functor = aFilterMgr.CreateDeflection2D()
1184         elif theCriterion == FT_NodeConnectivityNumber:
1185             functor = aFilterMgr.CreateNodeConnectivityNumber()
1186         elif theCriterion == FT_BallDiameter:
1187             functor = aFilterMgr.CreateBallDiameter()
1188         else:
1189             print("Error: given parameter is not numerical functor type.")
1190         aFilterMgr.UnRegister()
1191         return functor
1192
1193     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1194         """
1195         Create hypothesis
1196
1197         Parameters:
1198                 theHType (string): mesh hypothesis type
1199                 theLibName (string): mesh plug-in library name
1200
1201         Returns:
1202                 created hypothesis instance
1203         """
1204         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1205
1206         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1207             return hyp
1208
1209         # wrap hypothesis methods
1210         for meth_name in dir( hyp.__class__ ):
1211             if not meth_name.startswith("Get") and \
1212                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1213                 method = getattr ( hyp.__class__, meth_name )
1214                 if callable(method):
1215                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1216
1217         return hyp
1218
1219     def GetMeshInfo(self, obj):
1220         """
1221         Get the mesh statistic.
1222         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
1223         an item of :class:`SMESH.EntityType`.
1224
1225         Returns:
1226                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1227         """
1228
1229         if isinstance( obj, Mesh ):
1230             obj = obj.GetMesh()
1231         d = {}
1232         if hasattr(obj, "GetMeshInfo"):
1233             values = obj.GetMeshInfo()
1234             for i in range(SMESH.Entity_Last._v):
1235                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1236             pass
1237         return d
1238
1239     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1240         """
1241         Get minimum distance between two objects
1242
1243         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1244         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1245
1246         Parameters:
1247                 src1 (SMESH.SMESH_IDSource): first source object
1248                 src2 (SMESH.SMESH_IDSource): second source object
1249                 id1 (int): node/element id from the first source
1250                 id2 (int): node/element id from the second (or first) source
1251                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1252                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1253
1254         Returns:
1255                 minimum distance value
1256
1257         See also: 
1258                 :meth:`GetMinDistance`
1259         """
1260
1261         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1262         if result is None:
1263             result = 0.0
1264         else:
1265             result = result.value
1266         return result
1267
1268     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1269         """
1270         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1271
1272         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1273         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1274
1275         Parameters:
1276                 src1 (SMESH.SMESH_IDSource): first source object
1277                 src2 (SMESH.SMESH_IDSource): second source object
1278                 id1 (int): node/element id from the first source
1279                 id2 (int): node/element id from the second (or first) source
1280                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1281                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1282
1283         Returns:
1284                 :class:`SMESH.Measure` structure or None if input data is invalid
1285         See also: 
1286                 :meth:`MinDistance`
1287         """
1288
1289         if isinstance(src1, Mesh): src1 = src1.mesh
1290         if isinstance(src2, Mesh): src2 = src2.mesh
1291         if src2 is None and id2 != 0: src2 = src1
1292         if not hasattr(src1, "_narrow"): return None
1293         src1 = src1._narrow(SMESH.SMESH_IDSource)
1294         if not src1: return None
1295         unRegister = genObjUnRegister()
1296         if id1 != 0:
1297             m = src1.GetMesh()
1298             e = m.GetMeshEditor()
1299             if isElem1:
1300                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1301             else:
1302                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1303             unRegister.set( src1 )
1304             pass
1305         if hasattr(src2, "_narrow"):
1306             src2 = src2._narrow(SMESH.SMESH_IDSource)
1307             if src2 and id2 != 0:
1308                 m = src2.GetMesh()
1309                 e = m.GetMeshEditor()
1310                 if isElem2:
1311                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1312                 else:
1313                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1314                 unRegister.set( src2 )
1315                 pass
1316             pass
1317         aMeasurements = self.CreateMeasurements()
1318         unRegister.set( aMeasurements )
1319         result = aMeasurements.MinDistance(src1, src2)
1320         return result
1321
1322     def BoundingBox(self, objects):
1323         """
1324         Get bounding box of the specified object(s)
1325
1326         Parameters:
1327                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1328
1329         Returns:
1330                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1331
1332         See also: 
1333                :meth:`GetBoundingBox`
1334         """
1335
1336         result = self.GetBoundingBox(objects)
1337         if result is None:
1338             result = (0.0,)*6
1339         else:
1340             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1341         return result
1342
1343     def GetBoundingBox(self, objects):
1344         """
1345         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1346
1347         Parameters:
1348                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1349
1350         Returns:
1351                 :class:`SMESH.Measure` structure
1352
1353         See also: 
1354                 :meth:`BoundingBox`
1355         """
1356
1357         if isinstance(objects, tuple):
1358             objects = list(objects)
1359         if not isinstance(objects, list):
1360             objects = [objects]
1361         srclist = []
1362         for o in objects:
1363             if isinstance(o, Mesh):
1364                 srclist.append(o.mesh)
1365             elif hasattr(o, "_narrow"):
1366                 src = o._narrow(SMESH.SMESH_IDSource)
1367                 if src: srclist.append(src)
1368                 pass
1369             pass
1370         aMeasurements = self.CreateMeasurements()
1371         result = aMeasurements.BoundingBox(srclist)
1372         aMeasurements.UnRegister()
1373         return result
1374
1375     def GetLength(self, obj):
1376         """
1377         Get sum of lengths of all 1D elements in the mesh object.
1378
1379         Parameters:
1380                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1381
1382         Returns:
1383                 sum of lengths of all 1D elements
1384         """
1385
1386         if isinstance(obj, Mesh): obj = obj.mesh
1387         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1388         aMeasurements = self.CreateMeasurements()
1389         value = aMeasurements.Length(obj)
1390         aMeasurements.UnRegister()
1391         return value
1392
1393     def GetArea(self, obj):
1394         """
1395         Get sum of areas of all 2D elements in the mesh object.
1396
1397         Parameters:
1398                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1399
1400         Returns:
1401                 sum of areas of all 2D elements
1402         """
1403
1404         if isinstance(obj, Mesh): obj = obj.mesh
1405         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1406         aMeasurements = self.CreateMeasurements()
1407         value = aMeasurements.Area(obj)
1408         aMeasurements.UnRegister()
1409         return value
1410
1411     def GetVolume(self, obj):
1412         """
1413         Get sum of volumes of all 3D elements in the mesh object.
1414
1415         Parameters:
1416                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1417
1418         Returns:
1419                 sum of volumes of all 3D elements
1420         """
1421
1422         if isinstance(obj, Mesh): obj = obj.mesh
1423         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1424         aMeasurements = self.CreateMeasurements()
1425         value = aMeasurements.Volume(obj)
1426         aMeasurements.UnRegister()
1427         return value
1428
1429     def GetGravityCenter(self, obj):
1430         """
1431         Get gravity center of all nodes of the mesh object.
1432         
1433         Parameters:            
1434                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1435
1436         Returns:        
1437             Three components of the gravity center (x,y,z)
1438         """
1439         if isinstance(obj, Mesh): obj = obj.mesh
1440         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1441         aMeasurements = self.CreateMeasurements()
1442         pointStruct = aMeasurements.GravityCenter(obj)
1443         aMeasurements.UnRegister()
1444         return pointStruct.x, pointStruct.y, pointStruct.z
1445
1446     def GetAngle(self, p1, p2, p3 ):
1447         """
1448         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1449
1450         Parameters:            
1451                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
1452                           or list [x,y,z]
1453
1454         Returns:        
1455             Angle in radians
1456         """
1457         if isinstance( p1, list ): p1 = PointStruct(*p1)
1458         if isinstance( p2, list ): p2 = PointStruct(*p2)
1459         if isinstance( p3, list ): p3 = PointStruct(*p3)
1460
1461         aMeasurements = self.CreateMeasurements()
1462         angle = aMeasurements.Angle(p1,p2,p3)
1463         aMeasurements.UnRegister()
1464
1465         return angle
1466
1467
1468     pass # end of class smeshBuilder
1469
1470 import omniORB
1471 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1472 """Registering the new proxy for SMESH.SMESH_Gen"""
1473
1474
1475 def New( instance=None, instanceGeom=None):
1476     """
1477     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1478     interface to create or load meshes.
1479
1480     Typical use is::
1481
1482         import salome
1483         salome.salome_init()
1484         from salome.smesh import smeshBuilder
1485         smesh = smeshBuilder.New()
1486
1487     Parameters:
1488         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1489         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1490     Returns:
1491         :class:`smeshBuilder` instance
1492     """
1493     global engine
1494     global smeshInst
1495     global doLcc
1496     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1497         import sys
1498         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1499         instance = None
1500     engine = instance
1501     if engine is None:
1502         doLcc = True
1503     smeshInst = smeshBuilder()
1504     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1505     smeshInst.init_smesh(instanceGeom)
1506     return smeshInst
1507
1508
1509 # Public class: Mesh
1510 # ==================
1511
1512
1513 class Mesh(metaclass = MeshMeta):
1514     """
1515     This class allows defining and managing a mesh.
1516     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1517     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1518     new nodes and elements and by changing the existing entities), to get information
1519     about a mesh and to export a mesh in different formats.
1520     """    
1521
1522     geom = 0
1523     mesh = 0
1524     editor = 0
1525
1526     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1527
1528         """
1529         Constructor
1530
1531         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1532         sets the GUI name of this mesh to *name*.
1533
1534         Parameters:
1535                 smeshpyD: an instance of smeshBuilder class
1536                 geompyD: an instance of geomBuilder class
1537                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1538                 name: Study name of the mesh
1539         """
1540
1541         self.smeshpyD = smeshpyD
1542         self.geompyD = geompyD
1543         if obj is None:
1544             obj = 0
1545         objHasName = False
1546         if obj != 0:
1547             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1548                 self.geom = obj
1549                 objHasName = True
1550                 # publish geom of mesh (issue 0021122)
1551                 if not self.geom.GetStudyEntry():
1552                     objHasName = False
1553                     geompyD.init_geom()
1554                     if name:
1555                         geo_name = name + " shape"
1556                     else:
1557                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1558                     geompyD.addToStudy( self.geom, geo_name )
1559                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1560
1561             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1562                 self.SetMesh(obj)
1563         else:
1564             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1565         if name:
1566             self.smeshpyD.SetName(self.mesh, name)
1567         elif objHasName:
1568             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1569
1570         if not self.geom:
1571             self.geom = self.mesh.GetShapeToMesh()
1572
1573         self.editor   = self.mesh.GetMeshEditor()
1574         self.functors = [None] * SMESH.FT_Undefined._v
1575
1576         # set self to algoCreator's
1577         for attrName in dir(self):
1578             attr = getattr( self, attrName )
1579             if isinstance( attr, algoCreator ):
1580                 setattr( self, attrName, attr.copy( self ))
1581                 pass
1582             pass
1583         pass
1584
1585     def __del__(self):
1586         """
1587         Destructor. Clean-up resources
1588         """
1589         if self.mesh:
1590             #self.mesh.UnRegister()
1591             pass
1592         pass
1593
1594     def SetMesh(self, theMesh):
1595         """
1596         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1597
1598         Parameters:
1599                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1600         """
1601
1602
1603         # do not call Register() as this prevents mesh servant deletion at closing study
1604         #if self.mesh: self.mesh.UnRegister()
1605         self.mesh = theMesh
1606         if self.mesh:
1607             #self.mesh.Register()
1608             self.geom = self.mesh.GetShapeToMesh()
1609         pass
1610
1611     def GetMesh(self):
1612         """
1613         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1614
1615         Returns:
1616                 a :class:`SMESH.SMESH_Mesh` object
1617         """
1618
1619         return self.mesh
1620
1621     def GetName(self):
1622         """
1623         Get the name of the mesh
1624
1625         Returns:
1626                 the name of the mesh as a string
1627         """
1628
1629         name = GetName(self.GetMesh())
1630         return name
1631
1632     def SetName(self, name):
1633         """
1634         Set a name to the mesh
1635
1636         Parameters:
1637                 name: a new name of the mesh
1638         """
1639
1640         self.smeshpyD.SetName(self.GetMesh(), name)
1641
1642     def GetSubMesh(self, geom, name):
1643         """
1644         Get a sub-mesh object associated to a *geom* geometrical object.
1645
1646         Parameters:
1647                 geom: a geometrical object (shape)
1648                 name: a name for the sub-mesh in the Object Browser
1649
1650         Returns:
1651                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1652                 which lies on the given shape
1653
1654         Note:
1655                 A sub-mesh is implicitly created when a sub-shape is specified at
1656                 creating an algorithm, for example::
1657
1658                    algo1D = mesh.Segment(geom=Edge_1)
1659
1660                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1661                 The created sub-mesh can be retrieved from the algorithm::
1662
1663                    submesh = algo1D.GetSubMesh()
1664         """
1665
1666         AssureGeomPublished( self, geom, name )
1667         submesh = self.mesh.GetSubMesh( geom, name )
1668         return submesh
1669
1670     def GetShape(self):
1671         """
1672         Return the shape associated to the mesh
1673
1674         Returns:
1675                 a GEOM_Object
1676         """
1677
1678         return self.geom
1679
1680     def SetShape(self, geom):
1681         """
1682         Associate the given shape to the mesh (entails the recreation of the mesh)
1683
1684         Parameters:
1685                 geom: the shape to be meshed (GEOM_Object)
1686         """
1687
1688         self.mesh = self.smeshpyD.CreateMesh(geom)
1689
1690     def HasShapeToMesh(self):
1691         """
1692         Return ``True`` if this mesh is based on geometry
1693         """
1694         return self.mesh.HasShapeToMesh()
1695
1696     def Load(self):
1697         """
1698         Load mesh from the study after opening the study
1699         """
1700         self.mesh.Load()
1701
1702     def IsReadyToCompute(self, theSubObject):
1703         """
1704         Return true if the hypotheses are defined well
1705
1706         Parameters:
1707                 theSubObject: a sub-shape of a mesh shape
1708
1709         Returns:
1710                 True or False
1711         """
1712
1713         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1714
1715     def GetAlgoState(self, theSubObject):
1716         """
1717         Return errors of hypotheses definition.
1718         The list of errors is empty if everything is OK.
1719
1720         Parameters:
1721                 theSubObject: a sub-shape of a mesh shape
1722
1723         Returns:
1724                 a list of errors
1725         """
1726
1727         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1728
1729     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1730         """
1731         Return a geometrical object on which the given element was built.
1732         The returned geometrical object, if not nil, is either found in the
1733         study or published by this method with the given name
1734
1735         Parameters:
1736             theElementID: the id of the mesh element
1737             theGeomName: the user-defined name of the geometrical object
1738
1739         Returns:
1740             GEOM.GEOM_Object instance
1741         """
1742
1743         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1744
1745     def MeshDimension(self):
1746         """
1747         Return the mesh dimension depending on the dimension of the underlying shape
1748         or, if the mesh is not based on any shape, basing on deimension of elements
1749
1750         Returns:
1751                 mesh dimension as an integer value [0,3]
1752         """
1753
1754         if self.mesh.HasShapeToMesh():
1755             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1756             if len( shells ) > 0 :
1757                 return 3
1758             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1759                 return 2
1760             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1761                 return 1
1762             else:
1763                 return 0;
1764         else:
1765             if self.NbVolumes() > 0: return 3
1766             if self.NbFaces()   > 0: return 2
1767             if self.NbEdges()   > 0: return 1
1768         return 0
1769
1770     def Evaluate(self, geom=0):
1771         """
1772         Evaluate size of prospective mesh on a shape
1773
1774         Returns:
1775                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1776                 To know predicted number of e.g. edges, inquire it this way::
1777
1778                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1779         """
1780
1781         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1782             if self.geom == 0:
1783                 geom = self.mesh.GetShapeToMesh()
1784             else:
1785                 geom = self.geom
1786         return self.smeshpyD.Evaluate(self.mesh, geom)
1787
1788
1789     def Compute(self, geom=0, discardModifs=False, refresh=False):
1790         """
1791         Compute the mesh and return the status of the computation
1792
1793         Parameters:
1794                 geom: geomtrical shape on which mesh data should be computed
1795                 discardModifs: if True and the mesh has been edited since
1796                         a last total re-compute and that may prevent successful partial re-compute,
1797                         then the mesh is cleaned before Compute()
1798                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1799
1800         Returns:
1801                 True or False
1802         """
1803
1804         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1805             if self.geom == 0:
1806                 geom = self.mesh.GetShapeToMesh()
1807             else:
1808                 geom = self.geom
1809         ok = False
1810         try:
1811             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1812                 self.mesh.Clear()
1813             ok = self.smeshpyD.Compute(self.mesh, geom)
1814         except SALOME.SALOME_Exception as ex:
1815             print("Mesh computation failed, exception caught:")
1816             print("    ", ex.details.text)
1817         except:
1818             import traceback
1819             print("Mesh computation failed, exception caught:")
1820             traceback.print_exc()
1821         if True:#not ok:
1822             allReasons = ""
1823
1824             # Treat compute errors
1825             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1826             shapeText = ""
1827             for err in computeErrors:
1828                 if self.mesh.HasShapeToMesh():
1829                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1830                 errText = ""
1831                 stdErrors = ["OK",                   #COMPERR_OK
1832                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1833                              "std::exception",       #COMPERR_STD_EXCEPTION
1834                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1835                              "..",                   #COMPERR_SLM_EXCEPTION
1836                              "Unknown exception",    #COMPERR_EXCEPTION
1837                              "Memory allocation problem", #COMPERR_MEMORY_PB
1838                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1839                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1840                              "Warning",              #COMPERR_WARNING
1841                              "Computation cancelled",#COMPERR_CANCELED
1842                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1843                 if err.code > 0:
1844                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1845                 else:
1846                     errText = "code %s" % -err.code
1847                 if errText: errText += ". "
1848                 errText += err.comment
1849                 if allReasons: allReasons += "\n"
1850                 if ok:
1851                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1852                 else:
1853                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1854                 pass
1855
1856             # Treat hyp errors
1857             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1858             for err in errors:
1859                 if err.isGlobalAlgo:
1860                     glob = "global"
1861                 else:
1862                     glob = "local"
1863                     pass
1864                 dim = err.algoDim
1865                 name = err.algoName
1866                 if len(name) == 0:
1867                     reason = '%s %sD algorithm is missing' % (glob, dim)
1868                 elif err.state == HYP_MISSING:
1869                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1870                               % (glob, dim, name, dim))
1871                 elif err.state == HYP_NOTCONFORM:
1872                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1873                 elif err.state == HYP_BAD_PARAMETER:
1874                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1875                               % ( glob, dim, name ))
1876                 elif err.state == HYP_BAD_GEOMETRY:
1877                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1878                               'geometry' % ( glob, dim, name ))
1879                 elif err.state == HYP_HIDDEN_ALGO:
1880                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1881                               'algorithm of upper dimension generating %sD mesh'
1882                               % ( glob, dim, name, glob, dim ))
1883                 else:
1884                     reason = ("For unknown reason. "
1885                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1886                     pass
1887                 if allReasons: allReasons += "\n"
1888                 allReasons += "-  " + reason
1889                 pass
1890             if not ok or allReasons != "":
1891                 msg = '"' + GetName(self.mesh) + '"'
1892                 if ok: msg += " has been computed with warnings"
1893                 else:  msg += " has not been computed"
1894                 if allReasons != "": msg += ":"
1895                 else:                msg += "."
1896                 print(msg)
1897                 print(allReasons)
1898             pass
1899         if salome.sg.hasDesktop():
1900             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1901                 if refresh: salome.sg.updateObjBrowser()
1902
1903         return ok
1904
1905     def GetComputeErrors(self, shape=0 ):
1906         """
1907         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1908         """
1909
1910         if shape == 0:
1911             shape = self.mesh.GetShapeToMesh()
1912         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1913
1914     def GetSubShapeName(self, subShapeID ):
1915         """
1916         Return a name of a sub-shape by its ID.
1917         Possible variants (for *subShapeID* == 3):
1918
1919                 - **"Face_12"** - published sub-shape
1920                 - **FACE #3** - not published sub-shape
1921                 - **sub-shape #3** - invalid sub-shape ID
1922                 - **#3** - error in this function
1923
1924         Parameters:
1925                 subShapeID: a unique ID of a sub-shape
1926
1927         Returns:
1928                 a string describing the sub-shape
1929
1930         """
1931
1932         if not self.mesh.HasShapeToMesh():
1933             return ""
1934         try:
1935             shapeText = ""
1936             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1937             s = salome.myStudy
1938             mainSO = s.FindObjectIOR(mainIOR)
1939             if mainSO:
1940                 if subShapeID == 1:
1941                     shapeText = '"%s"' % mainSO.GetName()
1942                 subIt = s.NewChildIterator(mainSO)
1943                 while subIt.More():
1944                     subSO = subIt.Value()
1945                     subIt.Next()
1946                     obj = subSO.GetObject()
1947                     if not obj: continue
1948                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1949                     if not go: continue
1950                     try:
1951                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1952                     except:
1953                         continue
1954                     if ids == subShapeID:
1955                         shapeText = '"%s"' % subSO.GetName()
1956                         break
1957             if not shapeText:
1958                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1959                 if shape:
1960                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1961                 else:
1962                     shapeText = 'sub-shape #%s' % (subShapeID)
1963         except:
1964             shapeText = "#%s" % (subShapeID)
1965         return shapeText
1966
1967     def GetFailedShapes(self, publish=False):
1968         """
1969         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1970         error of an algorithm
1971
1972         Parameters:
1973                 publish: if *True*, the returned groups will be published in the study
1974
1975         Returns:
1976                 a list of GEOM groups each named after a failed algorithm
1977         """
1978
1979
1980         algo2shapes = {}
1981         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1982         for err in computeErrors:
1983             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1984             if not shape: continue
1985             if err.algoName in algo2shapes:
1986                 algo2shapes[ err.algoName ].append( shape )
1987             else:
1988                 algo2shapes[ err.algoName ] = [ shape ]
1989             pass
1990
1991         groups = []
1992         for algoName, shapes in list(algo2shapes.items()):
1993             while shapes:
1994                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
1995                 otherTypeShapes = []
1996                 sameTypeShapes  = []
1997                 group = self.geompyD.CreateGroup( self.geom, groupType )
1998                 for shape in shapes:
1999                     if shape.GetShapeType() == shapes[0].GetShapeType():
2000                         sameTypeShapes.append( shape )
2001                     else:
2002                         otherTypeShapes.append( shape )
2003                 self.geompyD.UnionList( group, sameTypeShapes )
2004                 if otherTypeShapes:
2005                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2006                 else:
2007                     group.SetName( algoName )
2008                 groups.append( group )
2009                 shapes = otherTypeShapes
2010             pass
2011         if publish:
2012             for group in groups:
2013                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2014         return groups
2015
2016     def GetMeshOrder(self):
2017         """
2018         Return sub-mesh objects list in meshing order
2019
2020         Returns:
2021                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2022         """
2023
2024         return self.mesh.GetMeshOrder()
2025
2026     def SetMeshOrder(self, submeshes):
2027         """
2028         Set order in which concurrent sub-meshes should be meshed
2029
2030         Parameters:
2031                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2032         """
2033
2034         return self.mesh.SetMeshOrder(submeshes)
2035
2036     def Clear(self, refresh=False):
2037         """
2038         Remove all nodes and elements generated on geometry. Imported elements remain.
2039
2040         Parameters:
2041                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2042         """
2043
2044         self.mesh.Clear()
2045         if ( salome.sg.hasDesktop() ):
2046             if refresh: salome.sg.updateObjBrowser()
2047
2048     def ClearSubMesh(self, geomId, refresh=False):
2049         """
2050         Remove all nodes and elements of indicated shape
2051
2052         Parameters:
2053                 geomId: the ID of a sub-shape to remove elements on
2054                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2055         """
2056
2057         self.mesh.ClearSubMesh(geomId)
2058         if salome.sg.hasDesktop():
2059             if refresh: salome.sg.updateObjBrowser()
2060
2061     def AutomaticTetrahedralization(self, fineness=0):
2062         """
2063         Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2064
2065         Parameters:
2066                 fineness: [0.0,1.0] defines mesh fineness
2067
2068         Returns:
2069                 True or False
2070         """
2071
2072         dim = self.MeshDimension()
2073         # assign hypotheses
2074         self.RemoveGlobalHypotheses()
2075         self.Segment().AutomaticLength(fineness)
2076         if dim > 1 :
2077             self.Triangle().LengthFromEdges()
2078             pass
2079         if dim > 2 :
2080             self.Tetrahedron()
2081             pass
2082         return self.Compute()
2083
2084     def AutomaticHexahedralization(self, fineness=0):
2085         """
2086         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2087
2088         Parameters:
2089                 fineness: [0.0, 1.0] defines mesh fineness
2090
2091         Returns:
2092                 True or False
2093         """
2094
2095         dim = self.MeshDimension()
2096         # assign the hypotheses
2097         self.RemoveGlobalHypotheses()
2098         self.Segment().AutomaticLength(fineness)
2099         if dim > 1 :
2100             self.Quadrangle()
2101             pass
2102         if dim > 2 :
2103             self.Hexahedron()
2104             pass
2105         return self.Compute()
2106
2107     def AddHypothesis(self, hyp, geom=0):
2108         """
2109         Assign a hypothesis
2110
2111         Parameters:
2112                 hyp: a hypothesis to assign
2113                 geom: a subhape of mesh geometry
2114
2115         Returns:
2116                 :class:`SMESH.Hypothesis_Status`
2117         """
2118
2119         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2120             hyp, geom = geom, hyp
2121         if isinstance( hyp, Mesh_Algorithm ):
2122             hyp = hyp.GetAlgorithm()
2123             pass
2124         if not geom:
2125             geom = self.geom
2126             if not geom:
2127                 geom = self.mesh.GetShapeToMesh()
2128             pass
2129         isApplicable = True
2130         if self.mesh.HasShapeToMesh():
2131             hyp_type     = hyp.GetName()
2132             lib_name     = hyp.GetLibName()
2133             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2134             # if checkAll and geom:
2135             #     checkAll = geom.GetType() == 37
2136             checkAll     = False
2137             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2138         if isApplicable:
2139             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2140             status = self.mesh.AddHypothesis(geom, hyp)
2141         else:
2142             status = HYP_BAD_GEOMETRY, ""
2143         hyp_name = GetName( hyp )
2144         geom_name = ""
2145         if geom:
2146             geom_name = geom.GetName()
2147         isAlgo = hyp._narrow( SMESH_Algo )
2148         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2149         return status
2150
2151     def IsUsedHypothesis(self, hyp, geom):
2152         """
2153         Return True if an algorithm or hypothesis is assigned to a given shape
2154
2155         Parameters:
2156                 hyp: an algorithm or hypothesis to check
2157                 geom: a subhape of mesh geometry
2158
2159         Returns:
2160                 True of False
2161         """
2162
2163         if not hyp: # or not geom
2164             return False
2165         if isinstance( hyp, Mesh_Algorithm ):
2166             hyp = hyp.GetAlgorithm()
2167             pass
2168         hyps = self.GetHypothesisList(geom)
2169         for h in hyps:
2170             if h.GetId() == hyp.GetId():
2171                 return True
2172         return False
2173
2174     def RemoveHypothesis(self, hyp, geom=0):
2175         """
2176         Unassign a hypothesis
2177
2178         Parameters:
2179                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2180                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2181
2182         Returns:
2183                 :class:`SMESH.Hypothesis_Status`
2184         """
2185
2186         if not hyp:
2187             return None
2188         if isinstance( hyp, Mesh_Algorithm ):
2189             hyp = hyp.GetAlgorithm()
2190             pass
2191         shape = geom
2192         if not shape:
2193             shape = self.geom
2194             pass
2195         if self.IsUsedHypothesis( hyp, shape ):
2196             return self.mesh.RemoveHypothesis( shape, hyp )
2197         hypName = GetName( hyp )
2198         geoName = GetName( shape )
2199         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2200         return None
2201
2202     def GetHypothesisList(self, geom):
2203         """
2204         Get the list of hypotheses added on a geometry
2205
2206         Parameters:
2207                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2208
2209         Returns:
2210                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2211         """
2212
2213         return self.mesh.GetHypothesisList( geom )
2214
2215     def RemoveGlobalHypotheses(self):
2216         """
2217         Remove all global hypotheses
2218         """
2219
2220         current_hyps = self.mesh.GetHypothesisList( self.geom )
2221         for hyp in current_hyps:
2222             self.mesh.RemoveHypothesis( self.geom, hyp )
2223             pass
2224         pass
2225     def ExportMED(self, *args, **kwargs):
2226         """
2227         Export the mesh in a file in MED format
2228         allowing to overwrite the file if it exists or add the exported data to its contents
2229
2230         Parameters:
2231                 fileName: is the file name
2232                 auto_groups (boolean): parameter for creating/not creating
2233                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2234                         the typical use is auto_groups=False.
2235                 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2236                         The minor must be between 0 and the current minor version of MED file library.
2237                         If minor is equal to -1, the minor version is not changed (default).
2238                         The major version (x, where version is x.y.z) cannot be changed.
2239                 overwrite (boolean): parameter for overwriting/not overwriting the file
2240                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2241                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2242
2243                         - 1D if all mesh nodes lie on OX coordinate axis, or
2244                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2245                         - 3D in the rest cases.
2246
2247                         If *autoDimension* is *False*, the space dimension is always 3.
2248                 fields: list of GEOM fields defined on the shape to mesh.
2249                 geomAssocFields: each character of this string means a need to export a 
2250                         corresponding field; correspondence between fields and characters 
2251                         is following:
2252
2253                         - 'v' stands for "_vertices_" field;
2254                         - 'e' stands for "_edges_" field;
2255                         - 'f' stands for "_faces_" field;
2256                         - 's' stands for "_solids_" field.
2257
2258                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2259                              close to zero within a given tolerance, the coordinate is set to zero.
2260                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2261         """
2262         # process positional arguments
2263         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2264         fileName        = args[0]
2265         auto_groups     = args[1] if len(args) > 1 else False
2266         minor           = args[2] if len(args) > 2 else -1
2267         overwrite       = args[3] if len(args) > 3 else True
2268         meshPart        = args[4] if len(args) > 4 else None
2269         autoDimension   = args[5] if len(args) > 5 else True
2270         fields          = args[6] if len(args) > 6 else []
2271         geomAssocFields = args[7] if len(args) > 7 else ''
2272         z_tolerance     = args[8] if len(args) > 8 else -1.
2273         # process keywords arguments
2274         auto_groups     = kwargs.get("auto_groups", auto_groups)
2275         minor           = kwargs.get("minor", minor)
2276         overwrite       = kwargs.get("overwrite", overwrite)
2277         meshPart        = kwargs.get("meshPart", meshPart)
2278         autoDimension   = kwargs.get("autoDimension", autoDimension)
2279         fields          = kwargs.get("fields", fields)
2280         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2281         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2282
2283         # invoke engine's function
2284         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2285             unRegister = genObjUnRegister()
2286             if isinstance( meshPart, list ):
2287                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2288                 unRegister.set( meshPart )
2289
2290             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2291             self.mesh.SetParameters(Parameters)
2292
2293             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2294                                        fields, geomAssocFields, z_tolerance)
2295         else:
2296             self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2297
2298     def ExportSAUV(self, f, auto_groups=0):
2299         """
2300         Export the mesh in a file in SAUV format
2301
2302
2303         Parameters:
2304                 f: is the file name
2305                 auto_groups: boolean parameter for creating/not creating
2306                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2307                         the typical use is auto_groups=False.
2308         """
2309
2310         self.mesh.ExportSAUV(f, auto_groups)
2311
2312     def ExportDAT(self, f, meshPart=None):
2313         """
2314         Export the mesh in a file in DAT format
2315
2316         Parameters:
2317                 f: the file name
2318                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2319         """
2320
2321         if meshPart:
2322             unRegister = genObjUnRegister()
2323             if isinstance( meshPart, list ):
2324                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2325                 unRegister.set( meshPart )
2326             self.mesh.ExportPartToDAT( meshPart, f )
2327         else:
2328             self.mesh.ExportDAT(f)
2329
2330     def ExportUNV(self, f, meshPart=None):
2331         """
2332         Export the mesh in a file in UNV format
2333
2334         Parameters:
2335                 f: the file name
2336                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2337         """
2338
2339         if meshPart:
2340             unRegister = genObjUnRegister()
2341             if isinstance( meshPart, list ):
2342                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2343                 unRegister.set( meshPart )
2344             self.mesh.ExportPartToUNV( meshPart, f )
2345         else:
2346             self.mesh.ExportUNV(f)
2347
2348     def ExportSTL(self, f, ascii=1, meshPart=None):
2349         """
2350         Export the mesh in a file in STL format
2351
2352         Parameters:
2353                 f: the file name
2354                 ascii: defines the file encoding
2355                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2356         """
2357
2358         if meshPart:
2359             unRegister = genObjUnRegister()
2360             if isinstance( meshPart, list ):
2361                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2362                 unRegister.set( meshPart )
2363             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2364         else:
2365             self.mesh.ExportSTL(f, ascii)
2366
2367     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2368         """
2369         Export the mesh in a file in CGNS format
2370
2371         Parameters:
2372                 f: is the file name
2373                 overwrite: boolean parameter for overwriting/not overwriting the file
2374                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2375                 groupElemsByType: if True all elements of same entity type are exported at ones,
2376                         else elements are exported in order of their IDs which can cause creation
2377                         of multiple cgns sections
2378         """
2379
2380         unRegister = genObjUnRegister()
2381         if isinstance( meshPart, list ):
2382             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2383             unRegister.set( meshPart )
2384         if isinstance( meshPart, Mesh ):
2385             meshPart = meshPart.mesh
2386         elif not meshPart:
2387             meshPart = self.mesh
2388         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2389
2390     def ExportGMF(self, f, meshPart=None):
2391         """
2392         Export the mesh in a file in GMF format.
2393         GMF files must have .mesh extension for the ASCII format and .meshb for
2394         the bynary format. Other extensions are not allowed.
2395
2396         Parameters:
2397                 f: is the file name
2398                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2399         """
2400
2401         unRegister = genObjUnRegister()
2402         if isinstance( meshPart, list ):
2403             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2404             unRegister.set( meshPart )
2405         if isinstance( meshPart, Mesh ):
2406             meshPart = meshPart.mesh
2407         elif not meshPart:
2408             meshPart = self.mesh
2409         self.mesh.ExportGMF(meshPart, f, True)
2410
2411     def ExportToMED(self, *args, **kwargs):
2412         """
2413         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2414         Export the mesh in a file in MED format
2415         allowing to overwrite the file if it exists or add the exported data to its contents
2416
2417         Parameters:
2418                 fileName: the file name
2419                 opt (boolean): parameter for creating/not creating
2420                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2421                 overwrite: boolean parameter for overwriting/not overwriting the file
2422                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2423
2424                         - 1D if all mesh nodes lie on OX coordinate axis, or
2425                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2426                         - 3D in the rest cases.
2427
2428                         If **autoDimension** is *False*, the space dimension is always 3.
2429         """
2430     
2431         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2432         # process positional arguments
2433         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2434         fileName      = args[0]
2435         auto_groups   = args[1] if len(args) > 1 else False
2436         overwrite     = args[2] if len(args) > 2 else True
2437         autoDimension = args[3] if len(args) > 3 else True
2438         # process keywords arguments
2439         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2440         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2441         overwrite     = kwargs.get("overwrite", overwrite)
2442         autoDimension = kwargs.get("autoDimension", autoDimension)
2443         minor = -1
2444         # invoke engine's function
2445         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2446
2447     def ExportToMEDX(self, *args, **kwargs):
2448         """
2449         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2450         Export the mesh in a file in MED format
2451
2452         Parameters:
2453                 fileName: the file name
2454                 opt (boolean): parameter for creating/not creating
2455                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2456                 overwrite: boolean parameter for overwriting/not overwriting the file
2457                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2458
2459                         - 1D if all mesh nodes lie on OX coordinate axis, or
2460                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2461                         - 3D in the rest cases.
2462
2463                         If **autoDimension** is *False*, the space dimension is always 3.
2464                 """
2465
2466         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2467         # process positional arguments
2468         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2469         fileName      = args[0]
2470         auto_groups   = args[1] if len(args) > 1 else False
2471         overwrite     = args[2] if len(args) > 2 else True
2472         autoDimension = args[3] if len(args) > 3 else True
2473         # process keywords arguments
2474         auto_groups   = kwargs.get("auto_groups", auto_groups)
2475         overwrite     = kwargs.get("overwrite", overwrite)
2476         autoDimension = kwargs.get("autoDimension", autoDimension)
2477         minor = -1
2478         # invoke engine's function
2479         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2480
2481     # Operations with groups:
2482     # ----------------------
2483     def CreateEmptyGroup(self, elementType, name):
2484         """
2485         Create an empty standalone mesh group
2486
2487         Parameters:
2488                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2489                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2490                 name: the name of the mesh group
2491
2492         Returns:
2493                 :class:`SMESH.SMESH_Group`
2494         """
2495
2496         return self.mesh.CreateGroup(elementType, name)
2497
2498     def Group(self, grp, name=""):
2499         """
2500         Create a mesh group based on the geometric object *grp*
2501         and give it a *name*.
2502         If *name* is not defined the name of the geometric group is used
2503
2504         Note:
2505                 Works like :meth:`GroupOnGeom`.
2506
2507         Parameters:
2508                 grp:  a geometric group, a vertex, an edge, a face or a solid
2509                 name: the name of the mesh group
2510
2511         Returns:
2512                 :class:`SMESH.SMESH_GroupOnGeom`
2513         """
2514
2515         return self.GroupOnGeom(grp, name)
2516
2517     def GroupOnGeom(self, grp, name="", typ=None):
2518         """
2519         Create a mesh group based on the geometrical object *grp*
2520         and give it a *name*.
2521         if *name* is not defined the name of the geometric group is used
2522
2523         Parameters:
2524                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2525                 name: the name of the mesh group
2526                 typ:  the type of elements in the group; either of
2527                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2528                         automatically detected by the type of the geometry
2529
2530         Returns:
2531                 :class:`SMESH.SMESH_GroupOnGeom`
2532         """
2533
2534         AssureGeomPublished( self, grp, name )
2535         if name == "":
2536             name = grp.GetName()
2537         if not typ:
2538             typ = self._groupTypeFromShape( grp )
2539         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2540
2541     def _groupTypeFromShape( self, shape ):
2542         """
2543         Pivate method to get a type of group on geometry
2544         """
2545         tgeo = str(shape.GetShapeType())
2546         if tgeo == "VERTEX":
2547             typ = NODE
2548         elif tgeo == "EDGE":
2549             typ = EDGE
2550         elif tgeo == "FACE" or tgeo == "SHELL":
2551             typ = FACE
2552         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2553             typ = VOLUME
2554         elif tgeo == "COMPOUND":
2555             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2556             if not sub:
2557                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2558             return self._groupTypeFromShape( sub[0] )
2559         else:
2560             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2561         return typ
2562
2563     def GroupOnFilter(self, typ, name, filter):
2564         """
2565         Create a mesh group with given *name* based on the *filter*.
2566         It is a special type of group dynamically updating it's contents during
2567         mesh modification
2568
2569         Parameters:
2570                 typ: the type of elements in the group; either of
2571                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2572                 name: the name of the mesh group
2573                 filter (SMESH.Filter): the filter defining group contents
2574
2575         Returns:
2576                 :class:`SMESH.SMESH_GroupOnFilter`
2577         """
2578
2579         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2580
2581     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2582         """
2583         Create a mesh group by the given ids of elements
2584
2585         Parameters:
2586                 groupName: the name of the mesh group
2587                 elementType: the type of elements in the group; either of
2588                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2589                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2590
2591         Returns:
2592                 :class:`SMESH.SMESH_Group`
2593         """
2594
2595         group = self.mesh.CreateGroup(elementType, groupName)
2596         if isinstance( elemIDs, Mesh ):
2597             elemIDs = elemIDs.GetMesh()
2598         if hasattr( elemIDs, "GetIDs" ):
2599             if hasattr( elemIDs, "SetMesh" ):
2600                 elemIDs.SetMesh( self.GetMesh() )
2601             group.AddFrom( elemIDs )
2602         else:
2603             group.Add(elemIDs)
2604         return group
2605
2606     def MakeGroup(self,
2607                   groupName,
2608                   elementType,
2609                   CritType=FT_Undefined,
2610                   Compare=FT_EqualTo,
2611                   Threshold="",
2612                   UnaryOp=FT_Undefined,
2613                   Tolerance=1e-07):
2614         """
2615         Create a mesh group by the given conditions
2616
2617         Parameters:
2618                 groupName: the name of the mesh group
2619                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2620                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2621                         Note that the items starting from FT_LessThan are not suitable for CritType.
2622                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2623                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2624                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2625                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2626                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2627
2628         Returns:
2629                 :class:`SMESH.SMESH_GroupOnFilter`
2630         """
2631
2632         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2633         group = self.MakeGroupByCriterion(groupName, aCriterion)
2634         return group
2635
2636     def MakeGroupByCriterion(self, groupName, Criterion):
2637         """
2638         Create a mesh group by the given criterion
2639
2640         Parameters:
2641                 groupName: the name of the mesh group
2642                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2643
2644         Returns:
2645                 :class:`SMESH.SMESH_GroupOnFilter`
2646
2647         See Also:
2648                 :meth:`smeshBuilder.GetCriterion`
2649         """
2650
2651         return self.MakeGroupByCriteria( groupName, [Criterion] )
2652
2653     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2654         """
2655         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2656
2657         Parameters:
2658                 groupName: the name of the mesh group
2659                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2660                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2661
2662         Returns:
2663                 :class:`SMESH.SMESH_GroupOnFilter`
2664
2665         See Also:
2666                 :meth:`smeshBuilder.GetCriterion`
2667         """
2668
2669         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2670         group = self.MakeGroupByFilter(groupName, aFilter)
2671         return group
2672
2673     def MakeGroupByFilter(self, groupName, theFilter):
2674         """
2675         Create a mesh group by the given filter
2676
2677         Parameters:
2678                 groupName (string): the name of the mesh group
2679                 theFilter (SMESH.Filter): the filter
2680
2681         Returns:
2682                 :class:`SMESH.SMESH_GroupOnFilter`
2683
2684         See Also:
2685                 :meth:`smeshBuilder.GetFilter`
2686         """
2687
2688         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2689         #theFilter.SetMesh( self.mesh )
2690         #group.AddFrom( theFilter )
2691         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2692         return group
2693
2694     def RemoveGroup(self, group):
2695         """
2696         Remove a group
2697
2698         Parameters:
2699                 group (SMESH.SMESH_GroupBase): group to remove
2700         """
2701
2702         self.mesh.RemoveGroup(group)
2703
2704     def RemoveGroupWithContents(self, group):
2705         """
2706         Remove a group with its contents
2707
2708         Parameters:
2709                 group (SMESH.SMESH_GroupBase): group to remove
2710         """
2711
2712         self.mesh.RemoveGroupWithContents(group)
2713
2714     def GetGroups(self, elemType = SMESH.ALL):
2715         """
2716         Get the list of groups existing in the mesh in the order of creation 
2717         (starting from the oldest one)
2718
2719         Parameters:
2720                 elemType (SMESH.ElementType): type of elements the groups contain;
2721                         by default groups of elements of all types are returned
2722
2723         Returns:
2724                 a list of :class:`SMESH.SMESH_GroupBase`
2725         """
2726
2727         groups = self.mesh.GetGroups()
2728         if elemType == SMESH.ALL:
2729             return groups
2730         typedGroups = []
2731         for g in groups:
2732             if g.GetType() == elemType:
2733                 typedGroups.append( g )
2734                 pass
2735             pass
2736         return typedGroups
2737
2738     def NbGroups(self):
2739         """
2740         Get the number of groups existing in the mesh
2741
2742         Returns:
2743                 the quantity of groups as an integer value
2744         """
2745
2746         return self.mesh.NbGroups()
2747
2748     def GetGroupNames(self):
2749         """
2750         Get the list of names of groups existing in the mesh
2751
2752         Returns:
2753                 list of strings
2754         """
2755
2756         groups = self.GetGroups()
2757         names = []
2758         for group in groups:
2759             names.append(group.GetName())
2760         return names
2761
2762     def GetGroupByName(self, name, elemType = None):
2763         """
2764         Find groups by name and type
2765
2766         Parameters:
2767                 name (string): name of the group of interest
2768                 elemType (SMESH.ElementType): type of elements the groups contain;
2769                         by default one group of any type is returned;
2770                         if elemType == SMESH.ALL then all groups of any type are returned
2771
2772         Returns:
2773                 a list of :class:`SMESH.SMESH_GroupBase`
2774         """
2775
2776         groups = []
2777         for group in self.GetGroups():
2778             if group.GetName() == name:
2779                 if elemType is None:
2780                     return [group]
2781                 if ( elemType == SMESH.ALL or
2782                      group.GetType() == elemType ):
2783                     groups.append( group )
2784         return groups
2785
2786     def UnionGroups(self, group1, group2, name):
2787         """
2788         Produce a union of two groups.
2789         A new group is created. All mesh elements that are
2790         present in the initial groups are added to the new one
2791
2792         Parameters:
2793            group1 (SMESH.SMESH_GroupBase): a group
2794            group2 (SMESH.SMESH_GroupBase): another group
2795
2796         Returns:
2797                 instance of :class:`SMESH.SMESH_Group`
2798         """
2799
2800         return self.mesh.UnionGroups(group1, group2, name)
2801
2802     def UnionListOfGroups(self, groups, name):
2803         """
2804         Produce a union list of groups.
2805         New group is created. All mesh elements that are present in
2806         initial groups are added to the new one
2807
2808         Parameters:
2809            groups: list of :class:`SMESH.SMESH_GroupBase`
2810
2811         Returns:
2812                 instance of :class:`SMESH.SMESH_Group`
2813         """
2814         return self.mesh.UnionListOfGroups(groups, name)
2815
2816     def IntersectGroups(self, group1, group2, name):
2817         """
2818         Prodice an intersection of two groups.
2819         A new group is created. All mesh elements that are common
2820         for the two initial groups are added to the new one.
2821
2822         Parameters:
2823            group1 (SMESH.SMESH_GroupBase): a group
2824            group2 (SMESH.SMESH_GroupBase): another group
2825
2826         Returns:
2827                 instance of :class:`SMESH.SMESH_Group`
2828         """
2829
2830         return self.mesh.IntersectGroups(group1, group2, name)
2831
2832     def IntersectListOfGroups(self, groups, name):
2833         """
2834         Produce an intersection of groups.
2835         New group is created. All mesh elements that are present in all
2836         initial groups simultaneously are added to the new one
2837
2838         Parameters:
2839            groups: a list of :class:`SMESH.SMESH_GroupBase`
2840
2841         Returns:
2842                 instance of :class:`SMESH.SMESH_Group`
2843         """
2844         return self.mesh.IntersectListOfGroups(groups, name)
2845
2846     def CutGroups(self, main_group, tool_group, name):
2847         """
2848         Produce a cut of two groups.
2849         A new group is created. All mesh elements that are present in
2850         the main group but are not present in the tool group are added to the new one
2851
2852         Parameters:
2853            main_group (SMESH.SMESH_GroupBase): a group to cut from
2854            tool_group (SMESH.SMESH_GroupBase): a group to cut by
2855
2856         Returns:
2857                 an instance of :class:`SMESH.SMESH_Group`
2858         """
2859
2860         return self.mesh.CutGroups(main_group, tool_group, name)
2861
2862     def CutListOfGroups(self, main_groups, tool_groups, name):
2863         """
2864         Produce a cut of groups.
2865         A new group is created. All mesh elements that are present in main groups
2866         but do not present in tool groups are added to the new one
2867
2868         Parameters:
2869            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
2870            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
2871
2872         Returns:
2873                 an instance of :class:`SMESH.SMESH_Group`
2874         """
2875
2876         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2877
2878     def CreateDimGroup(self, groups, elemType, name,
2879                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2880         """
2881         Create a standalone group of entities basing on nodes of other groups.
2882
2883         Parameters:
2884                 groups: list of reference :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2885                 elemType: a type of elements to include to the new group; either of
2886                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2887                 name: a name of the new group.
2888                 nbCommonNodes: a criterion of inclusion of an element to the new group
2889                         basing on number of element nodes common with reference *groups*.
2890                         Meaning of possible values are:
2891
2892                                 - SMESH.ALL_NODES - include if all nodes are common,
2893                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2894                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2895                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
2896                 underlyingOnly: if *True* (default), an element is included to the
2897                         new group provided that it is based on nodes of an element of *groups*;
2898                         in this case the reference *groups* are supposed to be of higher dimension
2899                         than *elemType*, which can be useful for example to get all faces lying on
2900                         volumes of the reference *groups*.
2901
2902         Returns:
2903                 an instance of :class:`SMESH.SMESH_Group`
2904         """
2905
2906         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2907             groups = [groups]
2908         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2909
2910     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2911         """
2912         Distribute all faces of the mesh among groups using sharp edges and optionally
2913         existing 1D elements as group boundaries.
2914
2915         Parameters:
2916                 sharpAngle: edge is considered sharp if an angle between normals of
2917                             adjacent faces is more than \a sharpAngle in degrees.
2918                 createEdges (boolean): to create 1D elements for detected sharp edges.
2919                 useExistingEdges (boolean): to use existing edges as group boundaries
2920         Returns:
2921                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2922         """
2923         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2924         self.mesh.SetParameters(Parameters)
2925         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2926
2927     def ConvertToStandalone(self, group):
2928         """
2929         Convert group on geom into standalone group
2930         """
2931
2932         return self.mesh.ConvertToStandalone(group)
2933
2934     # Get some info about mesh:
2935     # ------------------------
2936
2937     def GetLog(self, clearAfterGet):
2938         """
2939         Return the log of nodes and elements added or removed
2940         since the previous clear of the log.
2941
2942         Parameters:
2943                 clearAfterGet: log is emptied after Get (safe if concurrents access)
2944
2945         Returns:
2946                 list of SMESH.log_block structures { commandType, number, coords, indexes }
2947         """
2948
2949         return self.mesh.GetLog(clearAfterGet)
2950
2951     def ClearLog(self):
2952         """
2953         Clear the log of nodes and elements added or removed since the previous
2954         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
2955         """
2956
2957         self.mesh.ClearLog()
2958
2959     def SetAutoColor(self, theAutoColor):
2960         """
2961         Toggle auto color mode on the object.
2962         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2963
2964         Parameters:
2965                 theAutoColor (boolean): the flag which toggles auto color mode.
2966         """
2967
2968         self.mesh.SetAutoColor(theAutoColor)
2969
2970     def GetAutoColor(self):
2971         """
2972         Get flag of object auto color mode.
2973
2974         Returns:
2975                 True or False
2976         """
2977
2978         return self.mesh.GetAutoColor()
2979
2980     def GetId(self):
2981         """
2982         Get the internal ID
2983
2984         Returns:
2985             integer value, which is the internal Id of the mesh
2986         """
2987
2988         return self.mesh.GetId()
2989
2990     def HasDuplicatedGroupNamesMED(self):
2991         """
2992         Check the group names for duplications.
2993         Consider the maximum group name length stored in MED file.
2994
2995         Returns:
2996             True or False
2997         """
2998
2999         return self.mesh.HasDuplicatedGroupNamesMED()
3000
3001     def GetMeshEditor(self):
3002         """
3003         Obtain the mesh editor tool
3004
3005         Returns:
3006             an instance of :class:`SMESH.SMESH_MeshEditor`
3007         """
3008
3009         return self.editor
3010
3011     def GetIDSource(self, ids, elemType = SMESH.ALL):
3012         """
3013         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3014         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3015
3016         Parameters:
3017                 ids: list of IDs
3018                 elemType: type of elements; this parameter is used to distinguish
3019                         IDs of nodes from IDs of elements; by default ids are treated as
3020                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3021
3022         Returns:
3023             an instance of :class:`SMESH.SMESH_IDSource`
3024
3025         Warning:
3026                 call UnRegister() for the returned object as soon as it is no more useful::
3027
3028                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3029                         mesh.DoSomething( idSrc )
3030                         idSrc.UnRegister()
3031         """
3032
3033         if isinstance( ids, int ):
3034             ids = [ids]
3035         return self.editor.MakeIDSource(ids, elemType)
3036
3037
3038     # Get information about mesh contents:
3039     # ------------------------------------
3040
3041     def GetMeshInfo(self, obj = None):
3042         """
3043         Get the mesh statistic.
3044         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
3045         an item of :class:`SMESH.EntityType`.
3046
3047         Returns:
3048                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3049         """
3050
3051         if not obj: obj = self.mesh
3052         return self.smeshpyD.GetMeshInfo(obj)
3053
3054     def NbNodes(self):
3055         """
3056         Return the number of nodes in the mesh
3057
3058         Returns:
3059             an integer value
3060         """
3061
3062         return self.mesh.NbNodes()
3063
3064     def NbElements(self):
3065         """
3066         Return the number of elements in the mesh
3067
3068         Returns:
3069             an integer value
3070         """
3071
3072         return self.mesh.NbElements()
3073
3074     def Nb0DElements(self):
3075         """
3076         Return the number of 0d elements in the mesh
3077
3078         Returns:
3079             an integer value
3080         """
3081
3082         return self.mesh.Nb0DElements()
3083
3084     def NbBalls(self):
3085         """
3086         Return the number of ball discrete elements in the mesh
3087
3088         Returns:
3089             an integer value
3090         """
3091
3092         return self.mesh.NbBalls()
3093
3094     def NbEdges(self):
3095         """
3096         Return the number of edges in the mesh
3097
3098         Returns:
3099             an integer value
3100         """
3101
3102         return self.mesh.NbEdges()
3103
3104     def NbEdgesOfOrder(self, elementOrder):
3105         """
3106         Return the number of edges with the given order in the mesh
3107
3108         Parameters:
3109                 elementOrder: the order of elements
3110                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3111
3112         Returns:
3113             an integer value
3114         """
3115
3116         return self.mesh.NbEdgesOfOrder(elementOrder)
3117
3118     def NbFaces(self):
3119         """
3120         Return the number of faces in the mesh
3121
3122         Returns:
3123             an integer value
3124         """
3125
3126         return self.mesh.NbFaces()
3127
3128     def NbFacesOfOrder(self, elementOrder):
3129         """
3130         Return the number of faces with the given order in the mesh
3131
3132         Parameters:
3133                 elementOrder: the order of elements
3134                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3135
3136         Returns:
3137             an integer value
3138         """
3139
3140         return self.mesh.NbFacesOfOrder(elementOrder)
3141
3142     def NbTriangles(self):
3143         """
3144         Return the number of triangles in the mesh
3145
3146         Returns:
3147             an integer value
3148         """
3149
3150         return self.mesh.NbTriangles()
3151
3152     def NbTrianglesOfOrder(self, elementOrder):
3153         """
3154         Return the number of triangles with the given order in the mesh
3155
3156         Parameters:
3157                 elementOrder: is the order of elements
3158                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3159
3160         Returns:
3161             an integer value
3162         """
3163
3164         return self.mesh.NbTrianglesOfOrder(elementOrder)
3165
3166     def NbBiQuadTriangles(self):
3167         """
3168         Return the number of biquadratic triangles in the mesh
3169
3170         Returns:
3171             an integer value
3172         """
3173
3174         return self.mesh.NbBiQuadTriangles()
3175
3176     def NbQuadrangles(self):
3177         """
3178         Return the number of quadrangles in the mesh
3179
3180         Returns:
3181             an integer value
3182         """
3183
3184         return self.mesh.NbQuadrangles()
3185
3186     def NbQuadranglesOfOrder(self, elementOrder):
3187         """
3188         Return the number of quadrangles with the given order in the mesh
3189
3190         Parameters:
3191                 elementOrder: the order of elements
3192                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3193
3194         Returns:
3195             an integer value
3196         """
3197
3198         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3199
3200     def NbBiQuadQuadrangles(self):
3201         """
3202         Return the number of biquadratic quadrangles in the mesh
3203
3204         Returns:
3205             an integer value
3206         """
3207
3208         return self.mesh.NbBiQuadQuadrangles()
3209
3210     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3211         """
3212         Return the number of polygons of given order in the mesh
3213
3214         Parameters:
3215                 elementOrder: the order of elements
3216                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3217
3218         Returns:
3219             an integer value
3220         """
3221
3222         return self.mesh.NbPolygonsOfOrder(elementOrder)
3223
3224     def NbVolumes(self):
3225         """
3226         Return the number of volumes in the mesh
3227
3228         Returns:
3229             an integer value
3230         """
3231
3232         return self.mesh.NbVolumes()
3233
3234
3235     def NbVolumesOfOrder(self, elementOrder):
3236         """
3237         Return the number of volumes with the given order in the mesh
3238
3239         Parameters:
3240                 elementOrder:  the order of elements
3241                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3242
3243         Returns:
3244             an integer value
3245         """
3246
3247         return self.mesh.NbVolumesOfOrder(elementOrder)
3248
3249     def NbTetras(self):
3250         """
3251         Return the number of tetrahedrons in the mesh
3252
3253         Returns:
3254             an integer value
3255         """
3256
3257         return self.mesh.NbTetras()
3258
3259     def NbTetrasOfOrder(self, elementOrder):
3260         """
3261         Return the number of tetrahedrons with the given order in the mesh
3262
3263         Parameters:
3264                 elementOrder:  the order of elements
3265                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3266
3267         Returns:
3268             an integer value
3269         """
3270
3271         return self.mesh.NbTetrasOfOrder(elementOrder)
3272
3273     def NbHexas(self):
3274         """
3275         Return the number of hexahedrons in the mesh
3276
3277         Returns:
3278             an integer value
3279         """
3280
3281         return self.mesh.NbHexas()
3282
3283     def NbHexasOfOrder(self, elementOrder):
3284         """
3285         Return the number of hexahedrons with the given order in the mesh
3286
3287         Parameters:
3288                 elementOrder:  the order of elements
3289                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3290
3291         Returns:
3292             an integer value
3293         """
3294
3295         return self.mesh.NbHexasOfOrder(elementOrder)
3296
3297     def NbTriQuadraticHexas(self):
3298         """
3299         Return the number of triquadratic hexahedrons in the mesh
3300
3301         Returns:
3302             an integer value
3303         """
3304
3305         return self.mesh.NbTriQuadraticHexas()
3306
3307     def NbPyramids(self):
3308         """
3309         Return the number of pyramids in the mesh
3310
3311         Returns:
3312             an integer value
3313         """
3314
3315         return self.mesh.NbPyramids()
3316
3317     def NbPyramidsOfOrder(self, elementOrder):
3318         """
3319         Return the number of pyramids with the given order in the mesh
3320
3321         Parameters:
3322                 elementOrder:  the order of elements
3323                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3324
3325         Returns:
3326             an integer value
3327         """
3328
3329         return self.mesh.NbPyramidsOfOrder(elementOrder)
3330
3331     def NbPrisms(self):
3332         """
3333         Return the number of prisms in the mesh
3334
3335         Returns:
3336             an integer value
3337         """
3338
3339         return self.mesh.NbPrisms()
3340
3341     def NbPrismsOfOrder(self, elementOrder):
3342         """
3343         Return the number of prisms with the given order in the mesh
3344
3345         Parameters:
3346                 elementOrder:  the order of elements
3347                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3348
3349         Returns:
3350             an integer value
3351         """
3352
3353         return self.mesh.NbPrismsOfOrder(elementOrder)
3354
3355     def NbHexagonalPrisms(self):
3356         """
3357         Return the number of hexagonal prisms in the mesh
3358
3359         Returns:
3360             an integer value
3361         """
3362
3363         return self.mesh.NbHexagonalPrisms()
3364
3365     def NbPolyhedrons(self):
3366         """
3367         Return the number of polyhedrons in the mesh
3368
3369         Returns:
3370             an integer value
3371         """
3372
3373         return self.mesh.NbPolyhedrons()
3374
3375     def NbSubMesh(self):
3376         """
3377         Return the number of submeshes in the mesh
3378
3379         Returns:
3380             an integer value
3381         """
3382
3383         return self.mesh.NbSubMesh()
3384
3385     def GetElementsId(self):
3386         """
3387         Return the list of all mesh elements IDs
3388
3389         Returns:
3390             the list of integer values
3391
3392         See Also:
3393             :meth:`GetElementsByType`
3394         """
3395
3396         return self.mesh.GetElementsId()
3397
3398     def GetElementsByType(self, elementType):
3399         """
3400         Return the list of IDs of mesh elements with the given type
3401
3402         Parameters:
3403                 elementType (SMESH.ElementType):  the required type of elements
3404
3405         Returns:
3406             list of integer values
3407         """
3408
3409         return self.mesh.GetElementsByType(elementType)
3410
3411     def GetNodesId(self):
3412         """
3413         Return the list of mesh nodes IDs
3414
3415         Returns:
3416             the list of integer values
3417         """
3418
3419         return self.mesh.GetNodesId()
3420
3421     # Get the information about mesh elements:
3422     # ------------------------------------
3423
3424     def GetElementType(self, id, iselem=True):
3425         """
3426         Return the type of mesh element or node
3427
3428         Returns:
3429             the value from :class:`SMESH.ElementType` enumeration. 
3430             Return SMESH.ALL if element or node with the given ID does not exist
3431         """
3432
3433         return self.mesh.GetElementType(id, iselem)
3434
3435     def GetElementGeomType(self, id):
3436         """
3437         Return the geometric type of mesh element
3438
3439         Returns:
3440             the value from :class:`SMESH.EntityType` enumeration.
3441         """
3442
3443         return self.mesh.GetElementGeomType(id)
3444
3445     def GetElementShape(self, id):
3446         """
3447         Return the shape type of mesh element
3448
3449         Returns:
3450             the value from :class:`SMESH.GeometryType` enumeration.
3451         """
3452
3453         return self.mesh.GetElementShape(id)
3454
3455     def GetSubMeshElementsId(self, Shape):
3456         """
3457         Return the list of sub-mesh elements IDs
3458
3459         Parameters:
3460                 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3461                        *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3462
3463         Returns:
3464             list of integer values
3465         """
3466
3467         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3468             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3469         else:
3470             ShapeID = Shape
3471         return self.mesh.GetSubMeshElementsId(ShapeID)
3472
3473     def GetSubMeshNodesId(self, Shape, all):
3474         """
3475         Return the list of sub-mesh nodes IDs
3476
3477         Parameters:
3478                 Shape: a geom object (sub-shape).
3479                        *Shape* must be the sub-shape of a :meth:`GetShape`
3480                 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3481
3482         Returns:
3483             list of integer values
3484         """
3485
3486         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3487             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3488         else:
3489             ShapeID = Shape
3490         return self.mesh.GetSubMeshNodesId(ShapeID, all)
3491
3492     def GetSubMeshElementType(self, Shape):
3493         """
3494         Return type of elements on given shape
3495
3496         Parameters:
3497                 Shape: a geom object (sub-shape).
3498                        *Shape* must be a sub-shape of a ShapeToMesh()
3499
3500         Returns:
3501             :class:`SMESH.ElementType`
3502         """
3503
3504         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3505             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3506         else:
3507             ShapeID = Shape
3508         return self.mesh.GetSubMeshElementType(ShapeID)
3509
3510     def Dump(self):
3511         """
3512         Get the mesh description
3513
3514         Returns:
3515             string value
3516         """
3517
3518         return self.mesh.Dump()
3519
3520
3521     # Get the information about nodes and elements of a mesh by its IDs:
3522     # -----------------------------------------------------------
3523
3524     def GetNodeXYZ(self, id):
3525         """
3526         Get XYZ coordinates of a node.
3527         If there is no node for the given ID - return an empty list
3528
3529         Returns:
3530             list of float values
3531         """
3532
3533         return self.mesh.GetNodeXYZ(id)
3534
3535     def GetNodeInverseElements(self, id):
3536         """
3537         Return list of IDs of inverse elements for the given node.
3538         If there is no node for the given ID - return an empty list
3539
3540         Returns:
3541             list of integer values
3542         """
3543
3544         return self.mesh.GetNodeInverseElements(id)
3545
3546     def GetNodePosition(self,NodeID):
3547         """
3548         Return the position of a node on the shape
3549
3550         Returns:
3551             :class:`SMESH.NodePosition`
3552         """
3553
3554         return self.mesh.GetNodePosition(NodeID)
3555
3556     def GetElementPosition(self,ElemID):
3557         """
3558         Return the position of an element on the shape
3559
3560         Returns:
3561             :class:`SMESH.ElementPosition`
3562         """
3563
3564         return self.mesh.GetElementPosition(ElemID)
3565
3566     def GetShapeID(self, id):
3567         """
3568         Return the ID of the shape, on which the given node was generated.
3569
3570         Returns:
3571             an integer value > 0 or -1 if there is no node for the given
3572             ID or the node is not assigned to any geometry
3573         """
3574
3575         return self.mesh.GetShapeID(id)
3576
3577     def GetShapeIDForElem(self,id):
3578         """
3579         Return the ID of the shape, on which the given element was generated.
3580
3581         Returns:
3582             an integer value > 0 or -1 if there is no element for the given
3583             ID or the element is not assigned to any geometry
3584         """
3585
3586         return self.mesh.GetShapeIDForElem(id)
3587
3588     def GetElemNbNodes(self, id):
3589         """
3590         Return the number of nodes of the given element
3591
3592         Returns:
3593             an integer value > 0 or -1 if there is no element for the given ID
3594         """
3595
3596         return self.mesh.GetElemNbNodes(id)
3597
3598     def GetElemNode(self, id, index):
3599         """
3600         Return the node ID the given (zero based) index for the given element.
3601
3602         * If there is no element for the given ID - return -1.
3603         * If there is no node for the given index - return -2.
3604
3605         Parameters:
3606             id (int): element ID
3607             index (int): node index within the element
3608
3609         Returns:
3610             an integer value (ID)
3611
3612         See Also:
3613             :meth:`GetElemNodes`
3614         """
3615
3616         return self.mesh.GetElemNode(id, index)
3617
3618     def GetElemNodes(self, id):
3619         """
3620         Return the IDs of nodes of the given element
3621
3622         Returns:
3623             a list of integer values
3624         """
3625
3626         return self.mesh.GetElemNodes(id)
3627
3628     def IsMediumNode(self, elementID, nodeID):
3629         """
3630         Return true if the given node is the medium node in the given quadratic element
3631         """
3632
3633         return self.mesh.IsMediumNode(elementID, nodeID)
3634
3635     def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3636         """
3637         Return true if the given node is the medium node in one of quadratic elements
3638
3639         Parameters:
3640                 nodeID: ID of the node
3641                 elementType:  the type of elements to check a state of the node, either of
3642                         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3643         """
3644
3645         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3646
3647     def ElemNbEdges(self, id):
3648         """
3649         Return the number of edges for the given element
3650         """
3651
3652         return self.mesh.ElemNbEdges(id)
3653
3654     def ElemNbFaces(self, id):
3655         """
3656         Return the number of faces for the given element
3657         """
3658
3659         return self.mesh.ElemNbFaces(id)
3660
3661     def GetElemFaceNodes(self,elemId, faceIndex):
3662         """
3663         Return nodes of given face (counted from zero) for given volumic element.
3664         """
3665
3666         return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3667
3668     def GetFaceNormal(self, faceId, normalized=False):
3669         """
3670         Return three components of normal of given mesh face
3671         (or an empty array in KO case)
3672         """
3673
3674         return self.mesh.GetFaceNormal(faceId,normalized)
3675
3676     def FindElementByNodes(self, nodes):
3677         """
3678         Return an element based on all given nodes.
3679         """
3680
3681         return self.mesh.FindElementByNodes(nodes)
3682
3683     def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3684         """
3685         Return elements including all given nodes.
3686         """
3687
3688         return self.mesh.GetElementsByNodes( nodes, elemType )
3689
3690     def IsPoly(self, id):
3691         """
3692         Return true if the given element is a polygon
3693         """
3694
3695         return self.mesh.IsPoly(id)
3696
3697     def IsQuadratic(self, id):
3698         """
3699         Return true if the given element is quadratic
3700         """
3701
3702         return self.mesh.IsQuadratic(id)
3703
3704     def GetBallDiameter(self, id):
3705         """
3706         Return diameter of a ball discrete element or zero in case of an invalid *id*
3707         """
3708
3709         return self.mesh.GetBallDiameter(id)
3710
3711     def BaryCenter(self, id):
3712         """
3713         Return XYZ coordinates of the barycenter of the given element.
3714         If there is no element for the given ID - return an empty list
3715
3716         Returns:
3717             a list of three double values
3718         """
3719
3720         return self.mesh.BaryCenter(id)
3721
3722     def GetIdsFromFilter(self, theFilter):
3723         """
3724         Pass mesh elements through the given filter and return IDs of fitting elements
3725
3726         Parameters:
3727                 theFilter: :class:`SMESH.Filter`
3728
3729         Returns:
3730             a list of ids
3731
3732         See Also:
3733             :meth:`SMESH.Filter.GetIDs`
3734         """
3735
3736         theFilter.SetMesh( self.mesh )
3737         return theFilter.GetIDs()
3738
3739     # Get mesh measurements information:
3740     # ------------------------------------
3741
3742     def GetFreeBorders(self):
3743         """
3744         Verify whether a 2D mesh element has free edges (edges connected to one face only).
3745         Return a list of special structures (borders).
3746
3747         Returns:
3748             a list of :class:`SMESH.FreeEdges.Border`
3749         """
3750
3751         aFilterMgr = self.smeshpyD.CreateFilterManager()
3752         aPredicate = aFilterMgr.CreateFreeEdges()
3753         aPredicate.SetMesh(self.mesh)
3754         aBorders = aPredicate.GetBorders()
3755         aFilterMgr.UnRegister()
3756         return aBorders
3757
3758     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3759         """
3760         Get minimum distance between two nodes, elements or distance to the origin
3761
3762         Parameters:
3763                 id1: first node/element id
3764                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3765                 isElem1: *True* if *id1* is element id, *False* if it is node id
3766                 isElem2: *True* if *id2* is element id, *False* if it is node id
3767
3768         Returns:
3769             minimum distance value
3770         See Also:
3771             :meth:`GetMinDistance`
3772         """
3773
3774         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3775         return aMeasure.value
3776
3777     def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3778         """
3779         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3780
3781         Parameters:
3782                 id1: first node/element id
3783                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3784                 isElem1: *True* if *id1* is element id, *False* if it is node id
3785                 isElem2: *True* if *id2* is element id, *False* if it is node id
3786
3787         Returns:
3788             :class:`SMESH.Measure` structure
3789         See Also:
3790             :meth:`MinDistance`
3791         """
3792
3793         if isElem1:
3794             id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3795         else:
3796             id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3797         if id2 != 0:
3798             if isElem2:
3799                 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3800             else:
3801                 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3802             pass
3803         else:
3804             id2 = None
3805
3806         aMeasurements = self.smeshpyD.CreateMeasurements()
3807         aMeasure = aMeasurements.MinDistance(id1, id2)
3808         genObjUnRegister([aMeasurements,id1, id2])
3809         return aMeasure
3810
3811     def BoundingBox(self, objects=None, isElem=False):
3812         """
3813         Get bounding box of the specified object(s)
3814
3815         Parameters:
3816                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3817                 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3818                         *False* specifies that *objects* are nodes
3819
3820         Returns:
3821             tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3822
3823         See Also: 
3824             :meth:`GetBoundingBox()`
3825         """
3826
3827         result = self.GetBoundingBox(objects, isElem)
3828         if result is None:
3829             result = (0.0,)*6
3830         else:
3831             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3832         return result
3833
3834     def GetBoundingBox(self, objects=None, isElem=False):
3835         """
3836         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3837
3838         Parameters:
3839                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3840                 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3841                         False means that *objects* are nodes
3842
3843         Returns:
3844             :class:`SMESH.Measure` structure
3845
3846         See Also: 
3847             :meth:`BoundingBox()`
3848         """
3849
3850         if objects is None:
3851             objects = [self.mesh]
3852         elif isinstance(objects, tuple):
3853             objects = list(objects)
3854         if not isinstance(objects, list):
3855             objects = [objects]
3856         if len(objects) > 0 and isinstance(objects[0], int):
3857             objects = [objects]
3858         srclist = []
3859         unRegister = genObjUnRegister()
3860         for o in objects:
3861             if isinstance(o, Mesh):
3862                 srclist.append(o.mesh)
3863             elif hasattr(o, "_narrow"):
3864                 src = o._narrow(SMESH.SMESH_IDSource)
3865                 if src: srclist.append(src)
3866                 pass
3867             elif isinstance(o, list):
3868                 if isElem:
3869                     srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3870                 else:
3871                     srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3872                 unRegister.set( srclist[-1] )
3873                 pass
3874             pass
3875         aMeasurements = self.smeshpyD.CreateMeasurements()
3876         unRegister.set( aMeasurements )
3877         aMeasure = aMeasurements.BoundingBox(srclist)
3878         return aMeasure
3879
3880     # Mesh edition (SMESH_MeshEditor functionality):
3881     # ---------------------------------------------
3882
3883     def RemoveElements(self, IDsOfElements):
3884         """
3885         Remove the elements from the mesh by ids
3886
3887         Parameters:
3888                 IDsOfElements: is a list of ids of elements to remove
3889
3890         Returns:
3891             True or False
3892         """
3893
3894         return self.editor.RemoveElements(IDsOfElements)
3895
3896     def RemoveNodes(self, IDsOfNodes):
3897         """
3898         Remove nodes from mesh by ids
3899
3900         Parameters:
3901                 IDsOfNodes: is a list of ids of nodes to remove
3902
3903         Returns:
3904             True or False
3905         """
3906
3907         return self.editor.RemoveNodes(IDsOfNodes)
3908
3909     def RemoveOrphanNodes(self):
3910         """
3911         Remove all orphan (free) nodes from mesh
3912
3913         Returns:
3914             number of the removed nodes
3915         """
3916
3917         return self.editor.RemoveOrphanNodes()
3918
3919     def AddNode(self, x, y, z):
3920         """
3921         Add a node to the mesh by coordinates
3922
3923         Returns:
3924             ID of the new node
3925         """
3926
3927         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3928         if hasVars: self.mesh.SetParameters(Parameters)
3929         return self.editor.AddNode( x, y, z)
3930
3931     def Add0DElement( self, IDOfNode, DuplicateElements=True ):
3932         """
3933         Create a 0D element on a node with given number.
3934
3935         Parameters:
3936                 IDOfNode: the ID of node for creation of the element.
3937                 DuplicateElements: to add one more 0D element to a node or not
3938
3939         Returns:
3940             ID of the new 0D element
3941         """
3942
3943         return self.editor.Add0DElement( IDOfNode, DuplicateElements )
3944
3945     def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
3946         """
3947         Create 0D elements on all nodes of the given elements except those
3948         nodes on which a 0D element already exists.
3949
3950         Parameters:
3951                 theObject: an object on whose nodes 0D elements will be created.
3952                         It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3953                 theGroupName: optional name of a group to add 0D elements created
3954                         and/or found on nodes of *theObject*.
3955                 DuplicateElements: to add one more 0D element to a node or not
3956
3957         Returns:
3958             an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
3959             IDs of new and/or found 0D elements. IDs of 0D elements
3960             can be retrieved from the returned object by 
3961             calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
3962         """
3963
3964         unRegister = genObjUnRegister()
3965         if isinstance( theObject, Mesh ):
3966             theObject = theObject.GetMesh()
3967         elif isinstance( theObject, list ):
3968             theObject = self.GetIDSource( theObject, SMESH.ALL )
3969             unRegister.set( theObject )
3970         return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
3971
3972     def AddBall(self, IDOfNode, diameter):
3973         """
3974         Create a ball element on a node with given ID.
3975
3976         Parameters:
3977                 IDOfNode: the ID of node for creation of the element.
3978                 diameter: the bal diameter.
3979
3980         Returns:
3981             ID of the new ball element
3982         """
3983
3984         return self.editor.AddBall( IDOfNode, diameter )
3985
3986     def AddEdge(self, IDsOfNodes):
3987         """
3988         Create a linear or quadratic edge (this is determined
3989         by the number of given nodes).
3990
3991         Parameters:
3992                 IDsOfNodes: list of node IDs for creation of the element.
3993                         The order of nodes in this list should correspond to
3994                         the :ref:`connectivity convention <connectivity_page>`.
3995
3996         Returns:
3997             ID of the new edge
3998         """
3999
4000         return self.editor.AddEdge(IDsOfNodes)
4001
4002     def AddFace(self, IDsOfNodes):
4003         """
4004         Create a linear or quadratic face (this is determined
4005         by the number of given nodes).
4006
4007         Parameters:
4008                 IDsOfNodes: list of node IDs for creation of the element.
4009                         The order of nodes in this list should correspond to
4010                         the :ref:`connectivity convention <connectivity_page>`.
4011
4012         Returns:
4013             ID of the new face
4014         """
4015
4016         return self.editor.AddFace(IDsOfNodes)
4017
4018     def AddPolygonalFace(self, IdsOfNodes):
4019         """
4020         Add a polygonal face defined by a list of node IDs
4021
4022         Parameters:
4023                 IdsOfNodes: the list of node IDs for creation of the element.
4024
4025         Returns:
4026             ID of the new face
4027         """
4028
4029         return self.editor.AddPolygonalFace(IdsOfNodes)
4030
4031     def AddQuadPolygonalFace(self, IdsOfNodes):
4032         """
4033         Add a quadratic polygonal face defined by a list of node IDs
4034
4035         Parameters:
4036                 IdsOfNodes: the list of node IDs for creation of the element;
4037                         corner nodes follow first.
4038
4039         Returns:
4040             ID of the new face
4041         """
4042
4043         return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4044
4045     def AddVolume(self, IDsOfNodes):
4046         """
4047         Create both simple and quadratic volume (this is determined
4048         by the number of given nodes).
4049
4050         Parameters:
4051                 IDsOfNodes: list of node IDs for creation of the element.
4052                         The order of nodes in this list should correspond to
4053                         the :ref:`connectivity convention <connectivity_page>`.
4054
4055         Returns:
4056             ID of the new volumic element
4057         """
4058
4059         return self.editor.AddVolume(IDsOfNodes)
4060
4061     def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4062         """
4063         Create a volume of many faces, giving nodes for each face.
4064
4065         Parameters:
4066                 IdsOfNodes: list of node IDs for volume creation, face by face.
4067                 Quantities: list of integer values, Quantities[i]
4068                         gives the quantity of nodes in face number i.
4069
4070         Returns:
4071             ID of the new volumic element
4072         """
4073
4074         return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4075
4076     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4077         """
4078         Create a volume of many faces, giving the IDs of the existing faces.
4079
4080         Note:
4081                 The created volume will refer only to the nodes
4082                 of the given faces, not to the faces themselves.
4083
4084         Parameters:
4085                 IdsOfFaces: the list of face IDs for volume creation.
4086
4087         Returns:
4088             ID of the new volumic element
4089         """
4090
4091         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4092
4093
4094     def SetNodeOnVertex(self, NodeID, Vertex):
4095         """
4096         Bind a node to a vertex
4097
4098         Parameters:
4099                 NodeID: a node ID
4100                 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4101
4102         Returns:
4103             True if succeed else raises an exception
4104         """
4105
4106         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4107             VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4108         else:
4109             VertexID = Vertex
4110         try:
4111             self.editor.SetNodeOnVertex(NodeID, VertexID)
4112         except SALOME.SALOME_Exception as inst:
4113             raise ValueError(inst.details.text)
4114         return True
4115
4116
4117     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4118         """
4119         Store the node position on an edge
4120
4121         Parameters:
4122                 NodeID: a node ID
4123                 Edge: an edge (GEOM.GEOM_Object) or edge ID
4124                 paramOnEdge: a parameter on the edge where the node is located
4125
4126         Returns:
4127             True if succeed else raises an exception
4128         """
4129
4130         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4131             EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4132         else:
4133             EdgeID = Edge
4134         try:
4135             self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4136         except SALOME.SALOME_Exception as inst:
4137             raise ValueError(inst.details.text)
4138         return True
4139
4140     def SetNodeOnFace(self, NodeID, Face, u, v):
4141         """
4142         Store node position on a face
4143
4144         Parameters:
4145                 NodeID: a node ID
4146                 Face: a face (GEOM.GEOM_Object) or face ID
4147                 u: U parameter on the face where the node is located
4148                 v: V parameter on the face where the node is located
4149
4150         Returns:
4151             True if succeed else raises an exception
4152         """
4153
4154         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4155             FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4156         else:
4157             FaceID = Face
4158         try:
4159             self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4160         except SALOME.SALOME_Exception as inst:
4161             raise ValueError(inst.details.text)
4162         return True
4163
4164     def SetNodeInVolume(self, NodeID, Solid):
4165         """
4166         Bind a node to a solid
4167
4168         Parameters:
4169                 NodeID: a node ID
4170                 Solid:  a solid (GEOM.GEOM_Object) or solid ID
4171
4172         Returns:
4173             True if succeed else raises an exception
4174         """
4175
4176         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4177             SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4178         else:
4179             SolidID = Solid
4180         try:
4181             self.editor.SetNodeInVolume(NodeID, SolidID)
4182         except SALOME.SALOME_Exception as inst:
4183             raise ValueError(inst.details.text)
4184         return True
4185
4186     def SetMeshElementOnShape(self, ElementID, Shape):
4187         """
4188         Bind an element to a shape
4189
4190         Parameters:
4191                 ElementID: an element ID
4192                 Shape: a shape (GEOM.GEOM_Object) or shape ID
4193
4194         Returns:
4195             True if succeed else raises an exception
4196         """
4197
4198         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4199             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4200         else:
4201             ShapeID = Shape
4202         try:
4203             self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4204         except SALOME.SALOME_Exception as inst:
4205             raise ValueError(inst.details.text)
4206         return True
4207
4208
4209     def MoveNode(self, NodeID, x, y, z):
4210         """
4211         Move the node with the given id
4212
4213         Parameters:
4214                 NodeID: the id of the node
4215                 x:  a new X coordinate
4216                 y:  a new Y coordinate
4217                 z:  a new Z coordinate
4218
4219         Returns:
4220             True if succeed else False
4221         """
4222
4223         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4224         if hasVars: self.mesh.SetParameters(Parameters)
4225         return self.editor.MoveNode(NodeID, x, y, z)
4226
4227     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4228         """
4229         Find the node closest to a point and moves it to a point location
4230
4231         Parameters:
4232                 x:  the X coordinate of a point
4233                 y:  the Y coordinate of a point
4234                 z:  the Z coordinate of a point
4235                 NodeID: if specified (>0), the node with this ID is moved,
4236                         otherwise, the node closest to point (*x*, *y*, *z*) is moved
4237
4238         Returns:
4239             the ID of a moved node
4240         """
4241
4242         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4243         if hasVars: self.mesh.SetParameters(Parameters)
4244         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4245
4246     def FindNodeClosestTo(self, x, y, z):
4247         """
4248         Find the node closest to a point
4249
4250         Parameters:
4251                 x:  the X coordinate of a point
4252                 y:  the Y coordinate of a point
4253                 z:  the Z coordinate of a point
4254
4255         Returns:
4256             the ID of a node
4257         """
4258
4259         #preview = self.mesh.GetMeshEditPreviewer()
4260         #return preview.MoveClosestNodeToPoint(x, y, z, -1)
4261         return self.editor.FindNodeClosestTo(x, y, z)
4262
4263     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4264         """
4265         Find the elements where a point lays IN or ON
4266
4267         Parameters:
4268                 x,y,z (float): coordinates of the point
4269                 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4270                         means elements of any type excluding nodes, discrete and 0D elements.
4271                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4272
4273         Returns:
4274             list of IDs of found elements
4275         """
4276         if meshPart:
4277             return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4278         else:
4279             return self.editor.FindElementsByPoint(x, y, z, elementType)
4280
4281     def ProjectPoint(self, x,y,z, meshObject, elementType):
4282         """
4283         Project a point to a mesh object.
4284         Return ID of an element of given type where the given point is projected
4285         and coordinates of the projection point.
4286         In the case if nothing found, return -1 and []
4287         """
4288         if ( isinstance( meshObject, Mesh )):
4289             meshObject = meshObject.GetMesh()
4290         return self.editor.ProjectPoint( x,y,z, meshObject, elementType )
4291
4292     def GetPointState(self, x, y, z):
4293         """
4294         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4295         smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4296         UNKNOWN state means that either mesh is wrong or the analysis fails.
4297         """
4298
4299         return self.editor.GetPointState(x, y, z)
4300
4301     def IsManifold(self):
4302         """
4303         Check if a 2D mesh is manifold
4304         """
4305
4306         return self.editor.IsManifold()
4307
4308     def IsCoherentOrientation2D(self):
4309         """
4310         Check if orientation of 2D elements is coherent
4311         """
4312
4313         return self.editor.IsCoherentOrientation2D()
4314
4315     def FindSharpEdges( self, angle, addExisting=False ):
4316         """
4317         Return sharp edges of faces and non-manifold ones.
4318         Optionally add existing edges.
4319
4320         Parameters:
4321                 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4322                 addExisting: to return existing edges (1D elements) as well
4323
4324         Returns:
4325             list of FaceEdge structures
4326         """
4327         angle = ParseParameters( angle )[0]
4328         return self.editor.FindSharpEdges( angle, addExisting )
4329
4330     def MeshToPassThroughAPoint(self, x, y, z):
4331         """
4332         Find the node closest to a point and moves it to a point location
4333
4334         Parameters:
4335                 x:  the X coordinate of a point
4336                 y:  the Y coordinate of a point
4337                 z:  the Z coordinate of a point
4338
4339         Returns:
4340             the ID of a moved node
4341         """
4342
4343         return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4344
4345     def InverseDiag(self, NodeID1, NodeID2):
4346         """
4347         Replace two neighbour triangles sharing Node1-Node2 link
4348         with the triangles built on the same 4 nodes but having other common link.
4349
4350         Parameters:
4351                 NodeID1:  the ID of the first node
4352                 NodeID2:  the ID of the second node
4353
4354         Returns:
4355             False if proper faces were not found
4356         """
4357         return self.editor.InverseDiag(NodeID1, NodeID2)
4358
4359     def DeleteDiag(self, NodeID1, NodeID2):
4360         """
4361         Replace two neighbour triangles sharing *Node1-Node2* link
4362         with a quadrangle built on the same 4 nodes.
4363
4364         Parameters:
4365                 NodeID1: ID of the first node
4366                 NodeID2: ID of the second node
4367
4368         Returns:
4369             False if proper faces were not found
4370         """
4371
4372         return self.editor.DeleteDiag(NodeID1, NodeID2)
4373
4374     def Reorient(self, IDsOfElements=None):
4375         """
4376         Reorient elements by ids
4377
4378         Parameters:
4379                 IDsOfElements: if undefined reorients all mesh elements
4380
4381         Returns:
4382             True if succeed else False
4383         """
4384
4385         if IDsOfElements == None:
4386             IDsOfElements = self.GetElementsId()
4387         return self.editor.Reorient(IDsOfElements)
4388
4389     def ReorientObject(self, theObject):
4390         """
4391         Reorient all elements of the object
4392
4393         Parameters:
4394                 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4395
4396         Returns:
4397             True if succeed else False
4398         """
4399
4400         if ( isinstance( theObject, Mesh )):
4401             theObject = theObject.GetMesh()
4402         return self.editor.ReorientObject(theObject)
4403
4404     def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4405         """
4406         Reorient faces contained in *the2DObject*.
4407
4408         Parameters:
4409                 the2DObject: is a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4410                 theDirection: is a desired direction of normal of *theFace*.
4411                         It can be either a GEOM vector or a list of coordinates [x,y,z].
4412                 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4413                         compared with theDirection. It can be either ID of face or a point
4414                         by which the face will be found. The point can be given as either
4415                         a GEOM vertex or a list of point coordinates.
4416
4417         Returns:
4418             number of reoriented faces
4419         """
4420
4421         unRegister = genObjUnRegister()
4422         # check the2DObject
4423         if isinstance( the2DObject, Mesh ):
4424             the2DObject = the2DObject.GetMesh()
4425         if isinstance( the2DObject, list ):
4426             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4427             unRegister.set( the2DObject )
4428         # check theDirection
4429         if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4430             theDirection = self.smeshpyD.GetDirStruct( theDirection )
4431         if isinstance( theDirection, list ):
4432             theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
4433         # prepare theFace and thePoint
4434         theFace = theFaceOrPoint
4435         thePoint = PointStruct(0,0,0)
4436         if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4437             thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4438             theFace = -1
4439         if isinstance( theFaceOrPoint, list ):
4440             thePoint = PointStruct( *theFaceOrPoint )
4441             theFace = -1
4442         if isinstance( theFaceOrPoint, PointStruct ):
4443             thePoint = theFaceOrPoint
4444             theFace = -1
4445         return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4446
4447     def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4448         """
4449         Reorient faces according to adjacent volumes.
4450
4451         Parameters:
4452                 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4453                         either IDs of faces or face groups.
4454                 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4455                 theOutsideNormal: to orient faces to have their normals
4456                         pointing either *outside* or *inside* the adjacent volumes.
4457
4458         Returns:
4459             number of reoriented faces.
4460         """
4461
4462         unRegister = genObjUnRegister()
4463         # check the2DObject
4464         if not isinstance( the2DObject, list ):
4465             the2DObject = [ the2DObject ]
4466         elif the2DObject and isinstance( the2DObject[0], int ):
4467             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4468             unRegister.set( the2DObject )
4469             the2DObject = [ the2DObject ]
4470         for i,obj2D in enumerate( the2DObject ):
4471             if isinstance( obj2D, Mesh ):
4472                 the2DObject[i] = obj2D.GetMesh()
4473             if isinstance( obj2D, list ):
4474                 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4475                 unRegister.set( the2DObject[i] )
4476         # check the3DObject
4477         if isinstance( the3DObject, Mesh ):
4478             the3DObject = the3DObject.GetMesh()
4479         if isinstance( the3DObject, list ):
4480             the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4481             unRegister.set( the3DObject )
4482         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4483
4484     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4485         """
4486         Fuse the neighbouring triangles into quadrangles.
4487
4488         Parameters:
4489                 IDsOfElements: The triangles to be fused.
4490                 theCriterion:  a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4491                         applied to possible quadrangles to choose a neighbour to fuse with.
4492                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4493                         to numerical functors.
4494                 MaxAngle: is the maximum angle between element normals at which the fusion
4495                         is still performed; theMaxAngle is measured in radians.
4496                         Also it could be a name of variable which defines angle in degrees.
4497
4498         Returns:
4499             True in case of success, False otherwise.
4500         """
4501
4502         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4503         self.mesh.SetParameters(Parameters)
4504         if not IDsOfElements:
4505             IDsOfElements = self.GetElementsId()
4506         Functor = self.smeshpyD.GetFunctor(theCriterion)
4507         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4508
4509     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4510         """
4511         Fuse the neighbouring triangles of the object into quadrangles
4512
4513         Parameters:
4514                 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4515                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4516                         applied to possible quadrangles to choose a neighbour to fuse with.
4517                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4518                         to numerical functors.
4519                 MaxAngle: a max angle between element normals at which the fusion
4520                         is still performed; theMaxAngle is measured in radians.
4521
4522         Returns:
4523             True in case of success, False otherwise.
4524         """
4525
4526         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4527         self.mesh.SetParameters(Parameters)
4528         if isinstance( theObject, Mesh ):
4529             theObject = theObject.GetMesh()
4530         Functor = self.smeshpyD.GetFunctor(theCriterion)
4531         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4532
4533     def QuadToTri (self, IDsOfElements, theCriterion = None):
4534         """
4535         Split quadrangles into triangles.
4536
4537         Parameters:
4538                 IDsOfElements: the faces to be splitted.
4539                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4540                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4541                         value, then quadrangles will be split by the smallest diagonal.
4542                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4543                         to numerical functors.
4544
4545         Returns:
4546             True in case of success, False otherwise.
4547         """
4548         if IDsOfElements == []:
4549             IDsOfElements = self.GetElementsId()
4550         if theCriterion is None:
4551             theCriterion = FT_MaxElementLength2D
4552         Functor = self.smeshpyD.GetFunctor(theCriterion)
4553         return self.editor.QuadToTri(IDsOfElements, Functor)
4554
4555     def QuadToTriObject (self, theObject, theCriterion = None):
4556         """
4557         Split quadrangles into triangles.
4558
4559         Parameters:
4560                 theObject: the object from which the list of elements is taken,
4561                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4562                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4563                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4564                         value, then quadrangles will be split by the smallest diagonal.
4565                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4566                         to numerical functors.
4567
4568         Returns:
4569             True in case of success, False otherwise.
4570         """
4571         if ( isinstance( theObject, Mesh )):
4572             theObject = theObject.GetMesh()
4573         if theCriterion is None:
4574             theCriterion = FT_MaxElementLength2D
4575         Functor = self.smeshpyD.GetFunctor(theCriterion)
4576         return self.editor.QuadToTriObject(theObject, Functor)
4577
4578     def QuadTo4Tri (self, theElements=[]):
4579         """
4580         Split each of given quadrangles into 4 triangles. A node is added at the center of
4581         a quadrangle.
4582
4583         Parameters:
4584                 theElements: the faces to be splitted. This can be either 
4585                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4586                         or a list of face IDs. By default all quadrangles are split
4587         """
4588         unRegister = genObjUnRegister()
4589         if isinstance( theElements, Mesh ):
4590             theElements = theElements.mesh
4591         elif not theElements:
4592             theElements = self.mesh
4593         elif isinstance( theElements, list ):
4594             theElements = self.GetIDSource( theElements, SMESH.FACE )
4595             unRegister.set( theElements )
4596         return self.editor.QuadTo4Tri( theElements )
4597
4598     def SplitQuad (self, IDsOfElements, Diag13):
4599         """
4600         Split quadrangles into triangles.
4601
4602         Parameters:
4603                 IDsOfElements: the faces to be splitted
4604                 Diag13 (boolean):        is used to choose a diagonal for splitting.
4605
4606         Returns:
4607             True in case of success, False otherwise.
4608         """
4609         if IDsOfElements == []:
4610             IDsOfElements = self.GetElementsId()
4611         return self.editor.SplitQuad(IDsOfElements, Diag13)
4612
4613     def SplitQuadObject (self, theObject, Diag13):
4614         """
4615         Split quadrangles into triangles.
4616
4617         Parameters:
4618                 theObject: the object from which the list of elements is taken,
4619                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4620                 Diag13 (boolean):    is used to choose a diagonal for splitting.
4621
4622         Returns:
4623             True in case of success, False otherwise.
4624         """
4625         if ( isinstance( theObject, Mesh )):
4626             theObject = theObject.GetMesh()
4627         return self.editor.SplitQuadObject(theObject, Diag13)
4628
4629     def BestSplit (self, IDOfQuad, theCriterion):
4630         """
4631         Find a better splitting of the given quadrangle.
4632
4633         Parameters:
4634                 IDOfQuad:   the ID of the quadrangle to be splitted.
4635                 theCriterion:  is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4636                         choose a diagonal for splitting.
4637                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4638                         to numerical functors.
4639
4640         Returns:
4641             * 1 if 1-3 diagonal is better, 
4642             * 2 if 2-4 diagonal is better, 
4643             * 0 if error occurs.
4644         """
4645         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4646
4647     def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4648         """
4649         Split volumic elements into tetrahedrons
4650
4651         Parameters:
4652                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4653                 method:  flags passing splitting method:
4654                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4655                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4656         """
4657         unRegister = genObjUnRegister()
4658         if isinstance( elems, Mesh ):
4659             elems = elems.GetMesh()
4660         if ( isinstance( elems, list )):
4661             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4662             unRegister.set( elems )
4663         self.editor.SplitVolumesIntoTetra(elems, method)
4664         return
4665
4666     def SplitBiQuadraticIntoLinear(self, elems=None):
4667         """
4668         Split bi-quadratic elements into linear ones without creation of additional nodes:
4669
4670             - bi-quadratic triangle will be split into 3 linear quadrangles;
4671             - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4672             - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4673
4674         Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
4675         will be split in order to keep the mesh conformal.
4676
4677         Parameters:
4678             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4679                 if None (default), all bi-quadratic elements will be split
4680         """
4681         unRegister = genObjUnRegister()
4682         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4683             elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4684             unRegister.set( elems )
4685         if elems is None:
4686             elems = [ self.GetMesh() ]
4687         if isinstance( elems, Mesh ):
4688             elems = [ elems.GetMesh() ]
4689         if not isinstance( elems, list ):
4690             elems = [elems]
4691         self.editor.SplitBiQuadraticIntoLinear( elems )
4692
4693     def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4694                                  method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4695         """
4696         Split hexahedra into prisms
4697
4698         Parameters:
4699                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4700                 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4701                         gives a normal vector defining facets to split into triangles.
4702                         *startHexPoint* can be either a triple of coordinates or a vertex.
4703                 facetNormal: a normal to a facet to split into triangles of a
4704                         hexahedron found by *startHexPoint*.
4705                         *facetNormal* can be either a triple of coordinates or an edge.
4706                 method:  flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4707                         smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4708                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4709                         to *startHexPoint* are split, else *startHexPoint*
4710                         is used to find the facet to split in all domains present in *elems*.
4711         """
4712         # IDSource
4713         unRegister = genObjUnRegister()
4714         if isinstance( elems, Mesh ):
4715             elems = elems.GetMesh()
4716         if ( isinstance( elems, list )):
4717             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4718             unRegister.set( elems )
4719             pass
4720         # axis
4721         if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4722             startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4723         elif isinstance( startHexPoint, list ):
4724             startHexPoint = SMESH.PointStruct( startHexPoint[0],
4725                                                startHexPoint[1],
4726                                                startHexPoint[2])
4727         if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4728             facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4729         elif isinstance( facetNormal, list ):
4730             facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4731                                                        facetNormal[1],
4732                                                        facetNormal[2])
4733         self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4734
4735         self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4736
4737     def SplitQuadsNearTriangularFacets(self):
4738         """
4739         Split quadrangle faces near triangular facets of volumes
4740         """
4741         faces_array = self.GetElementsByType(SMESH.FACE)
4742         for face_id in faces_array:
4743             if self.GetElemNbNodes(face_id) == 4: # quadrangle
4744                 quad_nodes = self.mesh.GetElemNodes(face_id)
4745                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4746                 isVolumeFound = False
4747                 for node1_elem in node1_elems:
4748                     if not isVolumeFound:
4749                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4750                             nb_nodes = self.GetElemNbNodes(node1_elem)
4751                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4752                                 volume_elem = node1_elem
4753                                 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4754                                 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4755                                     if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4756                                         isVolumeFound = True
4757                                         if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4758                                             self.SplitQuad([face_id], False) # diagonal 2-4
4759                                     elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4760                                         isVolumeFound = True
4761                                         self.SplitQuad([face_id], True) # diagonal 1-3
4762                                 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4763                                     if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4764                                         isVolumeFound = True
4765                                         self.SplitQuad([face_id], True) # diagonal 1-3
4766
4767     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4768         """
4769         Split hexahedrons into tetrahedrons.
4770
4771         This operation uses :doc:`pattern_mapping` functionality for splitting.
4772
4773         Parameters:
4774                 theObject: the object from which the list of hexahedrons is taken; 
4775                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4776                 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4777                         pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4778                         will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4779                         key-point will be mapped into *theNode001*-th node of each volume.
4780                         The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4781
4782         Returns:
4783             True in case of success, False otherwise.
4784         """
4785 #    Pattern:
4786 #                     5.---------.6
4787 #                    /|#*      /|
4788 #                   / | #*    / |
4789 #                  /  |  # * /  |
4790 #                 /   |   # /*  |
4791 #       (0,0,1) 4.---------.7 * |
4792 #                |#*  |1   | # *|
4793 #                | # *.----|---#.2
4794 #                |  #/ *   |   /
4795 #                |  /#  *  |  /
4796 #                | /   # * | /
4797 #                |/      #*|/
4798 #        (0,0,0) 0.---------.3
4799         pattern_tetra = "!!! Nb of points: \n 8 \n\
4800         !!! Points: \n\
4801         0 0 0  !- 0 \n\
4802         0 1 0  !- 1 \n\
4803         1 1 0  !- 2 \n\
4804         1 0 0  !- 3 \n\
4805         0 0 1  !- 4 \n\
4806         0 1 1  !- 5 \n\
4807         1 1 1  !- 6 \n\
4808         1 0 1  !- 7 \n\
4809         !!! Indices of points of 6 tetras: \n\
4810         0 3 4 1 \n\
4811         7 4 3 1 \n\
4812         4 7 5 1 \n\
4813         6 2 5 7 \n\
4814         1 5 2 7 \n\
4815         2 3 1 7 \n"
4816
4817         pattern = self.smeshpyD.GetPattern()
4818         isDone  = pattern.LoadFromFile(pattern_tetra)
4819         if not isDone:
4820             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4821             return isDone
4822
4823         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4824         isDone = pattern.MakeMesh(self.mesh, False, False)
4825         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4826
4827         # split quafrangle faces near triangular facets of volumes
4828         self.SplitQuadsNearTriangularFacets()
4829
4830         return isDone
4831
4832     def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
4833         """
4834         Split hexahedrons into prisms.
4835
4836         Uses the :doc:`pattern_mapping` functionality for splitting.
4837
4838         Parameters:
4839                 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
4840                 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
4841                         pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
4842                         will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
4843                         will be mapped into the *theNode001* -th node of each volume.
4844                         Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
4845
4846         Returns:
4847             True in case of success, False otherwise.
4848         """
4849 #        Pattern:     5.---------.6
4850 #                     /|#       /|
4851 #                    / | #     / |
4852 #                   /  |  #   /  |
4853 #                  /   |   # /   |
4854 #        (0,0,1) 4.---------.7   |
4855 #                 |    |    |    |
4856 #                 |   1.----|----.2
4857 #                 |   / *   |   /
4858 #                 |  /   *  |  /
4859 #                 | /     * | /
4860 #                 |/       *|/
4861 #        (0,0,0) 0.---------.3
4862         pattern_prism = "!!! Nb of points: \n 8 \n\
4863         !!! Points: \n\
4864         0 0 0  !- 0 \n\
4865         0 1 0  !- 1 \n\
4866         1 1 0  !- 2 \n\
4867         1 0 0  !- 3 \n\
4868         0 0 1  !- 4 \n\
4869         0 1 1  !- 5 \n\
4870         1 1 1  !- 6 \n\
4871         1 0 1  !- 7 \n\
4872         !!! Indices of points of 2 prisms: \n\
4873         0 1 3 4 5 7 \n\
4874         2 3 1 6 7 5 \n"
4875
4876         pattern = self.smeshpyD.GetPattern()
4877         isDone  = pattern.LoadFromFile(pattern_prism)
4878         if not isDone:
4879             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
4880             return isDone
4881
4882         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
4883         isDone = pattern.MakeMesh(self.mesh, False, False)
4884         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
4885
4886         # Split quafrangle faces near triangular facets of volumes
4887         self.SplitQuadsNearTriangularFacets()
4888
4889         return isDone
4890
4891     def Smooth(self, IDsOfElements, IDsOfFixedNodes,
4892                MaxNbOfIterations, MaxAspectRatio, Method):
4893         """
4894         Smooth elements
4895
4896         Parameters:
4897                 IDsOfElements: the list if ids of elements to smooth
4898                 IDsOfFixedNodes: the list of ids of fixed nodes.
4899                         Note that nodes built on edges and boundary nodes are always fixed.
4900                 MaxNbOfIterations: the maximum number of iterations
4901                 MaxAspectRatio: varies in range [1.0, inf]
4902                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4903                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
4904
4905         Returns:
4906             True in case of success, False otherwise.
4907         """
4908
4909         if IDsOfElements == []:
4910             IDsOfElements = self.GetElementsId()
4911         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4912         self.mesh.SetParameters(Parameters)
4913         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
4914                                   MaxNbOfIterations, MaxAspectRatio, Method)
4915
4916     def SmoothObject(self, theObject, IDsOfFixedNodes,
4917                      MaxNbOfIterations, MaxAspectRatio, Method):
4918         """
4919         Smooth elements which belong to the given object
4920
4921         Parameters:
4922                 theObject: the object to smooth
4923                 IDsOfFixedNodes: the list of ids of fixed nodes.
4924                         Note that nodes built on edges and boundary nodes are always fixed.
4925                 MaxNbOfIterations: the maximum number of iterations
4926                 MaxAspectRatio: varies in range [1.0, inf]
4927                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4928                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
4929
4930         Returns:
4931             True in case of success, False otherwise.
4932         """
4933
4934         if ( isinstance( theObject, Mesh )):
4935             theObject = theObject.GetMesh()
4936         return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
4937                                         MaxNbOfIterations, MaxAspectRatio, Method)
4938
4939     def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
4940                          MaxNbOfIterations, MaxAspectRatio, Method):
4941         """
4942         Parametrically smooth the given elements
4943
4944         Parameters:
4945                 IDsOfElements: the list if ids of elements to smooth
4946                 IDsOfFixedNodes: the list of ids of fixed nodes.
4947                         Note that nodes built on edges and boundary nodes are always fixed.
4948                 MaxNbOfIterations: the maximum number of iterations
4949                 MaxAspectRatio: varies in range [1.0, inf]
4950                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4951                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
4952
4953         Returns:
4954             True in case of success, False otherwise.
4955         """
4956
4957         if IDsOfElements == []:
4958             IDsOfElements = self.GetElementsId()
4959         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
4960         self.mesh.SetParameters(Parameters)
4961         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
4962                                             MaxNbOfIterations, MaxAspectRatio, Method)
4963
4964     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
4965                                MaxNbOfIterations, MaxAspectRatio, Method):
4966         """
4967         Parametrically smooth the elements which belong to the given object
4968
4969         Parameters:
4970                 theObject: the object to smooth
4971                 IDsOfFixedNodes: the list of ids of fixed nodes.
4972                         Note that nodes built on edges and boundary nodes are always fixed.
4973                 MaxNbOfIterations: the maximum number of iterations
4974                 MaxAspectRatio: varies in range [1.0, inf]
4975                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
4976                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
4977
4978         Returns:
4979             True in case of success, False otherwise.
4980         """
4981
4982         if ( isinstance( theObject, Mesh )):
4983             theObject = theObject.GetMesh()
4984         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
4985                                                   MaxNbOfIterations, MaxAspectRatio, Method)
4986
4987     def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
4988         """
4989         Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
4990         them with quadratic with the same id.
4991
4992         Parameters:
4993                 theForce3d: method of new node creation:
4994
4995                   * False - the medium node lies at the geometrical entity from which the mesh element is built
4996                   * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
4997                 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
4998                 theToBiQuad: If True, converts the mesh to bi-quadratic
4999
5000         Returns:
5001             :class:`SMESH.ComputeError` which can hold a warning
5002
5003         Warning:
5004             If *theSubMesh* is provided, the mesh can become non-conformal
5005         """
5006
5007         if isinstance( theSubMesh, Mesh ):
5008             theSubMesh = theSubMesh.mesh
5009         if theToBiQuad:
5010             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5011         else:
5012             if theSubMesh:
5013                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5014             else:
5015                 self.editor.ConvertToQuadratic(theForce3d)
5016         error = self.editor.GetLastError()
5017         if error and error.comment:
5018             print(error.comment)
5019         return error
5020
5021     def ConvertFromQuadratic(self, theSubMesh=None):
5022         """
5023         Convert the mesh from quadratic to ordinary,
5024         deletes old quadratic elements,
5025         replacing them with ordinary mesh elements with the same id.
5026
5027         Parameters:
5028             theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5029
5030         Warning:
5031             If *theSubMesh* is provided, the mesh can become non-conformal
5032         """
5033
5034         if theSubMesh:
5035             self.editor.ConvertFromQuadraticObject(theSubMesh)
5036         else:
5037             return self.editor.ConvertFromQuadratic()
5038
5039     def Make2DMeshFrom3D(self):
5040         """
5041         Create 2D mesh as skin on boundary faces of a 3D mesh
5042
5043         Returns:
5044             True if operation has been completed successfully, False otherwise
5045         """
5046
5047         return self.editor.Make2DMeshFrom3D()
5048
5049     def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5050                          toCopyElements=False, toCopyExistingBondary=False):
5051         """
5052         Create missing boundary elements
5053
5054         Parameters:
5055                 elements: elements whose boundary is to be checked:
5056                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5057                         If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5058                 dimension: defines type of boundary elements to create, either of
5059                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5060                         SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5061                 groupName: a name of group to store created boundary elements in,
5062                         "" means not to create the group
5063                 meshName: a name of new mesh to store created boundary elements in,
5064                         "" means not to create the new mesh
5065                 toCopyElements: if True, the checked elements will be copied into
5066                         the new mesh else only boundary elements will be copied into the new mesh
5067                 toCopyExistingBondary: if True, not only new but also pre-existing
5068                         boundary elements will be copied into the new mesh
5069
5070         Returns:
5071             tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5072         """
5073
5074         unRegister = genObjUnRegister()
5075         if isinstance( elements, Mesh ):
5076             elements = elements.GetMesh()
5077         if ( isinstance( elements, list )):
5078             elemType = SMESH.ALL
5079             if elements: elemType = self.GetElementType( elements[0], iselem=True)
5080             elements = self.editor.MakeIDSource(elements, elemType)
5081             unRegister.set( elements )
5082         mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5083                                                    toCopyElements,toCopyExistingBondary)
5084         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5085         return mesh, group
5086
5087     def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5088                              toCopyAll=False, groups=[]):
5089         """
5090         Create missing boundary elements around either the whole mesh or
5091         groups of elements
5092
5093         Parameters:
5094                 dimension: defines type of boundary elements to create, either of
5095                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5096                 groupName: a name of group to store all boundary elements in,
5097                         "" means not to create the group
5098                 meshName: a name of a new mesh, which is a copy of the initial
5099                         mesh + created boundary elements; "" means not to create the new mesh
5100                 toCopyAll: if True, the whole initial mesh will be copied into
5101                         the new mesh else only boundary elements will be copied into the new mesh
5102                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5103
5104         Returns:
5105                 tuple( long, mesh, groups )
5106                        - long - number of added boundary elements
5107                        - mesh - the :class:`Mesh` where elements were added to
5108                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5109         """
5110
5111         nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5112                                                            toCopyAll,groups)
5113         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5114         return nb, mesh, group
5115
5116     def RenumberNodes(self):
5117         """
5118         Renumber mesh nodes to remove unused node IDs
5119         """
5120         self.editor.RenumberNodes()
5121
5122     def RenumberElements(self):
5123         """
5124         Renumber mesh elements to remove unused element IDs
5125         """
5126         self.editor.RenumberElements()
5127
5128     def _getIdSourceList(self, arg, idType, unRegister):
5129         """
5130         Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5131         """
5132         if arg and isinstance( arg, list ):
5133             if isinstance( arg[0], int ):
5134                 arg = self.GetIDSource( arg, idType )
5135                 unRegister.set( arg )
5136             elif isinstance( arg[0], Mesh ):
5137                 arg[0] = arg[0].GetMesh()
5138         elif isinstance( arg, Mesh ):
5139             arg = arg.GetMesh()
5140         if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5141             arg = [arg]
5142         return arg
5143
5144     def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5145                              MakeGroups=False, TotalAngle=False):
5146         """
5147         Generate new elements by rotation of the given elements and nodes around the axis
5148
5149         Parameters:
5150                 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5151                 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5152                 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5153                 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5154                 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5155                         which defines angle in degrees
5156                 NbOfSteps: the number of steps
5157                 Tolerance: tolerance
5158                 MakeGroups: forces the generation of new groups from existing ones
5159                 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5160                         of all steps, else - size of each step
5161
5162         Returns:
5163             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5164         """
5165
5166         unRegister = genObjUnRegister()
5167         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5168         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5169         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5170
5171         if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5172             Axis = self.smeshpyD.GetAxisStruct( Axis )
5173         if isinstance( Axis, list ):
5174             Axis = SMESH.AxisStruct( *Axis )
5175
5176         AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5177         NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5178         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5179         self.mesh.SetParameters(Parameters)
5180         if TotalAngle and NbOfSteps:
5181             AngleInRadians /= NbOfSteps
5182         return self.editor.RotationSweepObjects( nodes, edges, faces,
5183                                                  Axis, AngleInRadians,
5184                                                  NbOfSteps, Tolerance, MakeGroups)
5185
5186     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5187                       MakeGroups=False, TotalAngle=False):
5188         """
5189         Generate new elements by rotation of the elements around the axis
5190
5191         Parameters:
5192             IDsOfElements: the list of ids of elements to sweep
5193             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5194             AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5195             NbOfSteps: the number of steps
5196             Tolerance: tolerance
5197             MakeGroups: forces the generation of new groups from existing ones
5198             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5199                 of all steps, else - size of each step
5200
5201         Returns:
5202             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5203         """
5204
5205         return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5206                                          AngleInRadians, NbOfSteps, Tolerance,
5207                                          MakeGroups, TotalAngle)
5208
5209     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5210                             MakeGroups=False, TotalAngle=False):
5211         """
5212         Generate new elements by rotation of the elements of object around the axis
5213         theObject object which elements should be sweeped.
5214         It can be a mesh, a sub mesh or a group.
5215
5216         Parameters:
5217             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5218             AngleInRadians: the angle of Rotation
5219             NbOfSteps: number of steps
5220             Tolerance: tolerance
5221             MakeGroups: forces the generation of new groups from existing ones
5222             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5223                 of all steps, else - size of each step
5224
5225         Returns:
5226             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5227         """
5228
5229         return self.RotationSweepObjects( [], theObject, theObject, Axis,
5230                                           AngleInRadians, NbOfSteps, Tolerance,
5231                                           MakeGroups, TotalAngle )
5232
5233     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5234                               MakeGroups=False, TotalAngle=False):
5235         """
5236         Generate new elements by rotation of the elements of object around the axis
5237         theObject object which elements should be sweeped.
5238         It can be a mesh, a sub mesh or a group.
5239
5240         Parameters:
5241             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5242             AngleInRadians: the angle of Rotation
5243             NbOfSteps: number of steps
5244             Tolerance: tolerance
5245             MakeGroups: forces the generation of new groups from existing ones
5246             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5247                 of all steps, else - size of each step
5248
5249         Returns:
5250             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, 
5251             empty list otherwise
5252         """
5253
5254         return self.RotationSweepObjects([],theObject,[], Axis,
5255                                          AngleInRadians, NbOfSteps, Tolerance,
5256                                          MakeGroups, TotalAngle)
5257
5258     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5259                               MakeGroups=False, TotalAngle=False):
5260         """
5261         Generate new elements by rotation of the elements of object around the axis
5262         theObject object which elements should be sweeped.
5263         It can be a mesh, a sub mesh or a group.
5264
5265         Parameters:
5266             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5267             AngleInRadians: the angle of Rotation
5268             NbOfSteps: number of steps
5269             Tolerance: tolerance
5270             MakeGroups: forces the generation of new groups from existing ones
5271             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5272                 of all steps, else - size of each step
5273
5274         Returns:
5275             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5276         """
5277
5278         return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5279                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5280
5281     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5282                               scaleFactors=[], linearVariation=False, basePoint=[] ):
5283         """
5284         Generate new elements by extrusion of the given elements and nodes
5285
5286         Parameters:
5287             nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5288             edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5289             faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5290             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5291                 the direction and value of extrusion for one step (the total extrusion
5292                 length will be NbOfSteps * ||StepVector||)
5293             NbOfSteps: the number of steps
5294             MakeGroups: forces the generation of new groups from existing ones
5295             scaleFactors: optional scale factors to apply during extrusion
5296             linearVariation: if *True*, scaleFactors are spread over all *scaleFactors*,
5297                 else scaleFactors[i] is applied to nodes at the i-th extrusion step
5298             basePoint: optional scaling center; if not provided, a gravity center of
5299                 nodes and elements being extruded is used as the scaling center.
5300                 It can be either
5301
5302                         - a list of tree components of the point or
5303                         - a node ID or
5304                         - a GEOM point
5305         Returns:
5306             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5307
5308         Example: :ref:`tui_extrusion`
5309         """
5310         unRegister = genObjUnRegister()
5311         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5312         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5313         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5314
5315         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5316             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5317         if isinstance( StepVector, list ):
5318             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5319
5320         if isinstance( basePoint, int):
5321             xyz = self.GetNodeXYZ( basePoint )
5322             if not xyz:
5323                 raise RuntimeError("Invalid node ID: %s" % basePoint)
5324             basePoint = xyz
5325         if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5326             basePoint = self.geompyD.PointCoordinates( basePoint )
5327
5328         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5329         Parameters = StepVector.PS.parameters + var_separator + Parameters
5330         self.mesh.SetParameters(Parameters)
5331
5332         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5333                                                   StepVector, NbOfSteps,
5334                                                   scaleFactors, linearVariation, basePoint,
5335                                                   MakeGroups)
5336
5337
5338     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5339         """
5340         Generate new elements by extrusion of the elements with given ids
5341
5342         Parameters:
5343             IDsOfElements: the list of ids of elements or nodes for extrusion
5344             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5345                 the direction and value of extrusion for one step (the total extrusion
5346                 length will be NbOfSteps * ||StepVector||)
5347             NbOfSteps: the number of steps
5348             MakeGroups: forces the generation of new groups from existing ones
5349             IsNodes: is True if elements with given ids are nodes
5350
5351         Returns:
5352             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5353
5354         Example: :ref:`tui_extrusion`
5355         """
5356         n,e,f = [],[],[]
5357         if IsNodes: n = IDsOfElements
5358         else      : e,f, = IDsOfElements,IDsOfElements
5359         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5360
5361     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5362                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5363         """
5364         Generate new elements by extrusion along the normal to a discretized surface or wire
5365
5366         Parameters:
5367             Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5368                 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5369             StepSize: length of one extrusion step (the total extrusion
5370                 length will be *NbOfSteps* *StepSize*).
5371             NbOfSteps: number of extrusion steps.
5372             ByAverageNormal: if True each node is translated by *StepSize*
5373                 along the average of the normal vectors to the faces sharing the node;
5374                 else each node is translated along the same average normal till
5375                 intersection with the plane got by translation of the face sharing
5376                 the node along its own normal by *StepSize*.
5377             UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5378                 for every node of *Elements*.
5379             MakeGroups: forces generation of new groups from existing ones.
5380             Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5381                 is not yet implemented. This parameter is used if *Elements* contains
5382                 both faces and edges, i.e. *Elements* is a Mesh.
5383
5384         Returns:
5385             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5386             empty list otherwise.
5387         Example: :ref:`tui_extrusion`
5388         """
5389
5390         unRegister = genObjUnRegister()
5391         if isinstance( Elements, Mesh ):
5392             Elements = [ Elements.GetMesh() ]
5393         if isinstance( Elements, list ):
5394             if not Elements:
5395                 raise RuntimeError("Elements empty!")
5396             if isinstance( Elements[0], int ):
5397                 Elements = self.GetIDSource( Elements, SMESH.ALL )
5398                 unRegister.set( Elements )
5399         if not isinstance( Elements, list ):
5400             Elements = [ Elements ]
5401         StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5402         self.mesh.SetParameters(Parameters)
5403         return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5404                                              ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5405
5406     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5407         """
5408         Generate new elements by extrusion of the elements or nodes which belong to the object
5409
5410         Parameters:
5411             theObject: the object whose elements or nodes should be processed.
5412                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5413             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5414                 the direction and value of extrusion for one step (the total extrusion
5415                 length will be NbOfSteps * ||StepVector||)
5416             NbOfSteps: the number of steps
5417             MakeGroups: forces the generation of new groups from existing ones
5418             IsNodes: is True if elements to extrude are nodes
5419
5420         Returns:
5421             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5422         Example: :ref:`tui_extrusion`
5423         """
5424
5425         n,e,f = [],[],[]
5426         if IsNodes: n    = theObject
5427         else      : e,f, = theObject,theObject
5428         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5429
5430     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5431         """
5432         Generate new elements by extrusion of edges which belong to the object
5433
5434         Parameters:
5435             theObject: object whose 1D elements should be processed.
5436                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5437             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5438                 the direction and value of extrusion for one step (the total extrusion
5439                 length will be NbOfSteps * ||StepVector||)
5440             NbOfSteps: the number of steps
5441             MakeGroups: to generate new groups from existing ones
5442
5443         Returns:
5444             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5445         Example: :ref:`tui_extrusion`
5446         """
5447
5448         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5449
5450     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5451         """
5452         Generate new elements by extrusion of faces which belong to the object
5453
5454         Parameters:
5455             theObject: object whose 2D elements should be processed.
5456                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5457             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5458                 the direction and value of extrusion for one step (the total extrusion
5459                 length will be NbOfSteps * ||StepVector||)
5460             NbOfSteps: the number of steps
5461             MakeGroups: forces the generation of new groups from existing ones
5462
5463         Returns:
5464             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5465         Example: :ref:`tui_extrusion`
5466         """
5467
5468         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5469
5470     def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5471                           ExtrFlags, SewTolerance, MakeGroups=False):
5472         """
5473         Generate new elements by extrusion of the elements with given ids
5474
5475         Parameters:
5476             IDsOfElements: is ids of elements
5477             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5478                 the direction and value of extrusion for one step (the total extrusion
5479                 length will be NbOfSteps * ||StepVector||)
5480             NbOfSteps: the number of steps
5481             ExtrFlags: sets flags for extrusion
5482             SewTolerance: uses for comparing locations of nodes if flag
5483                 EXTRUSION_FLAG_SEW is set
5484             MakeGroups: forces the generation of new groups from existing ones
5485
5486         Returns:
5487             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5488         """
5489
5490         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5491             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5492         if isinstance( StepVector, list ):
5493             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5494         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5495                                              ExtrFlags, SewTolerance, MakeGroups)
5496
5497     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
5498                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5499                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
5500         """
5501         Generate new elements by extrusion of the given elements and nodes along the path.
5502         The path of extrusion must be a meshed edge.
5503
5504         Parameters:
5505             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5506             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5507             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5508             PathMesh: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5509             PathShape: shape (edge) defines the sub-mesh of PathMesh if PathMesh
5510                 contains not only path segments, else it can be None
5511             NodeStart: the first or the last node on the path. Defines the direction of extrusion
5512             HasAngles: allows the shape to be rotated around the path
5513                 to get the resulting mesh in a helical fashion
5514             Angles: list of angles
5515             LinearVariation: forces the computation of rotation angles as linear
5516                 variation of the given Angles along path steps
5517             HasRefPoint: allows using the reference point
5518             RefPoint: the reference point around which the shape is rotated (the mass center of the
5519                 shape by default). The User can specify any point as the Reference Point. 
5520                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5521             MakeGroups: forces the generation of new groups from existing ones
5522
5523         Returns:
5524             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5525             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5526         Example: :ref:`tui_extrusion_along_path`
5527         """
5528
5529         unRegister = genObjUnRegister()
5530         Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5531         Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5532         Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5533
5534         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5535             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5536         if isinstance( RefPoint, list ):
5537             if not RefPoint: RefPoint = [0,0,0]
5538             RefPoint = SMESH.PointStruct( *RefPoint )
5539         if isinstance( PathMesh, Mesh ):
5540             PathMesh = PathMesh.GetMesh()
5541         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5542         Parameters = AnglesParameters + var_separator + RefPoint.parameters
5543         self.mesh.SetParameters(Parameters)
5544         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5545                                                      PathMesh, PathShape, NodeStart,
5546                                                      HasAngles, Angles, LinearVariation,
5547                                                      HasRefPoint, RefPoint, MakeGroups)
5548
5549     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5550                             HasAngles=False, Angles=[], LinearVariation=False,
5551                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5552                             ElemType=SMESH.FACE):
5553         """
5554         Generate new elements by extrusion of the given elements.
5555         The path of extrusion must be a meshed edge.
5556
5557         Parameters:
5558             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5559             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5560             NodeStart: the start node from Path. Defines the direction of extrusion
5561             HasAngles: allows the shape to be rotated around the path
5562                 to get the resulting mesh in a helical fashion
5563             Angles: list of angles in radians
5564             LinearVariation: forces the computation of rotation angles as linear
5565                 variation of the given Angles along path steps
5566             HasRefPoint: allows using the reference point
5567             RefPoint: the reference point around which the elements are rotated (the mass
5568                 center of the elements by default).
5569                 The User can specify any point as the Reference Point.
5570                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5571             MakeGroups: forces the generation of new groups from existing ones
5572             ElemType: type of elements for extrusion (if param Base is a mesh)
5573
5574         Returns:
5575             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5576             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5577             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5578             otherwise
5579         Example: :ref:`tui_extrusion_along_path`
5580         """
5581
5582         n,e,f = [],[],[]
5583         if ElemType == SMESH.NODE: n = Base
5584         if ElemType == SMESH.EDGE: e = Base
5585         if ElemType == SMESH.FACE: f = Base
5586         gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5587                                                HasAngles, Angles, LinearVariation,
5588                                                HasRefPoint, RefPoint, MakeGroups)
5589         if MakeGroups: return gr,er
5590         return er
5591
5592     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5593                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5594                            MakeGroups=False, LinearVariation=False):
5595         """
5596         Generate new elements by extrusion of the given elements.
5597         The path of extrusion must be a meshed edge.
5598
5599         Parameters:
5600             IDsOfElements: ids of elements
5601             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5602             PathShape: shape (edge) defines the sub-mesh for the path
5603             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5604             HasAngles: allows the shape to be rotated around the path
5605                 to get the resulting mesh in a helical fashion
5606             Angles: list of angles in radians
5607             HasRefPoint: allows using the reference point
5608             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5609                 The User can specify any point as the Reference Point.
5610                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5611             MakeGroups: forces the generation of new groups from existing ones
5612             LinearVariation: forces the computation of rotation angles as linear
5613                 variation of the given Angles along path steps
5614
5615         Returns:
5616             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5617             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5618             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5619         Example: :ref:`tui_extrusion_along_path`
5620         """
5621
5622         n,e,f = [],IDsOfElements,IDsOfElements
5623         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5624                                                NodeStart, HasAngles, Angles,
5625                                                LinearVariation,
5626                                                HasRefPoint, RefPoint, MakeGroups)
5627         if MakeGroups: return gr,er
5628         return er
5629
5630     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5631                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5632                                  MakeGroups=False, LinearVariation=False):
5633         """
5634         Generate new elements by extrusion of the elements which belong to the object.
5635         The path of extrusion must be a meshed edge.
5636
5637         Parameters:
5638             theObject: the object whose elements should be processed.
5639                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5640             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5641             PathShape: shape (edge) defines the sub-mesh for the path
5642             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5643             HasAngles: allows the shape to be rotated around the path
5644                 to get the resulting mesh in a helical fashion
5645             Angles: list of angles
5646             HasRefPoint: allows using the reference point
5647             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5648                 The User can specify any point as the Reference Point.
5649                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5650             MakeGroups: forces the generation of new groups from existing ones
5651             LinearVariation: forces the computation of rotation angles as linear
5652                 variation of the given Angles along path steps
5653
5654         Returns:
5655             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5656             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5657             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5658         Example: :ref:`tui_extrusion_along_path`
5659         """
5660
5661         n,e,f = [],theObject,theObject
5662         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5663                                                HasAngles, Angles, LinearVariation,
5664                                                HasRefPoint, RefPoint, MakeGroups)
5665         if MakeGroups: return gr,er
5666         return er
5667
5668     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5669                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5670                                    MakeGroups=False, LinearVariation=False):
5671         """
5672         Generate new elements by extrusion of mesh segments which belong to the object.
5673         The path of extrusion must be a meshed edge.
5674
5675         Parameters:
5676             theObject: the object whose 1D elements should be processed.
5677                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5678             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5679             PathShape: shape (edge) defines the sub-mesh for the path
5680             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5681             HasAngles: allows the shape to be rotated around the path
5682                 to get the resulting mesh in a helical fashion
5683             Angles: list of angles
5684             HasRefPoint: allows using the reference point
5685             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
5686                 The User can specify any point as the Reference Point.
5687                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5688             MakeGroups: forces the generation of new groups from existing ones
5689             LinearVariation: forces the computation of rotation angles as linear
5690                 variation of the given Angles along path steps
5691
5692         Returns:
5693             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5694             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5695             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5696         Example: :ref:`tui_extrusion_along_path`
5697         """
5698
5699         n,e,f = [],theObject,[]
5700         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5701                                                HasAngles, Angles, LinearVariation,
5702                                                HasRefPoint, RefPoint, MakeGroups)
5703         if MakeGroups: return gr,er
5704         return er
5705
5706     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5707                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5708                                    MakeGroups=False, LinearVariation=False):
5709         """
5710         Generate new elements by extrusion of faces which belong to the object.
5711         The path of extrusion must be a meshed edge.
5712
5713         Parameters:
5714             theObject: the object whose 2D elements should be processed.
5715                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5716             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5717             PathShape: shape (edge) defines the sub-mesh for the path
5718             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5719             HasAngles: allows the shape to be rotated around the path
5720                 to get the resulting mesh in a helical fashion
5721             Angles: list of angles
5722             HasRefPoint: allows using the reference point
5723             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5724                 The User can specify any point as the Reference Point.
5725                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5726             MakeGroups: forces the generation of new groups from existing ones
5727             LinearVariation: forces the computation of rotation angles as linear
5728                 variation of the given Angles along path steps
5729
5730         Returns:
5731             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5732             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5733             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5734         Example: :ref:`tui_extrusion_along_path`
5735         """
5736
5737         n,e,f = [],[],theObject
5738         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5739                                                HasAngles, Angles, LinearVariation,
5740                                                HasRefPoint, RefPoint, MakeGroups)
5741         if MakeGroups: return gr,er
5742         return er
5743
5744     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5745         """
5746         Create a symmetrical copy of mesh elements
5747
5748         Parameters:
5749             IDsOfElements: list of elements ids
5750             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5751             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5752                 If the *Mirror* is a geom object this parameter is unnecessary
5753             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5754             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5755
5756         Returns:
5757             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5758         """
5759
5760         if IDsOfElements == []:
5761             IDsOfElements = self.GetElementsId()
5762         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5763             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5764             theMirrorType = Mirror._mirrorType
5765         else:
5766             self.mesh.SetParameters(Mirror.parameters)
5767         if Copy and MakeGroups:
5768             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5769         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5770         return []
5771
5772     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5773         """
5774         Create a new mesh by a symmetrical copy of mesh elements
5775
5776         Parameters:
5777             IDsOfElements: the list of elements ids
5778             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5779             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5780                 If the *Mirror* is a geom object this parameter is unnecessary
5781             MakeGroups: to generate new groups from existing ones
5782             NewMeshName: a name of the new mesh to create
5783
5784         Returns:
5785             instance of class :class:`Mesh`
5786         """
5787
5788         if IDsOfElements == []:
5789             IDsOfElements = self.GetElementsId()
5790         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5791             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5792             theMirrorType = Mirror._mirrorType
5793         else:
5794             self.mesh.SetParameters(Mirror.parameters)
5795         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5796                                           MakeGroups, NewMeshName)
5797         return Mesh(self.smeshpyD,self.geompyD,mesh)
5798
5799     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5800         """
5801         Create a symmetrical copy of the object
5802
5803         Parameters:
5804             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5805             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5806             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5807                 If the *Mirror* is a geom object this parameter is unnecessary
5808             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5809             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5810
5811         Returns:
5812             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5813         """
5814
5815         if ( isinstance( theObject, Mesh )):
5816             theObject = theObject.GetMesh()
5817         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5818             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5819             theMirrorType = Mirror._mirrorType
5820         else:
5821             self.mesh.SetParameters(Mirror.parameters)
5822         if Copy and MakeGroups:
5823             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5824         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5825         return []
5826
5827     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5828         """
5829         Create a new mesh by a symmetrical copy of the object
5830
5831         Parameters:
5832             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5833             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5834             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5835                 If the *Mirror* is a geom object this parameter is unnecessary
5836             MakeGroups: forces the generation of new groups from existing ones
5837             NewMeshName: the name of the new mesh to create
5838
5839         Returns:
5840             instance of class :class:`Mesh`
5841         """
5842
5843         if ( isinstance( theObject, Mesh )):
5844             theObject = theObject.GetMesh()
5845         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5846             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5847             theMirrorType = Mirror._mirrorType
5848         else:
5849             self.mesh.SetParameters(Mirror.parameters)
5850         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5851                                                 MakeGroups, NewMeshName)
5852         return Mesh( self.smeshpyD,self.geompyD,mesh )
5853
5854     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5855         """
5856         Translate the elements
5857
5858         Parameters:
5859             IDsOfElements: list of elements ids
5860             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5861             Copy: allows copying the translated elements
5862             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5863
5864         Returns:
5865             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5866         """
5867
5868         if IDsOfElements == []:
5869             IDsOfElements = self.GetElementsId()
5870         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5871             Vector = self.smeshpyD.GetDirStruct(Vector)
5872         if isinstance( Vector, list ):
5873             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5874         self.mesh.SetParameters(Vector.PS.parameters)
5875         if Copy and MakeGroups:
5876             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5877         self.editor.Translate(IDsOfElements, Vector, Copy)
5878         return []
5879
5880     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5881         """
5882         Create a new mesh of translated elements
5883
5884         Parameters:
5885             IDsOfElements: list of elements ids
5886             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5887             MakeGroups: forces the generation of new groups from existing ones
5888             NewMeshName: the name of the newly created mesh
5889
5890         Returns:
5891             instance of class :class:`Mesh`
5892         """
5893
5894         if IDsOfElements == []:
5895             IDsOfElements = self.GetElementsId()
5896         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5897             Vector = self.smeshpyD.GetDirStruct(Vector)
5898         if isinstance( Vector, list ):
5899             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5900         self.mesh.SetParameters(Vector.PS.parameters)
5901         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5902         return Mesh ( self.smeshpyD, self.geompyD, mesh )
5903
5904     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5905         """
5906         Translate the object
5907
5908         Parameters:
5909             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5910             Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5911             Copy: allows copying the translated elements
5912             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5913
5914         Returns:
5915             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5916         """
5917
5918         if ( isinstance( theObject, Mesh )):
5919             theObject = theObject.GetMesh()
5920         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5921             Vector = self.smeshpyD.GetDirStruct(Vector)
5922         if isinstance( Vector, list ):
5923             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5924         self.mesh.SetParameters(Vector.PS.parameters)
5925         if Copy and MakeGroups:
5926             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5927         self.editor.TranslateObject(theObject, Vector, Copy)
5928         return []
5929
5930     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5931         """
5932         Create a new mesh from the translated object
5933
5934         Parameters:
5935             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5936             Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5937             MakeGroups: forces the generation of new groups from existing ones
5938             NewMeshName: the name of the newly created mesh
5939
5940         Returns:
5941             instance of class :class:`Mesh`
5942         """
5943
5944         if isinstance( theObject, Mesh ):
5945             theObject = theObject.GetMesh()
5946         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
5947             Vector = self.smeshpyD.GetDirStruct(Vector)
5948         if isinstance( Vector, list ):
5949             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5950         self.mesh.SetParameters(Vector.PS.parameters)
5951         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
5952         return Mesh( self.smeshpyD, self.geompyD, mesh )
5953
5954
5955
5956     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
5957         """
5958         Scale the object
5959
5960         Parameters:
5961             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5962             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5963             theScaleFact: list of 1-3 scale factors for axises
5964             Copy: allows copying the translated elements
5965             MakeGroups: forces the generation of new groups from existing
5966                 ones (if Copy)
5967
5968         Returns:
5969             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5970             empty list otherwise
5971         """
5972         unRegister = genObjUnRegister()
5973         if ( isinstance( theObject, Mesh )):
5974             theObject = theObject.GetMesh()
5975         if ( isinstance( theObject, list )):
5976             theObject = self.GetIDSource(theObject, SMESH.ALL)
5977             unRegister.set( theObject )
5978         if ( isinstance( thePoint, list )):
5979             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
5980         if ( isinstance( theScaleFact, float )):
5981             theScaleFact = [theScaleFact]
5982         if ( isinstance( theScaleFact, int )):
5983             theScaleFact = [ float(theScaleFact)]
5984
5985         self.mesh.SetParameters(thePoint.parameters)
5986
5987         if Copy and MakeGroups:
5988             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
5989         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
5990         return []
5991
5992     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
5993         """
5994         Create a new mesh from the translated object
5995
5996         Parameters:
5997             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5998             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
5999             theScaleFact: list of 1-3 scale factors for axises
6000             MakeGroups: forces the generation of new groups from existing ones
6001             NewMeshName: the name of the newly created mesh
6002
6003         Returns:
6004             instance of class :class:`Mesh`
6005         """
6006         unRegister = genObjUnRegister()
6007         if (isinstance(theObject, Mesh)):
6008             theObject = theObject.GetMesh()
6009         if ( isinstance( theObject, list )):
6010             theObject = self.GetIDSource(theObject,SMESH.ALL)
6011             unRegister.set( theObject )
6012         if ( isinstance( thePoint, list )):
6013             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6014         if ( isinstance( theScaleFact, float )):
6015             theScaleFact = [theScaleFact]
6016         if ( isinstance( theScaleFact, int )):
6017             theScaleFact = [ float(theScaleFact)]
6018
6019         self.mesh.SetParameters(thePoint.parameters)
6020         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6021                                          MakeGroups, NewMeshName)
6022         return Mesh( self.smeshpyD, self.geompyD, mesh )
6023
6024
6025
6026     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6027         """
6028         Rotate the elements
6029
6030         Parameters:
6031             IDsOfElements: list of elements ids
6032             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6033             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6034             Copy: allows copying the rotated elements
6035             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6036
6037         Returns:
6038             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6039         """
6040
6041
6042         if IDsOfElements == []:
6043             IDsOfElements = self.GetElementsId()
6044         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6045             Axis = self.smeshpyD.GetAxisStruct(Axis)
6046         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6047         Parameters = Axis.parameters + var_separator + Parameters
6048         self.mesh.SetParameters(Parameters)
6049         if Copy and MakeGroups:
6050             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6051         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6052         return []
6053
6054     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6055         """
6056         Create a new mesh of rotated elements
6057
6058         Parameters:
6059             IDsOfElements: list of element ids
6060             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6061             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6062             MakeGroups: forces the generation of new groups from existing ones
6063             NewMeshName: the name of the newly created mesh
6064
6065         Returns:
6066             instance of class :class:`Mesh`
6067         """
6068
6069         if IDsOfElements == []:
6070             IDsOfElements = self.GetElementsId()
6071         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6072             Axis = self.smeshpyD.GetAxisStruct(Axis)
6073         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6074         Parameters = Axis.parameters + var_separator + Parameters
6075         self.mesh.SetParameters(Parameters)
6076         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6077                                           MakeGroups, NewMeshName)
6078         return Mesh( self.smeshpyD, self.geompyD, mesh )
6079
6080     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6081         """
6082         Rotate the object
6083
6084         Parameters:
6085             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6086             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6087             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6088             Copy: allows copying the rotated elements
6089             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6090
6091         Returns:
6092             list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6093         """
6094
6095         if (isinstance(theObject, Mesh)):
6096             theObject = theObject.GetMesh()
6097         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6098             Axis = self.smeshpyD.GetAxisStruct(Axis)
6099         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6100         Parameters = Axis.parameters + ":" + Parameters
6101         self.mesh.SetParameters(Parameters)
6102         if Copy and MakeGroups:
6103             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6104         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6105         return []
6106
6107     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6108         """
6109         Create a new mesh from the rotated object
6110
6111         Parameters:
6112             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6113             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6114             AngleInRadians: the angle of rotation (in radians)  or a name of variable which defines angle in degrees
6115             MakeGroups: forces the generation of new groups from existing ones
6116             NewMeshName: the name of the newly created mesh
6117
6118         Returns:
6119             instance of class :class:`Mesh`
6120         """
6121
6122         if (isinstance( theObject, Mesh )):
6123             theObject = theObject.GetMesh()
6124         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6125             Axis = self.smeshpyD.GetAxisStruct(Axis)
6126         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6127         Parameters = Axis.parameters + ":" + Parameters
6128         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6129                                                        MakeGroups, NewMeshName)
6130         self.mesh.SetParameters(Parameters)
6131         return Mesh( self.smeshpyD, self.geompyD, mesh )
6132
6133     def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6134         """
6135         Create an offset mesh from the given 2D object
6136
6137         Parameters:
6138             theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6139             theValue (float): signed offset size
6140             MakeGroups (boolean): forces the generation of new groups from existing ones
6141             CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, 
6142                           False means to remove original elements.
6143             NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6144
6145         Returns:
6146             A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6147         """
6148
6149         if isinstance( theObject, Mesh ):
6150             theObject = theObject.GetMesh()
6151         theValue,Parameters,hasVars = ParseParameters(Value)
6152         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6153         self.mesh.SetParameters(Parameters)
6154         # if mesh_groups[0]:
6155         #     return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6156         return mesh_groups
6157
6158     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6159         """
6160         Find groups of adjacent nodes within Tolerance.
6161
6162         Parameters:
6163             Tolerance (float): the value of tolerance
6164             SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6165                 corner and medium nodes in separate groups thus preventing
6166                 their further merge.
6167
6168         Returns:
6169             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6170         """
6171
6172         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6173
6174     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6175                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
6176         """
6177         Find groups of adjacent nodes within Tolerance.
6178
6179         Parameters:
6180             Tolerance: the value of tolerance
6181             SubMeshOrGroup: :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6182             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6183             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6184                 corner and medium nodes in separate groups thus preventing
6185                 their further merge.
6186
6187         Returns:
6188             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6189         """
6190
6191         unRegister = genObjUnRegister()
6192         if (isinstance( SubMeshOrGroup, Mesh )):
6193             SubMeshOrGroup = SubMeshOrGroup.GetMesh()
6194         if not isinstance( exceptNodes, list ):
6195             exceptNodes = [ exceptNodes ]
6196         if exceptNodes and isinstance( exceptNodes[0], int ):
6197             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6198             unRegister.set( exceptNodes )
6199         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6200                                                         exceptNodes, SeparateCornerAndMediumNodes)
6201
6202     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6203         """
6204         Merge nodes
6205
6206         Parameters:
6207             GroupsOfNodes: a list of groups of nodes IDs for merging.
6208                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6209                 in all elements and groups by nodes 1 and 25 correspondingly
6210             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6211                 If *NodesToKeep* does not include a node to keep for some group to merge,
6212                 then the first node in the group is kept.
6213             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6214                 invalid
6215         """
6216         # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes()
6217         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6218
6219     def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
6220         """
6221         Find the elements built on the same nodes.
6222
6223         Parameters:
6224             MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6225
6226         Returns:
6227             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6228         """
6229
6230         if not MeshOrSubMeshOrGroup:
6231             MeshOrSubMeshOrGroup=self.mesh
6232         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6233             MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
6234         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
6235
6236     def MergeElements(self, GroupsOfElementsID):
6237         """
6238         Merge elements in each given group.
6239
6240         Parameters:
6241             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6242                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6243                 replaced in all groups by elements 1 and 25)
6244         """
6245
6246         self.editor.MergeElements(GroupsOfElementsID)
6247
6248     def MergeEqualElements(self):
6249         """
6250         Leave one element and remove all other elements built on the same nodes.
6251         """
6252
6253         self.editor.MergeEqualElements()
6254
6255     def FindFreeBorders(self, ClosedOnly=True):
6256         """
6257         Returns all or only closed free borders
6258
6259         Returns:
6260             list of SMESH.FreeBorder's
6261         """
6262
6263         return self.editor.FindFreeBorders( ClosedOnly )
6264
6265     def FillHole(self, holeNodes, groupName=""):
6266         """
6267         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6268
6269         Parameters:
6270             holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6271                 must describe all sequential nodes of the hole border. The first and the last
6272                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6273             groupName (string): name of a group to add new faces
6274         Returns:
6275             a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6276         """
6277
6278
6279         if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6280             holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6281         if not isinstance( holeNodes, SMESH.FreeBorder ):
6282             raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6283         self.editor.FillHole( holeNodes, groupName )
6284
6285     def FindCoincidentFreeBorders (self, tolerance=0.):
6286         """
6287         Return groups of FreeBorder's coincident within the given tolerance.
6288
6289         Parameters:
6290             tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6291                 size of elements adjacent to free borders being compared is used.
6292
6293         Returns:
6294             SMESH.CoincidentFreeBorders structure
6295         """
6296
6297         return self.editor.FindCoincidentFreeBorders( tolerance )
6298
6299     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6300         """
6301         Sew FreeBorder's of each group
6302
6303         Parameters:
6304             freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6305                 where each enclosed list contains node IDs of a group of coincident free
6306                 borders such that each consequent triple of IDs within a group describes
6307                 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6308                 last node of a border.
6309                 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6310                 groups of coincident free borders, each group including two borders.
6311             createPolygons: if :code:`True` faces adjacent to free borders are converted to
6312                 polygons if a node of opposite border falls on a face edge, else such
6313                 faces are split into several ones.
6314             createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6315                 polyhedra if a node of opposite border falls on a volume edge, else such
6316                 volumes, if any, remain intact and the mesh becomes non-conformal.
6317
6318         Returns:
6319             a number of successfully sewed groups
6320         """
6321
6322         if freeBorders and isinstance( freeBorders, list ):
6323             # construct SMESH.CoincidentFreeBorders
6324             if isinstance( freeBorders[0], int ):
6325                 freeBorders = [freeBorders]
6326             borders = []
6327             coincidentGroups = []
6328             for nodeList in freeBorders:
6329                 if not nodeList or len( nodeList ) % 3:
6330                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6331                 group = []
6332                 while nodeList:
6333                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6334                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
6335                     nodeList = nodeList[3:]
6336                     pass
6337                 coincidentGroups.append( group )
6338                 pass
6339             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6340
6341         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6342
6343     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6344                         FirstNodeID2, SecondNodeID2, LastNodeID2,
6345                         CreatePolygons, CreatePolyedrs):
6346         """
6347         Sew free borders
6348
6349         Returns:
6350             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6351         """
6352
6353         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6354                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
6355                                           CreatePolygons, CreatePolyedrs)
6356
6357     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6358                                FirstNodeID2, SecondNodeID2):
6359         """
6360         Sew conform free borders
6361
6362         Returns:
6363             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6364         """
6365
6366         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6367                                                  FirstNodeID2, SecondNodeID2)
6368
6369     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6370                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6371         """
6372         Sew border to side
6373
6374         Returns:
6375             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6376         """
6377
6378         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6379                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6380
6381     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6382                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6383                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6384         """
6385         Sew two sides of a mesh. The nodes belonging to Side1 are
6386         merged with the nodes of elements of Side2.
6387         The number of elements in theSide1 and in theSide2 must be
6388         equal and they should have similar nodal connectivity.
6389         The nodes to merge should belong to side borders and
6390         the first node should be linked to the second.
6391
6392         Returns:
6393             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6394         """
6395
6396         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6397                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6398                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6399
6400     def ChangeElemNodes(self, ide, newIDs):
6401         """
6402         Set new nodes for the given element.
6403
6404         Parameters:
6405             ide: the element ID
6406             newIDs: nodes IDs
6407
6408         Returns:
6409             False if the number of nodes does not correspond to the type of element
6410         """
6411
6412         return self.editor.ChangeElemNodes(ide, newIDs)
6413
6414     def GetLastCreatedNodes(self):
6415         """
6416         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6417         created, this method return the list of their IDs.
6418         If new nodes were not created - return empty list
6419
6420         Returns:
6421             the list of integer values (can be empty)
6422         """
6423
6424         return self.editor.GetLastCreatedNodes()
6425
6426     def GetLastCreatedElems(self):
6427         """
6428         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6429         created this method return the list of their IDs.
6430         If new elements were not created - return empty list
6431
6432         Returns:
6433             the list of integer values (can be empty)
6434         """
6435
6436         return self.editor.GetLastCreatedElems()
6437
6438     def ClearLastCreated(self):
6439         """
6440         Forget what nodes and elements were created by the last mesh edition operation
6441         """
6442
6443         self.editor.ClearLastCreated()
6444
6445     def DoubleElements(self, theElements, theGroupName=""):
6446         """
6447         Create duplicates of given elements, i.e. create new elements based on the
6448         same nodes as the given ones.
6449
6450         Parameters:
6451             theElements: container of elements to duplicate. It can be a
6452                 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` 
6453                 or a list of element IDs. If *theElements* is
6454                 a :class:`Mesh`, elements of highest dimension are duplicated
6455             theGroupName: a name of group to contain the generated elements.
6456                 If a group with such a name already exists, the new elements
6457                 are added to the existing group, else a new group is created.
6458                 If *theGroupName* is empty, new elements are not added
6459                 in any group.
6460
6461         Returns:
6462                 a :class:`group <SMESH.SMESH_Group>` where the new elements are added. 
6463                 None if *theGroupName* == "".
6464         """
6465
6466         unRegister = genObjUnRegister()
6467         if isinstance( theElements, Mesh ):
6468             theElements = theElements.mesh
6469         elif isinstance( theElements, list ):
6470             theElements = self.GetIDSource( theElements, SMESH.ALL )
6471             unRegister.set( theElements )
6472         return self.editor.DoubleElements(theElements, theGroupName)
6473
6474     def DoubleNodes(self, theNodes, theModifiedElems):
6475         """
6476         Create a hole in a mesh by doubling the nodes of some particular elements
6477
6478         Parameters:
6479             theNodes: IDs of nodes to be doubled
6480             theModifiedElems: IDs of elements to be updated by the new (doubled)
6481                 nodes. If list of element identifiers is empty then nodes are doubled but
6482                 they not assigned to elements
6483
6484         Returns:
6485             True if operation has been completed successfully, False otherwise
6486         """
6487
6488         return self.editor.DoubleNodes(theNodes, theModifiedElems)
6489
6490     def DoubleNode(self, theNodeId, theModifiedElems):
6491         """
6492         Create a hole in a mesh by doubling the nodes of some particular elements.
6493         This method provided for convenience works as :meth:`DoubleNodes`.
6494
6495         Parameters:
6496             theNodeId: IDs of node to double
6497             theModifiedElems: IDs of elements to update
6498
6499         Returns:
6500             True if operation has been completed successfully, False otherwise
6501         """
6502
6503         return self.editor.DoubleNode(theNodeId, theModifiedElems)
6504
6505     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6506         """
6507         Create a hole in a mesh by doubling the nodes of some particular elements.
6508         This method provided for convenience works as :meth:`DoubleNodes`.
6509
6510         Parameters:
6511             theNodes: group of nodes to double.
6512             theModifiedElems: group of elements to update.
6513             theMakeGroup: forces the generation of a group containing new nodes.
6514
6515         Returns:
6516             True or a created group if operation has been completed successfully,
6517             False or None otherwise
6518         """
6519
6520         if theMakeGroup:
6521             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6522         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6523
6524     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6525         """
6526         Create a hole in a mesh by doubling the nodes of some particular elements.
6527         This method provided for convenience works as :meth:`DoubleNodes`.
6528
6529         Parameters:
6530             theNodes: list of groups of nodes to double.
6531             theModifiedElems: list of groups of elements to update.
6532             theMakeGroup: forces the generation of a group containing new nodes.
6533
6534         Returns:
6535             True if operation has been completed successfully, False otherwise
6536         """
6537
6538         if theMakeGroup:
6539             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6540         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6541
6542     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6543         """
6544         Create a hole in a mesh by doubling the nodes of some particular elements
6545
6546         Parameters:
6547             theElems: the list of elements (edges or faces) to replicate.
6548                 The nodes for duplication could be found from these elements
6549             theNodesNot: list of nodes NOT to replicate
6550             theAffectedElems: the list of elements (cells and edges) to which the
6551                 replicated nodes should be associated to
6552
6553         Returns:
6554             True if operation has been completed successfully, False otherwise
6555         """
6556
6557         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6558
6559     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6560         """
6561         Create a hole in a mesh by doubling the nodes of some particular elements
6562
6563         Parameters:
6564             theElems: the list of elements (edges or faces) to replicate.
6565                 The nodes for duplication could be found from these elements
6566             theNodesNot: list of nodes NOT to replicate
6567             theShape: shape to detect affected elements (element which geometric center
6568                 located on or inside shape).
6569                 The replicated nodes should be associated to affected elements.
6570
6571         Returns:
6572             True if operation has been completed successfully, False otherwise
6573         """
6574
6575         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6576
6577     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6578                              theMakeGroup=False, theMakeNodeGroup=False):
6579         """
6580         Create a hole in a mesh by doubling the nodes of some particular elements.
6581         This method provided for convenience works as :meth:`DoubleNodes`.
6582
6583         Parameters:
6584             theElems: group of of elements (edges or faces) to replicate.
6585             theNodesNot: group of nodes NOT to replicate.
6586             theAffectedElems: group of elements to which the replicated nodes
6587                 should be associated to.
6588             theMakeGroup: forces the generation of a group containing new elements.
6589             theMakeNodeGroup: forces the generation of a group containing new nodes.
6590
6591         Returns:
6592             True or created groups (one or two) if operation has been completed successfully,
6593             False or None otherwise
6594         """
6595
6596         if theMakeGroup or theMakeNodeGroup:
6597             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6598                                                             theAffectedElems,
6599                                                             theMakeGroup, theMakeNodeGroup)
6600             if theMakeGroup and theMakeNodeGroup:
6601                 return twoGroups
6602             else:
6603                 return twoGroups[ int(theMakeNodeGroup) ]
6604         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6605
6606     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6607         """
6608         Create a hole in a mesh by doubling the nodes of some particular elements.
6609         This method provided for convenience works as :meth:`DoubleNodes`.
6610
6611         Parameters:
6612             theElems: group of of elements (edges or faces) to replicate
6613             theNodesNot: group of nodes not to replicate
6614             theShape: shape to detect affected elements (element which geometric center
6615                 located on or inside shape).
6616                 The replicated nodes should be associated to affected elements
6617         """
6618
6619         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6620
6621     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6622                              theMakeGroup=False, theMakeNodeGroup=False):
6623         """
6624         Create a hole in a mesh by doubling the nodes of some particular elements.
6625         This method provided for convenience works as :meth:`DoubleNodes`.
6626
6627         Parameters:
6628             theElems: list of groups of elements (edges or faces) to replicate
6629             theNodesNot: list of groups of nodes NOT to replicate
6630             theAffectedElems: group of elements to which the replicated nodes
6631                 should be associated to
6632             theMakeGroup: forces generation of a group containing new elements.
6633             theMakeNodeGroup: forces generation of a group containing new nodes
6634
6635         Returns:
6636             True or created groups (one or two) if operation has been completed successfully,
6637             False or None otherwise
6638         """
6639
6640         if theMakeGroup or theMakeNodeGroup:
6641             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6642                                                              theAffectedElems,
6643                                                              theMakeGroup, theMakeNodeGroup)
6644             if theMakeGroup and theMakeNodeGroup:
6645                 return twoGroups
6646             else:
6647                 return twoGroups[ int(theMakeNodeGroup) ]
6648         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6649
6650     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6651         """
6652         Create a hole in a mesh by doubling the nodes of some particular elements.
6653         This method provided for convenience works as :meth:`DoubleNodes`.
6654
6655         Parameters:
6656             theElems: list of groups of elements (edges or faces) to replicate
6657             theNodesNot: list of groups of nodes NOT to replicate
6658             theShape: shape to detect affected elements (element which geometric center
6659                 located on or inside shape).
6660                 The replicated nodes should be associated to affected elements
6661
6662         Returns:
6663             True if operation has been completed successfully, False otherwise
6664         """
6665
6666         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6667
6668     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6669         """
6670         Identify the elements that will be affected by node duplication (actual duplication is not performed).
6671         This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6672
6673         Parameters:
6674             theElems: list of groups of nodes or elements (edges or faces) to replicate
6675             theNodesNot: list of groups of nodes NOT to replicate
6676             theShape: shape to detect affected elements (element which geometric center
6677                 located on or inside shape).
6678                 The replicated nodes should be associated to affected elements
6679
6680         Returns:
6681             groups of affected elements in order: volumes, faces, edges
6682         """
6683
6684         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6685
6686     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6687
6688         """
6689         Double nodes on shared faces between groups of volumes and create flat elements on demand.
6690         The list of groups must describe a partition of the mesh volumes.
6691         The nodes of the internal faces at the boundaries of the groups are doubled.
6692         In option, the internal faces are replaced by flat elements.
6693         Triangles are transformed to prisms, and quadrangles to hexahedrons.
6694
6695         Parameters:
6696             theDomains: list of groups of volumes
6697             createJointElems: if True, create the elements
6698             onAllBoundaries: if True, the nodes and elements are also created on
6699                 the boundary between *theDomains* and the rest mesh
6700
6701         Returns:
6702             True if operation has been completed successfully, False otherwise
6703         """
6704
6705         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6706
6707     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6708         """
6709         Double nodes on some external faces and create flat elements.
6710         Flat elements are mainly used by some types of mechanic calculations.
6711
6712         Each group of the list must be constituted of faces.
6713         Triangles are transformed in prisms, and quadrangles in hexahedrons.
6714
6715         Parameters:
6716             theGroupsOfFaces: list of groups of faces
6717
6718         Returns:
6719             True if operation has been completed successfully, False otherwise
6720         """
6721
6722         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6723
6724     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6725         """
6726         Identify all the elements around a geom shape, get the faces delimiting the hole
6727         """
6728         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6729
6730     def MakePolyLine(self, segments, groupName='', isPreview=False ):
6731         """    
6732         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6733         the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6734         plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6735         If there are several paths connecting a pair of points, the shortest path is
6736         selected by the module. Position of the cutting plane is defined by the two
6737         points and an optional vector lying on the plane specified by a PolySegment.
6738         By default the vector is defined by Mesh module as following. A middle point
6739         of the two given points is computed. The middle point is projected to the mesh.
6740         The vector goes from the middle point to the projection point. In case of planar
6741         mesh, the vector is normal to the mesh.
6742
6743         In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6744
6745         Parameters:
6746             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6747             groupName: optional name of a group where created mesh segments will be added.
6748
6749         """    
6750         editor = self.editor
6751         if isPreview:
6752             editor = self.mesh.GetMeshEditPreviewer()
6753         segmentsRes = editor.MakePolyLine( segments, groupName )
6754         for i, seg in enumerate( segmentsRes ):
6755             segments[i].vector = seg.vector
6756         if isPreview:
6757             return editor.GetPreviewData()
6758         return None        
6759
6760     def GetFunctor(self, funcType ):
6761         """
6762         Return a cached numerical functor by its type.
6763
6764         Parameters:
6765             funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6766                 Note that not all items correspond to numerical functors.
6767
6768         Returns:
6769             :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6770         """
6771
6772         fn = self.functors[ funcType._v ]
6773         if not fn:
6774             fn = self.smeshpyD.GetFunctor(funcType)
6775             fn.SetMesh(self.mesh)
6776             self.functors[ funcType._v ] = fn
6777         return fn
6778
6779     def FunctorValue(self, funcType, elemId, isElem=True):
6780         """
6781         Return value of a functor for a given element
6782
6783         Parameters:
6784             funcType: an item of :class:`SMESH.FunctorType` enum.
6785             elemId: element or node ID
6786             isElem: *elemId* is ID of element or node
6787
6788         Returns:
6789             the functor value or zero in case of invalid arguments
6790         """
6791
6792         fn = self.GetFunctor( funcType )
6793         if fn.GetElementType() == self.GetElementType(elemId, isElem):
6794             val = fn.GetValue(elemId)
6795         else:
6796             val = 0
6797         return val
6798
6799     def GetLength(self, elemId=None):
6800         """
6801         Get length of 1D element or sum of lengths of all 1D mesh elements
6802
6803         Parameters:
6804             elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6805
6806         Returns:
6807             element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6808         """
6809
6810         length = 0
6811         if elemId == None:
6812             length = self.smeshpyD.GetLength(self)
6813         else:
6814             length = self.FunctorValue(SMESH.FT_Length, elemId)
6815         return length
6816
6817     def GetArea(self, elemId=None):
6818         """
6819         Get area of 2D element or sum of areas of all 2D mesh elements
6820         elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6821
6822         Returns:
6823             element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6824         """
6825
6826         area = 0
6827         if elemId == None:
6828             area = self.smeshpyD.GetArea(self)
6829         else:
6830             area = self.FunctorValue(SMESH.FT_Area, elemId)
6831         return area
6832
6833     def GetVolume(self, elemId=None):
6834         """
6835         Get volume of 3D element or sum of volumes of all 3D mesh elements
6836
6837         Parameters:
6838             elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6839
6840         Returns:
6841             element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6842         """
6843
6844         volume = 0
6845         if elemId == None:
6846             volume = self.smeshpyD.GetVolume(self)
6847         else:
6848             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6849         return volume
6850
6851     def GetAngle(self, node1, node2, node3 ):
6852         """
6853         Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
6854
6855         Parameters:            
6856                 node1,node2,node3: IDs of the three nodes
6857
6858         Returns:        
6859             Angle in radians
6860         """
6861         return self.smeshpyD.GetAngle( self.GetNodeXYZ( node1 ),
6862                                        self.GetNodeXYZ( node2 ),
6863                                        self.GetNodeXYZ( node3 ))
6864
6865     def GetMaxElementLength(self, elemId):
6866         """
6867         Get maximum element length.
6868
6869         Parameters:
6870             elemId: mesh element ID
6871
6872         Returns:
6873             element's maximum length value
6874         """
6875
6876         if self.GetElementType(elemId, True) == SMESH.VOLUME:
6877             ftype = SMESH.FT_MaxElementLength3D
6878         else:
6879             ftype = SMESH.FT_MaxElementLength2D
6880         return self.FunctorValue(ftype, elemId)
6881
6882     def GetAspectRatio(self, elemId):
6883         """
6884         Get aspect ratio of 2D or 3D element.
6885
6886         Parameters:
6887             elemId: mesh element ID
6888
6889         Returns:
6890             element's aspect ratio value
6891         """
6892
6893         if self.GetElementType(elemId, True) == SMESH.VOLUME:
6894             ftype = SMESH.FT_AspectRatio3D
6895         else:
6896             ftype = SMESH.FT_AspectRatio
6897         return self.FunctorValue(ftype, elemId)
6898
6899     def GetWarping(self, elemId):
6900         """
6901         Get warping angle of 2D element.
6902
6903         Parameters:
6904             elemId: mesh element ID
6905
6906         Returns:
6907             element's warping angle value
6908         """
6909
6910         return self.FunctorValue(SMESH.FT_Warping, elemId)
6911
6912     def GetMinimumAngle(self, elemId):
6913         """
6914         Get minimum angle of 2D element.
6915
6916         Parameters:
6917             elemId: mesh element ID
6918
6919         Returns:
6920             element's minimum angle value
6921         """
6922
6923         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
6924
6925     def GetTaper(self, elemId):
6926         """
6927         Get taper of 2D element.
6928
6929         Parameters:
6930             elemId: mesh element ID
6931
6932         Returns:
6933             element's taper value
6934         """
6935
6936         return self.FunctorValue(SMESH.FT_Taper, elemId)
6937
6938     def GetSkew(self, elemId):
6939         """
6940         Get skew of 2D element.
6941
6942         Parameters:
6943             elemId: mesh element ID
6944
6945         Returns:
6946             element's skew value
6947         """
6948
6949         return self.FunctorValue(SMESH.FT_Skew, elemId)
6950
6951     def GetMinMax(self, funType, meshPart=None):
6952         """
6953         Return minimal and maximal value of a given functor.
6954
6955         Parameters:
6956             funType (SMESH.FunctorType): a functor type.
6957                   Note that not all items of :class:`SMESH.FunctorType` corresponds
6958                   to numerical functors.
6959             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
6960
6961         Returns:
6962             tuple (min,max)
6963         """
6964
6965         unRegister = genObjUnRegister()
6966         if isinstance( meshPart, list ):
6967             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
6968             unRegister.set( meshPart )
6969         if isinstance( meshPart, Mesh ):
6970             meshPart = meshPart.mesh
6971         fun = self.GetFunctor( funType )
6972         if fun:
6973             if meshPart:
6974                 if hasattr( meshPart, "SetMesh" ):
6975                     meshPart.SetMesh( self.mesh ) # set mesh to filter
6976                 hist = fun.GetLocalHistogram( 1, False, meshPart )
6977             else:
6978                 hist = fun.GetHistogram( 1, False )
6979             if hist:
6980                 return hist[0].min, hist[0].max
6981         return None
6982
6983     pass # end of Mesh class
6984
6985
6986 class meshProxy(SMESH._objref_SMESH_Mesh):
6987     """
6988     Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
6989     with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
6990     """
6991     def __init__(self,*args):
6992         SMESH._objref_SMESH_Mesh.__init__(self,*args)
6993     def __deepcopy__(self, memo=None):
6994         new = self.__class__(self)
6995         return new
6996     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
6997         if len( args ) == 3:
6998             args += SMESH.ALL_NODES, True
6999         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7000     def ExportToMEDX(self, *args): # function removed
7001         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7002         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7003         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7004     def ExportToMED(self, *args): # function removed
7005         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7006         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7007         args2 = list(args)
7008         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7009             args2.append(True)
7010         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7011     def ExportPartToMED(self, *args): # 'version' parameter removed
7012         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7013         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7014     def ExportMED(self, *args): # signature of method changed
7015         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7016         args2 = list(args)
7017         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7018             args2.append(True)
7019         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7020     pass
7021 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7022
7023
7024 class submeshProxy(SMESH._objref_SMESH_subMesh):
7025
7026     """
7027     Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7028     """
7029     def __init__(self,*args):
7030         SMESH._objref_SMESH_subMesh.__init__(self,*args)
7031         self.mesh = None
7032     def __deepcopy__(self, memo=None):
7033         new = self.__class__(self)
7034         return new
7035
7036     def Compute(self,refresh=False):
7037         """
7038         Compute the sub-mesh and return the status of the computation
7039
7040         Parameters:
7041             refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7042
7043         Returns:
7044             True or False
7045
7046         This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7047         :meth:`smeshBuilder.Mesh.GetSubMesh`.
7048         """
7049
7050         if not self.mesh:
7051             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7052
7053         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7054
7055         if salome.sg.hasDesktop():
7056             if refresh: salome.sg.updateObjBrowser()
7057             pass
7058
7059         return ok
7060     pass
7061 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7062
7063
7064 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7065     """
7066     Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7067     compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7068     smeshBuilder.Mesh
7069     """
7070     def __init__(self,*args):
7071         SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7072         self.mesh = None
7073     def __getattr__(self, name ): # method called if an attribute not found
7074         if not self.mesh:         # look for name() method in Mesh class
7075             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7076         if hasattr( self.mesh, name ):
7077             return getattr( self.mesh, name )
7078         if name == "ExtrusionAlongPathObjX":
7079             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7080         print("meshEditor: attribute '%s' NOT FOUND" % name)
7081         return None
7082     def __deepcopy__(self, memo=None):
7083         new = self.__class__(self)
7084         return new
7085     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7086         if len( args ) == 1: args += False,
7087         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7088     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7089         if len( args ) == 2: args += False,
7090         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7091     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7092         if len( args ) == 1:
7093             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7094         NodesToKeep = args[1]
7095         AvoidMakingHoles = args[2] if len( args ) == 3 else False
7096         unRegister  = genObjUnRegister()
7097         if NodesToKeep:
7098             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7099                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7100             if not isinstance( NodesToKeep, list ):
7101                 NodesToKeep = [ NodesToKeep ]
7102         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7103     pass
7104 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7105
7106 class Pattern(SMESH._objref_SMESH_Pattern):
7107     """
7108     Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7109     variables in some methods
7110     """
7111
7112     def LoadFromFile(self, patternTextOrFile ):
7113         text = patternTextOrFile
7114         if os.path.exists( text ):
7115             text = open( patternTextOrFile ).read()
7116             pass
7117         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7118
7119     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7120         decrFun = lambda i: i-1
7121         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7122         theMesh.SetParameters(Parameters)
7123         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7124
7125     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7126         decrFun = lambda i: i-1
7127         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7128         theMesh.SetParameters(Parameters)
7129         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7130
7131     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7132         if isinstance( mesh, Mesh ):
7133             mesh = mesh.GetMesh()
7134         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7135
7136 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7137 """
7138 Registering the new proxy for Pattern
7139 """
7140
7141 class algoCreator:
7142     """
7143     Private class used to bind methods creating algorithms to the class Mesh
7144     """
7145
7146     def __init__(self, method):
7147         self.mesh = None
7148         self.defaultAlgoType = ""
7149         self.algoTypeToClass = {}
7150         self.method = method
7151
7152     def add(self, algoClass):
7153         """
7154         Store a python class of algorithm
7155         """
7156         if inspect.isclass(algoClass) and \
7157            hasattr( algoClass, "algoType"):
7158             self.algoTypeToClass[ algoClass.algoType ] = algoClass
7159             if not self.defaultAlgoType and \
7160                hasattr( algoClass, "isDefault") and algoClass.isDefault:
7161                 self.defaultAlgoType = algoClass.algoType
7162             #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7163
7164     def copy(self, mesh):
7165         """
7166         Create a copy of self and assign mesh to the copy
7167         """
7168
7169         other = algoCreator( self.method )
7170         other.defaultAlgoType = self.defaultAlgoType
7171         other.algoTypeToClass = self.algoTypeToClass
7172         other.mesh = mesh
7173         return other
7174
7175     def __call__(self,algo="",geom=0,*args):
7176         """
7177         Create an instance of algorithm
7178         """
7179         algoType = ""
7180         shape = 0
7181         if isinstance( algo, str ):
7182             algoType = algo
7183         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7184                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7185             shape = algo
7186         elif algo:
7187             args += (algo,)
7188
7189         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7190             shape = geom
7191         elif not algoType and isinstance( geom, str ):
7192             algoType = geom
7193         elif geom:
7194             args += (geom,)
7195         for arg in args:
7196             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7197                 shape = arg
7198             elif isinstance( arg, str ) and not algoType:
7199                 algoType = arg
7200             else:
7201                 import traceback, sys
7202                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
7203                 sys.stderr.write( msg + '\n' )
7204                 tb = traceback.extract_stack(None,2)
7205                 traceback.print_list( [tb[0]] )
7206         if not algoType:
7207             algoType = self.defaultAlgoType
7208         if not algoType and self.algoTypeToClass:
7209             algoType = sorted( self.algoTypeToClass.keys() )[0]
7210         if algoType in self.algoTypeToClass:
7211             #print("Create algo",algoType)
7212             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7213         raise RuntimeError( "No class found for algo type %s" % algoType)
7214         return None
7215
7216 class hypMethodWrapper:
7217     """
7218     Private class used to substitute and store variable parameters of hypotheses.
7219     """
7220
7221     def __init__(self, hyp, method):
7222         self.hyp    = hyp
7223         self.method = method
7224         #print("REBIND:", method.__name__)
7225         return
7226
7227     def __call__(self,*args):
7228         """
7229         call a method of hypothesis with calling SetVarParameter() before
7230         """
7231
7232         if not args:
7233             return self.method( self.hyp, *args ) # hypothesis method with no args
7234
7235         #print("MethWrapper.__call__", self.method.__name__, args)
7236         try:
7237             parsed = ParseParameters(*args)     # replace variables with their values
7238             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7239             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7240         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7241             # maybe there is a replaced string arg which is not variable
7242             result = self.method( self.hyp, *args )
7243         except ValueError as detail: # raised by ParseParameters()
7244             try:
7245                 result = self.method( self.hyp, *args )
7246             except omniORB.CORBA.BAD_PARAM:
7247                 raise ValueError(detail) # wrong variable name
7248
7249         return result
7250     pass
7251
7252 class genObjUnRegister:
7253     """
7254     A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7255     """
7256
7257     def __init__(self, genObj=None):
7258         self.genObjList = []
7259         self.set( genObj )
7260         return
7261
7262     def set(self, genObj):
7263         "Store one or a list of of SALOME.GenericObj'es"
7264         if isinstance( genObj, list ):
7265             self.genObjList.extend( genObj )
7266         else:
7267             self.genObjList.append( genObj )
7268         return
7269
7270     def __del__(self):
7271         for genObj in self.genObjList:
7272             if genObj and hasattr( genObj, "UnRegister" ):
7273                 genObj.UnRegister()
7274
7275 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7276     """
7277     Bind methods creating mesher plug-ins to the Mesh class
7278     """
7279
7280     # print("pluginName: ", pluginName)
7281     pluginBuilderName = pluginName + "Builder"
7282     try:
7283         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7284     except Exception as e:
7285         from salome_utils import verbose
7286         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7287         continue
7288     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7289     plugin = eval( pluginBuilderName )
7290     # print("  plugin:" , str(plugin))
7291
7292     # add methods creating algorithms to Mesh
7293     for k in dir( plugin ):
7294         if k[0] == '_': continue
7295         algo = getattr( plugin, k )
7296         #print("             algo:", str(algo))
7297         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7298             #print("                     meshMethod:" , str(algo.meshMethod))
7299             if not hasattr( Mesh, algo.meshMethod ):
7300                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7301                 pass
7302             _mmethod = getattr( Mesh, algo.meshMethod )
7303             if hasattr(  _mmethod, "add" ):
7304                 _mmethod.add(algo)
7305             pass
7306         pass
7307     pass
7308 del pluginName