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