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