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