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