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