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