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