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