Salome HOME
Merge branch 'occ/shaper2smesh'
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 #  File   : smeshBuilder.py
20 #  Author : Francis KLOSS, OCC
21 #  Module : SMESH
22
23 import salome
24 from salome.geom import geomBuilder
25
26 import SMESH # This is necessary for back compatibility
27 import omniORB                                       # back compatibility
28 SMESH.MED_V2_1    = 11 #omniORB.EnumItem("MED_V2_1", 11) # back compatibility: use number > MED minor version
29 SMESH.MED_V2_2    = 12 #omniORB.EnumItem("MED_V2_2", 12) # back compatibility: latest minor will be used
30 SMESH.MED_MINOR_0 = 20 # back compatibility
31 SMESH.MED_MINOR_1 = 21 # back compatibility
32 SMESH.MED_MINOR_2 = 22 # back compatibility
33 SMESH.MED_MINOR_3 = 23 # back compatibility
34 SMESH.MED_MINOR_4 = 24 # back compatibility
35 SMESH.MED_MINOR_5 = 25 # back compatibility
36 SMESH.MED_MINOR_6 = 26 # back compatibility
37 SMESH.MED_MINOR_7 = 27 # back compatibility
38 SMESH.MED_MINOR_8 = 28 # back compatibility
39 SMESH.MED_MINOR_9 = 29 # back compatibility
40
41 from   SMESH import *
42 from   salome.smesh.smesh_algorithm import Mesh_Algorithm
43
44 import SALOME
45 import SALOMEDS
46 import os
47 import inspect
48
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
51 # defined
52 #
53 try:
54     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
55 except TypeError:
56     def enumitem_eq(self, other):
57         try:
58             if isinstance(other, omniORB.EnumItem):
59                 if other._parent_id == self._parent_id:
60                     return self._v == other._v
61                 else:
62                     return self._parent_id == other._parent_id
63             else:
64                 return id(self) == id(other)
65         except:
66             return id(self) == id(other)
67
68     def enumitem_lt(self, other):
69         try:
70             if isinstance(other, omniORB.EnumItem):
71                 if other._parent_id == self._parent_id:
72                     return self._v < other._v
73                 else:
74                     return self._parent_id < other._parent_id
75             else:
76                 return id(self) < id(other)
77         except:
78             return id(self) < id(other)
79
80     def enumitem_le(self, other):
81         try:
82             if isinstance(other, omniORB.EnumItem):
83                 if other._parent_id == self._parent_id:
84                     return self._v <= other._v
85                 else:
86                     return self._parent_id <= other._parent_id
87             else:
88                 return id(self) <= id(other)
89         except:
90             return id(self) <= id(other)
91
92     def enumitem_gt(self, other):
93         try:
94             if isinstance(other, omniORB.EnumItem):
95                 if other._parent_id == self._parent_id:
96                     return self._v > other._v
97                 else:
98                     return self._parent_id > other._parent_id
99             else:
100                 return id(self) > id(other)
101         except:
102             return id(self) > id(other)
103
104     def enumitem_ge(self, other):
105         try:
106             if isinstance(other, omniORB.EnumItem):
107                 if other._parent_id == self._parent_id:
108                     return self._v >= other._v
109                 else:
110                     return self._parent_id >= other._parent_id
111             else:
112                 return id(self) >= id(other)
113         except:
114             return id(self) >= id(other)
115
116     omniORB.EnumItem.__eq__ = enumitem_eq
117     omniORB.EnumItem.__lt__ = enumitem_lt
118     omniORB.EnumItem.__le__ = enumitem_le
119     omniORB.EnumItem.__gt__ = enumitem_gt
120     omniORB.EnumItem.__ge__ = enumitem_ge
121
122
123 class MeshMeta(type):
124     """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
125     """
126     def __instancecheck__(cls, inst):
127         """Implement isinstance(inst, cls)."""
128         return any(cls.__subclasscheck__(c)
129                    for c in {type(inst), inst.__class__})
130
131     def __subclasscheck__(cls, sub):
132         """Implement issubclass(sub, cls)."""
133         return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
134
135 def DegreesToRadians(AngleInDegrees):
136     """Convert an angle from degrees to radians
137     """
138     from math import pi
139     return AngleInDegrees * pi / 180.0
140
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
144 var_separator = ":"
145
146 def ParseParameters(*args):
147     """
148     Return list of variable values from salome notebook.
149     The last argument, if is callable, is used to modify values got from notebook
150     """
151     Result = []
152     Parameters = ""
153     hasVariables = False
154     varModifFun=None
155     if args and callable(args[-1]):
156         args, varModifFun = args[:-1], args[-1]
157     for parameter in args:
158
159         Parameters += str(parameter) + var_separator
160
161         if isinstance(parameter,str):
162             # check if there is an inexistent variable name
163             if not notebook.isVariable(parameter):
164                 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165             parameter = notebook.get(parameter)
166             hasVariables = True
167             if varModifFun:
168                 parameter = varModifFun(parameter)
169                 pass
170             pass
171         Result.append(parameter)
172
173         pass
174     Parameters = Parameters[:-1]
175     Result.append( Parameters )
176     Result.append( hasVariables )
177     return Result
178
179 def ParseAngles(*args):
180     """
181     Parse parameters while converting variables to radians
182     """
183     return ParseParameters( *( args + (DegreesToRadians, )))
184
185 def __initPointStruct(point,*args):
186     """
187     Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188     Parameters are stored in PointStruct.parameters attribute
189     """
190     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
191     pass
192 SMESH.PointStruct.__init__ = __initPointStruct
193
194 def __initAxisStruct(ax,*args):
195     """
196     Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197     Parameters are stored in AxisStruct.parameters attribute
198     """
199     if len( args ) != 6:
200         raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
202     pass
203 SMESH.AxisStruct.__init__ = __initAxisStruct
204
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207     """Compare real values using smeshPrecisionConfusion as tolerance
208     """
209     if abs(val1 - val2) < tol:
210         return True
211     return False
212
213 NO_NAME = "NoName"
214
215 def GetName(obj):
216     """
217     Return a name of an object
218     
219     Returns:
220         object name
221     """
222     if obj:
223         # object not null
224         if isinstance(obj, SALOMEDS._objref_SObject):
225             # study object
226             return obj.GetName()
227         try:
228             ior  = salome.orb.object_to_string(obj)
229         except:
230             ior = None
231         if ior:
232             sobj = salome.myStudy.FindObjectIOR(ior)
233             if sobj:
234                 return sobj.GetName()
235             if hasattr(obj, "GetName"):
236                 # unknown CORBA object, having GetName() method
237                 return obj.GetName()
238             else:
239                 # unknown CORBA object, no GetName() method
240                 return NO_NAME
241             pass
242         if hasattr(obj, "GetName"):
243             # unknown non-CORBA object, having GetName() method
244             return obj.GetName()
245         pass
246     raise RuntimeError("Null or invalid object")
247
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
249     """
250     Print error message if a hypothesis was not assigned.
251     """
252     if isAlgo:
253         hypType = "algorithm"
254     else:
255         hypType = "hypothesis"
256         pass
257     reason = ""
258     if hasattr( status, "__getitem__" ):
259         status, reason = status[0], status[1]
260     if status == HYP_UNKNOWN_FATAL:
261         reason = "for unknown reason"
262     elif status == HYP_INCOMPATIBLE:
263         reason = "this hypothesis mismatches the algorithm"
264     elif status == HYP_NOTCONFORM:
265         reason = "a non-conform mesh would be built"
266     elif status == HYP_ALREADY_EXIST:
267         if isAlgo: return # it does not influence anything
268         reason = hypType + " of the same dimension is already assigned to this shape"
269     elif status == HYP_BAD_DIM:
270         reason = hypType + " mismatches the shape"
271     elif status == HYP_CONCURRENT :
272         reason = "there are concurrent hypotheses on sub-shapes"
273     elif status == HYP_BAD_SUBSHAPE:
274         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275     elif status == HYP_BAD_GEOMETRY:
276         reason = "the algorithm is not applicable to this geometry"
277     elif status == HYP_HIDDEN_ALGO:
278         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279     elif status == HYP_HIDING_ALGO:
280         reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281     elif status == HYP_NEED_SHAPE:
282         reason = "algorithm can't work without shape"
283     elif status == HYP_INCOMPAT_HYPS:
284         pass
285     else:
286         return
287     where = geomName
288     if where:
289         where = '"%s"' % geomName
290         if mesh:
291             meshName = GetName( mesh )
292             if meshName and meshName != NO_NAME:
293                 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294     if status < HYP_UNKNOWN_FATAL and where:
295         print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
296     elif where:
297         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
298     else:
299         print('"%s" was not assigned : %s' %( hypName, reason ))
300         pass
301
302 def AssureGeomPublished(mesh, geom, name=''):
303     """
304     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
305     """
306     if not mesh.smeshpyD.IsEnablePublish():
307         return
308     if not 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             if self.geom == 0:
1864                 geom = self.mesh.GetShapeToMesh()
1865             else:
1866                 geom = self.geom
1867         ok = False
1868         try:
1869             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1870                 self.mesh.Clear()
1871             ok = self.smeshpyD.Compute(self.mesh, geom)
1872         except SALOME.SALOME_Exception as ex:
1873             print("Mesh computation failed, exception caught:")
1874             print("    ", ex.details.text)
1875         except:
1876             import traceback
1877             print("Mesh computation failed, exception caught:")
1878             traceback.print_exc()
1879         if True:#not ok:
1880             allReasons = ""
1881
1882             # Treat compute errors
1883             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1884             shapeText = ""
1885             for err in computeErrors:
1886                 if self.mesh.HasShapeToMesh():
1887                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1888                 errText = ""
1889                 stdErrors = ["OK",                   #COMPERR_OK
1890                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1891                              "std::exception",       #COMPERR_STD_EXCEPTION
1892                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1893                              "..",                   #COMPERR_SLM_EXCEPTION
1894                              "Unknown exception",    #COMPERR_EXCEPTION
1895                              "Memory allocation problem", #COMPERR_MEMORY_PB
1896                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1897                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1898                              "Warning",              #COMPERR_WARNING
1899                              "Computation cancelled",#COMPERR_CANCELED
1900                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1901                 if err.code > 0:
1902                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1903                 else:
1904                     errText = "code %s" % -err.code
1905                 if errText: errText += ". "
1906                 errText += err.comment
1907                 if allReasons: allReasons += "\n"
1908                 if ok:
1909                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1910                 else:
1911                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1912                 pass
1913
1914             # Treat hyp errors
1915             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1916             for err in errors:
1917                 if err.isGlobalAlgo:
1918                     glob = "global"
1919                 else:
1920                     glob = "local"
1921                     pass
1922                 dim = err.algoDim
1923                 name = err.algoName
1924                 if len(name) == 0:
1925                     reason = '%s %sD algorithm is missing' % (glob, dim)
1926                 elif err.state == HYP_MISSING:
1927                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1928                               % (glob, dim, name, dim))
1929                 elif err.state == HYP_NOTCONFORM:
1930                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1931                 elif err.state == HYP_BAD_PARAMETER:
1932                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1933                               % ( glob, dim, name ))
1934                 elif err.state == HYP_BAD_GEOMETRY:
1935                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1936                               'geometry' % ( glob, dim, name ))
1937                 elif err.state == HYP_HIDDEN_ALGO:
1938                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1939                               'algorithm of upper dimension generating %sD mesh'
1940                               % ( glob, dim, name, glob, dim ))
1941                 else:
1942                     reason = ("For unknown reason. "
1943                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1944                     pass
1945                 if allReasons: allReasons += "\n"
1946                 allReasons += "-  " + reason
1947                 pass
1948             if not ok or allReasons != "":
1949                 msg = '"' + GetName(self.mesh) + '"'
1950                 if ok: msg += " has been computed with warnings"
1951                 else:  msg += " has not been computed"
1952                 if allReasons != "": msg += ":"
1953                 else:                msg += "."
1954                 print(msg)
1955                 print(allReasons)
1956             pass
1957         if salome.sg.hasDesktop():
1958             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1959                 if refresh: salome.sg.updateObjBrowser()
1960
1961         return ok
1962
1963     def GetComputeErrors(self, shape=0 ):
1964         """
1965         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1966         """
1967
1968         if shape == 0:
1969             shape = self.mesh.GetShapeToMesh()
1970         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1971
1972     def GetSubShapeName(self, subShapeID ):
1973         """
1974         Return a name of a sub-shape by its ID.
1975         Possible variants (for *subShapeID* == 3):
1976
1977                 - **"Face_12"** - published sub-shape
1978                 - **FACE #3** - not published sub-shape
1979                 - **sub-shape #3** - invalid sub-shape ID
1980                 - **#3** - error in this function
1981
1982         Parameters:
1983                 subShapeID: a unique ID of a sub-shape
1984
1985         Returns:
1986                 a string describing the sub-shape
1987
1988         """
1989
1990         if not self.mesh.HasShapeToMesh():
1991             return ""
1992         try:
1993             shapeText = ""
1994             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1995             s = salome.myStudy
1996             mainSO = s.FindObjectIOR(mainIOR)
1997             if mainSO:
1998                 if subShapeID == 1:
1999                     shapeText = '"%s"' % mainSO.GetName()
2000                 subIt = s.NewChildIterator(mainSO)
2001                 while subIt.More():
2002                     subSO = subIt.Value()
2003                     subIt.Next()
2004                     obj = subSO.GetObject()
2005                     if not obj: continue
2006                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
2007                     if not go: continue
2008                     try:
2009                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
2010                     except:
2011                         continue
2012                     if ids == subShapeID:
2013                         shapeText = '"%s"' % subSO.GetName()
2014                         break
2015             if not shapeText:
2016                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
2017                 if shape:
2018                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
2019                 else:
2020                     shapeText = 'sub-shape #%s' % (subShapeID)
2021         except:
2022             shapeText = "#%s" % (subShapeID)
2023         return shapeText
2024
2025     def GetFailedShapes(self, publish=False):
2026         """
2027         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
2028         error of an algorithm
2029
2030         Parameters:
2031                 publish: if *True*, the returned groups will be published in the study
2032
2033         Returns:
2034                 a list of GEOM groups each named after a failed algorithm
2035         """
2036
2037
2038         algo2shapes = {}
2039         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2040         for err in computeErrors:
2041             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2042             if not shape: continue
2043             if err.algoName in algo2shapes:
2044                 algo2shapes[ err.algoName ].append( shape )
2045             else:
2046                 algo2shapes[ err.algoName ] = [ shape ]
2047             pass
2048
2049         groups = []
2050         for algoName, shapes in list(algo2shapes.items()):
2051             while shapes:
2052                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2053                 otherTypeShapes = []
2054                 sameTypeShapes  = []
2055                 group = self.geompyD.CreateGroup( self.geom, groupType )
2056                 for shape in shapes:
2057                     if shape.GetShapeType() == shapes[0].GetShapeType():
2058                         sameTypeShapes.append( shape )
2059                     else:
2060                         otherTypeShapes.append( shape )
2061                 self.geompyD.UnionList( group, sameTypeShapes )
2062                 if otherTypeShapes:
2063                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2064                 else:
2065                     group.SetName( algoName )
2066                 groups.append( group )
2067                 shapes = otherTypeShapes
2068             pass
2069         if publish:
2070             for group in groups:
2071                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2072         return groups
2073
2074     def GetMeshOrder(self):
2075         """
2076         Return sub-mesh objects list in meshing order
2077
2078         Returns:
2079                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2080         """
2081
2082         return self.mesh.GetMeshOrder()
2083
2084     def SetMeshOrder(self, submeshes):
2085         """
2086         Set priority of sub-meshes. It works in two ways:
2087         
2088         * For sub-meshes with assigned algorithms of same dimension generating mesh of
2089           *several dimensions*, it sets the order in which the sub-meshes are computed.
2090         * For the rest sub-meshes, it sets the order in which the sub-meshes are checked
2091           when looking for meshing parameters to apply to a sub-shape. To impose the 
2092           order in which sub-meshes with uni-dimensional algorithms are computed, 
2093           call **submesh.Compute()** in a desired order.
2094
2095         Parameters:
2096                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
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             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2640             if not sub:
2641                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2642             return self._groupTypeFromShape( sub[0] )
2643         else:
2644             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2645         return typ
2646
2647     def GroupOnFilter(self, typ, name, filter):
2648         """
2649         Create a mesh group with given *name* based on the *filter*.
2650         It is a special type of group dynamically updating it's contents during
2651         mesh modification
2652
2653         Parameters:
2654                 typ: the type of elements in the group; either of
2655                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2656                 name: the name of the mesh group
2657                 filter (SMESH.Filter): the filter defining group contents
2658
2659         Returns:
2660                 :class:`SMESH.SMESH_GroupOnFilter`
2661         """
2662
2663         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2664
2665     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2666         """
2667         Create a mesh group by the given ids of elements
2668
2669         Parameters:
2670                 groupName: the name of the mesh group
2671                 elementType: the type of elements in the group; either of
2672                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2673                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2674
2675         Returns:
2676                 :class:`SMESH.SMESH_Group`
2677         """
2678
2679         group = self.mesh.CreateGroup(elementType, groupName)
2680         if isinstance( elemIDs, Mesh ):
2681             elemIDs = elemIDs.GetMesh()
2682         if hasattr( elemIDs, "GetIDs" ):
2683             if hasattr( elemIDs, "SetMesh" ):
2684                 elemIDs.SetMesh( self.GetMesh() )
2685             group.AddFrom( elemIDs )
2686         else:
2687             group.Add(elemIDs)
2688         return group
2689
2690     def MakeGroup(self,
2691                   groupName,
2692                   elementType,
2693                   CritType=FT_Undefined,
2694                   Compare=FT_EqualTo,
2695                   Threshold="",
2696                   UnaryOp=FT_Undefined,
2697                   Tolerance=1e-07):
2698         """
2699         Create a mesh group by the given conditions
2700
2701         Parameters:
2702                 groupName: the name of the mesh group
2703                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2704                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2705                         Note that the items starting from FT_LessThan are not suitable for CritType.
2706                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2707                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2708                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2709                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2710                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2711
2712         Returns:
2713                 :class:`SMESH.SMESH_GroupOnFilter`
2714         """
2715
2716         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2717         group = self.MakeGroupByCriterion(groupName, aCriterion)
2718         return group
2719
2720     def MakeGroupByCriterion(self, groupName, Criterion):
2721         """
2722         Create a mesh group by the given criterion
2723
2724         Parameters:
2725                 groupName: the name of the mesh group
2726                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2727
2728         Returns:
2729                 :class:`SMESH.SMESH_GroupOnFilter`
2730
2731         See Also:
2732                 :meth:`smeshBuilder.GetCriterion`
2733         """
2734
2735         return self.MakeGroupByCriteria( groupName, [Criterion] )
2736
2737     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2738         """
2739         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2740
2741         Parameters:
2742                 groupName: the name of the mesh group
2743                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2744                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2745
2746         Returns:
2747                 :class:`SMESH.SMESH_GroupOnFilter`
2748
2749         See Also:
2750                 :meth:`smeshBuilder.GetCriterion`
2751         """
2752
2753         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2754         group = self.MakeGroupByFilter(groupName, aFilter)
2755         return group
2756
2757     def MakeGroupByFilter(self, groupName, theFilter):
2758         """
2759         Create a mesh group by the given filter
2760
2761         Parameters:
2762                 groupName (string): the name of the mesh group
2763                 theFilter (SMESH.Filter): the filter
2764
2765         Returns:
2766                 :class:`SMESH.SMESH_GroupOnFilter`
2767
2768         See Also:
2769                 :meth:`smeshBuilder.GetFilter`
2770         """
2771
2772         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2773         #theFilter.SetMesh( self.mesh )
2774         #group.AddFrom( theFilter )
2775         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2776         return group
2777
2778     def RemoveGroup(self, group):
2779         """
2780         Remove a group
2781
2782         Parameters:
2783                 group (SMESH.SMESH_GroupBase): group to remove
2784         """
2785
2786         self.mesh.RemoveGroup(group)
2787
2788     def RemoveGroupWithContents(self, group):
2789         """
2790         Remove a group with its contents
2791
2792         Parameters:
2793                 group (SMESH.SMESH_GroupBase): group to remove
2794
2795         Note:
2796                 This operation can create gaps in numeration of nodes or elements.
2797                 Call :meth:`RenumberElements` to remove the gaps.
2798         """
2799
2800         self.mesh.RemoveGroupWithContents(group)
2801
2802     def GetGroups(self, elemType = SMESH.ALL):
2803         """
2804         Get the list of groups existing in the mesh in the order of creation 
2805         (starting from the oldest one)
2806
2807         Parameters:
2808                 elemType (SMESH.ElementType): type of elements the groups contain;
2809                         by default groups of elements of all types are returned
2810
2811         Returns:
2812                 a list of :class:`SMESH.SMESH_GroupBase`
2813         """
2814
2815         groups = self.mesh.GetGroups()
2816         if elemType == SMESH.ALL:
2817             return groups
2818         typedGroups = []
2819         for g in groups:
2820             if g.GetType() == elemType:
2821                 typedGroups.append( g )
2822                 pass
2823             pass
2824         return typedGroups
2825
2826     def NbGroups(self):
2827         """
2828         Get the number of groups existing in the mesh
2829
2830         Returns:
2831                 the quantity of groups as an integer value
2832         """
2833
2834         return self.mesh.NbGroups()
2835
2836     def GetGroupNames(self):
2837         """
2838         Get the list of names of groups existing in the mesh
2839
2840         Returns:
2841                 list of strings
2842         """
2843
2844         groups = self.GetGroups()
2845         names = []
2846         for group in groups:
2847             names.append(group.GetName())
2848         return names
2849
2850     def GetGroupByName(self, name, elemType = None):
2851         """
2852         Find groups by name and type
2853
2854         Parameters:
2855                 name (string): name of the group of interest
2856                 elemType (SMESH.ElementType): type of elements the groups contain;
2857                         by default one group of any type is returned;
2858                         if elemType == SMESH.ALL then all groups of any type are returned
2859
2860         Returns:
2861                 a list of :class:`SMESH.SMESH_GroupBase`
2862         """
2863
2864         groups = []
2865         for group in self.GetGroups():
2866             if group.GetName() == name:
2867                 if elemType is None:
2868                     return [group]
2869                 if ( elemType == SMESH.ALL or
2870                      group.GetType() == elemType ):
2871                     groups.append( group )
2872         return groups
2873
2874     def UnionGroups(self, group1, group2, name):
2875         """
2876         Produce a union of two groups.
2877         A new group is created. All mesh elements that are
2878         present in the initial groups are added to the new one
2879
2880         Parameters:
2881            group1 (SMESH.SMESH_GroupBase): a group
2882            group2 (SMESH.SMESH_GroupBase): another group
2883
2884         Returns:
2885                 instance of :class:`SMESH.SMESH_Group`
2886         """
2887
2888         return self.mesh.UnionGroups(group1, group2, name)
2889
2890     def UnionListOfGroups(self, groups, name):
2891         """
2892         Produce a union list of groups.
2893         New group is created. All mesh elements that are present in
2894         initial groups are added to the new one
2895
2896         Parameters:
2897            groups: list of :class:`SMESH.SMESH_GroupBase`
2898
2899         Returns:
2900                 instance of :class:`SMESH.SMESH_Group`
2901         """
2902         return self.mesh.UnionListOfGroups(groups, name)
2903
2904     def IntersectGroups(self, group1, group2, name):
2905         """
2906         Prodice an intersection of two groups.
2907         A new group is created. All mesh elements that are common
2908         for the two initial groups are added to the new one.
2909
2910         Parameters:
2911            group1 (SMESH.SMESH_GroupBase): a group
2912            group2 (SMESH.SMESH_GroupBase): another group
2913
2914         Returns:
2915                 instance of :class:`SMESH.SMESH_Group`
2916         """
2917
2918         return self.mesh.IntersectGroups(group1, group2, name)
2919
2920     def IntersectListOfGroups(self, groups, name):
2921         """
2922         Produce an intersection of groups.
2923         New group is created. All mesh elements that are present in all
2924         initial groups simultaneously are added to the new one
2925
2926         Parameters:
2927            groups: a list of :class:`SMESH.SMESH_GroupBase`
2928
2929         Returns:
2930                 instance of :class:`SMESH.SMESH_Group`
2931         """
2932         return self.mesh.IntersectListOfGroups(groups, name)
2933
2934     def CutGroups(self, main_group, tool_group, name):
2935         """
2936         Produce a cut of two groups.
2937         A new group is created. All mesh elements that are present in
2938         the main group but are not present in the tool group are added to the new one
2939
2940         Parameters:
2941            main_group (SMESH.SMESH_GroupBase): a group to cut from
2942            tool_group (SMESH.SMESH_GroupBase): a group to cut by
2943
2944         Returns:
2945                 an instance of :class:`SMESH.SMESH_Group`
2946         """
2947
2948         return self.mesh.CutGroups(main_group, tool_group, name)
2949
2950     def CutListOfGroups(self, main_groups, tool_groups, name):
2951         """
2952         Produce a cut of groups.
2953         A new group is created. All mesh elements that are present in main groups
2954         but do not present in tool groups are added to the new one
2955
2956         Parameters:
2957            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
2958            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
2959
2960         Returns:
2961                 an instance of :class:`SMESH.SMESH_Group`
2962         """
2963
2964         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2965
2966     def CreateDimGroup(self, groups, elemType, name,
2967                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2968         """
2969         Create a standalone group of entities basing on nodes of other groups.
2970
2971         Parameters:
2972                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2973                 elemType: a type of elements to include to the new group; either of
2974                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2975                 name: a name of the new group.
2976                 nbCommonNodes: a criterion of inclusion of an element to the new group
2977                         basing on number of element nodes common with reference *groups*.
2978                         Meaning of possible values are:
2979
2980                                 - SMESH.ALL_NODES - include if all nodes are common,
2981                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2982                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2983                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
2984                 underlyingOnly: if *True* (default), an element is included to the
2985                         new group provided that it is based on nodes of an element of *groups*;
2986                         in this case the reference *groups* are supposed to be of higher dimension
2987                         than *elemType*, which can be useful for example to get all faces lying on
2988                         volumes of the reference *groups*.
2989
2990         Returns:
2991                 an instance of :class:`SMESH.SMESH_Group`
2992         """
2993
2994         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2995             groups = [groups]
2996         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2997
2998     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2999         """
3000         Distribute all faces of the mesh among groups using sharp edges and optionally
3001         existing 1D elements as group boundaries.
3002
3003         Parameters:
3004                 sharpAngle: edge is considered sharp if an angle between normals of
3005                             adjacent faces is more than \a sharpAngle in degrees.
3006                 createEdges (boolean): to create 1D elements for detected sharp edges.
3007                 useExistingEdges (boolean): to use existing edges as group boundaries
3008         Returns:
3009                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3010         """
3011         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3012         self.mesh.SetParameters(Parameters)
3013         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3014
3015     def ConvertToStandalone(self, group):
3016         """
3017         Convert group on geom into standalone group
3018         """
3019
3020         return self.mesh.ConvertToStandalone(group)
3021
3022     # Get some info about mesh:
3023     # ------------------------
3024
3025     def GetLog(self, clearAfterGet):
3026         """
3027         Return the log of nodes and elements added or removed
3028         since the previous clear of the log.
3029
3030         Parameters:
3031                 clearAfterGet: log is emptied after Get (safe if concurrents access)
3032
3033         Returns:
3034                 list of SMESH.log_block structures { commandType, number, coords, indexes }
3035         """
3036
3037         return self.mesh.GetLog(clearAfterGet)
3038
3039     def ClearLog(self):
3040         """
3041         Clear the log of nodes and elements added or removed since the previous
3042         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3043         """
3044
3045         self.mesh.ClearLog()
3046
3047     def SetAutoColor(self, theAutoColor):
3048         """
3049         Toggle auto color mode on the object.
3050         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3051
3052         Parameters:
3053                 theAutoColor (boolean): the flag which toggles auto color mode.
3054         """
3055
3056         self.mesh.SetAutoColor(theAutoColor)
3057
3058     def GetAutoColor(self):
3059         """
3060         Get flag of object auto color mode.
3061
3062         Returns:
3063                 True or False
3064         """
3065
3066         return self.mesh.GetAutoColor()
3067
3068     def GetId(self):
3069         """
3070         Get the internal ID
3071
3072         Returns:
3073             integer value, which is the internal Id of the mesh
3074         """
3075
3076         return self.mesh.GetId()
3077
3078     def HasDuplicatedGroupNamesMED(self):
3079         """
3080         Check the group names for duplications.
3081         Consider the maximum group name length stored in MED file.
3082
3083         Returns:
3084             True or False
3085         """
3086
3087         return self.mesh.HasDuplicatedGroupNamesMED()
3088
3089     def GetMeshEditor(self):
3090         """
3091         Obtain the mesh editor tool
3092
3093         Returns:
3094             an instance of :class:`SMESH.SMESH_MeshEditor`
3095         """
3096
3097         return self.editor
3098
3099     def GetIDSource(self, ids, elemType = SMESH.ALL):
3100         """
3101         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3102         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3103
3104         Parameters:
3105                 ids: list of IDs
3106                 elemType: type of elements; this parameter is used to distinguish
3107                         IDs of nodes from IDs of elements; by default ids are treated as
3108                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3109
3110         Returns:
3111             an instance of :class:`SMESH.SMESH_IDSource`
3112
3113         Warning:
3114                 call UnRegister() for the returned object as soon as it is no more useful::
3115
3116                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3117                         mesh.DoSomething( idSrc )
3118                         idSrc.UnRegister()
3119         """
3120
3121         if isinstance( ids, int ):
3122             ids = [ids]
3123         return self.editor.MakeIDSource(ids, elemType)
3124
3125
3126     # Get information about mesh contents:
3127     # ------------------------------------
3128
3129     def GetMeshInfo(self, obj = None):
3130         """
3131         Get the mesh statistic.
3132
3133         Returns:
3134                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3135         """
3136
3137         if not obj: obj = self.mesh
3138         return self.smeshpyD.GetMeshInfo(obj)
3139
3140     def NbNodes(self):
3141         """
3142         Return the number of nodes in the mesh
3143
3144         Returns:
3145             an integer value
3146         """
3147
3148         return self.mesh.NbNodes()
3149
3150     def NbElements(self):
3151         """
3152         Return the number of elements in the mesh
3153
3154         Returns:
3155             an integer value
3156         """
3157
3158         return self.mesh.NbElements()
3159
3160     def Nb0DElements(self):
3161         """
3162         Return the number of 0d elements in the mesh
3163
3164         Returns:
3165             an integer value
3166         """
3167
3168         return self.mesh.Nb0DElements()
3169
3170     def NbBalls(self):
3171         """
3172         Return the number of ball discrete elements in the mesh
3173
3174         Returns:
3175             an integer value
3176         """
3177
3178         return self.mesh.NbBalls()
3179
3180     def NbEdges(self):
3181         """
3182         Return the number of edges in the mesh
3183
3184         Returns:
3185             an integer value
3186         """
3187
3188         return self.mesh.NbEdges()
3189
3190     def NbEdgesOfOrder(self, elementOrder):
3191         """
3192         Return the number of edges with the given order in the mesh
3193
3194         Parameters:
3195                 elementOrder: the order of elements
3196                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3197
3198         Returns:
3199             an integer value
3200         """
3201
3202         return self.mesh.NbEdgesOfOrder(elementOrder)
3203
3204     def NbFaces(self):
3205         """
3206         Return the number of faces in the mesh
3207
3208         Returns:
3209             an integer value
3210         """
3211
3212         return self.mesh.NbFaces()
3213
3214     def NbFacesOfOrder(self, elementOrder):
3215         """
3216         Return the number of faces with the given order in the mesh
3217
3218         Parameters:
3219                 elementOrder: the order of elements
3220                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3221
3222         Returns:
3223             an integer value
3224         """
3225
3226         return self.mesh.NbFacesOfOrder(elementOrder)
3227
3228     def NbTriangles(self):
3229         """
3230         Return the number of triangles in the mesh
3231
3232         Returns:
3233             an integer value
3234         """
3235
3236         return self.mesh.NbTriangles()
3237
3238     def NbTrianglesOfOrder(self, elementOrder):
3239         """
3240         Return the number of triangles with the given order in the mesh
3241
3242         Parameters:
3243                 elementOrder: is the order of elements
3244                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3245
3246         Returns:
3247             an integer value
3248         """
3249
3250         return self.mesh.NbTrianglesOfOrder(elementOrder)
3251
3252     def NbBiQuadTriangles(self):
3253         """
3254         Return the number of biquadratic triangles in the mesh
3255
3256         Returns:
3257             an integer value
3258         """
3259
3260         return self.mesh.NbBiQuadTriangles()
3261
3262     def NbQuadrangles(self):
3263         """
3264         Return the number of quadrangles in the mesh
3265
3266         Returns:
3267             an integer value
3268         """
3269
3270         return self.mesh.NbQuadrangles()
3271
3272     def NbQuadranglesOfOrder(self, elementOrder):
3273         """
3274         Return the number of quadrangles with the given order in the mesh
3275
3276         Parameters:
3277                 elementOrder: the order of elements
3278                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3279
3280         Returns:
3281             an integer value
3282         """
3283
3284         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3285
3286     def NbBiQuadQuadrangles(self):
3287         """
3288         Return the number of biquadratic quadrangles in the mesh
3289
3290         Returns:
3291             an integer value
3292         """
3293
3294         return self.mesh.NbBiQuadQuadrangles()
3295
3296     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3297         """
3298         Return the number of polygons of given order in the mesh
3299
3300         Parameters:
3301                 elementOrder: the order of elements
3302                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3303
3304         Returns:
3305             an integer value
3306         """
3307
3308         return self.mesh.NbPolygonsOfOrder(elementOrder)
3309
3310     def NbVolumes(self):
3311         """
3312         Return the number of volumes in the mesh
3313
3314         Returns:
3315             an integer value
3316         """
3317
3318         return self.mesh.NbVolumes()
3319
3320
3321     def NbVolumesOfOrder(self, elementOrder):
3322         """
3323         Return the number of volumes with the given order in the mesh
3324
3325         Parameters:
3326                 elementOrder:  the order of elements
3327                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3328
3329         Returns:
3330             an integer value
3331         """
3332
3333         return self.mesh.NbVolumesOfOrder(elementOrder)
3334
3335     def NbTetras(self):
3336         """
3337         Return the number of tetrahedrons in the mesh
3338
3339         Returns:
3340             an integer value
3341         """
3342
3343         return self.mesh.NbTetras()
3344
3345     def NbTetrasOfOrder(self, elementOrder):
3346         """
3347         Return the number of tetrahedrons with the given order in the mesh
3348
3349         Parameters:
3350                 elementOrder:  the order of elements
3351                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3352
3353         Returns:
3354             an integer value
3355         """
3356
3357         return self.mesh.NbTetrasOfOrder(elementOrder)
3358
3359     def NbHexas(self):
3360         """
3361         Return the number of hexahedrons in the mesh
3362
3363         Returns:
3364             an integer value
3365         """
3366
3367         return self.mesh.NbHexas()
3368
3369     def NbHexasOfOrder(self, elementOrder):
3370         """
3371         Return the number of hexahedrons with the given order in the mesh
3372
3373         Parameters:
3374                 elementOrder:  the order of elements
3375                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3376
3377         Returns:
3378             an integer value
3379         """
3380
3381         return self.mesh.NbHexasOfOrder(elementOrder)
3382
3383     def NbTriQuadraticHexas(self):
3384         """
3385         Return the number of triquadratic hexahedrons in the mesh
3386
3387         Returns:
3388             an integer value
3389         """
3390
3391         return self.mesh.NbTriQuadraticHexas()
3392
3393     def NbPyramids(self):
3394         """
3395         Return the number of pyramids in the mesh
3396
3397         Returns:
3398             an integer value
3399         """
3400
3401         return self.mesh.NbPyramids()
3402
3403     def NbPyramidsOfOrder(self, elementOrder):
3404         """
3405         Return the number of pyramids with the given order in the mesh
3406
3407         Parameters:
3408                 elementOrder:  the order of elements
3409                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3410
3411         Returns:
3412             an integer value
3413         """
3414
3415         return self.mesh.NbPyramidsOfOrder(elementOrder)
3416
3417     def NbPrisms(self):
3418         """
3419         Return the number of prisms in the mesh
3420
3421         Returns:
3422             an integer value
3423         """
3424
3425         return self.mesh.NbPrisms()
3426
3427     def NbPrismsOfOrder(self, elementOrder):
3428         """
3429         Return the number of prisms with the given order in the mesh
3430
3431         Parameters:
3432                 elementOrder:  the order of elements
3433                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3434
3435         Returns:
3436             an integer value
3437         """
3438
3439         return self.mesh.NbPrismsOfOrder(elementOrder)
3440
3441     def NbHexagonalPrisms(self):
3442         """
3443         Return the number of hexagonal prisms in the mesh
3444
3445         Returns:
3446             an integer value
3447         """
3448
3449         return self.mesh.NbHexagonalPrisms()
3450
3451     def NbPolyhedrons(self):
3452         """
3453         Return the number of polyhedrons in the mesh
3454
3455         Returns:
3456             an integer value
3457         """
3458
3459         return self.mesh.NbPolyhedrons()
3460
3461     def NbSubMesh(self):
3462         """
3463         Return the number of submeshes in the mesh
3464
3465         Returns:
3466             an integer value
3467         """
3468
3469         return self.mesh.NbSubMesh()
3470
3471     def GetElementsId(self):
3472         """
3473         Return the list of all mesh elements IDs
3474
3475         Returns:
3476             the list of integer values
3477
3478         See Also:
3479             :meth:`GetElementsByType`
3480         """
3481
3482         return self.mesh.GetElementsId()
3483
3484     def GetElementsByType(self, elementType):
3485         """
3486         Return the list of IDs of mesh elements with the given type
3487
3488         Parameters:
3489                 elementType (SMESH.ElementType):  the required type of elements
3490
3491         Returns:
3492             list of integer values
3493         """
3494
3495         return self.mesh.GetElementsByType(elementType)
3496
3497     def GetNodesId(self):
3498         """
3499         Return the list of mesh nodes IDs
3500
3501         Returns:
3502             the list of integer values
3503         """
3504
3505         return self.mesh.GetNodesId()
3506
3507     # Get the information about mesh elements:
3508     # ------------------------------------
3509
3510     def GetElementType(self, id, iselem=True):
3511         """
3512         Return the type of mesh element or node
3513
3514         Returns:
3515             the value from :class:`SMESH.ElementType` enumeration. 
3516             Return SMESH.ALL if element or node with the given ID does not exist
3517         """
3518
3519         return self.mesh.GetElementType(id, iselem)
3520
3521     def GetElementGeomType(self, id):
3522         """
3523         Return the geometric type of mesh element
3524
3525         Returns:
3526             the value from :class:`SMESH.EntityType` enumeration.
3527         """
3528
3529         return self.mesh.GetElementGeomType(id)
3530
3531     def GetElementShape(self, id):
3532         """
3533         Return the shape type of mesh element
3534
3535         Returns:
3536             the value from :class:`SMESH.GeometryType` enumeration.
3537         """
3538
3539         return self.mesh.GetElementShape(id)
3540
3541     def GetSubMeshElementsId(self, Shape):
3542         """
3543         Return the list of sub-mesh elements IDs
3544
3545         Parameters:
3546                 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3547                        *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3548
3549         Returns:
3550             list of integer values
3551         """
3552
3553         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3554             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3555         else:
3556             ShapeID = Shape
3557         return self.mesh.GetSubMeshElementsId(ShapeID)
3558
3559     def GetSubMeshNodesId(self, Shape, all):
3560         """
3561         Return the list of sub-mesh nodes IDs
3562
3563         Parameters:
3564                 Shape: a geom object (sub-shape).
3565                        *Shape* must be the sub-shape of a :meth:`GetShape`
3566                 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3567
3568         Returns:
3569             list of integer values
3570         """
3571
3572         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3573             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3574         else:
3575             ShapeID = Shape
3576         return self.mesh.GetSubMeshNodesId(ShapeID, all)
3577
3578     def GetSubMeshElementType(self, Shape):
3579         """
3580         Return type of elements on given shape
3581
3582         Parameters:
3583                 Shape: a geom object (sub-shape).
3584                        *Shape* must be a sub-shape of a ShapeToMesh()
3585
3586         Returns:
3587             :class:`SMESH.ElementType`
3588         """
3589
3590         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3591             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3592         else:
3593             ShapeID = Shape
3594         return self.mesh.GetSubMeshElementType(ShapeID)
3595
3596     def Dump(self):
3597         """
3598         Get the mesh description
3599
3600         Returns:
3601             string value
3602         """
3603
3604         return self.mesh.Dump()
3605
3606
3607     # Get the information about nodes and elements of a mesh by its IDs:
3608     # -----------------------------------------------------------
3609
3610     def GetNodeXYZ(self, id):
3611         """
3612         Get XYZ coordinates of a node.
3613         If there is no node for the given ID - return an empty list
3614
3615         Returns:
3616             list of float values
3617         """
3618
3619         return self.mesh.GetNodeXYZ(id)
3620
3621     def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3622         """
3623         Return list of IDs of inverse elements for the given node.
3624         If there is no node for the given ID - return an empty list
3625
3626         Parameters:
3627                 id: node ID
3628                 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3629
3630         Returns:
3631             list of integer values
3632         """
3633
3634         return self.mesh.GetNodeInverseElements(id,elemType)
3635
3636     def GetNodePosition(self,NodeID):
3637         """
3638         Return the position of a node on the shape
3639
3640         Returns:
3641             :class:`SMESH.NodePosition`
3642         """
3643
3644         return self.mesh.GetNodePosition(NodeID)
3645
3646     def GetElementPosition(self,ElemID):
3647         """
3648         Return the position of an element on the shape
3649
3650         Returns:
3651             :class:`SMESH.ElementPosition`
3652         """
3653
3654         return self.mesh.GetElementPosition(ElemID)
3655
3656     def GetShapeID(self, id):
3657         """
3658         Return the ID of the shape, on which the given node was generated.
3659
3660         Returns:
3661             an integer value > 0 or -1 if there is no node for the given
3662             ID or the node is not assigned to any geometry
3663         """
3664
3665         return self.mesh.GetShapeID(id)
3666
3667     def GetShapeIDForElem(self,id):
3668         """
3669         Return the ID of the shape, on which the given element was generated.
3670
3671         Returns:
3672             an integer value > 0 or -1 if there is no element for the given
3673             ID or the element is not assigned to any geometry
3674         """
3675
3676         return self.mesh.GetShapeIDForElem(id)
3677
3678     def GetElemNbNodes(self, id):
3679         """
3680         Return the number of nodes of the given element
3681
3682         Returns:
3683             an integer value > 0 or -1 if there is no element for the given ID
3684         """
3685
3686         return self.mesh.GetElemNbNodes(id)
3687
3688     def GetElemNode(self, id, index):
3689         """
3690         Return the node ID the given (zero based) index for the given element.
3691
3692         * If there is no element for the given ID - return -1.
3693         * If there is no node for the given index - return -2.
3694
3695         Parameters:
3696             id (int): element ID
3697             index (int): node index within the element
3698
3699         Returns:
3700             an integer value (ID)
3701
3702         See Also:
3703             :meth:`GetElemNodes`
3704         """
3705
3706         return self.mesh.GetElemNode(id, index)
3707
3708     def GetElemNodes(self, id):
3709         """
3710         Return the IDs of nodes of the given element
3711
3712         Returns:
3713             a list of integer values
3714         """
3715
3716         return self.mesh.GetElemNodes(id)
3717
3718     def IsMediumNode(self, elementID, nodeID):
3719         """
3720         Return true if the given node is the medium node in the given quadratic element
3721         """
3722
3723         return self.mesh.IsMediumNode(elementID, nodeID)
3724
3725     def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3726         """
3727         Return true if the given node is the medium node in one of quadratic elements
3728
3729         Parameters:
3730                 nodeID: ID of the node
3731                 elementType:  the type of elements to check a state of the node, either of
3732                         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3733         """
3734
3735         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3736
3737     def ElemNbEdges(self, id):
3738         """
3739         Return the number of edges for the given element
3740         """
3741
3742         return self.mesh.ElemNbEdges(id)
3743
3744     def ElemNbFaces(self, id):
3745         """
3746         Return the number of faces for the given element
3747         """
3748
3749         return self.mesh.ElemNbFaces(id)
3750
3751     def GetElemFaceNodes(self,elemId, faceIndex):
3752         """
3753         Return nodes of given face (counted from zero) for given volumic element.
3754         """
3755
3756         return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3757
3758     def GetFaceNormal(self, faceId, normalized=False):
3759         """
3760         Return three components of normal of given mesh face
3761         (or an empty array in KO case)
3762         """
3763
3764         return self.mesh.GetFaceNormal(faceId,normalized)
3765
3766     def FindElementByNodes(self, nodes):
3767         """
3768         Return an element based on all given nodes.
3769         """
3770
3771         return self.mesh.FindElementByNodes(nodes)
3772
3773     def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3774         """
3775         Return elements including all given nodes.
3776         """
3777
3778         return self.mesh.GetElementsByNodes( nodes, elemType )
3779
3780     def IsPoly(self, id):
3781         """
3782         Return true if the given element is a polygon
3783         """
3784
3785         return self.mesh.IsPoly(id)
3786
3787     def IsQuadratic(self, id):
3788         """
3789         Return true if the given element is quadratic
3790         """
3791
3792         return self.mesh.IsQuadratic(id)
3793
3794     def GetBallDiameter(self, id):
3795         """
3796         Return diameter of a ball discrete element or zero in case of an invalid *id*
3797         """
3798
3799         return self.mesh.GetBallDiameter(id)
3800
3801     def BaryCenter(self, id):
3802         """
3803         Return XYZ coordinates of the barycenter of the given element.
3804         If there is no element for the given ID - return an empty list
3805
3806         Returns:
3807             a list of three double values
3808
3809         See also: 
3810                 :meth:`smeshBuilder.GetGravityCenter`
3811         """
3812
3813         return self.mesh.BaryCenter(id)
3814
3815     def GetIdsFromFilter(self, filter, meshParts=[] ):
3816         """
3817         Pass mesh elements through the given filter and return IDs of fitting elements
3818
3819         Parameters:
3820                 filter: :class:`SMESH.Filter`
3821                 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3822
3823         Returns:
3824             a list of ids
3825
3826         See Also:
3827             :meth:`SMESH.Filter.GetIDs`
3828             :meth:`SMESH.Filter.GetElementsIdFromParts`
3829         """
3830
3831         filter.SetMesh( self.mesh )
3832
3833         if meshParts:
3834             if isinstance( meshParts, Mesh ):
3835                 filter.SetMesh( meshParts.GetMesh() )
3836                 return theFilter.GetIDs()
3837             if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3838                 meshParts = [ meshParts ]
3839             return filter.GetElementsIdFromParts( meshParts )
3840
3841         return filter.GetIDs()
3842
3843     # Get mesh measurements information:
3844     # ------------------------------------
3845
3846     def GetFreeBorders(self):
3847         """
3848         Verify whether a 2D mesh element has free edges (edges connected to one face only).
3849         Return a list of special structures (borders).
3850
3851         Returns:
3852             a list of :class:`SMESH.FreeEdges.Border`
3853         """
3854
3855         aFilterMgr = self.smeshpyD.CreateFilterManager()
3856         aPredicate = aFilterMgr.CreateFreeEdges()
3857         aPredicate.SetMesh(self.mesh)
3858         aBorders = aPredicate.GetBorders()
3859         aFilterMgr.UnRegister()
3860         return aBorders
3861
3862     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3863         """
3864         Get minimum distance between two nodes, elements or distance to the origin
3865
3866         Parameters:
3867                 id1: first node/element id
3868                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3869                 isElem1: *True* if *id1* is element id, *False* if it is node id
3870                 isElem2: *True* if *id2* is element id, *False* if it is node id
3871
3872         Returns:
3873             minimum distance value
3874         See Also:
3875             :meth:`GetMinDistance`
3876         """
3877
3878         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3879         return aMeasure.value
3880
3881     def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3882         """
3883         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3884
3885         Parameters:
3886                 id1: first node/element id
3887                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3888                 isElem1: *True* if *id1* is element id, *False* if it is node id
3889                 isElem2: *True* if *id2* is element id, *False* if it is node id
3890
3891         Returns:
3892             :class:`SMESH.Measure` structure
3893         See Also:
3894             :meth:`MinDistance`
3895         """
3896
3897         if isElem1:
3898             id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3899         else:
3900             id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3901         if id2 != 0:
3902             if isElem2:
3903                 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3904             else:
3905                 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3906             pass
3907         else:
3908             id2 = None
3909
3910         aMeasurements = self.smeshpyD.CreateMeasurements()
3911         aMeasure = aMeasurements.MinDistance(id1, id2)
3912         genObjUnRegister([aMeasurements,id1, id2])
3913         return aMeasure
3914
3915     def BoundingBox(self, objects=None, isElem=False):
3916         """
3917         Get bounding box of the specified object(s)
3918
3919         Parameters:
3920                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3921                 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
3922                         *False* specifies that *objects* are nodes
3923
3924         Returns:
3925             tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
3926
3927         See Also: 
3928             :meth:`GetBoundingBox()`
3929         """
3930
3931         result = self.GetBoundingBox(objects, isElem)
3932         if result is None:
3933             result = (0.0,)*6
3934         else:
3935             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
3936         return result
3937
3938     def GetBoundingBox(self, objects=None, isElem=False):
3939         """
3940         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
3941
3942         Parameters:
3943                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
3944                 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
3945                         False means that *objects* are nodes
3946
3947         Returns:
3948             :class:`SMESH.Measure` structure
3949
3950         See Also: 
3951             :meth:`BoundingBox()`
3952         """
3953
3954         if objects is None:
3955             objects = [self.mesh]
3956         elif isinstance(objects, tuple):
3957             objects = list(objects)
3958         if not isinstance(objects, list):
3959             objects = [objects]
3960         if len(objects) > 0 and isinstance(objects[0], int):
3961             objects = [objects]
3962         srclist = []
3963         unRegister = genObjUnRegister()
3964         for o in objects:
3965             if isinstance(o, Mesh):
3966                 srclist.append(o.mesh)
3967             elif hasattr(o, "_narrow"):
3968                 src = o._narrow(SMESH.SMESH_IDSource)
3969                 if src: srclist.append(src)
3970                 pass
3971             elif isinstance(o, list):
3972                 if isElem:
3973                     srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
3974                 else:
3975                     srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
3976                 unRegister.set( srclist[-1] )
3977                 pass
3978             pass
3979         aMeasurements = self.smeshpyD.CreateMeasurements()
3980         unRegister.set( aMeasurements )
3981         aMeasure = aMeasurements.BoundingBox(srclist)
3982         return aMeasure
3983
3984     # Mesh edition (SMESH_MeshEditor functionality):
3985     # ---------------------------------------------
3986
3987     def RemoveElements(self, IDsOfElements):
3988         """
3989         Remove the elements from the mesh by ids
3990
3991         Parameters:
3992                 IDsOfElements: is a list of ids of elements to remove
3993
3994         Returns:
3995             True or False
3996
3997         Note:
3998                 This operation can create gaps in numeration of elements.
3999                 Call :meth:`RenumberElements` to remove the gaps.
4000         """
4001
4002         return self.editor.RemoveElements(IDsOfElements)
4003
4004     def RemoveNodes(self, IDsOfNodes):
4005         """
4006         Remove nodes from mesh by ids
4007
4008         Parameters:
4009                 IDsOfNodes: is a list of ids of nodes to remove
4010
4011         Returns:
4012             True or False
4013
4014         Note:
4015                 This operation can create gaps in numeration of nodes.
4016                 Call :meth:`RenumberElements` to remove the gaps.
4017         """
4018
4019         return self.editor.RemoveNodes(IDsOfNodes)
4020
4021     def RemoveOrphanNodes(self):
4022         """
4023         Remove all orphan (free) nodes from mesh
4024
4025         Returns:
4026             number of the removed nodes
4027
4028         Note:
4029                 This operation can create gaps in numeration of nodes.
4030                 Call :meth:`RenumberElements` to remove the gaps.
4031         """
4032
4033         return self.editor.RemoveOrphanNodes()
4034
4035     def AddNode(self, x, y, z):
4036         """
4037         Add a node to the mesh by coordinates
4038
4039         Returns:
4040             ID of the new node
4041         """
4042
4043         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4044         if hasVars: self.mesh.SetParameters(Parameters)
4045         return self.editor.AddNode( x, y, z)
4046
4047     def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4048         """
4049         Create a 0D element on a node with given number.
4050
4051         Parameters:
4052                 IDOfNode: the ID of node for creation of the element.
4053                 DuplicateElements: to add one more 0D element to a node or not
4054
4055         Returns:
4056             ID of the new 0D element
4057         """
4058
4059         return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4060
4061     def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4062         """
4063         Create 0D elements on all nodes of the given elements except those
4064         nodes on which a 0D element already exists.
4065
4066         Parameters:
4067                 theObject: an object on whose nodes 0D elements will be created.
4068                         It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4069                 theGroupName: optional name of a group to add 0D elements created
4070                         and/or found on nodes of *theObject*.
4071                 DuplicateElements: to add one more 0D element to a node or not
4072
4073         Returns:
4074             an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4075             IDs of new and/or found 0D elements. IDs of 0D elements
4076             can be retrieved from the returned object by 
4077             calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4078         """
4079
4080         unRegister = genObjUnRegister()
4081         if isinstance( theObject, Mesh ):
4082             theObject = theObject.GetMesh()
4083         elif isinstance( theObject, list ):
4084             theObject = self.GetIDSource( theObject, SMESH.ALL )
4085             unRegister.set( theObject )
4086         return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4087
4088     def AddBall(self, IDOfNode, diameter):
4089         """
4090         Create a ball element on a node with given ID.
4091
4092         Parameters:
4093                 IDOfNode: the ID of node for creation of the element.
4094                 diameter: the bal diameter.
4095
4096         Returns:
4097             ID of the new ball element
4098         """
4099
4100         return self.editor.AddBall( IDOfNode, diameter )
4101
4102     def AddEdge(self, IDsOfNodes):
4103         """
4104         Create a linear or quadratic edge (this is determined
4105         by the number of given nodes).
4106
4107         Parameters:
4108                 IDsOfNodes: list of node IDs for creation of the element.
4109                         The order of nodes in this list should correspond to
4110                         the :ref:`connectivity convention <connectivity_page>`.
4111
4112         Returns:
4113             ID of the new edge
4114         """
4115
4116         return self.editor.AddEdge(IDsOfNodes)
4117
4118     def AddFace(self, IDsOfNodes):
4119         """
4120         Create a linear or quadratic face (this is determined
4121         by the number of given nodes).
4122
4123         Parameters:
4124                 IDsOfNodes: list of node IDs for creation of the element.
4125                         The order of nodes in this list should correspond to
4126                         the :ref:`connectivity convention <connectivity_page>`.
4127
4128         Returns:
4129             ID of the new face
4130         """
4131
4132         return self.editor.AddFace(IDsOfNodes)
4133
4134     def AddPolygonalFace(self, IdsOfNodes):
4135         """
4136         Add a polygonal face defined by a list of node IDs
4137
4138         Parameters:
4139                 IdsOfNodes: the list of node IDs for creation of the element.
4140
4141         Returns:
4142             ID of the new face
4143         """
4144
4145         return self.editor.AddPolygonalFace(IdsOfNodes)
4146
4147     def AddQuadPolygonalFace(self, IdsOfNodes):
4148         """
4149         Add a quadratic polygonal face defined by a list of node IDs
4150
4151         Parameters:
4152                 IdsOfNodes: the list of node IDs for creation of the element;
4153                         corner nodes follow first.
4154
4155         Returns:
4156             ID of the new face
4157         """
4158
4159         return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4160
4161     def AddVolume(self, IDsOfNodes):
4162         """
4163         Create both simple and quadratic volume (this is determined
4164         by the number of given nodes).
4165
4166         Parameters:
4167                 IDsOfNodes: list of node IDs for creation of the element.
4168                         The order of nodes in this list should correspond to
4169                         the :ref:`connectivity convention <connectivity_page>`.
4170
4171         Returns:
4172             ID of the new volumic element
4173         """
4174
4175         return self.editor.AddVolume(IDsOfNodes)
4176
4177     def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4178         """
4179         Create a volume of many faces, giving nodes for each face.
4180
4181         Parameters:
4182                 IdsOfNodes: list of node IDs for volume creation, face by face.
4183                 Quantities: list of integer values, Quantities[i]
4184                         gives the quantity of nodes in face number i.
4185
4186         Returns:
4187             ID of the new volumic element
4188         """
4189
4190         return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4191
4192     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4193         """
4194         Create a volume of many faces, giving the IDs of the existing faces.
4195
4196         Note:
4197                 The created volume will refer only to the nodes
4198                 of the given faces, not to the faces themselves.
4199
4200         Parameters:
4201                 IdsOfFaces: the list of face IDs for volume creation.
4202
4203         Returns:
4204             ID of the new volumic element
4205         """
4206
4207         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4208
4209
4210     def SetNodeOnVertex(self, NodeID, Vertex):
4211         """
4212         Bind a node to a vertex
4213
4214         Parameters:
4215                 NodeID: a node ID
4216                 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4217
4218         Returns:
4219             True if succeed else raises an exception
4220         """
4221
4222         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4223             VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4224         else:
4225             VertexID = Vertex
4226         try:
4227             self.editor.SetNodeOnVertex(NodeID, VertexID)
4228         except SALOME.SALOME_Exception as inst:
4229             raise ValueError(inst.details.text)
4230         return True
4231
4232
4233     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4234         """
4235         Store the node position on an edge
4236
4237         Parameters:
4238                 NodeID: a node ID
4239                 Edge: an edge (GEOM.GEOM_Object) or edge ID
4240                 paramOnEdge: a parameter on the edge where the node is located
4241
4242         Returns:
4243             True if succeed else raises an exception
4244         """
4245
4246         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4247             EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4248         else:
4249             EdgeID = Edge
4250         try:
4251             self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4252         except SALOME.SALOME_Exception as inst:
4253             raise ValueError(inst.details.text)
4254         return True
4255
4256     def SetNodeOnFace(self, NodeID, Face, u, v):
4257         """
4258         Store node position on a face
4259
4260         Parameters:
4261                 NodeID: a node ID
4262                 Face: a face (GEOM.GEOM_Object) or face ID
4263                 u: U parameter on the face where the node is located
4264                 v: V parameter on the face where the node is located
4265
4266         Returns:
4267             True if succeed else raises an exception
4268         """
4269
4270         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4271             FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4272         else:
4273             FaceID = Face
4274         try:
4275             self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4276         except SALOME.SALOME_Exception as inst:
4277             raise ValueError(inst.details.text)
4278         return True
4279
4280     def SetNodeInVolume(self, NodeID, Solid):
4281         """
4282         Bind a node to a solid
4283
4284         Parameters:
4285                 NodeID: a node ID
4286                 Solid:  a solid (GEOM.GEOM_Object) or solid ID
4287
4288         Returns:
4289             True if succeed else raises an exception
4290         """
4291
4292         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4293             SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4294         else:
4295             SolidID = Solid
4296         try:
4297             self.editor.SetNodeInVolume(NodeID, SolidID)
4298         except SALOME.SALOME_Exception as inst:
4299             raise ValueError(inst.details.text)
4300         return True
4301
4302     def SetMeshElementOnShape(self, ElementID, Shape):
4303         """
4304         Bind an element to a shape
4305
4306         Parameters:
4307                 ElementID: an element ID
4308                 Shape: a shape (GEOM.GEOM_Object) or shape ID
4309
4310         Returns:
4311             True if succeed else raises an exception
4312         """
4313
4314         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4315             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4316         else:
4317             ShapeID = Shape
4318         try:
4319             self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4320         except SALOME.SALOME_Exception as inst:
4321             raise ValueError(inst.details.text)
4322         return True
4323
4324
4325     def MoveNode(self, NodeID, x, y, z):
4326         """
4327         Move the node with the given id
4328
4329         Parameters:
4330                 NodeID: the id of the node
4331                 x:  a new X coordinate
4332                 y:  a new Y coordinate
4333                 z:  a new Z coordinate
4334
4335         Returns:
4336             True if succeed else False
4337         """
4338
4339         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4340         if hasVars: self.mesh.SetParameters(Parameters)
4341         return self.editor.MoveNode(NodeID, x, y, z)
4342
4343     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4344         """
4345         Find the node closest to a point and moves it to a point location
4346
4347         Parameters:
4348                 x:  the X coordinate of a point
4349                 y:  the Y coordinate of a point
4350                 z:  the Z coordinate of a point
4351                 NodeID: if specified (>0), the node with this ID is moved,
4352                         otherwise, the node closest to point (*x*, *y*, *z*) is moved
4353
4354         Returns:
4355             the ID of a moved node
4356         """
4357
4358         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4359         if hasVars: self.mesh.SetParameters(Parameters)
4360         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4361
4362     def FindNodeClosestTo(self, x, y, z):
4363         """
4364         Find the node closest to a point
4365
4366         Parameters:
4367                 x:  the X coordinate of a point
4368                 y:  the Y coordinate of a point
4369                 z:  the Z coordinate of a point
4370
4371         Returns:
4372             the ID of a node
4373         """
4374
4375         return self.editor.FindNodeClosestTo(x, y, z)
4376
4377     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4378         """
4379         Find the elements where a point lays IN or ON
4380
4381         Parameters:
4382                 x,y,z (float): coordinates of the point
4383                 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4384                         means elements of any type excluding nodes, discrete and 0D elements.
4385                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4386
4387         Returns:
4388             list of IDs of found elements
4389         """
4390         if meshPart:
4391             return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4392         else:
4393             return self.editor.FindElementsByPoint(x, y, z, elementType)
4394
4395     def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4396         """
4397         Project a point to a mesh object.
4398         Return ID of an element of given type where the given point is projected
4399         and coordinates of the projection point.
4400         In the case if nothing found, return -1 and []
4401         """
4402         if isinstance( meshObject, Mesh ):
4403             meshObject = meshObject.GetMesh()
4404         if not meshObject:
4405             meshObject = self.GetMesh()
4406         return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4407
4408     def GetPointState(self, x, y, z):
4409         """
4410         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4411         smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4412         UNKNOWN state means that either mesh is wrong or the analysis fails.
4413         """
4414
4415         return self.editor.GetPointState(x, y, z)
4416
4417     def IsManifold(self):
4418         """
4419         Check if a 2D mesh is manifold
4420         """
4421
4422         return self.editor.IsManifold()
4423
4424     def IsCoherentOrientation2D(self):
4425         """
4426         Check if orientation of 2D elements is coherent
4427         """
4428
4429         return self.editor.IsCoherentOrientation2D()
4430
4431     def Get1DBranches( self, edges, startNode = 0 ):
4432         """
4433         Partition given 1D elements into groups of contiguous edges.
4434         A node where number of meeting edges != 2 is a group end.
4435         An optional startNode is used to orient groups it belongs to.
4436
4437         Returns:
4438              A list of edge groups and a list of corresponding node groups,
4439              where the group is a list of IDs of edges or elements, like follows
4440              [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4441              If a group is closed, the first and last nodes of the group are same.
4442         """
4443         if isinstance( edges, Mesh ):
4444             edges = edges.GetMesh()
4445         unRegister = genObjUnRegister()
4446         if isinstance( edges, list ):
4447             edges = self.GetIDSource( edges, SMESH.EDGE )
4448             unRegister.set( edges )
4449         return self.editor.Get1DBranches( edges, startNode )
4450     
4451     def FindSharpEdges( self, angle, addExisting=False ):
4452         """
4453         Return sharp edges of faces and non-manifold ones.
4454         Optionally add existing edges.
4455
4456         Parameters:
4457                 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4458                 addExisting: to return existing edges (1D elements) as well
4459
4460         Returns:
4461             list of FaceEdge structures
4462         """
4463         angle = ParseParameters( angle )[0]
4464         return self.editor.FindSharpEdges( angle, addExisting )
4465
4466     def MeshToPassThroughAPoint(self, x, y, z):
4467         """
4468         Find the node closest to a point and moves it to a point location
4469
4470         Parameters:
4471                 x:  the X coordinate of a point
4472                 y:  the Y coordinate of a point
4473                 z:  the Z coordinate of a point
4474
4475         Returns:
4476             the ID of a moved node
4477         """
4478
4479         return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4480
4481     def InverseDiag(self, NodeID1, NodeID2):
4482         """
4483         Replace two neighbour triangles sharing Node1-Node2 link
4484         with the triangles built on the same 4 nodes but having other common link.
4485
4486         Parameters:
4487                 NodeID1:  the ID of the first node
4488                 NodeID2:  the ID of the second node
4489
4490         Returns:
4491             False if proper faces were not found
4492         """
4493         return self.editor.InverseDiag(NodeID1, NodeID2)
4494
4495     def DeleteDiag(self, NodeID1, NodeID2):
4496         """
4497         Replace two neighbour triangles sharing *Node1-Node2* link
4498         with a quadrangle built on the same 4 nodes.
4499
4500         Parameters:
4501                 NodeID1: ID of the first node
4502                 NodeID2: ID of the second node
4503
4504         Returns:
4505             False if proper faces were not found
4506
4507         Note:
4508                 This operation can create gaps in numeration of elements.
4509                 Call :meth:`RenumberElements` to remove the gaps.
4510         """
4511
4512         return self.editor.DeleteDiag(NodeID1, NodeID2)
4513
4514     def Reorient(self, IDsOfElements=None):
4515         """
4516         Reorient elements by ids
4517
4518         Parameters:
4519                 IDsOfElements: if undefined reorients all mesh elements
4520
4521         Returns:
4522             True if succeed else False
4523         """
4524
4525         if IDsOfElements == None:
4526             IDsOfElements = self.GetElementsId()
4527         return self.editor.Reorient(IDsOfElements)
4528
4529     def ReorientObject(self, theObject):
4530         """
4531         Reorient all elements of the object
4532
4533         Parameters:
4534                 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4535
4536         Returns:
4537             True if succeed else False
4538         """
4539
4540         if ( isinstance( theObject, Mesh )):
4541             theObject = theObject.GetMesh()
4542         return self.editor.ReorientObject(theObject)
4543
4544     def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4545         """
4546         Reorient faces contained in *the2DObject*.
4547
4548         Parameters:
4549                 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4550                 theDirection: a desired direction of normal of *theFace*.
4551                         It can be either a GEOM vector or a list of coordinates [x,y,z].
4552                 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4553                         compared with theDirection. It can be either ID of face or a point
4554                         by which the face will be found. The point can be given as either
4555                         a GEOM vertex or a list of point coordinates.
4556
4557         Returns:
4558             number of reoriented faces
4559         """
4560
4561         unRegister = genObjUnRegister()
4562         # check the2DObject
4563         if isinstance( the2DObject, Mesh ):
4564             the2DObject = the2DObject.GetMesh()
4565         if isinstance( the2DObject, list ):
4566             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4567             unRegister.set( the2DObject )
4568         # check theDirection
4569         if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4570             theDirection = self.smeshpyD.GetDirStruct( theDirection )
4571         if isinstance( theDirection, list ):
4572             theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
4573         # prepare theFace and thePoint
4574         theFace = theFaceOrPoint
4575         thePoint = PointStruct(0,0,0)
4576         if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4577             thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4578             theFace = -1
4579         if isinstance( theFaceOrPoint, list ):
4580             thePoint = PointStruct( *theFaceOrPoint )
4581             theFace = -1
4582         if isinstance( theFaceOrPoint, PointStruct ):
4583             thePoint = theFaceOrPoint
4584             theFace = -1
4585         return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4586
4587     def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4588         """
4589         Reorient faces according to adjacent volumes.
4590
4591         Parameters:
4592                 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4593                         either IDs of faces or face groups.
4594                 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4595                 theOutsideNormal: to orient faces to have their normals
4596                         pointing either *outside* or *inside* the adjacent volumes.
4597
4598         Returns:
4599             number of reoriented faces.
4600         """
4601
4602         unRegister = genObjUnRegister()
4603         # check the2DObject
4604         if not isinstance( the2DObject, list ):
4605             the2DObject = [ the2DObject ]
4606         elif the2DObject and isinstance( the2DObject[0], int ):
4607             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4608             unRegister.set( the2DObject )
4609             the2DObject = [ the2DObject ]
4610         for i,obj2D in enumerate( the2DObject ):
4611             if isinstance( obj2D, Mesh ):
4612                 the2DObject[i] = obj2D.GetMesh()
4613             if isinstance( obj2D, list ):
4614                 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4615                 unRegister.set( the2DObject[i] )
4616         # check the3DObject
4617         if isinstance( the3DObject, Mesh ):
4618             the3DObject = the3DObject.GetMesh()
4619         if isinstance( the3DObject, list ):
4620             the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4621             unRegister.set( the3DObject )
4622         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4623
4624     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4625         """
4626         Fuse the neighbouring triangles into quadrangles.
4627
4628         Parameters:
4629                 IDsOfElements: The triangles to be fused.
4630                 theCriterion:  a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4631                         applied to possible quadrangles to choose a neighbour to fuse with.
4632                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4633                         to numerical functors.
4634                 MaxAngle: is the maximum angle between element normals at which the fusion
4635                         is still performed; theMaxAngle is measured in radians.
4636                         Also it could be a name of variable which defines angle in degrees.
4637
4638         Returns:
4639             True in case of success, False otherwise.
4640
4641         Note:
4642                 This operation can create gaps in numeration of elements.
4643                 Call :meth:`RenumberElements` to remove the gaps.
4644         """
4645
4646         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4647         self.mesh.SetParameters(Parameters)
4648         if not IDsOfElements:
4649             IDsOfElements = self.GetElementsId()
4650         Functor = self.smeshpyD.GetFunctor(theCriterion)
4651         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4652
4653     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4654         """
4655         Fuse the neighbouring triangles of the object into quadrangles
4656
4657         Parameters:
4658                 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4659                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4660                         applied to possible quadrangles to choose a neighbour to fuse with.
4661                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4662                         to numerical functors.
4663                 MaxAngle: a max angle between element normals at which the fusion
4664                         is still performed; theMaxAngle is measured in radians.
4665
4666         Returns:
4667             True in case of success, False otherwise.
4668
4669         Note:
4670                 This operation can create gaps in numeration of elements.
4671                 Call :meth:`RenumberElements` to remove the gaps.
4672         """
4673
4674         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4675         self.mesh.SetParameters(Parameters)
4676         if isinstance( theObject, Mesh ):
4677             theObject = theObject.GetMesh()
4678         Functor = self.smeshpyD.GetFunctor(theCriterion)
4679         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4680
4681     def QuadToTri (self, IDsOfElements, theCriterion = None):
4682         """
4683         Split quadrangles into triangles.
4684
4685         Parameters:
4686                 IDsOfElements: the faces to be splitted.
4687                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4688                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4689                         value, then quadrangles will be split by the smallest diagonal.
4690                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4691                         to numerical functors.
4692
4693         Returns:
4694             True in case of success, False otherwise.
4695
4696         Note:
4697                 This operation can create gaps in numeration of elements.
4698                 Call :meth:`RenumberElements` to remove the gaps.
4699         """
4700         if IDsOfElements == []:
4701             IDsOfElements = self.GetElementsId()
4702         if theCriterion is None:
4703             theCriterion = FT_MaxElementLength2D
4704         Functor = self.smeshpyD.GetFunctor(theCriterion)
4705         return self.editor.QuadToTri(IDsOfElements, Functor)
4706
4707     def QuadToTriObject (self, theObject, theCriterion = None):
4708         """
4709         Split quadrangles into triangles.
4710
4711         Parameters:
4712                 theObject: the object from which the list of elements is taken,
4713                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4714                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4715                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4716                         value, then quadrangles will be split by the smallest diagonal.
4717                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4718                         to numerical functors.
4719
4720         Returns:
4721             True in case of success, False otherwise.
4722
4723         Note:
4724                 This operation can create gaps in numeration of elements.
4725                 Call :meth:`RenumberElements` to remove the gaps.
4726         """
4727         if ( isinstance( theObject, Mesh )):
4728             theObject = theObject.GetMesh()
4729         if theCriterion is None:
4730             theCriterion = FT_MaxElementLength2D
4731         Functor = self.smeshpyD.GetFunctor(theCriterion)
4732         return self.editor.QuadToTriObject(theObject, Functor)
4733
4734     def QuadTo4Tri (self, theElements=[]):
4735         """
4736         Split each of given quadrangles into 4 triangles. A node is added at the center of
4737         a quadrangle.
4738
4739         Parameters:
4740                 theElements: the faces to be splitted. This can be either 
4741                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4742                         or a list of face IDs. By default all quadrangles are split
4743
4744         Note:
4745                 This operation can create gaps in numeration of elements.
4746                 Call :meth:`RenumberElements` to remove the gaps.
4747         """
4748         unRegister = genObjUnRegister()
4749         if isinstance( theElements, Mesh ):
4750             theElements = theElements.mesh
4751         elif not theElements:
4752             theElements = self.mesh
4753         elif isinstance( theElements, list ):
4754             theElements = self.GetIDSource( theElements, SMESH.FACE )
4755             unRegister.set( theElements )
4756         return self.editor.QuadTo4Tri( theElements )
4757
4758     def SplitQuad (self, IDsOfElements, Diag13):
4759         """
4760         Split quadrangles into triangles.
4761
4762         Parameters:
4763                 IDsOfElements: the faces to be splitted
4764                 Diag13 (boolean):        is used to choose a diagonal for splitting.
4765
4766         Returns:
4767             True in case of success, False otherwise.
4768
4769         Note:
4770                 This operation can create gaps in numeration of elements.
4771                 Call :meth:`RenumberElements` to remove the gaps.
4772         """
4773         if IDsOfElements == []:
4774             IDsOfElements = self.GetElementsId()
4775         return self.editor.SplitQuad(IDsOfElements, Diag13)
4776
4777     def SplitQuadObject (self, theObject, Diag13):
4778         """
4779         Split quadrangles into triangles.
4780
4781         Parameters:
4782                 theObject: the object from which the list of elements is taken,
4783                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4784                 Diag13 (boolean):    is used to choose a diagonal for splitting.
4785
4786         Returns:
4787             True in case of success, False otherwise.
4788
4789         Note:
4790                 This operation can create gaps in numeration of elements.
4791                 Call :meth:`RenumberElements` to remove the gaps.
4792         """
4793         if ( isinstance( theObject, Mesh )):
4794             theObject = theObject.GetMesh()
4795         return self.editor.SplitQuadObject(theObject, Diag13)
4796
4797     def BestSplit (self, IDOfQuad, theCriterion):
4798         """
4799         Find a better splitting of the given quadrangle.
4800
4801         Parameters:
4802                 IDOfQuad:   the ID of the quadrangle to be splitted.
4803                 theCriterion:  is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4804                         choose a diagonal for splitting.
4805                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4806                         to numerical functors.
4807
4808         Returns:
4809             * 1 if 1-3 diagonal is better, 
4810             * 2 if 2-4 diagonal is better, 
4811             * 0 if error occurs.
4812
4813         Note:
4814                 This operation can create gaps in numeration of elements.
4815                 Call :meth:`RenumberElements` to remove the gaps.
4816         """
4817         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4818
4819     def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4820         """
4821         Split volumic elements into tetrahedrons
4822
4823         Parameters:
4824                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4825                 method:  flags passing splitting method:
4826                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4827                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4828
4829         Note:
4830                 This operation can create gaps in numeration of elements.
4831                 Call :meth:`RenumberElements` to remove the gaps.
4832         """
4833         unRegister = genObjUnRegister()
4834         if isinstance( elems, Mesh ):
4835             elems = elems.GetMesh()
4836         if ( isinstance( elems, list )):
4837             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4838             unRegister.set( elems )
4839         self.editor.SplitVolumesIntoTetra(elems, method)
4840         return
4841
4842     def SplitBiQuadraticIntoLinear(self, elems=None):
4843         """
4844         Split bi-quadratic elements into linear ones without creation of additional nodes:
4845
4846             - bi-quadratic triangle will be split into 3 linear quadrangles;
4847             - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4848             - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4849
4850         Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
4851         will be split in order to keep the mesh conformal.
4852
4853         Parameters:
4854             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4855                 if None (default), all bi-quadratic elements will be split
4856
4857         Note:
4858                 This operation can create gaps in numeration of elements.
4859                 Call :meth:`RenumberElements` to remove the gaps.
4860         """
4861         unRegister = genObjUnRegister()
4862         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4863             elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4864             unRegister.set( elems )
4865         if elems is None:
4866             elems = [ self.GetMesh() ]
4867         if isinstance( elems, Mesh ):
4868             elems = [ elems.GetMesh() ]
4869         if not isinstance( elems, list ):
4870             elems = [elems]
4871         self.editor.SplitBiQuadraticIntoLinear( elems )
4872
4873     def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4874                                  method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4875         """
4876         Split hexahedra into prisms
4877
4878         Parameters:
4879                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4880                 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4881                         gives a normal vector defining facets to split into triangles.
4882                         *startHexPoint* can be either a triple of coordinates or a vertex.
4883                 facetNormal: a normal to a facet to split into triangles of a
4884                         hexahedron found by *startHexPoint*.
4885                         *facetNormal* can be either a triple of coordinates or an edge.
4886                 method:  flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4887                         smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4888                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4889                         to *startHexPoint* are split, else *startHexPoint*
4890                         is used to find the facet to split in all domains present in *elems*.
4891
4892         Note:
4893                 This operation can create gaps in numeration of elements.
4894                 Call :meth:`RenumberElements` to remove the gaps.
4895         """
4896         # IDSource
4897         unRegister = genObjUnRegister()
4898         if isinstance( elems, Mesh ):
4899             elems = elems.GetMesh()
4900         if ( isinstance( elems, list )):
4901             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4902             unRegister.set( elems )
4903             pass
4904         # axis
4905         if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4906             startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4907         elif isinstance( startHexPoint, list ):
4908             startHexPoint = SMESH.PointStruct( startHexPoint[0],
4909                                                startHexPoint[1],
4910                                                startHexPoint[2])
4911         if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
4912             facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
4913         elif isinstance( facetNormal, list ):
4914             facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
4915                                                        facetNormal[1],
4916                                                        facetNormal[2])
4917         self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
4918
4919         self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
4920
4921     def SplitQuadsNearTriangularFacets(self):
4922         """
4923         Split quadrangle faces near triangular facets of volumes
4924
4925         Note:
4926                 This operation can create gaps in numeration of elements.
4927                 Call :meth:`RenumberElements` to remove the gaps.
4928         """
4929         faces_array = self.GetElementsByType(SMESH.FACE)
4930         for face_id in faces_array:
4931             if self.GetElemNbNodes(face_id) == 4: # quadrangle
4932                 quad_nodes = self.mesh.GetElemNodes(face_id)
4933                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
4934                 isVolumeFound = False
4935                 for node1_elem in node1_elems:
4936                     if not isVolumeFound:
4937                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
4938                             nb_nodes = self.GetElemNbNodes(node1_elem)
4939                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
4940                                 volume_elem = node1_elem
4941                                 volume_nodes = self.mesh.GetElemNodes(volume_elem)
4942                                 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
4943                                     if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
4944                                         isVolumeFound = True
4945                                         if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
4946                                             self.SplitQuad([face_id], False) # diagonal 2-4
4947                                     elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
4948                                         isVolumeFound = True
4949                                         self.SplitQuad([face_id], True) # diagonal 1-3
4950                                 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
4951                                     if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
4952                                         isVolumeFound = True
4953                                         self.SplitQuad([face_id], True) # diagonal 1-3
4954
4955     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
4956         """
4957         Split hexahedrons into tetrahedrons.
4958
4959         This operation uses :doc:`pattern_mapping` functionality for splitting.
4960
4961         Parameters:
4962                 theObject: the object from which the list of hexahedrons is taken; 
4963                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4964                 theNode000,theNode001: within the range [0,7]; gives the orientation of the
4965                         pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
4966                         will be mapped into *theNode000*-th node of each volume, the (0,0,1)
4967                         key-point will be mapped into *theNode001*-th node of each volume.
4968                         The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
4969
4970         Returns:
4971             True in case of success, False otherwise.
4972
4973         Note:
4974                 This operation can create gaps in numeration of elements.
4975                 Call :meth:`RenumberElements` to remove the gaps.
4976         """
4977 #    Pattern:
4978 #                     5.---------.6
4979 #                    /|#*      /|
4980 #                   / | #*    / |
4981 #                  /  |  # * /  |
4982 #                 /   |   # /*  |
4983 #       (0,0,1) 4.---------.7 * |
4984 #                |#*  |1   | # *|
4985 #                | # *.----|---#.2
4986 #                |  #/ *   |   /
4987 #                |  /#  *  |  /
4988 #                | /   # * | /
4989 #                |/      #*|/
4990 #        (0,0,0) 0.---------.3
4991         pattern_tetra = "!!! Nb of points: \n 8 \n\
4992         !!! Points: \n\
4993         0 0 0  !- 0 \n\
4994         0 1 0  !- 1 \n\
4995         1 1 0  !- 2 \n\
4996         1 0 0  !- 3 \n\
4997         0 0 1  !- 4 \n\
4998         0 1 1  !- 5 \n\
4999         1 1 1  !- 6 \n\
5000         1 0 1  !- 7 \n\
5001         !!! Indices of points of 6 tetras: \n\
5002         0 3 4 1 \n\
5003         7 4 3 1 \n\
5004         4 7 5 1 \n\
5005         6 2 5 7 \n\
5006         1 5 2 7 \n\
5007         2 3 1 7 \n"
5008
5009         pattern = self.smeshpyD.GetPattern()
5010         isDone  = pattern.LoadFromFile(pattern_tetra)
5011         if not isDone:
5012             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5013             return isDone
5014
5015         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5016         isDone = pattern.MakeMesh(self.mesh, False, False)
5017         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5018
5019         # split quafrangle faces near triangular facets of volumes
5020         self.SplitQuadsNearTriangularFacets()
5021
5022         return isDone
5023
5024     def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5025         """
5026         Split hexahedrons into prisms.
5027
5028         Uses the :doc:`pattern_mapping` functionality for splitting.
5029
5030         Parameters:
5031                 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5032                 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5033                         pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5034                         will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5035                         will be mapped into the *theNode001* -th node of each volume.
5036                         Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5037
5038         Returns:
5039             True in case of success, False otherwise.
5040
5041         Note:
5042                 This operation can create gaps in numeration of elements.
5043                 Call :meth:`RenumberElements` to remove the gaps.
5044         """
5045 #        Pattern:     5.---------.6
5046 #                     /|#       /|
5047 #                    / | #     / |
5048 #                   /  |  #   /  |
5049 #                  /   |   # /   |
5050 #        (0,0,1) 4.---------.7   |
5051 #                 |    |    |    |
5052 #                 |   1.----|----.2
5053 #                 |   / *   |   /
5054 #                 |  /   *  |  /
5055 #                 | /     * | /
5056 #                 |/       *|/
5057 #        (0,0,0) 0.---------.3
5058         pattern_prism = "!!! Nb of points: \n 8 \n\
5059         !!! Points: \n\
5060         0 0 0  !- 0 \n\
5061         0 1 0  !- 1 \n\
5062         1 1 0  !- 2 \n\
5063         1 0 0  !- 3 \n\
5064         0 0 1  !- 4 \n\
5065         0 1 1  !- 5 \n\
5066         1 1 1  !- 6 \n\
5067         1 0 1  !- 7 \n\
5068         !!! Indices of points of 2 prisms: \n\
5069         0 1 3 4 5 7 \n\
5070         2 3 1 6 7 5 \n"
5071
5072         pattern = self.smeshpyD.GetPattern()
5073         isDone  = pattern.LoadFromFile(pattern_prism)
5074         if not isDone:
5075             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5076             return isDone
5077
5078         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5079         isDone = pattern.MakeMesh(self.mesh, False, False)
5080         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5081
5082         # Split quafrangle faces near triangular facets of volumes
5083         self.SplitQuadsNearTriangularFacets()
5084
5085         return isDone
5086
5087     def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5088                MaxNbOfIterations, MaxAspectRatio, Method):
5089         """
5090         Smooth elements
5091
5092         Parameters:
5093                 IDsOfElements: the list if ids of elements to smooth
5094                 IDsOfFixedNodes: the list of ids of fixed nodes.
5095                         Note that nodes built on edges and boundary nodes are always fixed.
5096                 MaxNbOfIterations: the maximum number of iterations
5097                 MaxAspectRatio: varies in range [1.0, inf]
5098                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5099                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5100
5101         Returns:
5102             True in case of success, False otherwise.
5103         """
5104
5105         if IDsOfElements == []:
5106             IDsOfElements = self.GetElementsId()
5107         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5108         self.mesh.SetParameters(Parameters)
5109         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5110                                   MaxNbOfIterations, MaxAspectRatio, Method)
5111
5112     def SmoothObject(self, theObject, IDsOfFixedNodes,
5113                      MaxNbOfIterations, MaxAspectRatio, Method):
5114         """
5115         Smooth elements which belong to the given object
5116
5117         Parameters:
5118                 theObject: the object to smooth
5119                 IDsOfFixedNodes: the list of ids of fixed nodes.
5120                         Note that nodes built on edges and boundary nodes are always fixed.
5121                 MaxNbOfIterations: the maximum number of iterations
5122                 MaxAspectRatio: varies in range [1.0, inf]
5123                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5124                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5125
5126         Returns:
5127             True in case of success, False otherwise.
5128         """
5129
5130         if ( isinstance( theObject, Mesh )):
5131             theObject = theObject.GetMesh()
5132         return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5133                                         MaxNbOfIterations, MaxAspectRatio, Method)
5134
5135     def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5136                          MaxNbOfIterations, MaxAspectRatio, Method):
5137         """
5138         Parametrically smooth the given elements
5139
5140         Parameters:
5141                 IDsOfElements: the list if ids of elements to smooth
5142                 IDsOfFixedNodes: the list of ids of fixed nodes.
5143                         Note that nodes built on edges and boundary nodes are always fixed.
5144                 MaxNbOfIterations: the maximum number of iterations
5145                 MaxAspectRatio: varies in range [1.0, inf]
5146                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5147                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5148
5149         Returns:
5150             True in case of success, False otherwise.
5151         """
5152
5153         if IDsOfElements == []:
5154             IDsOfElements = self.GetElementsId()
5155         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5156         self.mesh.SetParameters(Parameters)
5157         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5158                                             MaxNbOfIterations, MaxAspectRatio, Method)
5159
5160     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5161                                MaxNbOfIterations, MaxAspectRatio, Method):
5162         """
5163         Parametrically smooth the elements which belong to the given object
5164
5165         Parameters:
5166                 theObject: the object to smooth
5167                 IDsOfFixedNodes: the list of ids of fixed nodes.
5168                         Note that nodes built on edges and boundary nodes are always fixed.
5169                 MaxNbOfIterations: the maximum number of iterations
5170                 MaxAspectRatio: varies in range [1.0, inf]
5171                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5172                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5173
5174         Returns:
5175             True in case of success, False otherwise.
5176         """
5177
5178         if ( isinstance( theObject, Mesh )):
5179             theObject = theObject.GetMesh()
5180         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5181                                                   MaxNbOfIterations, MaxAspectRatio, Method)
5182
5183     def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5184         """
5185         Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5186         them with quadratic with the same id.
5187
5188         Parameters:
5189                 theForce3d: method of new node creation:
5190
5191                   * False - the medium node lies at the geometrical entity from which the mesh element is built
5192                   * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5193                 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5194                 theToBiQuad: If True, converts the mesh to bi-quadratic
5195
5196         Returns:
5197             :class:`SMESH.ComputeError` which can hold a warning
5198
5199         Warning:
5200             If *theSubMesh* is provided, the mesh can become non-conformal
5201
5202         Note:
5203                 This operation can create gaps in numeration of nodes or elements.
5204                 Call :meth:`RenumberElements` to remove the gaps.
5205         """
5206
5207         if isinstance( theSubMesh, Mesh ):
5208             theSubMesh = theSubMesh.mesh
5209         if theToBiQuad:
5210             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5211         else:
5212             if theSubMesh:
5213                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5214             else:
5215                 self.editor.ConvertToQuadratic(theForce3d)
5216         error = self.editor.GetLastError()
5217         if error and error.comment:
5218             print(error.comment)
5219         return error
5220
5221     def ConvertFromQuadratic(self, theSubMesh=None):
5222         """
5223         Convert the mesh from quadratic to ordinary,
5224         deletes old quadratic elements,
5225         replacing them with ordinary mesh elements with the same id.
5226
5227         Parameters:
5228             theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5229
5230         Warning:
5231             If *theSubMesh* is provided, the mesh can become non-conformal
5232
5233         Note:
5234                 This operation can create gaps in numeration of nodes or elements.
5235                 Call :meth:`RenumberElements` to remove the gaps.
5236         """
5237
5238         if theSubMesh:
5239             self.editor.ConvertFromQuadraticObject(theSubMesh)
5240         else:
5241             return self.editor.ConvertFromQuadratic()
5242
5243     def Make2DMeshFrom3D(self):
5244         """
5245         Create 2D mesh as skin on boundary faces of a 3D mesh
5246
5247         Returns:
5248             True if operation has been completed successfully, False otherwise
5249         """
5250
5251         return self.editor.Make2DMeshFrom3D()
5252
5253     def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5254                          toCopyElements=False, toCopyExistingBondary=False):
5255         """
5256         Create missing boundary elements
5257
5258         Parameters:
5259                 elements: elements whose boundary is to be checked:
5260                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5261                         If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5262                 dimension: defines type of boundary elements to create, either of
5263                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5264                         SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5265                 groupName: a name of group to store created boundary elements in,
5266                         "" means not to create the group
5267                 meshName: a name of new mesh to store created boundary elements in,
5268                         "" means not to create the new mesh
5269                 toCopyElements: if True, the checked elements will be copied into
5270                         the new mesh else only boundary elements will be copied into the new mesh
5271                 toCopyExistingBondary: if True, not only new but also pre-existing
5272                         boundary elements will be copied into the new mesh
5273
5274         Returns:
5275             tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5276         """
5277
5278         unRegister = genObjUnRegister()
5279         if isinstance( elements, Mesh ):
5280             elements = elements.GetMesh()
5281         if ( isinstance( elements, list )):
5282             elemType = SMESH.ALL
5283             if elements: elemType = self.GetElementType( elements[0], iselem=True)
5284             elements = self.editor.MakeIDSource(elements, elemType)
5285             unRegister.set( elements )
5286         mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5287                                                    toCopyElements,toCopyExistingBondary)
5288         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5289         return mesh, group
5290
5291     def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5292                              toCopyAll=False, groups=[]):
5293         """
5294         Create missing boundary elements around either the whole mesh or
5295         groups of elements
5296
5297         Parameters:
5298                 dimension: defines type of boundary elements to create, either of
5299                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5300                 groupName: a name of group to store all boundary elements in,
5301                         "" means not to create the group
5302                 meshName: a name of a new mesh, which is a copy of the initial
5303                         mesh + created boundary elements; "" means not to create the new mesh
5304                 toCopyAll: if True, the whole initial mesh will be copied into
5305                         the new mesh else only boundary elements will be copied into the new mesh
5306                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5307
5308         Returns:
5309                 tuple( long, mesh, group )
5310                        - long - number of added boundary elements
5311                        - mesh - the :class:`Mesh` where elements were added to
5312                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5313         """
5314
5315         nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5316                                                            toCopyAll,groups)
5317         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5318         return nb, mesh, group
5319
5320     def RenumberNodes(self):
5321         """
5322         Renumber mesh nodes to remove unused node IDs
5323         """
5324         self.editor.RenumberNodes()
5325
5326     def RenumberElements(self):
5327         """
5328         Renumber mesh elements to remove unused element IDs
5329         """
5330         self.editor.RenumberElements()
5331
5332     def _getIdSourceList(self, arg, idType, unRegister):
5333         """
5334         Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5335         """
5336         if arg and isinstance( arg, list ):
5337             if isinstance( arg[0], int ):
5338                 arg = self.GetIDSource( arg, idType )
5339                 unRegister.set( arg )
5340             elif isinstance( arg[0], Mesh ):
5341                 arg[0] = arg[0].GetMesh()
5342         elif isinstance( arg, Mesh ):
5343             arg = arg.GetMesh()
5344         if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5345             arg = [arg]
5346         return arg
5347
5348     def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5349                              MakeGroups=False, TotalAngle=False):
5350         """
5351         Generate new elements by rotation of the given elements and nodes around the axis
5352
5353         Parameters:
5354                 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5355                 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5356                 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5357                 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5358                 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5359                         which defines angle in degrees
5360                 NbOfSteps: the number of steps
5361                 Tolerance: tolerance
5362                 MakeGroups: forces the generation of new groups from existing ones
5363                 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5364                         of all steps, else - size of each step
5365
5366         Returns:
5367             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5368         """
5369
5370         unRegister = genObjUnRegister()
5371         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5372         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5373         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5374
5375         if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5376             Axis = self.smeshpyD.GetAxisStruct( Axis )
5377         if isinstance( Axis, list ):
5378             Axis = SMESH.AxisStruct( *Axis )
5379
5380         AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5381         NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5382         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5383         self.mesh.SetParameters(Parameters)
5384         if TotalAngle and NbOfSteps:
5385             AngleInRadians /= NbOfSteps
5386         return self.editor.RotationSweepObjects( nodes, edges, faces,
5387                                                  Axis, AngleInRadians,
5388                                                  NbOfSteps, Tolerance, MakeGroups)
5389
5390     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5391                       MakeGroups=False, TotalAngle=False):
5392         """
5393         Generate new elements by rotation of the elements around the axis
5394
5395         Parameters:
5396             IDsOfElements: the list of ids of elements to sweep
5397             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5398             AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5399             NbOfSteps: the number of steps
5400             Tolerance: tolerance
5401             MakeGroups: forces the generation of new groups from existing ones
5402             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5403                 of all steps, else - size of each step
5404
5405         Returns:
5406             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5407         """
5408
5409         return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5410                                          AngleInRadians, NbOfSteps, Tolerance,
5411                                          MakeGroups, TotalAngle)
5412
5413     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5414                             MakeGroups=False, TotalAngle=False):
5415         """
5416         Generate new elements by rotation of the elements of object around the axis
5417         theObject object which elements should be sweeped.
5418         It can be a mesh, a sub mesh or a group.
5419
5420         Parameters:
5421             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5422             AngleInRadians: the angle of Rotation
5423             NbOfSteps: number of steps
5424             Tolerance: tolerance
5425             MakeGroups: forces the generation of new groups from existing ones
5426             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5427                 of all steps, else - size of each step
5428
5429         Returns:
5430             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5431         """
5432
5433         return self.RotationSweepObjects( [], theObject, theObject, Axis,
5434                                           AngleInRadians, NbOfSteps, Tolerance,
5435                                           MakeGroups, TotalAngle )
5436
5437     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5438                               MakeGroups=False, TotalAngle=False):
5439         """
5440         Generate new elements by rotation of the elements of object around the axis
5441         theObject object which elements should be sweeped.
5442         It can be a mesh, a sub mesh or a group.
5443
5444         Parameters:
5445             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5446             AngleInRadians: the angle of Rotation
5447             NbOfSteps: number of steps
5448             Tolerance: tolerance
5449             MakeGroups: forces the generation of new groups from existing ones
5450             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5451                 of all steps, else - size of each step
5452
5453         Returns:
5454             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, 
5455             empty list otherwise
5456         """
5457
5458         return self.RotationSweepObjects([],theObject,[], Axis,
5459                                          AngleInRadians, NbOfSteps, Tolerance,
5460                                          MakeGroups, TotalAngle)
5461
5462     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5463                               MakeGroups=False, TotalAngle=False):
5464         """
5465         Generate new elements by rotation of the elements of object around the axis
5466         theObject object which elements should be sweeped.
5467         It can be a mesh, a sub mesh or a group.
5468
5469         Parameters:
5470             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5471             AngleInRadians: the angle of Rotation
5472             NbOfSteps: number of steps
5473             Tolerance: tolerance
5474             MakeGroups: forces the generation of new groups from existing ones
5475             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5476                 of all steps, else - size of each step
5477
5478         Returns:
5479             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5480         """
5481
5482         return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5483                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5484
5485     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5486                               scaleFactors=[], linearVariation=False, basePoint=[],
5487                               angles=[], anglesVariation=False):
5488         """
5489         Generate new elements by extrusion of the given elements and nodes
5490
5491         Parameters:
5492             nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5493             edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5494             faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5495             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5496                 the direction and value of extrusion for one step (the total extrusion
5497                 length will be NbOfSteps * ||StepVector||)
5498             NbOfSteps: the number of steps
5499             MakeGroups: forces the generation of new groups from existing ones
5500             scaleFactors: optional scale factors to apply during extrusion
5501             linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5502                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5503             basePoint: optional scaling and rotation center; if not provided, a gravity center of
5504                 nodes and elements being extruded is used as the scaling center.
5505                 It can be either
5506
5507                         - a list of tree components of the point or
5508                         - a node ID or
5509                         - a GEOM point
5510             angles: list of angles in radians. Nodes at each extrusion step are rotated 
5511                 around *basePoint*, additionally to previous steps.
5512             anglesVariation: forces the computation of rotation angles as linear
5513                 variation of the given *angles* along path steps
5514         Returns:
5515             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5516
5517         Example: :ref:`tui_extrusion`
5518         """
5519         unRegister = genObjUnRegister()
5520         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5521         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5522         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5523
5524         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5525             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5526         if isinstance( StepVector, list ):
5527             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5528
5529         if isinstance( basePoint, int):
5530             xyz = self.GetNodeXYZ( basePoint )
5531             if not xyz:
5532                 raise RuntimeError("Invalid node ID: %s" % basePoint)
5533             basePoint = xyz
5534         if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5535             basePoint = self.geompyD.PointCoordinates( basePoint )
5536
5537         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5538         scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5539         angles,angleParameters,hasVars = ParseAngles(angles)
5540         Parameters = StepVector.PS.parameters + var_separator + \
5541                      Parameters + var_separator + \
5542                      scaleParameters + var_separator + angleParameters
5543         self.mesh.SetParameters(Parameters)
5544
5545         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5546                                                   StepVector, NbOfSteps, MakeGroups,
5547                                                   scaleFactors, linearVariation, basePoint,
5548                                                   angles, anglesVariation )
5549
5550
5551     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5552         """
5553         Generate new elements by extrusion of the elements with given ids
5554
5555         Parameters:
5556             IDsOfElements: the list of ids of elements or nodes for extrusion
5557             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5558                 the direction and value of extrusion for one step (the total extrusion
5559                 length will be NbOfSteps * ||StepVector||)
5560             NbOfSteps: the number of steps
5561             MakeGroups: forces the generation of new groups from existing ones
5562             IsNodes: is True if elements with given ids are nodes
5563
5564         Returns:
5565             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5566
5567         Example: :ref:`tui_extrusion`
5568         """
5569         n,e,f = [],[],[]
5570         if IsNodes: n = IDsOfElements
5571         else      : e,f, = IDsOfElements,IDsOfElements
5572         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5573
5574     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5575                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5576         """
5577         Generate new elements by extrusion along the normal to a discretized surface or wire
5578
5579         Parameters:
5580             Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5581                 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5582             StepSize: length of one extrusion step (the total extrusion
5583                 length will be *NbOfSteps* *StepSize*).
5584             NbOfSteps: number of extrusion steps.
5585             ByAverageNormal: if True each node is translated by *StepSize*
5586                 along the average of the normal vectors to the faces sharing the node;
5587                 else each node is translated along the same average normal till
5588                 intersection with the plane got by translation of the face sharing
5589                 the node along its own normal by *StepSize*.
5590             UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5591                 for every node of *Elements*.
5592             MakeGroups: forces generation of new groups from existing ones.
5593             Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5594                 is not yet implemented. This parameter is used if *Elements* contains
5595                 both faces and edges, i.e. *Elements* is a Mesh.
5596
5597         Returns:
5598             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5599             empty list otherwise.
5600         Example: :ref:`tui_extrusion`
5601         """
5602
5603         unRegister = genObjUnRegister()
5604         if isinstance( Elements, Mesh ):
5605             Elements = [ Elements.GetMesh() ]
5606         if isinstance( Elements, list ):
5607             if not Elements:
5608                 raise RuntimeError("Elements empty!")
5609             if isinstance( Elements[0], Mesh ):
5610                 Elements = [ Elements[0].GetMesh() ]
5611             if isinstance( Elements[0], int ):
5612                 Elements = self.GetIDSource( Elements, SMESH.ALL )
5613                 unRegister.set( Elements )
5614         if not isinstance( Elements, list ):
5615             Elements = [ Elements ]
5616         StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5617         self.mesh.SetParameters(Parameters)
5618         return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5619                                              ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5620
5621     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5622         """
5623         Generate new elements by extrusion of the elements or nodes which belong to the object
5624
5625         Parameters:
5626             theObject: the object whose elements or nodes should be processed.
5627                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5628             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5629                 the direction and value of extrusion for one step (the total extrusion
5630                 length will be NbOfSteps * ||StepVector||)
5631             NbOfSteps: the number of steps
5632             MakeGroups: forces the generation of new groups from existing ones
5633             IsNodes: is True if elements to extrude are nodes
5634
5635         Returns:
5636             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5637         Example: :ref:`tui_extrusion`
5638         """
5639
5640         n,e,f = [],[],[]
5641         if IsNodes: n    = theObject
5642         else      : e,f, = theObject,theObject
5643         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5644
5645     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5646         """
5647         Generate new elements by extrusion of edges which belong to the object
5648
5649         Parameters:
5650             theObject: object whose 1D elements should be processed.
5651                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5652             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5653                 the direction and value of extrusion for one step (the total extrusion
5654                 length will be NbOfSteps * ||StepVector||)
5655             NbOfSteps: the number of steps
5656             MakeGroups: to generate new groups from existing ones
5657
5658         Returns:
5659             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5660         Example: :ref:`tui_extrusion`
5661         """
5662
5663         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5664
5665     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5666         """
5667         Generate new elements by extrusion of faces which belong to the object
5668
5669         Parameters:
5670             theObject: object whose 2D elements should be processed.
5671                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5672             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5673                 the direction and value of extrusion for one step (the total extrusion
5674                 length will be NbOfSteps * ||StepVector||)
5675             NbOfSteps: the number of steps
5676             MakeGroups: forces the generation of new groups from existing ones
5677
5678         Returns:
5679             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5680         Example: :ref:`tui_extrusion`
5681         """
5682
5683         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5684
5685     def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5686                           ExtrFlags, SewTolerance, MakeGroups=False):
5687         """
5688         Generate new elements by extrusion of the elements with given ids
5689
5690         Parameters:
5691             IDsOfElements: is ids of elements
5692             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5693                 the direction and value of extrusion for one step (the total extrusion
5694                 length will be NbOfSteps * ||StepVector||)
5695             NbOfSteps: the number of steps
5696             ExtrFlags: sets flags for extrusion
5697             SewTolerance: uses for comparing locations of nodes if flag
5698                 EXTRUSION_FLAG_SEW is set
5699             MakeGroups: forces the generation of new groups from existing ones
5700
5701         Returns:
5702             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5703         """
5704
5705         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5706             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5707         if isinstance( StepVector, list ):
5708             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5709         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5710                                              ExtrFlags, SewTolerance, MakeGroups)
5711
5712     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5713                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5714                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5715                                   ScaleFactors=[], ScalesVariation=False):
5716         """
5717         Generate new elements by extrusion of the given elements and nodes along the path.
5718         The path of extrusion must be a meshed edge.
5719
5720         Parameters:
5721             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5722             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5723             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5724             PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5725             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
5726             NodeStart: the first or the last node on the path. Defines the direction of extrusion
5727             HasAngles: not used obsolete
5728             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5729                 around *basePoint*, additionally to previous steps.
5730             LinearVariation: forces the computation of rotation angles as linear
5731                 variation of the given Angles along path steps
5732             HasRefPoint: allows using the reference point
5733             RefPoint: optional scaling and rotation center (mass center of the extruded
5734                 elements by default). The User can specify any point as the Reference Point. 
5735                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5736             MakeGroups: forces the generation of new groups from existing ones
5737             ScaleFactors: optional scale factors to apply during extrusion
5738             ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5739                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5740
5741         Returns:
5742             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5743             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5744         Example: :ref:`tui_extrusion_along_path`
5745         """
5746
5747         unRegister = genObjUnRegister()
5748         Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5749         Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5750         Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5751
5752         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5753             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5754         if isinstance( RefPoint, list ):
5755             if not RefPoint: RefPoint = [0,0,0]
5756             RefPoint = SMESH.PointStruct( *RefPoint )
5757         if isinstance( PathObject, Mesh ):
5758             PathObject = PathObject.GetMesh()
5759         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5760         ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5761         Parameters = AnglesParameters + var_separator + \
5762                      RefPoint.parameters + var_separator + ScalesParameters 
5763         self.mesh.SetParameters(Parameters)
5764         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5765                                                      PathObject, PathShape, NodeStart,
5766                                                      HasAngles, Angles, LinearVariation,
5767                                                      HasRefPoint, RefPoint, MakeGroups,
5768                                                      ScaleFactors, ScalesVariation)
5769
5770     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5771                             HasAngles=False, Angles=[], LinearVariation=False,
5772                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5773                             ElemType=SMESH.FACE):
5774         """
5775         Generate new elements by extrusion of the given elements.
5776         The path of extrusion must be a meshed edge.
5777
5778         Parameters:
5779             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5780             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5781             NodeStart: the start node from Path. Defines the direction of extrusion
5782             HasAngles: not used obsolete
5783             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5784                 around *basePoint*, additionally to previous steps.
5785             LinearVariation: forces the computation of rotation angles as linear
5786                 variation of the given Angles along path steps
5787             HasRefPoint: allows using the reference point
5788             RefPoint: the reference point around which the elements are rotated (the mass
5789                 center of the elements by default).
5790                 The User can specify any point as the Reference Point.
5791                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5792             MakeGroups: forces the generation of new groups from existing ones
5793             ElemType: type of elements for extrusion (if param Base is a mesh)
5794
5795         Returns:
5796             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5797             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5798             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5799             otherwise
5800         Example: :ref:`tui_extrusion_along_path`
5801         """
5802
5803         n,e,f = [],[],[]
5804         if ElemType == SMESH.NODE: n = Base
5805         if ElemType == SMESH.EDGE: e = Base
5806         if ElemType == SMESH.FACE: f = Base
5807         gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5808                                                HasAngles, Angles, LinearVariation,
5809                                                HasRefPoint, RefPoint, MakeGroups)
5810         if MakeGroups: return gr,er
5811         return er
5812
5813     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5814                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5815                            MakeGroups=False, LinearVariation=False):
5816         """
5817         Generate new elements by extrusion of the given elements.
5818         The path of extrusion must be a meshed edge.
5819
5820         Parameters:
5821             IDsOfElements: ids of elements
5822             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5823             PathShape: shape (edge) defines the sub-mesh for the path
5824             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5825             HasAngles: not used obsolete
5826             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5827                 around *basePoint*, additionally to previous steps.
5828             HasRefPoint: allows using the reference point
5829             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5830                 The User can specify any point as the Reference Point.
5831                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5832             MakeGroups: forces the generation of new groups from existing ones
5833             LinearVariation: forces the computation of rotation angles as linear
5834                 variation of the given Angles along path steps
5835
5836         Returns:
5837             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5838             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5839             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5840         Example: :ref:`tui_extrusion_along_path`
5841         """
5842
5843         if not IDsOfElements:
5844             IDsOfElements = [ self.GetMesh() ]
5845         n,e,f = [],IDsOfElements,IDsOfElements
5846         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5847                                                NodeStart, HasAngles, Angles,
5848                                                LinearVariation,
5849                                                HasRefPoint, RefPoint, MakeGroups)
5850         if MakeGroups: return gr,er
5851         return er
5852
5853     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5854                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5855                                  MakeGroups=False, LinearVariation=False):
5856         """
5857         Generate new elements by extrusion of the elements which belong to the object.
5858         The path of extrusion must be a meshed edge.
5859
5860         Parameters:
5861             theObject: the object whose elements should be processed.
5862                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5863             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5864             PathShape: shape (edge) defines the sub-mesh for the path
5865             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5866             HasAngles: not used obsolete
5867             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5868                 around *basePoint*, additionally to previous steps.
5869             HasRefPoint: allows using the reference point
5870             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5871                 The User can specify any point as the Reference Point.
5872                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5873             MakeGroups: forces the generation of new groups from existing ones
5874             LinearVariation: forces the computation of rotation angles as linear
5875                 variation of the given Angles along path steps
5876
5877         Returns:
5878             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5879             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5880             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5881         Example: :ref:`tui_extrusion_along_path`
5882         """
5883
5884         n,e,f = [],theObject,theObject
5885         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5886                                                HasAngles, Angles, LinearVariation,
5887                                                HasRefPoint, RefPoint, MakeGroups)
5888         if MakeGroups: return gr,er
5889         return er
5890
5891     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5892                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5893                                    MakeGroups=False, LinearVariation=False):
5894         """
5895         Generate new elements by extrusion of mesh segments which belong to the object.
5896         The path of extrusion must be a meshed edge.
5897
5898         Parameters:
5899             theObject: the object whose 1D elements should be processed.
5900                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5901             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5902             PathShape: shape (edge) defines the sub-mesh for the path
5903             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5904             HasAngles: not used obsolete
5905             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5906                 around *basePoint*, additionally to previous steps.
5907             HasRefPoint: allows using the reference point
5908             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
5909                 The User can specify any point as the Reference Point.
5910                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5911             MakeGroups: forces the generation of new groups from existing ones
5912             LinearVariation: forces the computation of rotation angles as linear
5913                 variation of the given Angles along path steps
5914
5915         Returns:
5916             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5917             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5918             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5919         Example: :ref:`tui_extrusion_along_path`
5920         """
5921
5922         n,e,f = [],theObject,[]
5923         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5924                                                HasAngles, Angles, LinearVariation,
5925                                                HasRefPoint, RefPoint, MakeGroups)
5926         if MakeGroups: return gr,er
5927         return er
5928
5929     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5930                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5931                                    MakeGroups=False, LinearVariation=False):
5932         """
5933         Generate new elements by extrusion of faces which belong to the object.
5934         The path of extrusion must be a meshed edge.
5935
5936         Parameters:
5937             theObject: the object whose 2D elements should be processed.
5938                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5939             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5940             PathShape: shape (edge) defines the sub-mesh for the path
5941             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5942             HasAngles: not used obsolete
5943             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5944                 around *basePoint*, additionally to previous steps.
5945             HasRefPoint: allows using the reference point
5946             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5947                 The User can specify any point as the Reference Point.
5948                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5949             MakeGroups: forces the generation of new groups from existing ones
5950             LinearVariation: forces the computation of rotation angles as linear
5951                 variation of the given Angles along path steps
5952
5953         Returns:
5954             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5955             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5956             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5957         Example: :ref:`tui_extrusion_along_path`
5958         """
5959
5960         n,e,f = [],[],theObject
5961         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5962                                                HasAngles, Angles, LinearVariation,
5963                                                HasRefPoint, RefPoint, MakeGroups)
5964         if MakeGroups: return gr,er
5965         return er
5966
5967     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5968         """
5969         Create a symmetrical copy of mesh elements
5970
5971         Parameters:
5972             IDsOfElements: list of elements ids
5973             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5974             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5975                 If the *Mirror* is a geom object this parameter is unnecessary
5976             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5977             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5978
5979         Returns:
5980             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5981         """
5982
5983         if IDsOfElements == []:
5984             IDsOfElements = self.GetElementsId()
5985         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5986             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5987             theMirrorType = Mirror._mirrorType
5988         else:
5989             self.mesh.SetParameters(Mirror.parameters)
5990         if Copy and MakeGroups:
5991             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5992         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5993         return []
5994
5995     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5996         """
5997         Create a new mesh by a symmetrical copy of mesh elements
5998
5999         Parameters:
6000             IDsOfElements: the list of elements ids
6001             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6002             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6003                 If the *Mirror* is a geom object this parameter is unnecessary
6004             MakeGroups: to generate new groups from existing ones
6005             NewMeshName: a name of the new mesh to create
6006
6007         Returns:
6008             instance of class :class:`Mesh`
6009         """
6010
6011         if IDsOfElements == []:
6012             IDsOfElements = self.GetElementsId()
6013         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6014             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6015             theMirrorType = Mirror._mirrorType
6016         else:
6017             self.mesh.SetParameters(Mirror.parameters)
6018         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6019                                           MakeGroups, NewMeshName)
6020         return Mesh(self.smeshpyD,self.geompyD,mesh)
6021
6022     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6023         """
6024         Create a symmetrical copy of the object
6025
6026         Parameters:
6027             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6028             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6029             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6030                 If the *Mirror* is a geom object this parameter is unnecessary
6031             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6032             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6033
6034         Returns:
6035             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6036         """
6037
6038         if ( isinstance( theObject, Mesh )):
6039             theObject = theObject.GetMesh()
6040         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6041             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6042             theMirrorType = Mirror._mirrorType
6043         else:
6044             self.mesh.SetParameters(Mirror.parameters)
6045         if Copy and MakeGroups:
6046             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6047         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6048         return []
6049
6050     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6051         """
6052         Create a new mesh by a symmetrical copy of the object
6053
6054         Parameters:
6055             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6056             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6057             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6058                 If the *Mirror* is a geom object this parameter is unnecessary
6059             MakeGroups: forces the generation of new groups from existing ones
6060             NewMeshName: the name of the new mesh to create
6061
6062         Returns:
6063             instance of class :class:`Mesh`
6064         """
6065
6066         if ( isinstance( theObject, Mesh )):
6067             theObject = theObject.GetMesh()
6068         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6069             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6070             theMirrorType = Mirror._mirrorType
6071         else:
6072             self.mesh.SetParameters(Mirror.parameters)
6073         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6074                                                 MakeGroups, NewMeshName)
6075         return Mesh( self.smeshpyD,self.geompyD,mesh )
6076
6077     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6078         """
6079         Translate the elements
6080
6081         Parameters:
6082             IDsOfElements: list of elements ids
6083             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6084             Copy: allows copying the translated elements
6085             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6086
6087         Returns:
6088             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6089         """
6090
6091         if IDsOfElements == []:
6092             IDsOfElements = self.GetElementsId()
6093         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6094             Vector = self.smeshpyD.GetDirStruct(Vector)
6095         if isinstance( Vector, list ):
6096             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6097         self.mesh.SetParameters(Vector.PS.parameters)
6098         if Copy and MakeGroups:
6099             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6100         self.editor.Translate(IDsOfElements, Vector, Copy)
6101         return []
6102
6103     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6104         """
6105         Create a new mesh of translated elements
6106
6107         Parameters:
6108             IDsOfElements: list of elements ids
6109             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6110             MakeGroups: forces the generation of new groups from existing ones
6111             NewMeshName: the name of the newly created mesh
6112
6113         Returns:
6114             instance of class :class:`Mesh`
6115         """
6116
6117         if IDsOfElements == []:
6118             IDsOfElements = self.GetElementsId()
6119         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6120             Vector = self.smeshpyD.GetDirStruct(Vector)
6121         if isinstance( Vector, list ):
6122             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6123         self.mesh.SetParameters(Vector.PS.parameters)
6124         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6125         return Mesh ( self.smeshpyD, self.geompyD, mesh )
6126
6127     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6128         """
6129         Translate the object
6130
6131         Parameters:
6132             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6133             Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6134             Copy: allows copying the translated elements
6135             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6136
6137         Returns:
6138             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6139         """
6140
6141         if ( isinstance( theObject, Mesh )):
6142             theObject = theObject.GetMesh()
6143         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6144             Vector = self.smeshpyD.GetDirStruct(Vector)
6145         if isinstance( Vector, list ):
6146             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6147         self.mesh.SetParameters(Vector.PS.parameters)
6148         if Copy and MakeGroups:
6149             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6150         self.editor.TranslateObject(theObject, Vector, Copy)
6151         return []
6152
6153     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6154         """
6155         Create a new mesh from the translated object
6156
6157         Parameters:
6158             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6159             Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6160             MakeGroups: forces the generation of new groups from existing ones
6161             NewMeshName: the name of the newly created mesh
6162
6163         Returns:
6164             instance of class :class:`Mesh`
6165         """
6166
6167         if isinstance( theObject, Mesh ):
6168             theObject = theObject.GetMesh()
6169         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6170             Vector = self.smeshpyD.GetDirStruct(Vector)
6171         if isinstance( Vector, list ):
6172             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6173         self.mesh.SetParameters(Vector.PS.parameters)
6174         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6175         return Mesh( self.smeshpyD, self.geompyD, mesh )
6176
6177
6178
6179     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6180         """
6181         Scale the object
6182
6183         Parameters:
6184             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6185             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6186             theScaleFact: list of 1-3 scale factors for axises
6187             Copy: allows copying the translated elements
6188             MakeGroups: forces the generation of new groups from existing
6189                 ones (if Copy)
6190
6191         Returns:
6192             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6193             empty list otherwise
6194         """
6195         unRegister = genObjUnRegister()
6196         if ( isinstance( theObject, Mesh )):
6197             theObject = theObject.GetMesh()
6198         if ( isinstance( theObject, list )):
6199             theObject = self.GetIDSource(theObject, SMESH.ALL)
6200             unRegister.set( theObject )
6201         if ( isinstance( thePoint, list )):
6202             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6203         if ( isinstance( theScaleFact, float )):
6204             theScaleFact = [theScaleFact]
6205         if ( isinstance( theScaleFact, int )):
6206             theScaleFact = [ float(theScaleFact)]
6207
6208         self.mesh.SetParameters(thePoint.parameters)
6209
6210         if Copy and MakeGroups:
6211             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6212         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6213         return []
6214
6215     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6216         """
6217         Create a new mesh from the translated object
6218
6219         Parameters:
6220             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6221             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6222             theScaleFact: list of 1-3 scale factors for axises
6223             MakeGroups: forces the generation of new groups from existing ones
6224             NewMeshName: the name of the newly created mesh
6225
6226         Returns:
6227             instance of class :class:`Mesh`
6228         """
6229         unRegister = genObjUnRegister()
6230         if (isinstance(theObject, Mesh)):
6231             theObject = theObject.GetMesh()
6232         if ( isinstance( theObject, list )):
6233             theObject = self.GetIDSource(theObject,SMESH.ALL)
6234             unRegister.set( theObject )
6235         if ( isinstance( thePoint, list )):
6236             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6237         if ( isinstance( theScaleFact, float )):
6238             theScaleFact = [theScaleFact]
6239         if ( isinstance( theScaleFact, int )):
6240             theScaleFact = [ float(theScaleFact)]
6241
6242         self.mesh.SetParameters(thePoint.parameters)
6243         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6244                                          MakeGroups, NewMeshName)
6245         return Mesh( self.smeshpyD, self.geompyD, mesh )
6246
6247
6248
6249     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6250         """
6251         Rotate the elements
6252
6253         Parameters:
6254             IDsOfElements: list of elements ids
6255             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6256             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6257             Copy: allows copying the rotated elements
6258             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6259
6260         Returns:
6261             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6262         """
6263
6264
6265         if IDsOfElements == []:
6266             IDsOfElements = self.GetElementsId()
6267         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6268             Axis = self.smeshpyD.GetAxisStruct(Axis)
6269         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6270         Parameters = Axis.parameters + var_separator + Parameters
6271         self.mesh.SetParameters(Parameters)
6272         if Copy and MakeGroups:
6273             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6274         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6275         return []
6276
6277     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6278         """
6279         Create a new mesh of rotated elements
6280
6281         Parameters:
6282             IDsOfElements: list of element ids
6283             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6284             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6285             MakeGroups: forces the generation of new groups from existing ones
6286             NewMeshName: the name of the newly created mesh
6287
6288         Returns:
6289             instance of class :class:`Mesh`
6290         """
6291
6292         if IDsOfElements == []:
6293             IDsOfElements = self.GetElementsId()
6294         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6295             Axis = self.smeshpyD.GetAxisStruct(Axis)
6296         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6297         Parameters = Axis.parameters + var_separator + Parameters
6298         self.mesh.SetParameters(Parameters)
6299         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6300                                           MakeGroups, NewMeshName)
6301         return Mesh( self.smeshpyD, self.geompyD, mesh )
6302
6303     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6304         """
6305         Rotate the object
6306
6307         Parameters:
6308             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6309             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6310             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6311             Copy: allows copying the rotated elements
6312             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6313
6314         Returns:
6315             list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6316         """
6317
6318         if (isinstance(theObject, Mesh)):
6319             theObject = theObject.GetMesh()
6320         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6321             Axis = self.smeshpyD.GetAxisStruct(Axis)
6322         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6323         Parameters = Axis.parameters + ":" + Parameters
6324         self.mesh.SetParameters(Parameters)
6325         if Copy and MakeGroups:
6326             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6327         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6328         return []
6329
6330     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6331         """
6332         Create a new mesh from the rotated object
6333
6334         Parameters:
6335             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6336             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6337             AngleInRadians: the angle of rotation (in radians)  or a name of variable which defines angle in degrees
6338             MakeGroups: forces the generation of new groups from existing ones
6339             NewMeshName: the name of the newly created mesh
6340
6341         Returns:
6342             instance of class :class:`Mesh`
6343         """
6344
6345         if (isinstance( theObject, Mesh )):
6346             theObject = theObject.GetMesh()
6347         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6348             Axis = self.smeshpyD.GetAxisStruct(Axis)
6349         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6350         Parameters = Axis.parameters + ":" + Parameters
6351         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6352                                                        MakeGroups, NewMeshName)
6353         self.mesh.SetParameters(Parameters)
6354         return Mesh( self.smeshpyD, self.geompyD, mesh )
6355
6356     def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6357         """
6358         Create an offset mesh from the given 2D object
6359
6360         Parameters:
6361             theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6362             theValue (float): signed offset size
6363             MakeGroups (boolean): forces the generation of new groups from existing ones
6364             CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, 
6365                           False means to remove original elements.
6366             NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6367
6368         Returns:
6369             A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6370         """
6371
6372         if isinstance( theObject, Mesh ):
6373             theObject = theObject.GetMesh()
6374         theValue,Parameters,hasVars = ParseParameters(Value)
6375         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6376         self.mesh.SetParameters(Parameters)
6377         # if mesh_groups[0]:
6378         #     return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6379         return mesh_groups
6380
6381     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6382         """
6383         Find groups of adjacent nodes within Tolerance.
6384
6385         Parameters:
6386             Tolerance (float): the value of tolerance
6387             SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6388                 corner and medium nodes in separate groups thus preventing
6389                 their further merge.
6390
6391         Returns:
6392             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6393         """
6394
6395         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6396
6397     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6398                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
6399         """
6400         Find groups of adjacent nodes within Tolerance.
6401
6402         Parameters:
6403             Tolerance: the value of tolerance
6404             SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6405             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6406             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6407                 corner and medium nodes in separate groups thus preventing
6408                 their further merge.
6409
6410         Returns:
6411             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6412         """
6413
6414         unRegister = genObjUnRegister()
6415         if not isinstance( SubMeshOrGroup, list ):
6416             SubMeshOrGroup = [ SubMeshOrGroup ]
6417         for i,obj in enumerate( SubMeshOrGroup ):
6418             if isinstance( obj, Mesh ):
6419                 SubMeshOrGroup = [ obj.GetMesh() ]
6420                 break
6421             if isinstance( obj, int ):
6422                 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6423                 unRegister.set( SubMeshOrGroup )
6424                 break
6425
6426         if not isinstance( exceptNodes, list ):
6427             exceptNodes = [ exceptNodes ]
6428         if exceptNodes and isinstance( exceptNodes[0], int ):
6429             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6430             unRegister.set( exceptNodes )
6431
6432         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6433                                                         exceptNodes, SeparateCornerAndMediumNodes)
6434
6435     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6436         """
6437         Merge nodes
6438
6439         Parameters:
6440             GroupsOfNodes: a list of groups of nodes IDs for merging.
6441                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6442                 in all elements and mesh groups by nodes 1 and 25 correspondingly
6443             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6444                 If *NodesToKeep* does not include a node to keep for some group to merge,
6445                 then the first node in the group is kept.
6446             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6447                 invalid
6448
6449         Note:
6450                 This operation can create gaps in numeration of nodes or elements.
6451                 Call :meth:`RenumberElements` to remove the gaps.
6452         """
6453         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6454
6455     def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6456         """
6457         Find the elements built on the same nodes.
6458
6459         Parameters:
6460             MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6461             exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6462
6463
6464         Returns:
6465             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6466         """
6467
6468         unRegister = genObjUnRegister()
6469         if MeshOrSubMeshOrGroup is None:
6470             MeshOrSubMeshOrGroup = [ self.mesh ]
6471         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6472             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6473         elif not isinstance( MeshOrSubMeshOrGroup, list ):
6474             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6475         if isinstance( MeshOrSubMeshOrGroup[0], int ):
6476             MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6477             unRegister.set( MeshOrSubMeshOrGroup )
6478         for item in MeshOrSubMeshOrGroup:
6479             if isinstance( item, Mesh ):
6480                 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6481
6482         if not isinstance( exceptElements, list ):
6483             exceptElements = [ exceptElements ]
6484         if exceptElements and isinstance( exceptElements[0], int ):
6485             exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6486             unRegister.set( exceptElements )
6487
6488         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6489
6490     def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6491         """
6492         Merge elements in each given group.
6493
6494         Parameters:
6495             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6496                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6497                 replaced in all mesh groups by elements 1 and 25)
6498             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6499                 If *ElementsToKeep* does not include an element to keep for some group to merge,
6500                 then the first element in the group is kept.
6501
6502         Note:
6503                 This operation can create gaps in numeration of elements.
6504                 Call :meth:`RenumberElements` to remove the gaps.
6505         """
6506
6507         unRegister = genObjUnRegister()
6508         if ElementsToKeep:
6509             if not isinstance( ElementsToKeep, list ):
6510                 ElementsToKeep = [ ElementsToKeep ]
6511             if isinstance( ElementsToKeep[0], int ):
6512                 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6513                 unRegister.set( ElementsToKeep )
6514
6515         self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6516
6517     def MergeEqualElements(self):
6518         """
6519         Leave one element and remove all other elements built on the same nodes.
6520
6521         Note:
6522                 This operation can create gaps in numeration of elements.
6523                 Call :meth:`RenumberElements` to remove the gaps.
6524         """
6525
6526         self.editor.MergeEqualElements()
6527
6528     def FindFreeBorders(self, ClosedOnly=True):
6529         """
6530         Returns all or only closed free borders
6531
6532         Returns:
6533             list of SMESH.FreeBorder's
6534         """
6535
6536         return self.editor.FindFreeBorders( ClosedOnly )
6537
6538     def FillHole(self, holeNodes, groupName=""):
6539         """
6540         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6541
6542         Parameters:
6543             holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6544                 must describe all sequential nodes of the hole border. The first and the last
6545                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6546             groupName (string): name of a group to add new faces
6547         Returns:
6548             a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6549         """
6550
6551
6552         if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6553             holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6554         if not isinstance( holeNodes, SMESH.FreeBorder ):
6555             raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6556         return self.editor.FillHole( holeNodes, groupName )
6557
6558     def FindCoincidentFreeBorders (self, tolerance=0.):
6559         """
6560         Return groups of FreeBorder's coincident within the given tolerance.
6561
6562         Parameters:
6563             tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6564                 size of elements adjacent to free borders being compared is used.
6565
6566         Returns:
6567             SMESH.CoincidentFreeBorders structure
6568         """
6569
6570         return self.editor.FindCoincidentFreeBorders( tolerance )
6571
6572     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6573         """
6574         Sew FreeBorder's of each group
6575
6576         Parameters:
6577             freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6578                 where each enclosed list contains node IDs of a group of coincident free
6579                 borders such that each consequent triple of IDs within a group describes
6580                 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6581                 last node of a border.
6582                 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6583                 groups of coincident free borders, each group including two borders.
6584             createPolygons: if :code:`True` faces adjacent to free borders are converted to
6585                 polygons if a node of opposite border falls on a face edge, else such
6586                 faces are split into several ones.
6587             createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6588                 polyhedra if a node of opposite border falls on a volume edge, else such
6589                 volumes, if any, remain intact and the mesh becomes non-conformal.
6590
6591         Returns:
6592             a number of successfully sewed groups
6593
6594         Note:
6595                 This operation can create gaps in numeration of nodes or elements.
6596                 Call :meth:`RenumberElements` to remove the gaps.
6597         """
6598
6599         if freeBorders and isinstance( freeBorders, list ):
6600             # construct SMESH.CoincidentFreeBorders
6601             if isinstance( freeBorders[0], int ):
6602                 freeBorders = [freeBorders]
6603             borders = []
6604             coincidentGroups = []
6605             for nodeList in freeBorders:
6606                 if not nodeList or len( nodeList ) % 3:
6607                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6608                 group = []
6609                 while nodeList:
6610                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6611                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
6612                     nodeList = nodeList[3:]
6613                     pass
6614                 coincidentGroups.append( group )
6615                 pass
6616             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6617
6618         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6619
6620     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6621                         FirstNodeID2, SecondNodeID2, LastNodeID2,
6622                         CreatePolygons, CreatePolyedrs):
6623         """
6624         Sew free borders
6625
6626         Returns:
6627             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6628
6629         Note:
6630                 This operation can create gaps in numeration of nodes or elements.
6631                 Call :meth:`RenumberElements` to remove the gaps.
6632         """
6633
6634         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6635                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
6636                                           CreatePolygons, CreatePolyedrs)
6637
6638     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6639                                FirstNodeID2, SecondNodeID2):
6640         """
6641         Sew conform free borders
6642
6643         Returns:
6644             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6645
6646         Note:
6647                 This operation can create gaps in numeration of elements.
6648                 Call :meth:`RenumberElements` to remove the gaps.
6649         """
6650
6651         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6652                                                  FirstNodeID2, SecondNodeID2)
6653
6654     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6655                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6656         """
6657         Sew border to side
6658
6659         Returns:
6660             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6661
6662         Note:
6663                 This operation can create gaps in numeration of elements.
6664                 Call :meth:`RenumberElements` to remove the gaps.
6665         """
6666
6667         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6668                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6669
6670     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6671                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6672                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6673         """
6674         Sew two sides of a mesh. The nodes belonging to Side1 are
6675         merged with the nodes of elements of Side2.
6676         The number of elements in theSide1 and in theSide2 must be
6677         equal and they should have similar nodal connectivity.
6678         The nodes to merge should belong to side borders and
6679         the first node should be linked to the second.
6680
6681         Returns:
6682             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6683
6684         Note:
6685                 This operation can create gaps in numeration of nodes.
6686                 Call :meth:`RenumberElements` to remove the gaps.
6687         """
6688
6689         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6690                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6691                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6692
6693     def ChangeElemNodes(self, ide, newIDs):
6694         """
6695         Set new nodes for the given element. Number of nodes should be kept.
6696
6697         Parameters:
6698             ide: the element ID
6699             newIDs: nodes IDs
6700
6701         Returns:
6702             False if the number of nodes does not correspond to the type of element
6703         """
6704
6705         return self.editor.ChangeElemNodes(ide, newIDs)
6706
6707     def GetLastCreatedNodes(self):
6708         """
6709         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6710         created, this method return the list of their IDs.
6711         If new nodes were not created - return empty list
6712
6713         Returns:
6714             the list of integer values (can be empty)
6715         """
6716
6717         return self.editor.GetLastCreatedNodes()
6718
6719     def GetLastCreatedElems(self):
6720         """
6721         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6722         created this method return the list of their IDs.
6723         If new elements were not created - return empty list
6724
6725         Returns:
6726             the list of integer values (can be empty)
6727         """
6728
6729         return self.editor.GetLastCreatedElems()
6730
6731     def ClearLastCreated(self):
6732         """
6733         Forget what nodes and elements were created by the last mesh edition operation
6734         """
6735
6736         self.editor.ClearLastCreated()
6737
6738     def DoubleElements(self, theElements, theGroupName=""):
6739         """
6740         Create duplicates of given elements, i.e. create new elements based on the
6741         same nodes as the given ones.
6742
6743         Parameters:
6744             theElements: container of elements to duplicate. It can be a
6745                 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` 
6746                 or a list of element IDs. If *theElements* is
6747                 a :class:`Mesh`, elements of highest dimension are duplicated
6748             theGroupName: a name of group to contain the generated elements.
6749                 If a group with such a name already exists, the new elements
6750                 are added to the existing group, else a new group is created.
6751                 If *theGroupName* is empty, new elements are not added
6752                 in any group.
6753
6754         Returns:
6755                 a :class:`group <SMESH.SMESH_Group>` where the new elements are added. 
6756                 None if *theGroupName* == "".
6757         """
6758
6759         unRegister = genObjUnRegister()
6760         if isinstance( theElements, Mesh ):
6761             theElements = theElements.mesh
6762         elif isinstance( theElements, list ):
6763             theElements = self.GetIDSource( theElements, SMESH.ALL )
6764             unRegister.set( theElements )
6765         return self.editor.DoubleElements(theElements, theGroupName)
6766
6767     def DoubleNodes(self, theNodes, theModifiedElems):
6768         """
6769         Create a hole in a mesh by doubling the nodes of some particular elements
6770
6771         Parameters:
6772             theNodes: IDs of nodes to be doubled
6773             theModifiedElems: IDs of elements to be updated by the new (doubled)
6774                 nodes. If list of element identifiers is empty then nodes are doubled but
6775                 they not assigned to elements
6776
6777         Returns:
6778             True if operation has been completed successfully, False otherwise
6779         """
6780
6781         return self.editor.DoubleNodes(theNodes, theModifiedElems)
6782
6783     def DoubleNode(self, theNodeId, theModifiedElems):
6784         """
6785         Create a hole in a mesh by doubling the nodes of some particular elements.
6786         This method provided for convenience works as :meth:`DoubleNodes`.
6787
6788         Parameters:
6789             theNodeId: IDs of node to double
6790             theModifiedElems: IDs of elements to update
6791
6792         Returns:
6793             True if operation has been completed successfully, False otherwise
6794         """
6795
6796         return self.editor.DoubleNode(theNodeId, theModifiedElems)
6797
6798     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6799         """
6800         Create a hole in a mesh by doubling the nodes of some particular elements.
6801         This method provided for convenience works as :meth:`DoubleNodes`.
6802
6803         Parameters:
6804             theNodes: group of nodes to double.
6805             theModifiedElems: group of elements to update.
6806             theMakeGroup: forces the generation of a group containing new nodes.
6807
6808         Returns:
6809             True or a created group if operation has been completed successfully,
6810             False or None otherwise
6811         """
6812
6813         if theMakeGroup:
6814             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6815         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6816
6817     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6818         """
6819         Create a hole in a mesh by doubling the nodes of some particular elements.
6820         This method provided for convenience works as :meth:`DoubleNodes`.
6821
6822         Parameters:
6823             theNodes: list of groups of nodes to double.
6824             theModifiedElems: list of groups of elements to update.
6825             theMakeGroup: forces the generation of a group containing new nodes.
6826
6827         Returns:
6828             True if operation has been completed successfully, False otherwise
6829         """
6830
6831         if theMakeGroup:
6832             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6833         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6834
6835     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6836         """
6837         Create a hole in a mesh by doubling the nodes of some particular elements
6838
6839         Parameters:
6840             theElems: the list of elements (edges or faces) to replicate.
6841                 The nodes for duplication could be found from these elements
6842             theNodesNot: list of nodes NOT to replicate
6843             theAffectedElems: the list of elements (cells and edges) to which the
6844                 replicated nodes should be associated to
6845
6846         Returns:
6847             True if operation has been completed successfully, False otherwise
6848         """
6849
6850         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6851
6852     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6853         """
6854         Create a hole in a mesh by doubling the nodes of some particular elements
6855
6856         Parameters:
6857             theElems: the list of elements (edges or faces) to replicate.
6858                 The nodes for duplication could be found from these elements
6859             theNodesNot: list of nodes NOT to replicate
6860             theShape: shape to detect affected elements (element which geometric center
6861                 located on or inside shape).
6862                 The replicated nodes should be associated to affected elements.
6863
6864         Returns:
6865             True if operation has been completed successfully, False otherwise
6866         """
6867
6868         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6869
6870     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6871                              theMakeGroup=False, theMakeNodeGroup=False):
6872         """
6873         Create a hole in a mesh by doubling the nodes of some particular elements.
6874         This method provided for convenience works as :meth:`DoubleNodes`.
6875
6876         Parameters:
6877             theElems: group of of elements (edges or faces) to replicate.
6878             theNodesNot: group of nodes NOT to replicate.
6879             theAffectedElems: group of elements to which the replicated nodes
6880                 should be associated to.
6881             theMakeGroup: forces the generation of a group containing new elements.
6882             theMakeNodeGroup: forces the generation of a group containing new nodes.
6883
6884         Returns:
6885             True or created groups (one or two) if operation has been completed successfully,
6886             False or None otherwise
6887         """
6888
6889         if theMakeGroup or theMakeNodeGroup:
6890             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6891                                                             theAffectedElems,
6892                                                             theMakeGroup, theMakeNodeGroup)
6893             if theMakeGroup and theMakeNodeGroup:
6894                 return twoGroups
6895             else:
6896                 return twoGroups[ int(theMakeNodeGroup) ]
6897         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6898
6899     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6900         """
6901         Create a hole in a mesh by doubling the nodes of some particular elements.
6902         This method provided for convenience works as :meth:`DoubleNodes`.
6903
6904         Parameters:
6905             theElems: group of of elements (edges or faces) to replicate
6906             theNodesNot: group of nodes not to replicate
6907             theShape: shape to detect affected elements (element which geometric center
6908                 located on or inside shape).
6909                 The replicated nodes should be associated to affected elements
6910         """
6911
6912         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6913
6914     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6915                              theMakeGroup=False, theMakeNodeGroup=False):
6916         """
6917         Create a hole in a mesh by doubling the nodes of some particular elements.
6918         This method provided for convenience works as :meth:`DoubleNodes`.
6919
6920         Parameters:
6921             theElems: list of groups of elements (edges or faces) to replicate
6922             theNodesNot: list of groups of nodes NOT to replicate
6923             theAffectedElems: group of elements to which the replicated nodes
6924                 should be associated to
6925             theMakeGroup: forces generation of a group containing new elements.
6926             theMakeNodeGroup: forces generation of a group containing new nodes
6927
6928         Returns:
6929             True or created groups (one or two) if operation has been completed successfully,
6930             False or None otherwise
6931         """
6932
6933         if theMakeGroup or theMakeNodeGroup:
6934             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6935                                                              theAffectedElems,
6936                                                              theMakeGroup, theMakeNodeGroup)
6937             if theMakeGroup and theMakeNodeGroup:
6938                 return twoGroups
6939             else:
6940                 return twoGroups[ int(theMakeNodeGroup) ]
6941         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6942
6943     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6944         """
6945         Create a hole in a mesh by doubling the nodes of some particular elements.
6946         This method provided for convenience works as :meth:`DoubleNodes`.
6947
6948         Parameters:
6949             theElems: list of groups of elements (edges or faces) to replicate
6950             theNodesNot: list of groups of nodes NOT to replicate
6951             theShape: shape to detect affected elements (element which geometric center
6952                 located on or inside shape).
6953                 The replicated nodes should be associated to affected elements
6954
6955         Returns:
6956             True if operation has been completed successfully, False otherwise
6957         """
6958
6959         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6960
6961     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6962         """
6963         Identify the elements that will be affected by node duplication (actual duplication is not performed).
6964         This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6965
6966         Parameters:
6967             theElems: list of groups of nodes or elements (edges or faces) to replicate
6968             theNodesNot: list of groups of nodes NOT to replicate
6969             theShape: shape to detect affected elements (element which geometric center
6970                 located on or inside shape).
6971                 The replicated nodes should be associated to affected elements
6972
6973         Returns:
6974             groups of affected elements in order: volumes, faces, edges
6975         """
6976
6977         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6978
6979     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6980
6981         """
6982         Double nodes on shared faces between groups of volumes and create flat elements on demand.
6983         The list of groups must describe a partition of the mesh volumes.
6984         The nodes of the internal faces at the boundaries of the groups are doubled.
6985         In option, the internal faces are replaced by flat elements.
6986         Triangles are transformed to prisms, and quadrangles to hexahedrons.
6987
6988         Parameters:
6989             theDomains: list of groups of volumes
6990             createJointElems: if True, create the elements
6991             onAllBoundaries: if True, the nodes and elements are also created on
6992                 the boundary between *theDomains* and the rest mesh
6993
6994         Returns:
6995             True if operation has been completed successfully, False otherwise
6996         """
6997
6998         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6999
7000     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7001         """
7002         Double nodes on some external faces and create flat elements.
7003         Flat elements are mainly used by some types of mechanic calculations.
7004
7005         Each group of the list must be constituted of faces.
7006         Triangles are transformed in prisms, and quadrangles in hexahedrons.
7007
7008         Parameters:
7009             theGroupsOfFaces: list of groups of faces
7010
7011         Returns:
7012             True if operation has been completed successfully, False otherwise
7013         """
7014
7015         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7016
7017     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7018         """
7019         Identify all the elements around a geom shape, get the faces delimiting the hole
7020         """
7021         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7022
7023     def MakePolyLine(self, segments, groupName='', isPreview=False ):
7024         """    
7025         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7026         the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7027         plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7028         If there are several paths connecting a pair of points, the shortest path is
7029         selected by the module. Position of the cutting plane is defined by the two
7030         points and an optional vector lying on the plane specified by a PolySegment.
7031         By default the vector is defined by Mesh module as following. A middle point
7032         of the two given points is computed. The middle point is projected to the mesh.
7033         The vector goes from the middle point to the projection point. In case of planar
7034         mesh, the vector is normal to the mesh.
7035
7036         In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7037
7038         Parameters:
7039             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7040             groupName: optional name of a group where created mesh segments will be added.
7041
7042         """    
7043         editor = self.editor
7044         if isPreview:
7045             editor = self.mesh.GetMeshEditPreviewer()
7046         segmentsRes = editor.MakePolyLine( segments, groupName )
7047         for i, seg in enumerate( segmentsRes ):
7048             segments[i].vector = seg.vector
7049         if isPreview:
7050             return editor.GetPreviewData()
7051         return None
7052
7053     def MakeSlot(self, segmentGroup, width ):
7054         """
7055         Create a slot of given width around given 1D elements lying on a triangle mesh.
7056         The slot is constructed by cutting faces by cylindrical surfaces made
7057         around each segment. Segments are expected to be created by MakePolyLine().
7058
7059         Returns:
7060                FaceEdge's located at the slot boundary
7061         """
7062         return self.editor.MakeSlot( segmentGroup, width )
7063
7064     def GetFunctor(self, funcType ):
7065         """
7066         Return a cached numerical functor by its type.
7067
7068         Parameters:
7069             funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7070                 Note that not all items correspond to numerical functors.
7071
7072         Returns:
7073             :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7074         """
7075
7076         fn = self.functors[ funcType._v ]
7077         if not fn:
7078             fn = self.smeshpyD.GetFunctor(funcType)
7079             fn.SetMesh(self.mesh)
7080             self.functors[ funcType._v ] = fn
7081         return fn
7082
7083     def FunctorValue(self, funcType, elemId, isElem=True):
7084         """
7085         Return value of a functor for a given element
7086
7087         Parameters:
7088             funcType: an item of :class:`SMESH.FunctorType` enum.
7089             elemId: element or node ID
7090             isElem: *elemId* is ID of element or node
7091
7092         Returns:
7093             the functor value or zero in case of invalid arguments
7094         """
7095
7096         fn = self.GetFunctor( funcType )
7097         if fn.GetElementType() == self.GetElementType(elemId, isElem):
7098             val = fn.GetValue(elemId)
7099         else:
7100             val = 0
7101         return val
7102
7103     def GetLength(self, elemId=None):
7104         """
7105         Get length of given 1D elements or of all 1D mesh elements
7106
7107         Parameters:
7108             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.
7109
7110         Returns:
7111             Sum of lengths of given elements
7112         """
7113
7114         length = 0
7115         if elemId == None:
7116             length = self.smeshpyD.GetLength(self)
7117         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7118             length = self.smeshpyD.GetLength(elemId)
7119         elif elemId == []:
7120             length = 0
7121         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7122             for obj in elemId:
7123                 length += self.smeshpyD.GetLength(obj)
7124         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7125             unRegister = genObjUnRegister()
7126             obj = self.GetIDSource( elemId )
7127             unRegister.set( obj )
7128             length = self.smeshpyD.GetLength( obj )
7129         else:
7130             length = self.FunctorValue(SMESH.FT_Length, elemId)
7131         return length
7132
7133     def GetArea(self, elemId=None):
7134         """
7135         Get area of given 2D elements or of all 2D mesh elements
7136
7137         Parameters:
7138             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.
7139
7140         Returns:
7141             Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7142         """
7143
7144         area = 0
7145         if elemId == None:
7146             area = self.smeshpyD.GetArea(self)
7147         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7148             area = self.smeshpyD.GetArea(elemId)
7149         elif elemId == []:
7150             area = 0
7151         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7152             for obj in elemId:
7153                 area += self.smeshpyD.GetArea(obj)
7154         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7155             unRegister = genObjUnRegister()
7156             obj = self.GetIDSource( elemId )
7157             unRegister.set( obj )
7158             area = self.smeshpyD.GetArea( obj )
7159         else:
7160             area = self.FunctorValue(SMESH.FT_Area, elemId)
7161         return area
7162
7163     def GetVolume(self, elemId=None):
7164         """
7165         Get volume of given 3D elements or of all 3D mesh elements
7166
7167         Parameters:
7168             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.
7169
7170         Returns:
7171             Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7172         """
7173
7174         volume = 0
7175         if elemId == None:
7176             volume= self.smeshpyD.GetVolume(self)
7177         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7178             volume= self.smeshpyD.GetVolume(elemId)
7179         elif elemId == []:
7180             volume = 0
7181         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7182             for obj in elemId:
7183                 volume+= self.smeshpyD.GetVolume(obj)
7184         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7185             unRegister = genObjUnRegister()
7186             obj = self.GetIDSource( elemId )
7187             unRegister.set( obj )
7188             volume= self.smeshpyD.GetVolume( obj )
7189         else:
7190             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7191         return volume
7192
7193     def GetAngle(self, node1, node2, node3 ):
7194         """
7195         Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7196
7197         Parameters:            
7198                 node1,node2,node3: IDs of the three nodes
7199
7200         Returns:        
7201             Angle in radians [0,PI]. -1 if failure case.
7202         """
7203         p1 = self.GetNodeXYZ( node1 )
7204         p2 = self.GetNodeXYZ( node2 )
7205         p3 = self.GetNodeXYZ( node3 )
7206         if p1 and p2 and p3:
7207             return self.smeshpyD.GetAngle( p1,p2,p3 )
7208         return -1.
7209
7210
7211     def GetMaxElementLength(self, elemId):
7212         """
7213         Get maximum element length.
7214
7215         Parameters:
7216             elemId: mesh element ID
7217
7218         Returns:
7219             element's maximum length value
7220         """
7221
7222         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7223             ftype = SMESH.FT_MaxElementLength3D
7224         else:
7225             ftype = SMESH.FT_MaxElementLength2D
7226         return self.FunctorValue(ftype, elemId)
7227
7228     def GetAspectRatio(self, elemId):
7229         """
7230         Get aspect ratio of 2D or 3D element.
7231
7232         Parameters:
7233             elemId: mesh element ID
7234
7235         Returns:
7236             element's aspect ratio value
7237         """
7238
7239         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7240             ftype = SMESH.FT_AspectRatio3D
7241         else:
7242             ftype = SMESH.FT_AspectRatio
7243         return self.FunctorValue(ftype, elemId)
7244
7245     def GetWarping(self, elemId):
7246         """
7247         Get warping angle of 2D element.
7248
7249         Parameters:
7250             elemId: mesh element ID
7251
7252         Returns:
7253             element's warping angle value
7254         """
7255
7256         return self.FunctorValue(SMESH.FT_Warping, elemId)
7257
7258     def GetMinimumAngle(self, elemId):
7259         """
7260         Get minimum angle of 2D element.
7261
7262         Parameters:
7263             elemId: mesh element ID
7264
7265         Returns:
7266             element's minimum angle value
7267         """
7268
7269         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7270
7271     def GetTaper(self, elemId):
7272         """
7273         Get taper of 2D element.
7274
7275         Parameters:
7276             elemId: mesh element ID
7277
7278         Returns:
7279             element's taper value
7280         """
7281
7282         return self.FunctorValue(SMESH.FT_Taper, elemId)
7283
7284     def GetSkew(self, elemId):
7285         """
7286         Get skew of 2D element.
7287
7288         Parameters:
7289             elemId: mesh element ID
7290
7291         Returns:
7292             element's skew value
7293         """
7294
7295         return self.FunctorValue(SMESH.FT_Skew, elemId)
7296
7297     def GetMinMax(self, funType, meshPart=None):
7298         """
7299         Return minimal and maximal value of a given functor.
7300
7301         Parameters:
7302             funType (SMESH.FunctorType): a functor type.
7303                   Note that not all items of :class:`SMESH.FunctorType` corresponds
7304                   to numerical functors.
7305             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7306
7307         Returns:
7308             tuple (min,max)
7309         """
7310
7311         unRegister = genObjUnRegister()
7312         if isinstance( meshPart, list ):
7313             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7314             unRegister.set( meshPart )
7315         if isinstance( meshPart, Mesh ):
7316             meshPart = meshPart.mesh
7317         fun = self.GetFunctor( funType )
7318         if fun:
7319             if meshPart:
7320                 if hasattr( meshPart, "SetMesh" ):
7321                     meshPart.SetMesh( self.mesh ) # set mesh to filter
7322                 hist = fun.GetLocalHistogram( 1, False, meshPart )
7323             else:
7324                 hist = fun.GetHistogram( 1, False )
7325             if hist:
7326                 return hist[0].min, hist[0].max
7327         return None
7328
7329     pass # end of Mesh class
7330
7331
7332 class meshProxy(SMESH._objref_SMESH_Mesh):
7333     """
7334     Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7335     with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7336     """
7337     def __init__(self,*args):
7338         SMESH._objref_SMESH_Mesh.__init__(self,*args)
7339     def __deepcopy__(self, memo=None):
7340         new = self.__class__(self)
7341         return new
7342     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7343         if len( args ) == 3:
7344             args += SMESH.ALL_NODES, True
7345         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7346     def ExportToMEDX(self, *args): # function removed
7347         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7348         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7349         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7350     def ExportToMED(self, *args): # function removed
7351         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7352         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7353         args2 = list(args)
7354         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7355             args2.append(True)
7356         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7357     def ExportPartToMED(self, *args): # 'version' parameter removed
7358         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7359         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7360     def ExportMED(self, *args): # signature of method changed
7361         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7362         args2 = list(args)
7363         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7364             args2.append(True)
7365         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7366     pass
7367 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7368
7369
7370 class submeshProxy(SMESH._objref_SMESH_subMesh):
7371
7372     """
7373     Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7374     """
7375     def __init__(self,*args):
7376         SMESH._objref_SMESH_subMesh.__init__(self,*args)
7377         self.mesh = None
7378     def __deepcopy__(self, memo=None):
7379         new = self.__class__(self)
7380         return new
7381
7382     def Compute(self,refresh=False):
7383         """
7384         Compute the sub-mesh and return the status of the computation
7385
7386         Parameters:
7387             refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7388
7389         Returns:
7390             True or False
7391
7392         This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7393         :meth:`smeshBuilder.Mesh.GetSubMesh`.
7394         """
7395
7396         if not self.mesh:
7397             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7398
7399         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7400
7401         if salome.sg.hasDesktop():
7402             if refresh: salome.sg.updateObjBrowser()
7403             pass
7404
7405         return ok
7406     pass
7407 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7408
7409
7410 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7411     """
7412     Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7413     compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7414     smeshBuilder.Mesh
7415     """
7416     def __init__(self,*args):
7417         SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7418         self.mesh = None
7419     def __getattr__(self, name ): # method called if an attribute not found
7420         if not self.mesh:         # look for name() method in Mesh class
7421             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7422         if hasattr( self.mesh, name ):
7423             return getattr( self.mesh, name )
7424         if name == "ExtrusionAlongPathObjX":
7425             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7426         print("meshEditor: attribute '%s' NOT FOUND" % name)
7427         return None
7428     def __deepcopy__(self, memo=None):
7429         new = self.__class__(self)
7430         return new
7431     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7432         if len( args ) == 1: args += False,
7433         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7434     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7435         if len( args ) == 2: args += False,
7436         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7437     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7438         if len( args ) == 1:
7439             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7440         NodesToKeep = args[1]
7441         AvoidMakingHoles = args[2] if len( args ) == 3 else False
7442         unRegister  = genObjUnRegister()
7443         if NodesToKeep:
7444             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7445                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7446             if not isinstance( NodesToKeep, list ):
7447                 NodesToKeep = [ NodesToKeep ]
7448         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7449     pass
7450 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7451
7452 class Pattern(SMESH._objref_SMESH_Pattern):
7453     """
7454     Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7455     variables in some methods
7456     """
7457
7458     def LoadFromFile(self, patternTextOrFile ):
7459         text = patternTextOrFile
7460         if os.path.exists( text ):
7461             text = open( patternTextOrFile ).read()
7462             pass
7463         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7464
7465     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7466         decrFun = lambda i: i-1
7467         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7468         theMesh.SetParameters(Parameters)
7469         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7470
7471     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7472         decrFun = lambda i: i-1
7473         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7474         theMesh.SetParameters(Parameters)
7475         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7476
7477     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7478         if isinstance( mesh, Mesh ):
7479             mesh = mesh.GetMesh()
7480         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7481
7482 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7483 """
7484 Registering the new proxy for Pattern
7485 """
7486
7487 class algoCreator:
7488     """
7489     Private class used to bind methods creating algorithms to the class Mesh
7490     """
7491
7492     def __init__(self, method):
7493         self.mesh = None
7494         self.defaultAlgoType = ""
7495         self.algoTypeToClass = {}
7496         self.method = method
7497
7498     def add(self, algoClass):
7499         """
7500         Store a python class of algorithm
7501         """
7502         if inspect.isclass(algoClass) and \
7503            hasattr( algoClass, "algoType"):
7504             self.algoTypeToClass[ algoClass.algoType ] = algoClass
7505             if not self.defaultAlgoType and \
7506                hasattr( algoClass, "isDefault") and algoClass.isDefault:
7507                 self.defaultAlgoType = algoClass.algoType
7508             #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7509
7510     def copy(self, mesh):
7511         """
7512         Create a copy of self and assign mesh to the copy
7513         """
7514
7515         other = algoCreator( self.method )
7516         other.defaultAlgoType = self.defaultAlgoType
7517         other.algoTypeToClass = self.algoTypeToClass
7518         other.mesh = mesh
7519         return other
7520
7521     def __call__(self,algo="",geom=0,*args):
7522         """
7523         Create an instance of algorithm
7524         """
7525         algoType = ""
7526         shape = 0
7527         if isinstance( algo, str ):
7528             algoType = algo
7529         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7530                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7531             shape = algo
7532         elif algo:
7533             args += (algo,)
7534
7535         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7536             shape = geom
7537         elif not algoType and isinstance( geom, str ):
7538             algoType = geom
7539         elif geom:
7540             args += (geom,)
7541         for arg in args:
7542             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7543                 shape = arg
7544             elif isinstance( arg, str ) and not algoType:
7545                 algoType = arg
7546             else:
7547                 import traceback, sys
7548                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
7549                 sys.stderr.write( msg + '\n' )
7550                 tb = traceback.extract_stack(None,2)
7551                 traceback.print_list( [tb[0]] )
7552         if not algoType:
7553             algoType = self.defaultAlgoType
7554         if not algoType and self.algoTypeToClass:
7555             algoType = sorted( self.algoTypeToClass.keys() )[0]
7556         if algoType in self.algoTypeToClass:
7557             #print("Create algo",algoType)
7558             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7559         raise RuntimeError( "No class found for algo type %s" % algoType)
7560         return None
7561
7562 class hypMethodWrapper:
7563     """
7564     Private class used to substitute and store variable parameters of hypotheses.
7565     """
7566
7567     def __init__(self, hyp, method):
7568         self.hyp    = hyp
7569         self.method = method
7570         #print("REBIND:", method.__name__)
7571         return
7572
7573     def __call__(self,*args):
7574         """
7575         call a method of hypothesis with calling SetVarParameter() before
7576         """
7577
7578         if not args:
7579             return self.method( self.hyp, *args ) # hypothesis method with no args
7580
7581         #print("MethWrapper.__call__", self.method.__name__, args)
7582         try:
7583             parsed = ParseParameters(*args)     # replace variables with their values
7584             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7585             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7586         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7587             # maybe there is a replaced string arg which is not variable
7588             result = self.method( self.hyp, *args )
7589         except ValueError as detail: # raised by ParseParameters()
7590             try:
7591                 result = self.method( self.hyp, *args )
7592             except omniORB.CORBA.BAD_PARAM:
7593                 raise ValueError(detail) # wrong variable name
7594
7595         return result
7596     pass
7597
7598 class genObjUnRegister:
7599     """
7600     A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7601     """
7602
7603     def __init__(self, genObj=None):
7604         self.genObjList = []
7605         self.set( genObj )
7606         return
7607
7608     def set(self, genObj):
7609         "Store one or a list of of SALOME.GenericObj'es"
7610         if isinstance( genObj, list ):
7611             self.genObjList.extend( genObj )
7612         else:
7613             self.genObjList.append( genObj )
7614         return
7615
7616     def __del__(self):
7617         for genObj in self.genObjList:
7618             if genObj and hasattr( genObj, "UnRegister" ):
7619                 genObj.UnRegister()
7620
7621 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7622     """
7623     Bind methods creating mesher plug-ins to the Mesh class
7624     """
7625
7626     # print("pluginName: ", pluginName)
7627     pluginBuilderName = pluginName + "Builder"
7628     try:
7629         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7630     except Exception as e:
7631         from salome_utils import verbose
7632         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7633         continue
7634     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7635     plugin = eval( pluginBuilderName )
7636     # print("  plugin:" , str(plugin))
7637
7638     # add methods creating algorithms to Mesh
7639     for k in dir( plugin ):
7640         if k[0] == '_': continue
7641         algo = getattr( plugin, k )
7642         #print("             algo:", str(algo))
7643         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7644             #print("                     meshMethod:" , str(algo.meshMethod))
7645             if not hasattr( Mesh, algo.meshMethod ):
7646                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7647                 pass
7648             _mmethod = getattr( Mesh, algo.meshMethod )
7649             if hasattr(  _mmethod, "add" ):
7650                 _mmethod.add(algo)
7651             pass
7652         pass
7653     pass
7654 del pluginName