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