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