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