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