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