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