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