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