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