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