Salome HOME
23617: EDF 14133 - Complete Merge Nodes / Merge Elements operations
[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         if not IDsOfElements:
5684             IDsOfElements = [ self.GetMesh() ]
5685         n,e,f = [],IDsOfElements,IDsOfElements
5686         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5687                                                NodeStart, HasAngles, Angles,
5688                                                LinearVariation,
5689                                                HasRefPoint, RefPoint, MakeGroups)
5690         if MakeGroups: return gr,er
5691         return er
5692
5693     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5694                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5695                                  MakeGroups=False, LinearVariation=False):
5696         """
5697         Generate new elements by extrusion of the elements which belong to the object.
5698         The path of extrusion must be a meshed edge.
5699
5700         Parameters:
5701             theObject: the object whose elements should be processed.
5702                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5703             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5704             PathShape: shape (edge) defines the sub-mesh for the path
5705             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5706             HasAngles: allows the shape to be rotated around the path
5707                 to get the resulting mesh in a helical fashion
5708             Angles: list of angles
5709             HasRefPoint: allows using the reference point
5710             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5711                 The User can specify any point as the Reference Point.
5712                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5713             MakeGroups: forces the generation of new groups from existing ones
5714             LinearVariation: forces the computation of rotation angles as linear
5715                 variation of the given Angles along path steps
5716
5717         Returns:
5718             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5719             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5720             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5721         Example: :ref:`tui_extrusion_along_path`
5722         """
5723
5724         n,e,f = [],theObject,theObject
5725         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5726                                                HasAngles, Angles, LinearVariation,
5727                                                HasRefPoint, RefPoint, MakeGroups)
5728         if MakeGroups: return gr,er
5729         return er
5730
5731     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5732                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5733                                    MakeGroups=False, LinearVariation=False):
5734         """
5735         Generate new elements by extrusion of mesh segments which belong to the object.
5736         The path of extrusion must be a meshed edge.
5737
5738         Parameters:
5739             theObject: the object whose 1D elements should be processed.
5740                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5741             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5742             PathShape: shape (edge) defines the sub-mesh for the path
5743             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5744             HasAngles: allows the shape to be rotated around the path
5745                 to get the resulting mesh in a helical fashion
5746             Angles: list of angles
5747             HasRefPoint: allows using the reference point
5748             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
5749                 The User can specify any point as the Reference Point.
5750                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5751             MakeGroups: forces the generation of new groups from existing ones
5752             LinearVariation: forces the computation of rotation angles as linear
5753                 variation of the given Angles along path steps
5754
5755         Returns:
5756             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5757             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5758             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5759         Example: :ref:`tui_extrusion_along_path`
5760         """
5761
5762         n,e,f = [],theObject,[]
5763         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5764                                                HasAngles, Angles, LinearVariation,
5765                                                HasRefPoint, RefPoint, MakeGroups)
5766         if MakeGroups: return gr,er
5767         return er
5768
5769     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
5770                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5771                                    MakeGroups=False, LinearVariation=False):
5772         """
5773         Generate new elements by extrusion of faces which belong to the object.
5774         The path of extrusion must be a meshed edge.
5775
5776         Parameters:
5777             theObject: the object whose 2D elements should be processed.
5778                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5779             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5780             PathShape: shape (edge) defines the sub-mesh for the path
5781             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5782             HasAngles: allows the shape to be rotated around the path
5783                 to get the resulting mesh in a helical fashion
5784             Angles: list of angles
5785             HasRefPoint: allows using the reference point
5786             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5787                 The User can specify any point as the Reference Point.
5788                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5789             MakeGroups: forces the generation of new groups from existing ones
5790             LinearVariation: forces the computation of rotation angles as linear
5791                 variation of the given Angles along path steps
5792
5793         Returns:
5794             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5795             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5796             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5797         Example: :ref:`tui_extrusion_along_path`
5798         """
5799
5800         n,e,f = [],[],theObject
5801         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5802                                                HasAngles, Angles, LinearVariation,
5803                                                HasRefPoint, RefPoint, MakeGroups)
5804         if MakeGroups: return gr,er
5805         return er
5806
5807     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5808         """
5809         Create a symmetrical copy of mesh elements
5810
5811         Parameters:
5812             IDsOfElements: list of elements ids
5813             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5814             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5815                 If the *Mirror* is a geom object this parameter is unnecessary
5816             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
5817             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5818
5819         Returns:
5820             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5821         """
5822
5823         if IDsOfElements == []:
5824             IDsOfElements = self.GetElementsId()
5825         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5826             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5827             theMirrorType = Mirror._mirrorType
5828         else:
5829             self.mesh.SetParameters(Mirror.parameters)
5830         if Copy and MakeGroups:
5831             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
5832         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
5833         return []
5834
5835     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
5836         """
5837         Create a new mesh by a symmetrical copy of mesh elements
5838
5839         Parameters:
5840             IDsOfElements: the list of elements ids
5841             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5842             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5843                 If the *Mirror* is a geom object this parameter is unnecessary
5844             MakeGroups: to generate new groups from existing ones
5845             NewMeshName: a name of the new mesh to create
5846
5847         Returns:
5848             instance of class :class:`Mesh`
5849         """
5850
5851         if IDsOfElements == []:
5852             IDsOfElements = self.GetElementsId()
5853         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5854             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5855             theMirrorType = Mirror._mirrorType
5856         else:
5857             self.mesh.SetParameters(Mirror.parameters)
5858         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
5859                                           MakeGroups, NewMeshName)
5860         return Mesh(self.smeshpyD,self.geompyD,mesh)
5861
5862     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
5863         """
5864         Create a symmetrical copy of the object
5865
5866         Parameters:
5867             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5868             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5869             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5870                 If the *Mirror* is a geom object this parameter is unnecessary
5871             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
5872             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5873
5874         Returns:
5875             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5876         """
5877
5878         if ( isinstance( theObject, Mesh )):
5879             theObject = theObject.GetMesh()
5880         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5881             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5882             theMirrorType = Mirror._mirrorType
5883         else:
5884             self.mesh.SetParameters(Mirror.parameters)
5885         if Copy and MakeGroups:
5886             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
5887         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
5888         return []
5889
5890     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
5891         """
5892         Create a new mesh by a symmetrical copy of the object
5893
5894         Parameters:
5895             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5896             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
5897             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
5898                 If the *Mirror* is a geom object this parameter is unnecessary
5899             MakeGroups: forces the generation of new groups from existing ones
5900             NewMeshName: the name of the new mesh to create
5901
5902         Returns:
5903             instance of class :class:`Mesh`
5904         """
5905
5906         if ( isinstance( theObject, Mesh )):
5907             theObject = theObject.GetMesh()
5908         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
5909             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
5910             theMirrorType = Mirror._mirrorType
5911         else:
5912             self.mesh.SetParameters(Mirror.parameters)
5913         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
5914                                                 MakeGroups, NewMeshName)
5915         return Mesh( self.smeshpyD,self.geompyD,mesh )
5916
5917     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
5918         """
5919         Translate the elements
5920
5921         Parameters:
5922             IDsOfElements: list of elements ids
5923             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5924             Copy: allows copying the translated elements
5925             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5926
5927         Returns:
5928             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5929         """
5930
5931         if IDsOfElements == []:
5932             IDsOfElements = self.GetElementsId()
5933         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5934             Vector = self.smeshpyD.GetDirStruct(Vector)
5935         if isinstance( Vector, list ):
5936             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5937         self.mesh.SetParameters(Vector.PS.parameters)
5938         if Copy and MakeGroups:
5939             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
5940         self.editor.Translate(IDsOfElements, Vector, Copy)
5941         return []
5942
5943     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
5944         """
5945         Create a new mesh of translated elements
5946
5947         Parameters:
5948             IDsOfElements: list of elements ids
5949             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
5950             MakeGroups: forces the generation of new groups from existing ones
5951             NewMeshName: the name of the newly created mesh
5952
5953         Returns:
5954             instance of class :class:`Mesh`
5955         """
5956
5957         if IDsOfElements == []:
5958             IDsOfElements = self.GetElementsId()
5959         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5960             Vector = self.smeshpyD.GetDirStruct(Vector)
5961         if isinstance( Vector, list ):
5962             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5963         self.mesh.SetParameters(Vector.PS.parameters)
5964         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
5965         return Mesh ( self.smeshpyD, self.geompyD, mesh )
5966
5967     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
5968         """
5969         Translate the object
5970
5971         Parameters:
5972             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5973             Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
5974             Copy: allows copying the translated elements
5975             MakeGroups: forces the generation of new groups from existing ones (if Copy)
5976
5977         Returns:
5978             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5979         """
5980
5981         if ( isinstance( theObject, Mesh )):
5982             theObject = theObject.GetMesh()
5983         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
5984             Vector = self.smeshpyD.GetDirStruct(Vector)
5985         if isinstance( Vector, list ):
5986             Vector = self.smeshpyD.MakeDirStruct(*Vector)
5987         self.mesh.SetParameters(Vector.PS.parameters)
5988         if Copy and MakeGroups:
5989             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
5990         self.editor.TranslateObject(theObject, Vector, Copy)
5991         return []
5992
5993     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
5994         """
5995         Create a new mesh from the translated object
5996
5997         Parameters:
5998             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
5999             Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6000             MakeGroups: forces the generation of new groups from existing ones
6001             NewMeshName: the name of the newly created mesh
6002
6003         Returns:
6004             instance of class :class:`Mesh`
6005         """
6006
6007         if isinstance( theObject, Mesh ):
6008             theObject = theObject.GetMesh()
6009         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6010             Vector = self.smeshpyD.GetDirStruct(Vector)
6011         if isinstance( Vector, list ):
6012             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6013         self.mesh.SetParameters(Vector.PS.parameters)
6014         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6015         return Mesh( self.smeshpyD, self.geompyD, mesh )
6016
6017
6018
6019     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6020         """
6021         Scale the object
6022
6023         Parameters:
6024             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6025             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6026             theScaleFact: list of 1-3 scale factors for axises
6027             Copy: allows copying the translated elements
6028             MakeGroups: forces the generation of new groups from existing
6029                 ones (if Copy)
6030
6031         Returns:
6032             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6033             empty list otherwise
6034         """
6035         unRegister = genObjUnRegister()
6036         if ( isinstance( theObject, Mesh )):
6037             theObject = theObject.GetMesh()
6038         if ( isinstance( theObject, list )):
6039             theObject = self.GetIDSource(theObject, SMESH.ALL)
6040             unRegister.set( theObject )
6041         if ( isinstance( thePoint, list )):
6042             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6043         if ( isinstance( theScaleFact, float )):
6044             theScaleFact = [theScaleFact]
6045         if ( isinstance( theScaleFact, int )):
6046             theScaleFact = [ float(theScaleFact)]
6047
6048         self.mesh.SetParameters(thePoint.parameters)
6049
6050         if Copy and MakeGroups:
6051             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6052         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6053         return []
6054
6055     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6056         """
6057         Create a new mesh from the translated object
6058
6059         Parameters:
6060             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6061             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6062             theScaleFact: list of 1-3 scale factors for axises
6063             MakeGroups: forces the generation of new groups from existing ones
6064             NewMeshName: the name of the newly created mesh
6065
6066         Returns:
6067             instance of class :class:`Mesh`
6068         """
6069         unRegister = genObjUnRegister()
6070         if (isinstance(theObject, Mesh)):
6071             theObject = theObject.GetMesh()
6072         if ( isinstance( theObject, list )):
6073             theObject = self.GetIDSource(theObject,SMESH.ALL)
6074             unRegister.set( theObject )
6075         if ( isinstance( thePoint, list )):
6076             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6077         if ( isinstance( theScaleFact, float )):
6078             theScaleFact = [theScaleFact]
6079         if ( isinstance( theScaleFact, int )):
6080             theScaleFact = [ float(theScaleFact)]
6081
6082         self.mesh.SetParameters(thePoint.parameters)
6083         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6084                                          MakeGroups, NewMeshName)
6085         return Mesh( self.smeshpyD, self.geompyD, mesh )
6086
6087
6088
6089     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6090         """
6091         Rotate the elements
6092
6093         Parameters:
6094             IDsOfElements: list of elements ids
6095             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6096             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6097             Copy: allows copying the rotated elements
6098             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6099
6100         Returns:
6101             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6102         """
6103
6104
6105         if IDsOfElements == []:
6106             IDsOfElements = self.GetElementsId()
6107         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6108             Axis = self.smeshpyD.GetAxisStruct(Axis)
6109         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6110         Parameters = Axis.parameters + var_separator + Parameters
6111         self.mesh.SetParameters(Parameters)
6112         if Copy and MakeGroups:
6113             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6114         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6115         return []
6116
6117     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6118         """
6119         Create a new mesh of rotated elements
6120
6121         Parameters:
6122             IDsOfElements: list of element ids
6123             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6124             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6125             MakeGroups: forces the generation of new groups from existing ones
6126             NewMeshName: the name of the newly created mesh
6127
6128         Returns:
6129             instance of class :class:`Mesh`
6130         """
6131
6132         if IDsOfElements == []:
6133             IDsOfElements = self.GetElementsId()
6134         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6135             Axis = self.smeshpyD.GetAxisStruct(Axis)
6136         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6137         Parameters = Axis.parameters + var_separator + Parameters
6138         self.mesh.SetParameters(Parameters)
6139         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6140                                           MakeGroups, NewMeshName)
6141         return Mesh( self.smeshpyD, self.geompyD, mesh )
6142
6143     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6144         """
6145         Rotate the object
6146
6147         Parameters:
6148             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6149             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6150             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6151             Copy: allows copying the rotated elements
6152             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6153
6154         Returns:
6155             list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6156         """
6157
6158         if (isinstance(theObject, Mesh)):
6159             theObject = theObject.GetMesh()
6160         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6161             Axis = self.smeshpyD.GetAxisStruct(Axis)
6162         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6163         Parameters = Axis.parameters + ":" + Parameters
6164         self.mesh.SetParameters(Parameters)
6165         if Copy and MakeGroups:
6166             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6167         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6168         return []
6169
6170     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6171         """
6172         Create a new mesh from the rotated object
6173
6174         Parameters:
6175             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6176             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6177             AngleInRadians: the angle of rotation (in radians)  or a name of variable which defines angle in degrees
6178             MakeGroups: forces the generation of new groups from existing ones
6179             NewMeshName: the name of the newly created mesh
6180
6181         Returns:
6182             instance of class :class:`Mesh`
6183         """
6184
6185         if (isinstance( theObject, Mesh )):
6186             theObject = theObject.GetMesh()
6187         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6188             Axis = self.smeshpyD.GetAxisStruct(Axis)
6189         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6190         Parameters = Axis.parameters + ":" + Parameters
6191         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6192                                                        MakeGroups, NewMeshName)
6193         self.mesh.SetParameters(Parameters)
6194         return Mesh( self.smeshpyD, self.geompyD, mesh )
6195
6196     def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6197         """
6198         Create an offset mesh from the given 2D object
6199
6200         Parameters:
6201             theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6202             theValue (float): signed offset size
6203             MakeGroups (boolean): forces the generation of new groups from existing ones
6204             CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, 
6205                           False means to remove original elements.
6206             NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6207
6208         Returns:
6209             A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6210         """
6211
6212         if isinstance( theObject, Mesh ):
6213             theObject = theObject.GetMesh()
6214         theValue,Parameters,hasVars = ParseParameters(Value)
6215         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6216         self.mesh.SetParameters(Parameters)
6217         # if mesh_groups[0]:
6218         #     return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6219         return mesh_groups
6220
6221     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6222         """
6223         Find groups of adjacent nodes within Tolerance.
6224
6225         Parameters:
6226             Tolerance (float): the value of tolerance
6227             SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6228                 corner and medium nodes in separate groups thus preventing
6229                 their further merge.
6230
6231         Returns:
6232             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6233         """
6234
6235         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6236
6237     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6238                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
6239         """
6240         Find groups of adjacent nodes within Tolerance.
6241
6242         Parameters:
6243             Tolerance: the value of tolerance
6244             SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6245             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6246             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6247                 corner and medium nodes in separate groups thus preventing
6248                 their further merge.
6249
6250         Returns:
6251             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6252         """
6253
6254         unRegister = genObjUnRegister()
6255         if not isinstance( SubMeshOrGroup, list ):
6256             SubMeshOrGroup = [ SubMeshOrGroup ]
6257         for i,obj in enumerate( SubMeshOrGroup ):
6258             if isinstance( obj, Mesh ):
6259                 SubMeshOrGroup = [ obj.GetMesh() ]
6260                 break
6261             if isinstance( obj, int ):
6262                 SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE )
6263                 unRegister.set( SubMeshOrGroup )
6264                 break
6265
6266         if not isinstance( exceptNodes, list ):
6267             exceptNodes = [ exceptNodes ]
6268         if exceptNodes and isinstance( exceptNodes[0], int ):
6269             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6270             unRegister.set( exceptNodes )
6271
6272         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6273                                                         exceptNodes, SeparateCornerAndMediumNodes)
6274
6275     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6276         """
6277         Merge nodes
6278
6279         Parameters:
6280             GroupsOfNodes: a list of groups of nodes IDs for merging.
6281                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6282                 in all elements and mesh groups by nodes 1 and 25 correspondingly
6283             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6284                 If *NodesToKeep* does not include a node to keep for some group to merge,
6285                 then the first node in the group is kept.
6286             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6287                 invalid
6288         """
6289         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6290
6291     def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6292         """
6293         Find the elements built on the same nodes.
6294
6295         Parameters:
6296             MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6297             exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6298
6299
6300         Returns:
6301             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6302         """
6303
6304         unRegister = genObjUnRegister()
6305         if MeshOrSubMeshOrGroup is None:
6306             MeshOrSubMeshOrGroup = [ self.mesh ]
6307         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6308             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6309         elif not isinstance( MeshOrSubMeshOrGroup, list ):
6310             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6311         if isinstance( MeshOrSubMeshOrGroup[0], int ):
6312             MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6313             unRegister.set( MeshOrSubMeshOrGroup )
6314         for item in MeshOrSubMeshOrGroup:
6315             if isinstance( item, Mesh ):
6316                 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6317
6318         if not isinstance( exceptElements, list ):
6319             exceptElements = [ exceptElements ]
6320         if exceptElements and isinstance( exceptElements[0], int ):
6321             exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6322             unRegister.set( exceptElements )
6323
6324         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6325
6326     def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6327         """
6328         Merge elements in each given group.
6329
6330         Parameters:
6331             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6332                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6333                 replaced in all mesh groups by elements 1 and 25)
6334             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6335                 If *ElementsToKeep* does not include an element to keep for some group to merge,
6336                 then the first element in the group is kept.
6337         """
6338
6339         unRegister = genObjUnRegister()
6340         if ElementsToKeep:
6341             if not isinstance( ElementsToKeep, list ):
6342                 ElementsToKeep = [ ElementsToKeep ]
6343             if isinstance( ElementsToKeep[0], int ):
6344                 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6345                 unRegister.set( ElementsToKeep )
6346
6347         self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6348
6349     def MergeEqualElements(self):
6350         """
6351         Leave one element and remove all other elements built on the same nodes.
6352         """
6353
6354         self.editor.MergeEqualElements()
6355
6356     def FindFreeBorders(self, ClosedOnly=True):
6357         """
6358         Returns all or only closed free borders
6359
6360         Returns:
6361             list of SMESH.FreeBorder's
6362         """
6363
6364         return self.editor.FindFreeBorders( ClosedOnly )
6365
6366     def FillHole(self, holeNodes, groupName=""):
6367         """
6368         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6369
6370         Parameters:
6371             holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6372                 must describe all sequential nodes of the hole border. The first and the last
6373                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6374             groupName (string): name of a group to add new faces
6375         Returns:
6376             a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6377         """
6378
6379
6380         if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6381             holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6382         if not isinstance( holeNodes, SMESH.FreeBorder ):
6383             raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6384         self.editor.FillHole( holeNodes, groupName )
6385
6386     def FindCoincidentFreeBorders (self, tolerance=0.):
6387         """
6388         Return groups of FreeBorder's coincident within the given tolerance.
6389
6390         Parameters:
6391             tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6392                 size of elements adjacent to free borders being compared is used.
6393
6394         Returns:
6395             SMESH.CoincidentFreeBorders structure
6396         """
6397
6398         return self.editor.FindCoincidentFreeBorders( tolerance )
6399
6400     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6401         """
6402         Sew FreeBorder's of each group
6403
6404         Parameters:
6405             freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6406                 where each enclosed list contains node IDs of a group of coincident free
6407                 borders such that each consequent triple of IDs within a group describes
6408                 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6409                 last node of a border.
6410                 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6411                 groups of coincident free borders, each group including two borders.
6412             createPolygons: if :code:`True` faces adjacent to free borders are converted to
6413                 polygons if a node of opposite border falls on a face edge, else such
6414                 faces are split into several ones.
6415             createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6416                 polyhedra if a node of opposite border falls on a volume edge, else such
6417                 volumes, if any, remain intact and the mesh becomes non-conformal.
6418
6419         Returns:
6420             a number of successfully sewed groups
6421         """
6422
6423         if freeBorders and isinstance( freeBorders, list ):
6424             # construct SMESH.CoincidentFreeBorders
6425             if isinstance( freeBorders[0], int ):
6426                 freeBorders = [freeBorders]
6427             borders = []
6428             coincidentGroups = []
6429             for nodeList in freeBorders:
6430                 if not nodeList or len( nodeList ) % 3:
6431                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6432                 group = []
6433                 while nodeList:
6434                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6435                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
6436                     nodeList = nodeList[3:]
6437                     pass
6438                 coincidentGroups.append( group )
6439                 pass
6440             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6441
6442         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6443
6444     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6445                         FirstNodeID2, SecondNodeID2, LastNodeID2,
6446                         CreatePolygons, CreatePolyedrs):
6447         """
6448         Sew free borders
6449
6450         Returns:
6451             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6452         """
6453
6454         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6455                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
6456                                           CreatePolygons, CreatePolyedrs)
6457
6458     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6459                                FirstNodeID2, SecondNodeID2):
6460         """
6461         Sew conform free borders
6462
6463         Returns:
6464             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6465         """
6466
6467         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6468                                                  FirstNodeID2, SecondNodeID2)
6469
6470     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6471                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6472         """
6473         Sew border to side
6474
6475         Returns:
6476             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6477         """
6478
6479         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6480                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6481
6482     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6483                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6484                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6485         """
6486         Sew two sides of a mesh. The nodes belonging to Side1 are
6487         merged with the nodes of elements of Side2.
6488         The number of elements in theSide1 and in theSide2 must be
6489         equal and they should have similar nodal connectivity.
6490         The nodes to merge should belong to side borders and
6491         the first node should be linked to the second.
6492
6493         Returns:
6494             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6495         """
6496
6497         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6498                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6499                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6500
6501     def ChangeElemNodes(self, ide, newIDs):
6502         """
6503         Set new nodes for the given element.
6504
6505         Parameters:
6506             ide: the element ID
6507             newIDs: nodes IDs
6508
6509         Returns:
6510             False if the number of nodes does not correspond to the type of element
6511         """
6512
6513         return self.editor.ChangeElemNodes(ide, newIDs)
6514
6515     def GetLastCreatedNodes(self):
6516         """
6517         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6518         created, this method return the list of their IDs.
6519         If new nodes were not created - return empty list
6520
6521         Returns:
6522             the list of integer values (can be empty)
6523         """
6524
6525         return self.editor.GetLastCreatedNodes()
6526
6527     def GetLastCreatedElems(self):
6528         """
6529         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6530         created this method return the list of their IDs.
6531         If new elements were not created - return empty list
6532
6533         Returns:
6534             the list of integer values (can be empty)
6535         """
6536
6537         return self.editor.GetLastCreatedElems()
6538
6539     def ClearLastCreated(self):
6540         """
6541         Forget what nodes and elements were created by the last mesh edition operation
6542         """
6543
6544         self.editor.ClearLastCreated()
6545
6546     def DoubleElements(self, theElements, theGroupName=""):
6547         """
6548         Create duplicates of given elements, i.e. create new elements based on the
6549         same nodes as the given ones.
6550
6551         Parameters:
6552             theElements: container of elements to duplicate. It can be a
6553                 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` 
6554                 or a list of element IDs. If *theElements* is
6555                 a :class:`Mesh`, elements of highest dimension are duplicated
6556             theGroupName: a name of group to contain the generated elements.
6557                 If a group with such a name already exists, the new elements
6558                 are added to the existing group, else a new group is created.
6559                 If *theGroupName* is empty, new elements are not added
6560                 in any group.
6561
6562         Returns:
6563                 a :class:`group <SMESH.SMESH_Group>` where the new elements are added. 
6564                 None if *theGroupName* == "".
6565         """
6566
6567         unRegister = genObjUnRegister()
6568         if isinstance( theElements, Mesh ):
6569             theElements = theElements.mesh
6570         elif isinstance( theElements, list ):
6571             theElements = self.GetIDSource( theElements, SMESH.ALL )
6572             unRegister.set( theElements )
6573         return self.editor.DoubleElements(theElements, theGroupName)
6574
6575     def DoubleNodes(self, theNodes, theModifiedElems):
6576         """
6577         Create a hole in a mesh by doubling the nodes of some particular elements
6578
6579         Parameters:
6580             theNodes: IDs of nodes to be doubled
6581             theModifiedElems: IDs of elements to be updated by the new (doubled)
6582                 nodes. If list of element identifiers is empty then nodes are doubled but
6583                 they not assigned to elements
6584
6585         Returns:
6586             True if operation has been completed successfully, False otherwise
6587         """
6588
6589         return self.editor.DoubleNodes(theNodes, theModifiedElems)
6590
6591     def DoubleNode(self, theNodeId, theModifiedElems):
6592         """
6593         Create a hole in a mesh by doubling the nodes of some particular elements.
6594         This method provided for convenience works as :meth:`DoubleNodes`.
6595
6596         Parameters:
6597             theNodeId: IDs of node to double
6598             theModifiedElems: IDs of elements to update
6599
6600         Returns:
6601             True if operation has been completed successfully, False otherwise
6602         """
6603
6604         return self.editor.DoubleNode(theNodeId, theModifiedElems)
6605
6606     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6607         """
6608         Create a hole in a mesh by doubling the nodes of some particular elements.
6609         This method provided for convenience works as :meth:`DoubleNodes`.
6610
6611         Parameters:
6612             theNodes: group of nodes to double.
6613             theModifiedElems: group of elements to update.
6614             theMakeGroup: forces the generation of a group containing new nodes.
6615
6616         Returns:
6617             True or a created group if operation has been completed successfully,
6618             False or None otherwise
6619         """
6620
6621         if theMakeGroup:
6622             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6623         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6624
6625     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6626         """
6627         Create a hole in a mesh by doubling the nodes of some particular elements.
6628         This method provided for convenience works as :meth:`DoubleNodes`.
6629
6630         Parameters:
6631             theNodes: list of groups of nodes to double.
6632             theModifiedElems: list of groups of elements to update.
6633             theMakeGroup: forces the generation of a group containing new nodes.
6634
6635         Returns:
6636             True if operation has been completed successfully, False otherwise
6637         """
6638
6639         if theMakeGroup:
6640             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6641         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6642
6643     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6644         """
6645         Create a hole in a mesh by doubling the nodes of some particular elements
6646
6647         Parameters:
6648             theElems: the list of elements (edges or faces) to replicate.
6649                 The nodes for duplication could be found from these elements
6650             theNodesNot: list of nodes NOT to replicate
6651             theAffectedElems: the list of elements (cells and edges) to which the
6652                 replicated nodes should be associated to
6653
6654         Returns:
6655             True if operation has been completed successfully, False otherwise
6656         """
6657
6658         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6659
6660     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6661         """
6662         Create a hole in a mesh by doubling the nodes of some particular elements
6663
6664         Parameters:
6665             theElems: the list of elements (edges or faces) to replicate.
6666                 The nodes for duplication could be found from these elements
6667             theNodesNot: list of nodes NOT to replicate
6668             theShape: shape to detect affected elements (element which geometric center
6669                 located on or inside shape).
6670                 The replicated nodes should be associated to affected elements.
6671
6672         Returns:
6673             True if operation has been completed successfully, False otherwise
6674         """
6675
6676         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6677
6678     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6679                              theMakeGroup=False, theMakeNodeGroup=False):
6680         """
6681         Create a hole in a mesh by doubling the nodes of some particular elements.
6682         This method provided for convenience works as :meth:`DoubleNodes`.
6683
6684         Parameters:
6685             theElems: group of of elements (edges or faces) to replicate.
6686             theNodesNot: group of nodes NOT to replicate.
6687             theAffectedElems: group of elements to which the replicated nodes
6688                 should be associated to.
6689             theMakeGroup: forces the generation of a group containing new elements.
6690             theMakeNodeGroup: forces the generation of a group containing new nodes.
6691
6692         Returns:
6693             True or created groups (one or two) if operation has been completed successfully,
6694             False or None otherwise
6695         """
6696
6697         if theMakeGroup or theMakeNodeGroup:
6698             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6699                                                             theAffectedElems,
6700                                                             theMakeGroup, theMakeNodeGroup)
6701             if theMakeGroup and theMakeNodeGroup:
6702                 return twoGroups
6703             else:
6704                 return twoGroups[ int(theMakeNodeGroup) ]
6705         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6706
6707     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6708         """
6709         Create a hole in a mesh by doubling the nodes of some particular elements.
6710         This method provided for convenience works as :meth:`DoubleNodes`.
6711
6712         Parameters:
6713             theElems: group of of elements (edges or faces) to replicate
6714             theNodesNot: group of nodes not to replicate
6715             theShape: shape to detect affected elements (element which geometric center
6716                 located on or inside shape).
6717                 The replicated nodes should be associated to affected elements
6718         """
6719
6720         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
6721
6722     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
6723                              theMakeGroup=False, theMakeNodeGroup=False):
6724         """
6725         Create a hole in a mesh by doubling the nodes of some particular elements.
6726         This method provided for convenience works as :meth:`DoubleNodes`.
6727
6728         Parameters:
6729             theElems: list of groups of elements (edges or faces) to replicate
6730             theNodesNot: list of groups of nodes NOT to replicate
6731             theAffectedElems: group of elements to which the replicated nodes
6732                 should be associated to
6733             theMakeGroup: forces generation of a group containing new elements.
6734             theMakeNodeGroup: forces generation of a group containing new nodes
6735
6736         Returns:
6737             True or created groups (one or two) if operation has been completed successfully,
6738             False or None otherwise
6739         """
6740
6741         if theMakeGroup or theMakeNodeGroup:
6742             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
6743                                                              theAffectedElems,
6744                                                              theMakeGroup, theMakeNodeGroup)
6745             if theMakeGroup and theMakeNodeGroup:
6746                 return twoGroups
6747             else:
6748                 return twoGroups[ int(theMakeNodeGroup) ]
6749         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
6750
6751     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6752         """
6753         Create a hole in a mesh by doubling the nodes of some particular elements.
6754         This method provided for convenience works as :meth:`DoubleNodes`.
6755
6756         Parameters:
6757             theElems: list of groups of elements (edges or faces) to replicate
6758             theNodesNot: list of groups of nodes NOT to replicate
6759             theShape: shape to detect affected elements (element which geometric center
6760                 located on or inside shape).
6761                 The replicated nodes should be associated to affected elements
6762
6763         Returns:
6764             True if operation has been completed successfully, False otherwise
6765         """
6766
6767         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
6768
6769     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
6770         """
6771         Identify the elements that will be affected by node duplication (actual duplication is not performed).
6772         This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
6773
6774         Parameters:
6775             theElems: list of groups of nodes or elements (edges or faces) to replicate
6776             theNodesNot: list of groups of nodes NOT to replicate
6777             theShape: shape to detect affected elements (element which geometric center
6778                 located on or inside shape).
6779                 The replicated nodes should be associated to affected elements
6780
6781         Returns:
6782             groups of affected elements in order: volumes, faces, edges
6783         """
6784
6785         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
6786
6787     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
6788
6789         """
6790         Double nodes on shared faces between groups of volumes and create flat elements on demand.
6791         The list of groups must describe a partition of the mesh volumes.
6792         The nodes of the internal faces at the boundaries of the groups are doubled.
6793         In option, the internal faces are replaced by flat elements.
6794         Triangles are transformed to prisms, and quadrangles to hexahedrons.
6795
6796         Parameters:
6797             theDomains: list of groups of volumes
6798             createJointElems: if True, create the elements
6799             onAllBoundaries: if True, the nodes and elements are also created on
6800                 the boundary between *theDomains* and the rest mesh
6801
6802         Returns:
6803             True if operation has been completed successfully, False otherwise
6804         """
6805
6806         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
6807
6808     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
6809         """
6810         Double nodes on some external faces and create flat elements.
6811         Flat elements are mainly used by some types of mechanic calculations.
6812
6813         Each group of the list must be constituted of faces.
6814         Triangles are transformed in prisms, and quadrangles in hexahedrons.
6815
6816         Parameters:
6817             theGroupsOfFaces: list of groups of faces
6818
6819         Returns:
6820             True if operation has been completed successfully, False otherwise
6821         """
6822
6823         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
6824
6825     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
6826         """
6827         Identify all the elements around a geom shape, get the faces delimiting the hole
6828         """
6829         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
6830
6831     def MakePolyLine(self, segments, groupName='', isPreview=False ):
6832         """    
6833         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
6834         the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
6835         plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
6836         If there are several paths connecting a pair of points, the shortest path is
6837         selected by the module. Position of the cutting plane is defined by the two
6838         points and an optional vector lying on the plane specified by a PolySegment.
6839         By default the vector is defined by Mesh module as following. A middle point
6840         of the two given points is computed. The middle point is projected to the mesh.
6841         The vector goes from the middle point to the projection point. In case of planar
6842         mesh, the vector is normal to the mesh.
6843
6844         In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
6845
6846         Parameters:
6847             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
6848             groupName: optional name of a group where created mesh segments will be added.
6849
6850         """    
6851         editor = self.editor
6852         if isPreview:
6853             editor = self.mesh.GetMeshEditPreviewer()
6854         segmentsRes = editor.MakePolyLine( segments, groupName )
6855         for i, seg in enumerate( segmentsRes ):
6856             segments[i].vector = seg.vector
6857         if isPreview:
6858             return editor.GetPreviewData()
6859         return None
6860
6861     def MakeSlot(self, segmentGroup, width ):
6862         """
6863         Create a slot of given width around given 1D elements lying on a triangle mesh.
6864         The slot is consrtucted by cutting faces by cylindrical surfaces made
6865         around each segment. Segments are expected to be created by MakePolyLine().
6866
6867         Returns:
6868                FaceEdge's located at the slot boundary
6869         """
6870         return self.editor.MakeSlot( segmentGroup, width )
6871
6872     def GetFunctor(self, funcType ):
6873         """
6874         Return a cached numerical functor by its type.
6875
6876         Parameters:
6877             funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
6878                 Note that not all items correspond to numerical functors.
6879
6880         Returns:
6881             :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
6882         """
6883
6884         fn = self.functors[ funcType._v ]
6885         if not fn:
6886             fn = self.smeshpyD.GetFunctor(funcType)
6887             fn.SetMesh(self.mesh)
6888             self.functors[ funcType._v ] = fn
6889         return fn
6890
6891     def FunctorValue(self, funcType, elemId, isElem=True):
6892         """
6893         Return value of a functor for a given element
6894
6895         Parameters:
6896             funcType: an item of :class:`SMESH.FunctorType` enum.
6897             elemId: element or node ID
6898             isElem: *elemId* is ID of element or node
6899
6900         Returns:
6901             the functor value or zero in case of invalid arguments
6902         """
6903
6904         fn = self.GetFunctor( funcType )
6905         if fn.GetElementType() == self.GetElementType(elemId, isElem):
6906             val = fn.GetValue(elemId)
6907         else:
6908             val = 0
6909         return val
6910
6911     def GetLength(self, elemId=None):
6912         """
6913         Get length of 1D element or sum of lengths of all 1D mesh elements
6914
6915         Parameters:
6916             elemId: mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
6917
6918         Returns:
6919             element's length value if *elemId* is specified or sum of all 1D mesh elements' lengths otherwise
6920         """
6921
6922         length = 0
6923         if elemId == None:
6924             length = self.smeshpyD.GetLength(self)
6925         else:
6926             length = self.FunctorValue(SMESH.FT_Length, elemId)
6927         return length
6928
6929     def GetArea(self, elemId=None):
6930         """
6931         Get area of 2D element or sum of areas of all 2D mesh elements
6932         elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
6933
6934         Returns:
6935             element's area value if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
6936         """
6937
6938         area = 0
6939         if elemId == None:
6940             area = self.smeshpyD.GetArea(self)
6941         else:
6942             area = self.FunctorValue(SMESH.FT_Area, elemId)
6943         return area
6944
6945     def GetVolume(self, elemId=None):
6946         """
6947         Get volume of 3D element or sum of volumes of all 3D mesh elements
6948
6949         Parameters:
6950             elemId: mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
6951
6952         Returns:
6953             element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
6954         """
6955
6956         volume = 0
6957         if elemId == None:
6958             volume = self.smeshpyD.GetVolume(self)
6959         else:
6960             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
6961         return volume
6962
6963     def GetAngle(self, node1, node2, node3 ):
6964         """
6965         Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
6966
6967         Parameters:            
6968                 node1,node2,node3: IDs of the three nodes
6969
6970         Returns:        
6971             Angle in radians [0,PI]. -1 if failure case.
6972         """
6973         p1 = self.GetNodeXYZ( node1 )
6974         p2 = self.GetNodeXYZ( node2 )
6975         p3 = self.GetNodeXYZ( node3 )
6976         if p1 and p2 and p3:
6977             return self.smeshpyD.GetAngle( p1,p2,p3 )
6978         return -1.
6979
6980
6981     def GetMaxElementLength(self, elemId):
6982         """
6983         Get maximum element length.
6984
6985         Parameters:
6986             elemId: mesh element ID
6987
6988         Returns:
6989             element's maximum length value
6990         """
6991
6992         if self.GetElementType(elemId, True) == SMESH.VOLUME:
6993             ftype = SMESH.FT_MaxElementLength3D
6994         else:
6995             ftype = SMESH.FT_MaxElementLength2D
6996         return self.FunctorValue(ftype, elemId)
6997
6998     def GetAspectRatio(self, elemId):
6999         """
7000         Get aspect ratio of 2D or 3D element.
7001
7002         Parameters:
7003             elemId: mesh element ID
7004
7005         Returns:
7006             element's aspect ratio value
7007         """
7008
7009         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7010             ftype = SMESH.FT_AspectRatio3D
7011         else:
7012             ftype = SMESH.FT_AspectRatio
7013         return self.FunctorValue(ftype, elemId)
7014
7015     def GetWarping(self, elemId):
7016         """
7017         Get warping angle of 2D element.
7018
7019         Parameters:
7020             elemId: mesh element ID
7021
7022         Returns:
7023             element's warping angle value
7024         """
7025
7026         return self.FunctorValue(SMESH.FT_Warping, elemId)
7027
7028     def GetMinimumAngle(self, elemId):
7029         """
7030         Get minimum angle of 2D element.
7031
7032         Parameters:
7033             elemId: mesh element ID
7034
7035         Returns:
7036             element's minimum angle value
7037         """
7038
7039         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7040
7041     def GetTaper(self, elemId):
7042         """
7043         Get taper of 2D element.
7044
7045         Parameters:
7046             elemId: mesh element ID
7047
7048         Returns:
7049             element's taper value
7050         """
7051
7052         return self.FunctorValue(SMESH.FT_Taper, elemId)
7053
7054     def GetSkew(self, elemId):
7055         """
7056         Get skew of 2D element.
7057
7058         Parameters:
7059             elemId: mesh element ID
7060
7061         Returns:
7062             element's skew value
7063         """
7064
7065         return self.FunctorValue(SMESH.FT_Skew, elemId)
7066
7067     def GetMinMax(self, funType, meshPart=None):
7068         """
7069         Return minimal and maximal value of a given functor.
7070
7071         Parameters:
7072             funType (SMESH.FunctorType): a functor type.
7073                   Note that not all items of :class:`SMESH.FunctorType` corresponds
7074                   to numerical functors.
7075             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7076
7077         Returns:
7078             tuple (min,max)
7079         """
7080
7081         unRegister = genObjUnRegister()
7082         if isinstance( meshPart, list ):
7083             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7084             unRegister.set( meshPart )
7085         if isinstance( meshPart, Mesh ):
7086             meshPart = meshPart.mesh
7087         fun = self.GetFunctor( funType )
7088         if fun:
7089             if meshPart:
7090                 if hasattr( meshPart, "SetMesh" ):
7091                     meshPart.SetMesh( self.mesh ) # set mesh to filter
7092                 hist = fun.GetLocalHistogram( 1, False, meshPart )
7093             else:
7094                 hist = fun.GetHistogram( 1, False )
7095             if hist:
7096                 return hist[0].min, hist[0].max
7097         return None
7098
7099     pass # end of Mesh class
7100
7101
7102 class meshProxy(SMESH._objref_SMESH_Mesh):
7103     """
7104     Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7105     with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7106     """
7107     def __init__(self,*args):
7108         SMESH._objref_SMESH_Mesh.__init__(self,*args)
7109     def __deepcopy__(self, memo=None):
7110         new = self.__class__(self)
7111         return new
7112     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7113         if len( args ) == 3:
7114             args += SMESH.ALL_NODES, True
7115         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7116     def ExportToMEDX(self, *args): # function removed
7117         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7118         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7119         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7120     def ExportToMED(self, *args): # function removed
7121         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7122         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7123         args2 = list(args)
7124         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7125             args2.append(True)
7126         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7127     def ExportPartToMED(self, *args): # 'version' parameter removed
7128         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7129         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7130     def ExportMED(self, *args): # signature of method changed
7131         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7132         args2 = list(args)
7133         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7134             args2.append(True)
7135         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7136     pass
7137 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7138
7139
7140 class submeshProxy(SMESH._objref_SMESH_subMesh):
7141
7142     """
7143     Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7144     """
7145     def __init__(self,*args):
7146         SMESH._objref_SMESH_subMesh.__init__(self,*args)
7147         self.mesh = None
7148     def __deepcopy__(self, memo=None):
7149         new = self.__class__(self)
7150         return new
7151
7152     def Compute(self,refresh=False):
7153         """
7154         Compute the sub-mesh and return the status of the computation
7155
7156         Parameters:
7157             refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7158
7159         Returns:
7160             True or False
7161
7162         This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7163         :meth:`smeshBuilder.Mesh.GetSubMesh`.
7164         """
7165
7166         if not self.mesh:
7167             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7168
7169         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7170
7171         if salome.sg.hasDesktop():
7172             if refresh: salome.sg.updateObjBrowser()
7173             pass
7174
7175         return ok
7176     pass
7177 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7178
7179
7180 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7181     """
7182     Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7183     compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7184     smeshBuilder.Mesh
7185     """
7186     def __init__(self,*args):
7187         SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7188         self.mesh = None
7189     def __getattr__(self, name ): # method called if an attribute not found
7190         if not self.mesh:         # look for name() method in Mesh class
7191             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7192         if hasattr( self.mesh, name ):
7193             return getattr( self.mesh, name )
7194         if name == "ExtrusionAlongPathObjX":
7195             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7196         print("meshEditor: attribute '%s' NOT FOUND" % name)
7197         return None
7198     def __deepcopy__(self, memo=None):
7199         new = self.__class__(self)
7200         return new
7201     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7202         if len( args ) == 1: args += False,
7203         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7204     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7205         if len( args ) == 2: args += False,
7206         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7207     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7208         if len( args ) == 1:
7209             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7210         NodesToKeep = args[1]
7211         AvoidMakingHoles = args[2] if len( args ) == 3 else False
7212         unRegister  = genObjUnRegister()
7213         if NodesToKeep:
7214             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7215                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7216             if not isinstance( NodesToKeep, list ):
7217                 NodesToKeep = [ NodesToKeep ]
7218         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7219     pass
7220 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7221
7222 class Pattern(SMESH._objref_SMESH_Pattern):
7223     """
7224     Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7225     variables in some methods
7226     """
7227
7228     def LoadFromFile(self, patternTextOrFile ):
7229         text = patternTextOrFile
7230         if os.path.exists( text ):
7231             text = open( patternTextOrFile ).read()
7232             pass
7233         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7234
7235     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7236         decrFun = lambda i: i-1
7237         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7238         theMesh.SetParameters(Parameters)
7239         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7240
7241     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7242         decrFun = lambda i: i-1
7243         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7244         theMesh.SetParameters(Parameters)
7245         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7246
7247     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7248         if isinstance( mesh, Mesh ):
7249             mesh = mesh.GetMesh()
7250         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7251
7252 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7253 """
7254 Registering the new proxy for Pattern
7255 """
7256
7257 class algoCreator:
7258     """
7259     Private class used to bind methods creating algorithms to the class Mesh
7260     """
7261
7262     def __init__(self, method):
7263         self.mesh = None
7264         self.defaultAlgoType = ""
7265         self.algoTypeToClass = {}
7266         self.method = method
7267
7268     def add(self, algoClass):
7269         """
7270         Store a python class of algorithm
7271         """
7272         if inspect.isclass(algoClass) and \
7273            hasattr( algoClass, "algoType"):
7274             self.algoTypeToClass[ algoClass.algoType ] = algoClass
7275             if not self.defaultAlgoType and \
7276                hasattr( algoClass, "isDefault") and algoClass.isDefault:
7277                 self.defaultAlgoType = algoClass.algoType
7278             #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7279
7280     def copy(self, mesh):
7281         """
7282         Create a copy of self and assign mesh to the copy
7283         """
7284
7285         other = algoCreator( self.method )
7286         other.defaultAlgoType = self.defaultAlgoType
7287         other.algoTypeToClass = self.algoTypeToClass
7288         other.mesh = mesh
7289         return other
7290
7291     def __call__(self,algo="",geom=0,*args):
7292         """
7293         Create an instance of algorithm
7294         """
7295         algoType = ""
7296         shape = 0
7297         if isinstance( algo, str ):
7298             algoType = algo
7299         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7300                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7301             shape = algo
7302         elif algo:
7303             args += (algo,)
7304
7305         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7306             shape = geom
7307         elif not algoType and isinstance( geom, str ):
7308             algoType = geom
7309         elif geom:
7310             args += (geom,)
7311         for arg in args:
7312             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7313                 shape = arg
7314             elif isinstance( arg, str ) and not algoType:
7315                 algoType = arg
7316             else:
7317                 import traceback, sys
7318                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
7319                 sys.stderr.write( msg + '\n' )
7320                 tb = traceback.extract_stack(None,2)
7321                 traceback.print_list( [tb[0]] )
7322         if not algoType:
7323             algoType = self.defaultAlgoType
7324         if not algoType and self.algoTypeToClass:
7325             algoType = sorted( self.algoTypeToClass.keys() )[0]
7326         if algoType in self.algoTypeToClass:
7327             #print("Create algo",algoType)
7328             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7329         raise RuntimeError( "No class found for algo type %s" % algoType)
7330         return None
7331
7332 class hypMethodWrapper:
7333     """
7334     Private class used to substitute and store variable parameters of hypotheses.
7335     """
7336
7337     def __init__(self, hyp, method):
7338         self.hyp    = hyp
7339         self.method = method
7340         #print("REBIND:", method.__name__)
7341         return
7342
7343     def __call__(self,*args):
7344         """
7345         call a method of hypothesis with calling SetVarParameter() before
7346         """
7347
7348         if not args:
7349             return self.method( self.hyp, *args ) # hypothesis method with no args
7350
7351         #print("MethWrapper.__call__", self.method.__name__, args)
7352         try:
7353             parsed = ParseParameters(*args)     # replace variables with their values
7354             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7355             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7356         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7357             # maybe there is a replaced string arg which is not variable
7358             result = self.method( self.hyp, *args )
7359         except ValueError as detail: # raised by ParseParameters()
7360             try:
7361                 result = self.method( self.hyp, *args )
7362             except omniORB.CORBA.BAD_PARAM:
7363                 raise ValueError(detail) # wrong variable name
7364
7365         return result
7366     pass
7367
7368 class genObjUnRegister:
7369     """
7370     A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7371     """
7372
7373     def __init__(self, genObj=None):
7374         self.genObjList = []
7375         self.set( genObj )
7376         return
7377
7378     def set(self, genObj):
7379         "Store one or a list of of SALOME.GenericObj'es"
7380         if isinstance( genObj, list ):
7381             self.genObjList.extend( genObj )
7382         else:
7383             self.genObjList.append( genObj )
7384         return
7385
7386     def __del__(self):
7387         for genObj in self.genObjList:
7388             if genObj and hasattr( genObj, "UnRegister" ):
7389                 genObj.UnRegister()
7390
7391 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
7392     """
7393     Bind methods creating mesher plug-ins to the Mesh class
7394     """
7395
7396     # print("pluginName: ", pluginName)
7397     pluginBuilderName = pluginName + "Builder"
7398     try:
7399         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7400     except Exception as e:
7401         from salome_utils import verbose
7402         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7403         continue
7404     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7405     plugin = eval( pluginBuilderName )
7406     # print("  plugin:" , str(plugin))
7407
7408     # add methods creating algorithms to Mesh
7409     for k in dir( plugin ):
7410         if k[0] == '_': continue
7411         algo = getattr( plugin, k )
7412         #print("             algo:", str(algo))
7413         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7414             #print("                     meshMethod:" , str(algo.meshMethod))
7415             if not hasattr( Mesh, algo.meshMethod ):
7416                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7417                 pass
7418             _mmethod = getattr( Mesh, algo.meshMethod )
7419             if hasattr(  _mmethod, "add" ):
7420                 _mmethod.add(algo)
7421             pass
7422         pass
7423     pass
7424 del pluginName