Salome HOME
43e8f431b10b79aecee19aef9b0087df0a47f39d
[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                     if salome.sg.hasDesktop():
1657                         so = salome.ObjectToSObject( self.geom )
1658                         comp = so.GetFatherComponent()
1659                         if comp.ComponentDataType() == "SHAPERSTUDY":
1660                             import shaperBuilder
1661                             self.geompyD = shaperBuilder.New()
1662                 except:
1663                     pass
1664                 if not self.geompyD:
1665                     self.geompyD = self.geom.GetGen()
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
2303     def ExportMEDCoupling(self, *args, **kwargs):
2304         """
2305         Export the mesh in a memory representation.
2306
2307         Parameters:
2308         auto_groups (boolean): parameter for creating/not creating
2309                 the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2310                 the typical use is auto_groups=False.
2311         overwrite (boolean): parameter for overwriting/not overwriting the file
2312         meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2313         autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2314
2315                 - 1D if all mesh nodes lie on OX coordinate axis, or
2316                 - 2D if all mesh nodes lie on XOY coordinate plane, or
2317                 - 3D in the rest cases.
2318
2319                 If *autoDimension* is *False*, the space dimension is always 3.
2320         fields: list of GEOM fields defined on the shape to mesh.
2321         geomAssocFields: each character of this string means a need to export a 
2322                 corresponding field; correspondence between fields and characters 
2323                 is following:
2324
2325                 - 'v' stands for "_vertices_" field;
2326                 - 'e' stands for "_edges_" field;
2327                 - 'f' stands for "_faces_" field;
2328                 - 's' stands for "_solids_" field.
2329
2330         zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2331                         close to zero within a given tolerance, the coordinate is set to zero.
2332                         If *ZTolerance* is negative (default), the node coordinates are kept as is.
2333         """
2334         auto_groups     = args[0] if len(args) > 0 else False
2335         meshPart        = args[1] if len(args) > 1 else None
2336         autoDimension   = args[2] if len(args) > 2 else True
2337         fields          = args[3] if len(args) > 3 else []
2338         geomAssocFields = args[4] if len(args) > 4 else ''
2339         z_tolerance     = args[5] if len(args) > 5 else -1.
2340         # process keywords arguments
2341         auto_groups     = kwargs.get("auto_groups", auto_groups)
2342         meshPart        = kwargs.get("meshPart", meshPart)
2343         autoDimension   = kwargs.get("autoDimension", autoDimension)
2344         fields          = kwargs.get("fields", fields)
2345         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2346         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2347
2348         # invoke engine's function
2349         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2350             unRegister = genObjUnRegister()
2351             if isinstance( meshPart, list ):
2352                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2353                 unRegister.set( meshPart )
2354
2355             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2356             self.mesh.SetParameters(Parameters)
2357
2358             intPtr = self.mesh.ExportPartToMEDCoupling(meshPart, auto_groups, autoDimension, fields, geomAssocFields, z_tolerance)
2359             import medcoupling
2360             dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2361             return medcoupling.MEDFileData.New(dab)
2362         else:
2363             intPtr = self.mesh.ExportMEDCoupling(auto_groups, autoDimension)
2364             import medcoupling
2365             dab = medcoupling.FromPyIntPtrToDataArrayByte(intPtr)
2366             return medcoupling.MEDFileMesh.New(dab)
2367
2368     def ExportMED(self, *args, **kwargs):
2369         """
2370         Export the mesh in a file in MED format
2371         allowing to overwrite the file if it exists or add the exported data to its contents
2372
2373         Parameters:
2374                 fileName: is the file name
2375                 auto_groups (boolean): parameter for creating/not creating
2376                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2377                         the typical use is auto_groups=False.
2378                 version (int): define the version (xy, where version is x.y.z) of MED file format.
2379                         For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40.
2380                         The rules of compatibility to write a mesh in an older version than 
2381                         the current version depend on the current version. For instance, 
2382                         with med 4.0 it is possible to write/append med files in 4.0.0 (default)
2383                         or 3.2.1 or 3.3.1 formats.
2384                         If the version is equal to -1, the version is not changed (default).
2385                 overwrite (boolean): parameter for overwriting/not overwriting the file
2386                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2387                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2388
2389                         - 1D if all mesh nodes lie on OX coordinate axis, or
2390                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2391                         - 3D in the rest cases.
2392
2393                         If *autoDimension* is *False*, the space dimension is always 3.
2394                 fields: list of GEOM fields defined on the shape to mesh.
2395                 geomAssocFields: each character of this string means a need to export a 
2396                         corresponding field; correspondence between fields and characters 
2397                         is following:
2398
2399                         - 'v' stands for "_vertices_" field;
2400                         - 'e' stands for "_edges_" field;
2401                         - 'f' stands for "_faces_" field;
2402                         - 's' stands for "_solids_" field.
2403
2404                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2405                              close to zero within a given tolerance, the coordinate is set to zero.
2406                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2407         """
2408         # process positional arguments
2409         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2410         fileName        = args[0]
2411         auto_groups     = args[1] if len(args) > 1 else False
2412         version         = args[2] if len(args) > 2 else -1
2413         overwrite       = args[3] if len(args) > 3 else True
2414         meshPart        = args[4] if len(args) > 4 else None
2415         autoDimension   = args[5] if len(args) > 5 else True
2416         fields          = args[6] if len(args) > 6 else []
2417         geomAssocFields = args[7] if len(args) > 7 else ''
2418         z_tolerance     = args[8] if len(args) > 8 else -1.
2419         # process keywords arguments
2420         auto_groups     = kwargs.get("auto_groups", auto_groups)
2421         version         = kwargs.get("version", version)
2422         version         = kwargs.get("minor", version)
2423         overwrite       = kwargs.get("overwrite", overwrite)
2424         meshPart        = kwargs.get("meshPart", meshPart)
2425         autoDimension   = kwargs.get("autoDimension", autoDimension)
2426         fields          = kwargs.get("fields", fields)
2427         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2428         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2429
2430         # invoke engine's function
2431         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2432             unRegister = genObjUnRegister()
2433             if isinstance( meshPart, list ):
2434                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2435                 unRegister.set( meshPart )
2436
2437             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2438             self.mesh.SetParameters(Parameters)
2439
2440             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups,
2441                                        version, overwrite, autoDimension,
2442                                        fields, geomAssocFields, z_tolerance)
2443         else:
2444             self.mesh.ExportMED(fileName, auto_groups, version, overwrite, autoDimension)
2445
2446     def ExportSAUV(self, f, auto_groups=0):
2447         """
2448         Export the mesh in a file in SAUV format
2449
2450
2451         Parameters:
2452                 f: is the file name
2453                 auto_groups: boolean parameter for creating/not creating
2454                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2455                         the typical use is auto_groups=False.
2456         """
2457
2458         self.mesh.ExportSAUV(f, auto_groups)
2459
2460     def ExportDAT(self, f, meshPart=None):
2461         """
2462         Export the mesh in a file in DAT format
2463
2464         Parameters:
2465                 f: the file name
2466                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2467         """
2468
2469         if meshPart:
2470             unRegister = genObjUnRegister()
2471             if isinstance( meshPart, list ):
2472                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2473                 unRegister.set( meshPart )
2474             self.mesh.ExportPartToDAT( meshPart, f )
2475         else:
2476             self.mesh.ExportDAT(f)
2477
2478     def ExportUNV(self, f, meshPart=None):
2479         """
2480         Export the mesh in a file in UNV format
2481
2482         Parameters:
2483                 f: the file name
2484                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2485         """
2486
2487         if meshPart:
2488             unRegister = genObjUnRegister()
2489             if isinstance( meshPart, list ):
2490                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2491                 unRegister.set( meshPart )
2492             self.mesh.ExportPartToUNV( meshPart, f )
2493         else:
2494             self.mesh.ExportUNV(f)
2495
2496     def ExportSTL(self, f, ascii=1, meshPart=None):
2497         """
2498         Export the mesh in a file in STL format
2499
2500         Parameters:
2501                 f: the file name
2502                 ascii: defines the file encoding
2503                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2504         """
2505
2506         if meshPart:
2507             unRegister = genObjUnRegister()
2508             if isinstance( meshPart, list ):
2509                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2510                 unRegister.set( meshPart )
2511             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2512         else:
2513             self.mesh.ExportSTL(f, ascii)
2514
2515     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2516         """
2517         Export the mesh in a file in CGNS format
2518
2519         Parameters:
2520                 f: is the file name
2521                 overwrite: boolean parameter for overwriting/not overwriting the file
2522                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2523                 groupElemsByType: if True all elements of same entity type are exported at ones,
2524                         else elements are exported in order of their IDs which can cause creation
2525                         of multiple cgns sections
2526         """
2527
2528         unRegister = genObjUnRegister()
2529         if isinstance( meshPart, list ):
2530             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2531             unRegister.set( meshPart )
2532         if isinstance( meshPart, Mesh ):
2533             meshPart = meshPart.mesh
2534         elif not meshPart:
2535             meshPart = self.mesh
2536         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2537
2538     def ExportGMF(self, f, meshPart=None):
2539         """
2540         Export the mesh in a file in GMF format.
2541         GMF files must have .mesh extension for the ASCII format and .meshb for
2542         the bynary format. Other extensions are not allowed.
2543
2544         Parameters:
2545                 f: is the file name
2546                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2547         """
2548
2549         unRegister = genObjUnRegister()
2550         if isinstance( meshPart, list ):
2551             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2552             unRegister.set( meshPart )
2553         if isinstance( meshPart, Mesh ):
2554             meshPart = meshPart.mesh
2555         elif not meshPart:
2556             meshPart = self.mesh
2557         self.mesh.ExportGMF(meshPart, f, True)
2558
2559     def ExportToMED(self, *args, **kwargs):
2560         """
2561         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2562         Export the mesh in a file in MED format
2563         allowing to overwrite the file if it exists or add the exported data to its contents
2564
2565         Parameters:
2566                 fileName: the file name
2567                 opt (boolean): parameter for creating/not creating
2568                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2569                 overwrite: boolean parameter for overwriting/not overwriting the file
2570                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2571
2572                         - 1D if all mesh nodes lie on OX coordinate axis, or
2573                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2574                         - 3D in the rest cases.
2575
2576                         If **autoDimension** is *False*, the space dimension is always 3.
2577         """
2578     
2579         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2580         # process positional arguments
2581         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2582         fileName      = args[0]
2583         auto_groups   = args[1] if len(args) > 1 else False
2584         overwrite     = args[2] if len(args) > 2 else True
2585         autoDimension = args[3] if len(args) > 3 else True
2586         # process keywords arguments
2587         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2588         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2589         overwrite     = kwargs.get("overwrite", overwrite)
2590         autoDimension = kwargs.get("autoDimension", autoDimension)
2591         minor = -1
2592         # invoke engine's function
2593         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2594
2595     def ExportToMEDX(self, *args, **kwargs):
2596         """
2597         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2598         Export the mesh in a file in MED format
2599
2600         Parameters:
2601                 fileName: the file name
2602                 opt (boolean): parameter for creating/not creating
2603                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2604                 overwrite: boolean parameter for overwriting/not overwriting the file
2605                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2606
2607                         - 1D if all mesh nodes lie on OX coordinate axis, or
2608                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2609                         - 3D in the rest cases.
2610
2611                         If **autoDimension** is *False*, the space dimension is always 3.
2612                 """
2613
2614         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2615         # process positional arguments
2616         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2617         fileName      = args[0]
2618         auto_groups   = args[1] if len(args) > 1 else False
2619         overwrite     = args[2] if len(args) > 2 else True
2620         autoDimension = args[3] if len(args) > 3 else True
2621         # process keywords arguments
2622         auto_groups   = kwargs.get("auto_groups", auto_groups)
2623         overwrite     = kwargs.get("overwrite", overwrite)
2624         autoDimension = kwargs.get("autoDimension", autoDimension)
2625         minor = -1
2626         # invoke engine's function
2627         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2628         return
2629
2630
2631     def Append(self, meshes, uniteIdenticalGroups = True,
2632                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2633         """
2634         Append given meshes into this mesh.
2635         All groups of input meshes will be created in this mesh.
2636
2637         Parameters:
2638                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2639                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2640                 mergeNodesAndElements: if True, equal nodes and elements are merged
2641                 mergeTolerance: tolerance for merging nodes
2642                 allGroups: forces creation of groups corresponding to every input mesh
2643         """
2644         self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2645                                    mergeNodesAndElements, mergeTolerance, allGroups,
2646                                    meshToAppendTo = self.GetMesh() )
2647
2648     # Operations with groups:
2649     # ----------------------
2650     def CreateEmptyGroup(self, elementType, name):
2651         """
2652         Create an empty standalone mesh group
2653
2654         Parameters:
2655                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2656                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2657                 name: the name of the mesh group
2658
2659         Returns:
2660                 :class:`SMESH.SMESH_Group`
2661         """
2662
2663         return self.mesh.CreateGroup(elementType, name)
2664
2665     def Group(self, grp, name=""):
2666         """
2667         Create a mesh group based on the geometric object *grp*
2668         and give it a *name*.
2669         If *name* is not defined the name of the geometric group is used
2670
2671         Note:
2672                 Works like :meth:`GroupOnGeom`.
2673
2674         Parameters:
2675                 grp:  a geometric group, a vertex, an edge, a face or a solid
2676                 name: the name of the mesh group
2677
2678         Returns:
2679                 :class:`SMESH.SMESH_GroupOnGeom`
2680         """
2681
2682         return self.GroupOnGeom(grp, name)
2683
2684     def GroupOnGeom(self, grp, name="", typ=None):
2685         """
2686         Create a mesh group based on the geometrical object *grp*
2687         and give it a *name*.
2688         if *name* is not defined the name of the geometric group is used
2689
2690         Parameters:
2691                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2692                 name: the name of the mesh group
2693                 typ:  the type of elements in the group; either of
2694                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2695                         automatically detected by the type of the geometry
2696
2697         Returns:
2698                 :class:`SMESH.SMESH_GroupOnGeom`
2699         """
2700
2701         AssureGeomPublished( self, grp, name )
2702         if name == "":
2703             name = grp.GetName()
2704         if not typ:
2705             typ = self._groupTypeFromShape( grp )
2706         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2707
2708     def _groupTypeFromShape( self, shape ):
2709         """
2710         Pivate method to get a type of group on geometry
2711         """
2712         tgeo = str(shape.GetShapeType())
2713         if tgeo == "VERTEX":
2714             typ = NODE
2715         elif tgeo == "EDGE" or tgeo == "WIRE":
2716             typ = EDGE
2717         elif tgeo == "FACE" or tgeo == "SHELL":
2718             typ = FACE
2719         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2720             typ = VOLUME
2721         elif tgeo == "COMPOUND":
2722             try:
2723               sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2724             except:
2725               # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of
2726               # simplification of access in geomBuilder: omniORB.registerObjref
2727               from SHAPERSTUDY_utils import getEngine
2728               gen = getEngine()
2729               if gen:
2730                 sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False)
2731             if not sub:
2732                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2733             return self._groupTypeFromShape( sub[0] )
2734         else:
2735             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2736         return typ
2737
2738     def GroupOnFilter(self, typ, name, filter):
2739         """
2740         Create a mesh group with given *name* based on the *filter*.
2741         It is a special type of group dynamically updating it's contents during
2742         mesh modification
2743
2744         Parameters:
2745                 typ: the type of elements in the group; either of
2746                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2747                 name: the name of the mesh group
2748                 filter (SMESH.Filter): the filter defining group contents
2749
2750         Returns:
2751                 :class:`SMESH.SMESH_GroupOnFilter`
2752         """
2753
2754         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2755
2756     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2757         """
2758         Create a mesh group by the given ids of elements
2759
2760         Parameters:
2761                 groupName: the name of the mesh group
2762                 elementType: the type of elements in the group; either of
2763                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2764                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2765
2766         Returns:
2767                 :class:`SMESH.SMESH_Group`
2768         """
2769
2770         group = self.mesh.CreateGroup(elementType, groupName)
2771         if isinstance( elemIDs, Mesh ):
2772             elemIDs = elemIDs.GetMesh()
2773         if hasattr( elemIDs, "GetIDs" ):
2774             if hasattr( elemIDs, "SetMesh" ):
2775                 elemIDs.SetMesh( self.GetMesh() )
2776             group.AddFrom( elemIDs )
2777         else:
2778             group.Add(elemIDs)
2779         return group
2780
2781     def MakeGroup(self,
2782                   groupName,
2783                   elementType,
2784                   CritType=FT_Undefined,
2785                   Compare=FT_EqualTo,
2786                   Threshold="",
2787                   UnaryOp=FT_Undefined,
2788                   Tolerance=1e-07):
2789         """
2790         Create a mesh group by the given conditions
2791
2792         Parameters:
2793                 groupName: the name of the mesh group
2794                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2795                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2796                         Note that the items starting from FT_LessThan are not suitable for CritType.
2797                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2798                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2799                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2800                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2801                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2802
2803         Returns:
2804                 :class:`SMESH.SMESH_GroupOnFilter`
2805         """
2806
2807         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2808         group = self.MakeGroupByCriterion(groupName, aCriterion)
2809         return group
2810
2811     def MakeGroupByCriterion(self, groupName, Criterion):
2812         """
2813         Create a mesh group by the given criterion
2814
2815         Parameters:
2816                 groupName: the name of the mesh group
2817                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2818
2819         Returns:
2820                 :class:`SMESH.SMESH_GroupOnFilter`
2821
2822         See Also:
2823                 :meth:`smeshBuilder.GetCriterion`
2824         """
2825
2826         return self.MakeGroupByCriteria( groupName, [Criterion] )
2827
2828     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2829         """
2830         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2831
2832         Parameters:
2833                 groupName: the name of the mesh group
2834                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2835                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2836
2837         Returns:
2838                 :class:`SMESH.SMESH_GroupOnFilter`
2839
2840         See Also:
2841                 :meth:`smeshBuilder.GetCriterion`
2842         """
2843
2844         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2845         group = self.MakeGroupByFilter(groupName, aFilter)
2846         return group
2847
2848     def MakeGroupByFilter(self, groupName, theFilter):
2849         """
2850         Create a mesh group by the given filter
2851
2852         Parameters:
2853                 groupName (string): the name of the mesh group
2854                 theFilter (SMESH.Filter): the filter
2855
2856         Returns:
2857                 :class:`SMESH.SMESH_GroupOnFilter`
2858
2859         See Also:
2860                 :meth:`smeshBuilder.GetFilter`
2861         """
2862
2863         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2864         #theFilter.SetMesh( self.mesh )
2865         #group.AddFrom( theFilter )
2866         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2867         return group
2868
2869     def RemoveGroup(self, group):
2870         """
2871         Remove a group
2872
2873         Parameters:
2874                 group (SMESH.SMESH_GroupBase): group to remove
2875         """
2876
2877         self.mesh.RemoveGroup(group)
2878
2879     def RemoveGroupWithContents(self, group):
2880         """
2881         Remove a group with its contents
2882
2883         Parameters:
2884                 group (SMESH.SMESH_GroupBase): group to remove
2885
2886         Note:
2887                 This operation can create gaps in numeration of nodes or elements.
2888                 Call :meth:`RenumberElements` to remove the gaps.
2889         """
2890
2891         self.mesh.RemoveGroupWithContents(group)
2892
2893     def GetGroups(self, elemType = SMESH.ALL):
2894         """
2895         Get the list of groups existing in the mesh in the order of creation 
2896         (starting from the oldest one)
2897
2898         Parameters:
2899                 elemType (SMESH.ElementType): type of elements the groups contain;
2900                         by default groups of elements of all types are returned
2901
2902         Returns:
2903                 a list of :class:`SMESH.SMESH_GroupBase`
2904         """
2905
2906         groups = self.mesh.GetGroups()
2907         if elemType == SMESH.ALL:
2908             return groups
2909         typedGroups = []
2910         for g in groups:
2911             if g.GetType() == elemType:
2912                 typedGroups.append( g )
2913                 pass
2914             pass
2915         return typedGroups
2916
2917     def NbGroups(self):
2918         """
2919         Get the number of groups existing in the mesh
2920
2921         Returns:
2922                 the quantity of groups as an integer value
2923         """
2924
2925         return self.mesh.NbGroups()
2926
2927     def GetGroupNames(self):
2928         """
2929         Get the list of names of groups existing in the mesh
2930
2931         Returns:
2932                 list of strings
2933         """
2934
2935         groups = self.GetGroups()
2936         names = []
2937         for group in groups:
2938             names.append(group.GetName())
2939         return names
2940
2941     def GetGroupByName(self, name, elemType = None):
2942         """
2943         Find groups by name and type
2944
2945         Parameters:
2946                 name (string): name of the group of interest
2947                 elemType (SMESH.ElementType): type of elements the groups contain;
2948                         by default one group of any type is returned;
2949                         if elemType == SMESH.ALL then all groups of any type are returned
2950
2951         Returns:
2952                 a list of :class:`SMESH.SMESH_GroupBase`
2953         """
2954
2955         groups = []
2956         for group in self.GetGroups():
2957             if group.GetName() == name:
2958                 if elemType is None:
2959                     return [group]
2960                 if ( elemType == SMESH.ALL or
2961                      group.GetType() == elemType ):
2962                     groups.append( group )
2963         return groups
2964
2965     def UnionGroups(self, group1, group2, name):
2966         """
2967         Produce a union of two groups.
2968         A new group is created. All mesh elements that are
2969         present in the initial groups are added to the new one
2970
2971         Parameters:
2972            group1 (SMESH.SMESH_GroupBase): a group
2973            group2 (SMESH.SMESH_GroupBase): another group
2974
2975         Returns:
2976                 instance of :class:`SMESH.SMESH_Group`
2977         """
2978
2979         return self.mesh.UnionGroups(group1, group2, name)
2980
2981     def UnionListOfGroups(self, groups, name):
2982         """
2983         Produce a union list of groups.
2984         New group is created. All mesh elements that are present in
2985         initial groups are added to the new one
2986
2987         Parameters:
2988            groups: list of :class:`SMESH.SMESH_GroupBase`
2989
2990         Returns:
2991                 instance of :class:`SMESH.SMESH_Group`
2992         """
2993         return self.mesh.UnionListOfGroups(groups, name)
2994
2995     def IntersectGroups(self, group1, group2, name):
2996         """
2997         Prodice an intersection of two groups.
2998         A new group is created. All mesh elements that are common
2999         for the two initial groups are added to the new one.
3000
3001         Parameters:
3002            group1 (SMESH.SMESH_GroupBase): a group
3003            group2 (SMESH.SMESH_GroupBase): another group
3004
3005         Returns:
3006                 instance of :class:`SMESH.SMESH_Group`
3007         """
3008
3009         return self.mesh.IntersectGroups(group1, group2, name)
3010
3011     def IntersectListOfGroups(self, groups, name):
3012         """
3013         Produce an intersection of groups.
3014         New group is created. All mesh elements that are present in all
3015         initial groups simultaneously are added to the new one
3016
3017         Parameters:
3018            groups: a list of :class:`SMESH.SMESH_GroupBase`
3019
3020         Returns:
3021                 instance of :class:`SMESH.SMESH_Group`
3022         """
3023         return self.mesh.IntersectListOfGroups(groups, name)
3024
3025     def CutGroups(self, main_group, tool_group, name):
3026         """
3027         Produce a cut of two groups.
3028         A new group is created. All mesh elements that are present in
3029         the main group but are not present in the tool group are added to the new one
3030
3031         Parameters:
3032            main_group (SMESH.SMESH_GroupBase): a group to cut from
3033            tool_group (SMESH.SMESH_GroupBase): a group to cut by
3034
3035         Returns:
3036                 an instance of :class:`SMESH.SMESH_Group`
3037         """
3038
3039         return self.mesh.CutGroups(main_group, tool_group, name)
3040
3041     def CutListOfGroups(self, main_groups, tool_groups, name):
3042         """
3043         Produce a cut of groups.
3044         A new group is created. All mesh elements that are present in main groups
3045         but do not present in tool groups are added to the new one
3046
3047         Parameters:
3048            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
3049            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
3050
3051         Returns:
3052                 an instance of :class:`SMESH.SMESH_Group`
3053         """
3054
3055         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
3056
3057     def CreateDimGroup(self, groups, elemType, name,
3058                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
3059         """
3060         Create a standalone group of entities basing on nodes of other groups.
3061
3062         Parameters:
3063                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
3064                 elemType: a type of elements to include to the new group; either of
3065                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
3066                 name: a name of the new group.
3067                 nbCommonNodes: a criterion of inclusion of an element to the new group
3068                         basing on number of element nodes common with reference *groups*.
3069                         Meaning of possible values are:
3070
3071                                 - SMESH.ALL_NODES - include if all nodes are common,
3072                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
3073                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
3074                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
3075                 underlyingOnly: if *True* (default), an element is included to the
3076                         new group provided that it is based on nodes of an element of *groups*;
3077                         in this case the reference *groups* are supposed to be of higher dimension
3078                         than *elemType*, which can be useful for example to get all faces lying on
3079                         volumes of the reference *groups*.
3080
3081         Returns:
3082                 an instance of :class:`SMESH.SMESH_Group`
3083         """
3084
3085         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
3086             groups = [groups]
3087         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
3088
3089     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
3090         """
3091         Distribute all faces of the mesh among groups using sharp edges and optionally
3092         existing 1D elements as group boundaries.
3093
3094         Parameters:
3095                 sharpAngle: edge is considered sharp if an angle between normals of
3096                             adjacent faces is more than \a sharpAngle in degrees.
3097                 createEdges (boolean): to create 1D elements for detected sharp edges.
3098                 useExistingEdges (boolean): to use existing edges as group boundaries
3099         Returns:
3100                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
3101         """
3102         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
3103         self.mesh.SetParameters(Parameters)
3104         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
3105
3106     def ConvertToStandalone(self, group):
3107         """
3108         Convert group on geom into standalone group
3109         """
3110
3111         return self.mesh.ConvertToStandalone(group)
3112
3113     # Get some info about mesh:
3114     # ------------------------
3115
3116     def GetLog(self, clearAfterGet):
3117         """
3118         Return the log of nodes and elements added or removed
3119         since the previous clear of the log.
3120
3121         Parameters:
3122                 clearAfterGet: log is emptied after Get (safe if concurrents access)
3123
3124         Returns:
3125                 list of SMESH.log_block structures { commandType, number, coords, indexes }
3126         """
3127
3128         return self.mesh.GetLog(clearAfterGet)
3129
3130     def ClearLog(self):
3131         """
3132         Clear the log of nodes and elements added or removed since the previous
3133         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3134         """
3135
3136         self.mesh.ClearLog()
3137
3138     def SetAutoColor(self, theAutoColor):
3139         """
3140         Toggle auto color mode on the object.
3141         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3142
3143         Parameters:
3144                 theAutoColor (boolean): the flag which toggles auto color mode.
3145         """
3146
3147         self.mesh.SetAutoColor(theAutoColor)
3148
3149     def GetAutoColor(self):
3150         """
3151         Get flag of object auto color mode.
3152
3153         Returns:
3154                 True or False
3155         """
3156
3157         return self.mesh.GetAutoColor()
3158
3159     def GetId(self):
3160         """
3161         Get the internal ID
3162
3163         Returns:
3164             integer value, which is the internal Id of the mesh
3165         """
3166
3167         return self.mesh.GetId()
3168
3169     def HasDuplicatedGroupNamesMED(self):
3170         """
3171         Check the group names for duplications.
3172         Consider the maximum group name length stored in MED file.
3173
3174         Returns:
3175             True or False
3176         """
3177
3178         return self.mesh.HasDuplicatedGroupNamesMED()
3179
3180     def GetMeshEditor(self):
3181         """
3182         Obtain the mesh editor tool
3183
3184         Returns:
3185             an instance of :class:`SMESH.SMESH_MeshEditor`
3186         """
3187
3188         return self.editor
3189
3190     def GetIDSource(self, ids, elemType = SMESH.ALL):
3191         """
3192         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3193         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3194
3195         Parameters:
3196                 ids: list of IDs
3197                 elemType: type of elements; this parameter is used to distinguish
3198                         IDs of nodes from IDs of elements; by default ids are treated as
3199                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3200
3201         Returns:
3202             an instance of :class:`SMESH.SMESH_IDSource`
3203
3204         Warning:
3205                 call UnRegister() for the returned object as soon as it is no more useful::
3206
3207                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3208                         mesh.DoSomething( idSrc )
3209                         idSrc.UnRegister()
3210         """
3211
3212         if isinstance( ids, int ):
3213             ids = [ids]
3214         return self.editor.MakeIDSource(ids, elemType)
3215
3216
3217     # Get information about mesh contents:
3218     # ------------------------------------
3219
3220     def GetMeshInfo(self, obj = None):
3221         """
3222         Get the mesh statistic.
3223
3224         Returns:
3225                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3226         """
3227
3228         if not obj: obj = self.mesh
3229         return self.smeshpyD.GetMeshInfo(obj)
3230
3231     def NbNodes(self):
3232         """
3233         Return the number of nodes in the mesh
3234
3235         Returns:
3236             an integer value
3237         """
3238
3239         return self.mesh.NbNodes()
3240
3241     def NbElements(self):
3242         """
3243         Return the number of elements in the mesh
3244
3245         Returns:
3246             an integer value
3247         """
3248
3249         return self.mesh.NbElements()
3250
3251     def Nb0DElements(self):
3252         """
3253         Return the number of 0d elements in the mesh
3254
3255         Returns:
3256             an integer value
3257         """
3258
3259         return self.mesh.Nb0DElements()
3260
3261     def NbBalls(self):
3262         """
3263         Return the number of ball discrete elements in the mesh
3264
3265         Returns:
3266             an integer value
3267         """
3268
3269         return self.mesh.NbBalls()
3270
3271     def NbEdges(self):
3272         """
3273         Return the number of edges in the mesh
3274
3275         Returns:
3276             an integer value
3277         """
3278
3279         return self.mesh.NbEdges()
3280
3281     def NbEdgesOfOrder(self, elementOrder):
3282         """
3283         Return the number of edges with the given order in the mesh
3284
3285         Parameters:
3286                 elementOrder: the order of elements
3287                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3288
3289         Returns:
3290             an integer value
3291         """
3292
3293         return self.mesh.NbEdgesOfOrder(elementOrder)
3294
3295     def NbFaces(self):
3296         """
3297         Return the number of faces in the mesh
3298
3299         Returns:
3300             an integer value
3301         """
3302
3303         return self.mesh.NbFaces()
3304
3305     def NbFacesOfOrder(self, elementOrder):
3306         """
3307         Return the number of faces with the given order in the mesh
3308
3309         Parameters:
3310                 elementOrder: the order of elements
3311                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3312
3313         Returns:
3314             an integer value
3315         """
3316
3317         return self.mesh.NbFacesOfOrder(elementOrder)
3318
3319     def NbTriangles(self):
3320         """
3321         Return the number of triangles in the mesh
3322
3323         Returns:
3324             an integer value
3325         """
3326
3327         return self.mesh.NbTriangles()
3328
3329     def NbTrianglesOfOrder(self, elementOrder):
3330         """
3331         Return the number of triangles with the given order in the mesh
3332
3333         Parameters:
3334                 elementOrder: is the order of elements
3335                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3336
3337         Returns:
3338             an integer value
3339         """
3340
3341         return self.mesh.NbTrianglesOfOrder(elementOrder)
3342
3343     def NbBiQuadTriangles(self):
3344         """
3345         Return the number of biquadratic triangles in the mesh
3346
3347         Returns:
3348             an integer value
3349         """
3350
3351         return self.mesh.NbBiQuadTriangles()
3352
3353     def NbQuadrangles(self):
3354         """
3355         Return the number of quadrangles in the mesh
3356
3357         Returns:
3358             an integer value
3359         """
3360
3361         return self.mesh.NbQuadrangles()
3362
3363     def NbQuadranglesOfOrder(self, elementOrder):
3364         """
3365         Return the number of quadrangles with the given order in the mesh
3366
3367         Parameters:
3368                 elementOrder: the order of elements
3369                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3370
3371         Returns:
3372             an integer value
3373         """
3374
3375         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3376
3377     def NbBiQuadQuadrangles(self):
3378         """
3379         Return the number of biquadratic quadrangles in the mesh
3380
3381         Returns:
3382             an integer value
3383         """
3384
3385         return self.mesh.NbBiQuadQuadrangles()
3386
3387     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3388         """
3389         Return the number of polygons of given order in the mesh
3390
3391         Parameters:
3392                 elementOrder: the order of elements
3393                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3394
3395         Returns:
3396             an integer value
3397         """
3398
3399         return self.mesh.NbPolygonsOfOrder(elementOrder)
3400
3401     def NbVolumes(self):
3402         """
3403         Return the number of volumes in the mesh
3404
3405         Returns:
3406             an integer value
3407         """
3408
3409         return self.mesh.NbVolumes()
3410
3411
3412     def NbVolumesOfOrder(self, elementOrder):
3413         """
3414         Return the number of volumes with the given order in the mesh
3415
3416         Parameters:
3417                 elementOrder:  the order of elements
3418                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3419
3420         Returns:
3421             an integer value
3422         """
3423
3424         return self.mesh.NbVolumesOfOrder(elementOrder)
3425
3426     def NbTetras(self):
3427         """
3428         Return the number of tetrahedrons in the mesh
3429
3430         Returns:
3431             an integer value
3432         """
3433
3434         return self.mesh.NbTetras()
3435
3436     def NbTetrasOfOrder(self, elementOrder):
3437         """
3438         Return the number of tetrahedrons with the given order in the mesh
3439
3440         Parameters:
3441                 elementOrder:  the order of elements
3442                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3443
3444         Returns:
3445             an integer value
3446         """
3447
3448         return self.mesh.NbTetrasOfOrder(elementOrder)
3449
3450     def NbHexas(self):
3451         """
3452         Return the number of hexahedrons in the mesh
3453
3454         Returns:
3455             an integer value
3456         """
3457
3458         return self.mesh.NbHexas()
3459
3460     def NbHexasOfOrder(self, elementOrder):
3461         """
3462         Return the number of hexahedrons with the given order in the mesh
3463
3464         Parameters:
3465                 elementOrder:  the order of elements
3466                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3467
3468         Returns:
3469             an integer value
3470         """
3471
3472         return self.mesh.NbHexasOfOrder(elementOrder)
3473
3474     def NbTriQuadraticHexas(self):
3475         """
3476         Return the number of triquadratic hexahedrons in the mesh
3477
3478         Returns:
3479             an integer value
3480         """
3481
3482         return self.mesh.NbTriQuadraticHexas()
3483
3484     def NbPyramids(self):
3485         """
3486         Return the number of pyramids in the mesh
3487
3488         Returns:
3489             an integer value
3490         """
3491
3492         return self.mesh.NbPyramids()
3493
3494     def NbPyramidsOfOrder(self, elementOrder):
3495         """
3496         Return the number of pyramids with the given order in the mesh
3497
3498         Parameters:
3499                 elementOrder:  the order of elements
3500                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3501
3502         Returns:
3503             an integer value
3504         """
3505
3506         return self.mesh.NbPyramidsOfOrder(elementOrder)
3507
3508     def NbPrisms(self):
3509         """
3510         Return the number of prisms in the mesh
3511
3512         Returns:
3513             an integer value
3514         """
3515
3516         return self.mesh.NbPrisms()
3517
3518     def NbPrismsOfOrder(self, elementOrder):
3519         """
3520         Return the number of prisms with the given order in the mesh
3521
3522         Parameters:
3523                 elementOrder:  the order of elements
3524                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3525
3526         Returns:
3527             an integer value
3528         """
3529
3530         return self.mesh.NbPrismsOfOrder(elementOrder)
3531
3532     def NbHexagonalPrisms(self):
3533         """
3534         Return the number of hexagonal prisms in the mesh
3535
3536         Returns:
3537             an integer value
3538         """
3539
3540         return self.mesh.NbHexagonalPrisms()
3541
3542     def NbPolyhedrons(self):
3543         """
3544         Return the number of polyhedrons in the mesh
3545
3546         Returns:
3547             an integer value
3548         """
3549
3550         return self.mesh.NbPolyhedrons()
3551
3552     def NbSubMesh(self):
3553         """
3554         Return the number of submeshes in the mesh
3555
3556         Returns:
3557             an integer value
3558         """
3559
3560         return self.mesh.NbSubMesh()
3561
3562     def GetElementsId(self):
3563         """
3564         Return the list of all mesh elements IDs
3565
3566         Returns:
3567             the list of integer values
3568
3569         See Also:
3570             :meth:`GetElementsByType`
3571         """
3572
3573         return self.mesh.GetElementsId()
3574
3575     def GetElementsByType(self, elementType):
3576         """
3577         Return the list of IDs of mesh elements with the given type
3578
3579         Parameters:
3580                 elementType (SMESH.ElementType):  the required type of elements
3581
3582         Returns:
3583             list of integer values
3584         """
3585
3586         return self.mesh.GetElementsByType(elementType)
3587
3588     def GetNodesId(self):
3589         """
3590         Return the list of mesh nodes IDs
3591
3592         Returns:
3593             the list of integer values
3594         """
3595
3596         return self.mesh.GetNodesId()
3597
3598     # Get the information about mesh elements:
3599     # ------------------------------------
3600
3601     def GetElementType(self, id, iselem=True):
3602         """
3603         Return the type of mesh element or node
3604
3605         Returns:
3606             the value from :class:`SMESH.ElementType` enumeration. 
3607             Return SMESH.ALL if element or node with the given ID does not exist
3608         """
3609
3610         return self.mesh.GetElementType(id, iselem)
3611
3612     def GetElementGeomType(self, id):
3613         """
3614         Return the geometric type of mesh element
3615
3616         Returns:
3617             the value from :class:`SMESH.EntityType` enumeration.
3618         """
3619
3620         return self.mesh.GetElementGeomType(id)
3621
3622     def GetElementShape(self, id):
3623         """
3624         Return the shape type of mesh element
3625
3626         Returns:
3627             the value from :class:`SMESH.GeometryType` enumeration.
3628         """
3629
3630         return self.mesh.GetElementShape(id)
3631
3632     def GetSubMeshElementsId(self, Shape):
3633         """
3634         Return the list of sub-mesh elements IDs
3635
3636         Parameters:
3637                 Shape (GEOM.GEOM_Object): a geom object (sub-shape).
3638                        *Shape* must be the sub-shape of the :meth:`main shape <GetShape>`
3639
3640         Returns:
3641             list of integer values
3642         """
3643
3644         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3645             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3646         else:
3647             ShapeID = Shape
3648         return self.mesh.GetSubMeshElementsId(ShapeID)
3649
3650     def GetSubMeshNodesId(self, Shape, all):
3651         """
3652         Return the list of sub-mesh nodes IDs
3653
3654         Parameters:
3655                 Shape: a geom object (sub-shape).
3656                        *Shape* must be the sub-shape of a :meth:`GetShape`
3657                 all: If True, gives all nodes of sub-mesh elements, otherwise gives only sub-mesh nodes
3658
3659         Returns:
3660             list of integer values
3661         """
3662
3663         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3664             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3665         else:
3666             ShapeID = Shape
3667         return self.mesh.GetSubMeshNodesId(ShapeID, all)
3668
3669     def GetSubMeshElementType(self, Shape):
3670         """
3671         Return type of elements on given shape
3672
3673         Parameters:
3674                 Shape: a geom object (sub-shape).
3675                        *Shape* must be a sub-shape of a ShapeToMesh()
3676
3677         Returns:
3678             :class:`SMESH.ElementType`
3679         """
3680
3681         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
3682             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3683         else:
3684             ShapeID = Shape
3685         return self.mesh.GetSubMeshElementType(ShapeID)
3686
3687     def Dump(self):
3688         """
3689         Get the mesh description
3690
3691         Returns:
3692             string value
3693         """
3694
3695         return self.mesh.Dump()
3696
3697
3698     # Get the information about nodes and elements of a mesh by its IDs:
3699     # -----------------------------------------------------------
3700
3701     def GetNodeXYZ(self, id):
3702         """
3703         Get XYZ coordinates of a node.
3704         If there is no node for the given ID - return an empty list
3705
3706         Returns:
3707             list of float values
3708         """
3709
3710         return self.mesh.GetNodeXYZ(id)
3711
3712     def GetNodeInverseElements(self, id, elemType=SMESH.ALL):
3713         """
3714         Return list of IDs of inverse elements for the given node.
3715         If there is no node for the given ID - return an empty list
3716
3717         Parameters:
3718                 id: node ID
3719                 elementType: :class:`type of elements <SMESH.ElementType>` (SMESH.EDGE, SMESH.FACE, SMESH.VOLUME, etc.)
3720
3721         Returns:
3722             list of integer values
3723         """
3724
3725         return self.mesh.GetNodeInverseElements(id,elemType)
3726
3727     def GetNodePosition(self,NodeID):
3728         """
3729         Return the position of a node on the shape
3730
3731         Returns:
3732             :class:`SMESH.NodePosition`
3733         """
3734
3735         return self.mesh.GetNodePosition(NodeID)
3736
3737     def GetElementPosition(self,ElemID):
3738         """
3739         Return the position of an element on the shape
3740
3741         Returns:
3742             :class:`SMESH.ElementPosition`
3743         """
3744
3745         return self.mesh.GetElementPosition(ElemID)
3746
3747     def GetShapeID(self, id):
3748         """
3749         Return the ID of the shape, on which the given node was generated.
3750
3751         Returns:
3752             an integer value > 0 or -1 if there is no node for the given
3753             ID or the node is not assigned to any geometry
3754         """
3755
3756         return self.mesh.GetShapeID(id)
3757
3758     def GetShapeIDForElem(self,id):
3759         """
3760         Return the ID of the shape, on which the given element was generated.
3761
3762         Returns:
3763             an integer value > 0 or -1 if there is no element for the given
3764             ID or the element is not assigned to any geometry
3765         """
3766
3767         return self.mesh.GetShapeIDForElem(id)
3768
3769     def GetElemNbNodes(self, id):
3770         """
3771         Return the number of nodes of the given element
3772
3773         Returns:
3774             an integer value > 0 or -1 if there is no element for the given ID
3775         """
3776
3777         return self.mesh.GetElemNbNodes(id)
3778
3779     def GetElemNode(self, id, index):
3780         """
3781         Return the node ID the given (zero based) index for the given element.
3782
3783         * If there is no element for the given ID - return -1.
3784         * If there is no node for the given index - return -2.
3785
3786         Parameters:
3787             id (int): element ID
3788             index (int): node index within the element
3789
3790         Returns:
3791             an integer value (ID)
3792
3793         See Also:
3794             :meth:`GetElemNodes`
3795         """
3796
3797         return self.mesh.GetElemNode(id, index)
3798
3799     def GetElemNodes(self, id):
3800         """
3801         Return the IDs of nodes of the given element
3802
3803         Returns:
3804             a list of integer values
3805         """
3806
3807         return self.mesh.GetElemNodes(id)
3808
3809     def IsMediumNode(self, elementID, nodeID):
3810         """
3811         Return true if the given node is the medium node in the given quadratic element
3812         """
3813
3814         return self.mesh.IsMediumNode(elementID, nodeID)
3815
3816     def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
3817         """
3818         Return true if the given node is the medium node in one of quadratic elements
3819
3820         Parameters:
3821                 nodeID: ID of the node
3822                 elementType:  the type of elements to check a state of the node, either of
3823                         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
3824         """
3825
3826         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
3827
3828     def ElemNbEdges(self, id):
3829         """
3830         Return the number of edges for the given element
3831         """
3832
3833         return self.mesh.ElemNbEdges(id)
3834
3835     def ElemNbFaces(self, id):
3836         """
3837         Return the number of faces for the given element
3838         """
3839
3840         return self.mesh.ElemNbFaces(id)
3841
3842     def GetElemFaceNodes(self,elemId, faceIndex):
3843         """
3844         Return nodes of given face (counted from zero) for given volumic element.
3845         """
3846
3847         return self.mesh.GetElemFaceNodes(elemId, faceIndex)
3848
3849     def GetFaceNormal(self, faceId, normalized=False):
3850         """
3851         Return three components of normal of given mesh face
3852         (or an empty array in KO case)
3853         """
3854
3855         return self.mesh.GetFaceNormal(faceId,normalized)
3856
3857     def FindElementByNodes(self, nodes):
3858         """
3859         Return an element based on all given nodes.
3860         """
3861
3862         return self.mesh.FindElementByNodes(nodes)
3863
3864     def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
3865         """
3866         Return elements including all given nodes.
3867         """
3868
3869         return self.mesh.GetElementsByNodes( nodes, elemType )
3870
3871     def IsPoly(self, id):
3872         """
3873         Return true if the given element is a polygon
3874         """
3875
3876         return self.mesh.IsPoly(id)
3877
3878     def IsQuadratic(self, id):
3879         """
3880         Return true if the given element is quadratic
3881         """
3882
3883         return self.mesh.IsQuadratic(id)
3884
3885     def GetBallDiameter(self, id):
3886         """
3887         Return diameter of a ball discrete element or zero in case of an invalid *id*
3888         """
3889
3890         return self.mesh.GetBallDiameter(id)
3891
3892     def BaryCenter(self, id):
3893         """
3894         Return XYZ coordinates of the barycenter of the given element.
3895         If there is no element for the given ID - return an empty list
3896
3897         Returns:
3898             a list of three double values
3899
3900         See also: 
3901                 :meth:`smeshBuilder.GetGravityCenter`
3902         """
3903
3904         return self.mesh.BaryCenter(id)
3905
3906     def GetIdsFromFilter(self, filter, meshParts=[] ):
3907         """
3908         Pass mesh elements through the given filter and return IDs of fitting elements
3909
3910         Parameters:
3911                 filter: :class:`SMESH.Filter`
3912                 meshParts: list of mesh parts (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to filter
3913
3914         Returns:
3915             a list of ids
3916
3917         See Also:
3918             :meth:`SMESH.Filter.GetIDs`
3919             :meth:`SMESH.Filter.GetElementsIdFromParts`
3920         """
3921
3922         filter.SetMesh( self.mesh )
3923
3924         if meshParts:
3925             if isinstance( meshParts, Mesh ):
3926                 filter.SetMesh( meshParts.GetMesh() )
3927                 return theFilter.GetIDs()
3928             if isinstance( meshParts, SMESH._objref_SMESH_IDSource ):
3929                 meshParts = [ meshParts ]
3930             return filter.GetElementsIdFromParts( meshParts )
3931
3932         return filter.GetIDs()
3933
3934     # Get mesh measurements information:
3935     # ------------------------------------
3936
3937     def GetFreeBorders(self):
3938         """
3939         Verify whether a 2D mesh element has free edges (edges connected to one face only).
3940         Return a list of special structures (borders).
3941
3942         Returns:
3943             a list of :class:`SMESH.FreeEdges.Border`
3944         """
3945
3946         aFilterMgr = self.smeshpyD.CreateFilterManager()
3947         aPredicate = aFilterMgr.CreateFreeEdges()
3948         aPredicate.SetMesh(self.mesh)
3949         aBorders = aPredicate.GetBorders()
3950         aFilterMgr.UnRegister()
3951         return aBorders
3952
3953     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3954         """
3955         Get minimum distance between two nodes, elements or distance to the origin
3956
3957         Parameters:
3958                 id1: first node/element id
3959                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3960                 isElem1: *True* if *id1* is element id, *False* if it is node id
3961                 isElem2: *True* if *id2* is element id, *False* if it is node id
3962
3963         Returns:
3964             minimum distance value
3965         See Also:
3966             :meth:`GetMinDistance`
3967         """
3968
3969         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
3970         return aMeasure.value
3971
3972     def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
3973         """
3974         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
3975
3976         Parameters:
3977                 id1: first node/element id
3978                 id2: second node/element id (if 0, distance from *id1* to the origin is computed)
3979                 isElem1: *True* if *id1* is element id, *False* if it is node id
3980                 isElem2: *True* if *id2* is element id, *False* if it is node id
3981
3982         Returns:
3983             :class:`SMESH.Measure` structure
3984         See Also:
3985             :meth:`MinDistance`
3986         """
3987
3988         if isElem1:
3989             id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
3990         else:
3991             id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
3992         if id2 != 0:
3993             if isElem2:
3994                 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
3995             else:
3996                 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
3997             pass
3998         else:
3999             id2 = None
4000
4001         aMeasurements = self.smeshpyD.CreateMeasurements()
4002         aMeasure = aMeasurements.MinDistance(id1, id2)
4003         genObjUnRegister([aMeasurements,id1, id2])
4004         return aMeasure
4005
4006     def BoundingBox(self, objects=None, isElem=False):
4007         """
4008         Get bounding box of the specified object(s)
4009
4010         Parameters:
4011                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4012                 isElem: if *objects* is a list of IDs, *True* value in this parameters specifies that *objects* are elements,
4013                         *False* specifies that *objects* are nodes
4014
4015         Returns:
4016             tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
4017
4018         See Also: 
4019             :meth:`GetBoundingBox()`
4020         """
4021
4022         result = self.GetBoundingBox(objects, isElem)
4023         if result is None:
4024             result = (0.0,)*6
4025         else:
4026             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
4027         return result
4028
4029     def GetBoundingBox(self, objects=None, isElem=False):
4030         """
4031         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
4032
4033         Parameters:
4034                 objects: single :class:`source object <SMESH.SMESH_IDSource>` or list of source objects or list of nodes/elements IDs
4035                 isElem: if *objects* is a list of IDs, True means that *objects* are elements,
4036                         False means that *objects* are nodes
4037
4038         Returns:
4039             :class:`SMESH.Measure` structure
4040
4041         See Also: 
4042             :meth:`BoundingBox()`
4043         """
4044
4045         if objects is None:
4046             objects = [self.mesh]
4047         elif isinstance(objects, tuple):
4048             objects = list(objects)
4049         if not isinstance(objects, list):
4050             objects = [objects]
4051         if len(objects) > 0 and isinstance(objects[0], int):
4052             objects = [objects]
4053         srclist = []
4054         unRegister = genObjUnRegister()
4055         for o in objects:
4056             if isinstance(o, Mesh):
4057                 srclist.append(o.mesh)
4058             elif hasattr(o, "_narrow"):
4059                 src = o._narrow(SMESH.SMESH_IDSource)
4060                 if src: srclist.append(src)
4061                 pass
4062             elif isinstance(o, list):
4063                 if isElem:
4064                     srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
4065                 else:
4066                     srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
4067                 unRegister.set( srclist[-1] )
4068                 pass
4069             pass
4070         aMeasurements = self.smeshpyD.CreateMeasurements()
4071         unRegister.set( aMeasurements )
4072         aMeasure = aMeasurements.BoundingBox(srclist)
4073         return aMeasure
4074
4075     # Mesh edition (SMESH_MeshEditor functionality):
4076     # ---------------------------------------------
4077
4078     def RemoveElements(self, IDsOfElements):
4079         """
4080         Remove the elements from the mesh by ids
4081
4082         Parameters:
4083                 IDsOfElements: is a list of ids of elements to remove
4084
4085         Returns:
4086             True or False
4087
4088         Note:
4089                 This operation can create gaps in numeration of elements.
4090                 Call :meth:`RenumberElements` to remove the gaps.
4091         """
4092
4093         return self.editor.RemoveElements(IDsOfElements)
4094
4095     def RemoveNodes(self, IDsOfNodes):
4096         """
4097         Remove nodes from mesh by ids
4098
4099         Parameters:
4100                 IDsOfNodes: is a list of ids of nodes to remove
4101
4102         Returns:
4103             True or False
4104
4105         Note:
4106                 This operation can create gaps in numeration of nodes.
4107                 Call :meth:`RenumberElements` to remove the gaps.
4108         """
4109
4110         return self.editor.RemoveNodes(IDsOfNodes)
4111
4112     def RemoveOrphanNodes(self):
4113         """
4114         Remove all orphan (free) nodes from mesh
4115
4116         Returns:
4117             number of the removed nodes
4118
4119         Note:
4120                 This operation can create gaps in numeration of nodes.
4121                 Call :meth:`RenumberElements` to remove the gaps.
4122         """
4123
4124         return self.editor.RemoveOrphanNodes()
4125
4126     def AddNode(self, x, y, z):
4127         """
4128         Add a node to the mesh by coordinates
4129
4130         Returns:
4131             ID of the new node
4132         """
4133
4134         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4135         if hasVars: self.mesh.SetParameters(Parameters)
4136         return self.editor.AddNode( x, y, z)
4137
4138     def Add0DElement( self, IDOfNode, DuplicateElements=True ):
4139         """
4140         Create a 0D element on a node with given number.
4141
4142         Parameters:
4143                 IDOfNode: the ID of node for creation of the element.
4144                 DuplicateElements: to add one more 0D element to a node or not
4145
4146         Returns:
4147             ID of the new 0D element
4148         """
4149
4150         return self.editor.Add0DElement( IDOfNode, DuplicateElements )
4151
4152     def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
4153         """
4154         Create 0D elements on all nodes of the given elements except those
4155         nodes on which a 0D element already exists.
4156
4157         Parameters:
4158                 theObject: an object on whose nodes 0D elements will be created.
4159                         It can be list of element IDs, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4160                 theGroupName: optional name of a group to add 0D elements created
4161                         and/or found on nodes of *theObject*.
4162                 DuplicateElements: to add one more 0D element to a node or not
4163
4164         Returns:
4165             an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding
4166             IDs of new and/or found 0D elements. IDs of 0D elements
4167             can be retrieved from the returned object by 
4168             calling :meth:`GetIDs() <SMESH.SMESH_IDSource.GetIDs>`
4169         """
4170
4171         unRegister = genObjUnRegister()
4172         if isinstance( theObject, Mesh ):
4173             theObject = theObject.GetMesh()
4174         elif isinstance( theObject, list ):
4175             theObject = self.GetIDSource( theObject, SMESH.ALL )
4176             unRegister.set( theObject )
4177         return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
4178
4179     def AddBall(self, IDOfNode, diameter):
4180         """
4181         Create a ball element on a node with given ID.
4182
4183         Parameters:
4184                 IDOfNode: the ID of node for creation of the element.
4185                 diameter: the bal diameter.
4186
4187         Returns:
4188             ID of the new ball element
4189         """
4190
4191         return self.editor.AddBall( IDOfNode, diameter )
4192
4193     def AddEdge(self, IDsOfNodes):
4194         """
4195         Create a linear or quadratic edge (this is determined
4196         by the number of given nodes).
4197
4198         Parameters:
4199                 IDsOfNodes: list of node IDs for creation of the element.
4200                         The order of nodes in this list should correspond to
4201                         the :ref:`connectivity convention <connectivity_page>`.
4202
4203         Returns:
4204             ID of the new edge
4205         """
4206
4207         return self.editor.AddEdge(IDsOfNodes)
4208
4209     def AddFace(self, IDsOfNodes):
4210         """
4211         Create a linear or quadratic face (this is determined
4212         by the number of given nodes).
4213
4214         Parameters:
4215                 IDsOfNodes: list of node IDs for creation of the element.
4216                         The order of nodes in this list should correspond to
4217                         the :ref:`connectivity convention <connectivity_page>`.
4218
4219         Returns:
4220             ID of the new face
4221         """
4222
4223         return self.editor.AddFace(IDsOfNodes)
4224
4225     def AddPolygonalFace(self, IdsOfNodes):
4226         """
4227         Add a polygonal face defined by a list of node IDs
4228
4229         Parameters:
4230                 IdsOfNodes: the list of node IDs for creation of the element.
4231
4232         Returns:
4233             ID of the new face
4234         """
4235
4236         return self.editor.AddPolygonalFace(IdsOfNodes)
4237
4238     def AddQuadPolygonalFace(self, IdsOfNodes):
4239         """
4240         Add a quadratic polygonal face defined by a list of node IDs
4241
4242         Parameters:
4243                 IdsOfNodes: the list of node IDs for creation of the element;
4244                         corner nodes follow first.
4245
4246         Returns:
4247             ID of the new face
4248         """
4249
4250         return self.editor.AddQuadPolygonalFace(IdsOfNodes)
4251
4252     def AddVolume(self, IDsOfNodes):
4253         """
4254         Create both simple and quadratic volume (this is determined
4255         by the number of given nodes).
4256
4257         Parameters:
4258                 IDsOfNodes: list of node IDs for creation of the element.
4259                         The order of nodes in this list should correspond to
4260                         the :ref:`connectivity convention <connectivity_page>`.
4261
4262         Returns:
4263             ID of the new volumic element
4264         """
4265
4266         return self.editor.AddVolume(IDsOfNodes)
4267
4268     def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
4269         """
4270         Create a volume of many faces, giving nodes for each face.
4271
4272         Parameters:
4273                 IdsOfNodes: list of node IDs for volume creation, face by face.
4274                 Quantities: list of integer values, Quantities[i]
4275                         gives the quantity of nodes in face number i.
4276
4277         Returns:
4278             ID of the new volumic element
4279         """
4280
4281         return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
4282
4283     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
4284         """
4285         Create a volume of many faces, giving the IDs of the existing faces.
4286
4287         Note:
4288                 The created volume will refer only to the nodes
4289                 of the given faces, not to the faces themselves.
4290
4291         Parameters:
4292                 IdsOfFaces: the list of face IDs for volume creation.
4293
4294         Returns:
4295             ID of the new volumic element
4296         """
4297
4298         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
4299
4300
4301     def SetNodeOnVertex(self, NodeID, Vertex):
4302         """
4303         Bind a node to a vertex
4304
4305         Parameters:
4306                 NodeID: a node ID
4307                 Vertex: a vertex (GEOM.GEOM_Object) or vertex ID
4308
4309         Returns:
4310             True if succeed else raises an exception
4311         """
4312
4313         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
4314             VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
4315         else:
4316             VertexID = Vertex
4317         try:
4318             self.editor.SetNodeOnVertex(NodeID, VertexID)
4319         except SALOME.SALOME_Exception as inst:
4320             raise ValueError(inst.details.text)
4321         return True
4322
4323
4324     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
4325         """
4326         Store the node position on an edge
4327
4328         Parameters:
4329                 NodeID: a node ID
4330                 Edge: an edge (GEOM.GEOM_Object) or edge ID
4331                 paramOnEdge: a parameter on the edge where the node is located
4332
4333         Returns:
4334             True if succeed else raises an exception
4335         """
4336
4337         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
4338             EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
4339         else:
4340             EdgeID = Edge
4341         try:
4342             self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
4343         except SALOME.SALOME_Exception as inst:
4344             raise ValueError(inst.details.text)
4345         return True
4346
4347     def SetNodeOnFace(self, NodeID, Face, u, v):
4348         """
4349         Store node position on a face
4350
4351         Parameters:
4352                 NodeID: a node ID
4353                 Face: a face (GEOM.GEOM_Object) or face ID
4354                 u: U parameter on the face where the node is located
4355                 v: V parameter on the face where the node is located
4356
4357         Returns:
4358             True if succeed else raises an exception
4359         """
4360
4361         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
4362             FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
4363         else:
4364             FaceID = Face
4365         try:
4366             self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
4367         except SALOME.SALOME_Exception as inst:
4368             raise ValueError(inst.details.text)
4369         return True
4370
4371     def SetNodeInVolume(self, NodeID, Solid):
4372         """
4373         Bind a node to a solid
4374
4375         Parameters:
4376                 NodeID: a node ID
4377                 Solid:  a solid (GEOM.GEOM_Object) or solid ID
4378
4379         Returns:
4380             True if succeed else raises an exception
4381         """
4382
4383         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
4384             SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
4385         else:
4386             SolidID = Solid
4387         try:
4388             self.editor.SetNodeInVolume(NodeID, SolidID)
4389         except SALOME.SALOME_Exception as inst:
4390             raise ValueError(inst.details.text)
4391         return True
4392
4393     def SetMeshElementOnShape(self, ElementID, Shape):
4394         """
4395         Bind an element to a shape
4396
4397         Parameters:
4398                 ElementID: an element ID
4399                 Shape: a shape (GEOM.GEOM_Object) or shape ID
4400
4401         Returns:
4402             True if succeed else raises an exception
4403         """
4404
4405         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
4406             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
4407         else:
4408             ShapeID = Shape
4409         try:
4410             self.editor.SetMeshElementOnShape(ElementID, ShapeID)
4411         except SALOME.SALOME_Exception as inst:
4412             raise ValueError(inst.details.text)
4413         return True
4414
4415
4416     def MoveNode(self, NodeID, x, y, z):
4417         """
4418         Move the node with the given id
4419
4420         Parameters:
4421                 NodeID: the id of the node
4422                 x:  a new X coordinate
4423                 y:  a new Y coordinate
4424                 z:  a new Z coordinate
4425
4426         Returns:
4427             True if succeed else False
4428         """
4429
4430         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4431         if hasVars: self.mesh.SetParameters(Parameters)
4432         return self.editor.MoveNode(NodeID, x, y, z)
4433
4434     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
4435         """
4436         Find the node closest to a point and moves it to a point location
4437
4438         Parameters:
4439                 x:  the X coordinate of a point
4440                 y:  the Y coordinate of a point
4441                 z:  the Z coordinate of a point
4442                 NodeID: if specified (>0), the node with this ID is moved,
4443                         otherwise, the node closest to point (*x*, *y*, *z*) is moved
4444
4445         Returns:
4446             the ID of a moved node
4447         """
4448
4449         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
4450         if hasVars: self.mesh.SetParameters(Parameters)
4451         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
4452
4453     def FindNodeClosestTo(self, x, y, z):
4454         """
4455         Find the node closest to a point
4456
4457         Parameters:
4458                 x:  the X coordinate of a point
4459                 y:  the Y coordinate of a point
4460                 z:  the Z coordinate of a point
4461
4462         Returns:
4463             the ID of a node
4464         """
4465
4466         return self.editor.FindNodeClosestTo(x, y, z)
4467
4468     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
4469         """
4470         Find the elements where a point lays IN or ON
4471
4472         Parameters:
4473                 x,y,z (float): coordinates of the point
4474                 elementType (SMESH.ElementType): type of elements to find; SMESH.ALL type
4475                         means elements of any type excluding nodes, discrete and 0D elements.
4476                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to search within
4477
4478         Returns:
4479             list of IDs of found elements
4480         """
4481         if meshPart:
4482             return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
4483         else:
4484             return self.editor.FindElementsByPoint(x, y, z, elementType)
4485
4486     def ProjectPoint(self, x,y,z, elementType, meshObject=None):
4487         """
4488         Project a point to a mesh object.
4489         Return ID of an element of given type where the given point is projected
4490         and coordinates of the projection point.
4491         In the case if nothing found, return -1 and []
4492         """
4493         if isinstance( meshObject, Mesh ):
4494             meshObject = meshObject.GetMesh()
4495         if not meshObject:
4496             meshObject = self.GetMesh()
4497         return self.editor.ProjectPoint( x,y,z, elementType, meshObject )
4498
4499     def GetPointState(self, x, y, z):
4500         """
4501         Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
4502         smesh.TopAbs_IN, smesh.TopAbs_OUT, smesh.TopAbs_ON and smesh.TopAbs_UNKNOWN.
4503         UNKNOWN state means that either mesh is wrong or the analysis fails.
4504         """
4505
4506         return self.editor.GetPointState(x, y, z)
4507
4508     def IsManifold(self):
4509         """
4510         Check if a 2D mesh is manifold
4511         """
4512
4513         return self.editor.IsManifold()
4514
4515     def IsCoherentOrientation2D(self):
4516         """
4517         Check if orientation of 2D elements is coherent
4518         """
4519
4520         return self.editor.IsCoherentOrientation2D()
4521
4522     def Get1DBranches( self, edges, startNode = 0 ):
4523         """
4524         Partition given 1D elements into groups of contiguous edges.
4525         A node where number of meeting edges != 2 is a group end.
4526         An optional startNode is used to orient groups it belongs to.
4527
4528         Returns:
4529              A list of edge groups and a list of corresponding node groups,
4530              where the group is a list of IDs of edges or nodes, like follows
4531              [[[branch_edges_1],[branch_edges_2]], [[branch_nodes_1],[branch_nodes_2]]].
4532              If a group is closed, the first and last nodes of the group are same.
4533         """
4534         if isinstance( edges, Mesh ):
4535             edges = edges.GetMesh()
4536         unRegister = genObjUnRegister()
4537         if isinstance( edges, list ):
4538             edges = self.GetIDSource( edges, SMESH.EDGE )
4539             unRegister.set( edges )
4540         return self.editor.Get1DBranches( edges, startNode )
4541     
4542     def FindSharpEdges( self, angle, addExisting=False ):
4543         """
4544         Return sharp edges of faces and non-manifold ones.
4545         Optionally add existing edges.
4546
4547         Parameters:
4548                 angle: angle (in degrees) between normals of adjacent faces to detect sharp edges
4549                 addExisting: to return existing edges (1D elements) as well
4550
4551         Returns:
4552             list of FaceEdge structures
4553         """
4554         angle = ParseParameters( angle )[0]
4555         return self.editor.FindSharpEdges( angle, addExisting )
4556
4557     def MeshToPassThroughAPoint(self, x, y, z):
4558         """
4559         Find the node closest to a point and moves it to a point location
4560
4561         Parameters:
4562                 x:  the X coordinate of a point
4563                 y:  the Y coordinate of a point
4564                 z:  the Z coordinate of a point
4565
4566         Returns:
4567             the ID of a moved node
4568         """
4569
4570         return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
4571
4572     def InverseDiag(self, NodeID1, NodeID2):
4573         """
4574         Replace two neighbour triangles sharing Node1-Node2 link
4575         with the triangles built on the same 4 nodes but having other common link.
4576
4577         Parameters:
4578                 NodeID1:  the ID of the first node
4579                 NodeID2:  the ID of the second node
4580
4581         Returns:
4582             False if proper faces were not found
4583         """
4584         return self.editor.InverseDiag(NodeID1, NodeID2)
4585
4586     def DeleteDiag(self, NodeID1, NodeID2):
4587         """
4588         Replace two neighbour triangles sharing *Node1-Node2* link
4589         with a quadrangle built on the same 4 nodes.
4590
4591         Parameters:
4592                 NodeID1: ID of the first node
4593                 NodeID2: ID of the second node
4594
4595         Returns:
4596             False if proper faces were not found
4597
4598         Note:
4599                 This operation can create gaps in numeration of elements.
4600                 Call :meth:`RenumberElements` to remove the gaps.
4601         """
4602
4603         return self.editor.DeleteDiag(NodeID1, NodeID2)
4604
4605     def Reorient(self, IDsOfElements=None):
4606         """
4607         Reorient elements by ids
4608
4609         Parameters:
4610                 IDsOfElements: if undefined reorients all mesh elements
4611
4612         Returns:
4613             True if succeed else False
4614         """
4615
4616         if IDsOfElements == None:
4617             IDsOfElements = self.GetElementsId()
4618         return self.editor.Reorient(IDsOfElements)
4619
4620     def ReorientObject(self, theObject):
4621         """
4622         Reorient all elements of the object
4623
4624         Parameters:
4625                 theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4626
4627         Returns:
4628             True if succeed else False
4629         """
4630
4631         if ( isinstance( theObject, Mesh )):
4632             theObject = theObject.GetMesh()
4633         return self.editor.ReorientObject(theObject)
4634
4635     def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
4636         """
4637         Reorient faces contained in *the2DObject*.
4638
4639         Parameters:
4640                 the2DObject: a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` or list of IDs of 2D elements
4641                 theDirection: a desired direction of normal of *theFace*.
4642                         It can be either a GEOM vector or a list of coordinates [x,y,z].
4643                 theFaceOrPoint: defines a face of *the2DObject* whose normal will be
4644                         compared with theDirection. It can be either ID of face or a point
4645                         by which the face will be found. The point can be given as either
4646                         a GEOM vertex or a list of point coordinates.
4647
4648         Returns:
4649             number of reoriented faces
4650         """
4651
4652         unRegister = genObjUnRegister()
4653         # check the2DObject
4654         if isinstance( the2DObject, Mesh ):
4655             the2DObject = the2DObject.GetMesh()
4656         if isinstance( the2DObject, list ):
4657             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4658             unRegister.set( the2DObject )
4659         # check theDirection
4660         if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
4661             theDirection = self.smeshpyD.GetDirStruct( theDirection )
4662         if isinstance( theDirection, list ):
4663             theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
4664         # prepare theFace and thePoint
4665         theFace = theFaceOrPoint
4666         thePoint = PointStruct(0,0,0)
4667         if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
4668             thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
4669             theFace = -1
4670         if isinstance( theFaceOrPoint, list ):
4671             thePoint = PointStruct( *theFaceOrPoint )
4672             theFace = -1
4673         if isinstance( theFaceOrPoint, PointStruct ):
4674             thePoint = theFaceOrPoint
4675             theFace = -1
4676         return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
4677
4678     def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
4679         """
4680         Reorient faces according to adjacent volumes.
4681
4682         Parameters:
4683                 the2DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of
4684                         either IDs of faces or face groups.
4685                 the3DObject: is a :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of IDs of volumes.
4686                 theOutsideNormal: to orient faces to have their normals
4687                         pointing either *outside* or *inside* the adjacent volumes.
4688
4689         Returns:
4690             number of reoriented faces.
4691         """
4692
4693         unRegister = genObjUnRegister()
4694         # check the2DObject
4695         if not isinstance( the2DObject, list ):
4696             the2DObject = [ the2DObject ]
4697         elif the2DObject and isinstance( the2DObject[0], int ):
4698             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
4699             unRegister.set( the2DObject )
4700             the2DObject = [ the2DObject ]
4701         for i,obj2D in enumerate( the2DObject ):
4702             if isinstance( obj2D, Mesh ):
4703                 the2DObject[i] = obj2D.GetMesh()
4704             if isinstance( obj2D, list ):
4705                 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
4706                 unRegister.set( the2DObject[i] )
4707         # check the3DObject
4708         if isinstance( the3DObject, Mesh ):
4709             the3DObject = the3DObject.GetMesh()
4710         if isinstance( the3DObject, list ):
4711             the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
4712             unRegister.set( the3DObject )
4713         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
4714
4715     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
4716         """
4717         Fuse the neighbouring triangles into quadrangles.
4718
4719         Parameters:
4720                 IDsOfElements: The triangles to be fused.
4721                 theCriterion:  a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4722                         applied to possible quadrangles to choose a neighbour to fuse with.
4723                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4724                         to numerical functors.
4725                 MaxAngle: is the maximum angle between element normals at which the fusion
4726                         is still performed; theMaxAngle is measured in radians.
4727                         Also it could be a name of variable which defines angle in degrees.
4728
4729         Returns:
4730             True in case of success, False otherwise.
4731
4732         Note:
4733                 This operation can create gaps in numeration of elements.
4734                 Call :meth:`RenumberElements` to remove the gaps.
4735         """
4736
4737         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4738         self.mesh.SetParameters(Parameters)
4739         if not IDsOfElements:
4740             IDsOfElements = self.GetElementsId()
4741         Functor = self.smeshpyD.GetFunctor(theCriterion)
4742         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
4743
4744     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
4745         """
4746         Fuse the neighbouring triangles of the object into quadrangles
4747
4748         Parameters:
4749                 theObject: is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4750                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`,
4751                         applied to possible quadrangles to choose a neighbour to fuse with.
4752                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4753                         to numerical functors.
4754                 MaxAngle: a max angle between element normals at which the fusion
4755                         is still performed; theMaxAngle is measured in radians.
4756
4757         Returns:
4758             True in case of success, False otherwise.
4759
4760         Note:
4761                 This operation can create gaps in numeration of elements.
4762                 Call :meth:`RenumberElements` to remove the gaps.
4763         """
4764
4765         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
4766         self.mesh.SetParameters(Parameters)
4767         if isinstance( theObject, Mesh ):
4768             theObject = theObject.GetMesh()
4769         Functor = self.smeshpyD.GetFunctor(theCriterion)
4770         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
4771
4772     def QuadToTri (self, IDsOfElements, theCriterion = None):
4773         """
4774         Split quadrangles into triangles.
4775
4776         Parameters:
4777                 IDsOfElements: the faces to be splitted.
4778                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4779                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4780                         value, then quadrangles will be split by the smallest diagonal.
4781                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4782                         to numerical functors.
4783
4784         Returns:
4785             True in case of success, False otherwise.
4786
4787         Note:
4788                 This operation can create gaps in numeration of elements.
4789                 Call :meth:`RenumberElements` to remove the gaps.
4790         """
4791         if IDsOfElements == []:
4792             IDsOfElements = self.GetElementsId()
4793         if theCriterion is None:
4794             theCriterion = FT_MaxElementLength2D
4795         Functor = self.smeshpyD.GetFunctor(theCriterion)
4796         return self.editor.QuadToTri(IDsOfElements, Functor)
4797
4798     def QuadToTriObject (self, theObject, theCriterion = None):
4799         """
4800         Split quadrangles into triangles.
4801
4802         Parameters:
4803                 theObject: the object from which the list of elements is taken,
4804                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4805                 theCriterion: is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4806                         choose a diagonal for splitting. If *theCriterion* is None, which is a default
4807                         value, then quadrangles will be split by the smallest diagonal.
4808                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4809                         to numerical functors.
4810
4811         Returns:
4812             True in case of success, False otherwise.
4813
4814         Note:
4815                 This operation can create gaps in numeration of elements.
4816                 Call :meth:`RenumberElements` to remove the gaps.
4817         """
4818         if ( isinstance( theObject, Mesh )):
4819             theObject = theObject.GetMesh()
4820         if theCriterion is None:
4821             theCriterion = FT_MaxElementLength2D
4822         Functor = self.smeshpyD.GetFunctor(theCriterion)
4823         return self.editor.QuadToTriObject(theObject, Functor)
4824
4825     def QuadTo4Tri (self, theElements=[]):
4826         """
4827         Split each of given quadrangles into 4 triangles. A node is added at the center of
4828         a quadrangle.
4829
4830         Parameters:
4831                 theElements: the faces to be splitted. This can be either 
4832                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`
4833                         or a list of face IDs. By default all quadrangles are split
4834
4835         Note:
4836                 This operation can create gaps in numeration of elements.
4837                 Call :meth:`RenumberElements` to remove the gaps.
4838         """
4839         unRegister = genObjUnRegister()
4840         if isinstance( theElements, Mesh ):
4841             theElements = theElements.mesh
4842         elif not theElements:
4843             theElements = self.mesh
4844         elif isinstance( theElements, list ):
4845             theElements = self.GetIDSource( theElements, SMESH.FACE )
4846             unRegister.set( theElements )
4847         return self.editor.QuadTo4Tri( theElements )
4848
4849     def SplitQuad (self, IDsOfElements, Diag13):
4850         """
4851         Split quadrangles into triangles.
4852
4853         Parameters:
4854                 IDsOfElements: the faces to be splitted
4855                 Diag13 (boolean):        is used to choose a diagonal for splitting.
4856
4857         Returns:
4858             True in case of success, False otherwise.
4859
4860         Note:
4861                 This operation can create gaps in numeration of elements.
4862                 Call :meth:`RenumberElements` to remove the gaps.
4863         """
4864         if IDsOfElements == []:
4865             IDsOfElements = self.GetElementsId()
4866         return self.editor.SplitQuad(IDsOfElements, Diag13)
4867
4868     def SplitQuadObject (self, theObject, Diag13):
4869         """
4870         Split quadrangles into triangles.
4871
4872         Parameters:
4873                 theObject: the object from which the list of elements is taken,
4874                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4875                 Diag13 (boolean):    is used to choose a diagonal for splitting.
4876
4877         Returns:
4878             True in case of success, False otherwise.
4879
4880         Note:
4881                 This operation can create gaps in numeration of elements.
4882                 Call :meth:`RenumberElements` to remove the gaps.
4883         """
4884         if ( isinstance( theObject, Mesh )):
4885             theObject = theObject.GetMesh()
4886         return self.editor.SplitQuadObject(theObject, Diag13)
4887
4888     def BestSplit (self, IDOfQuad, theCriterion):
4889         """
4890         Find a better splitting of the given quadrangle.
4891
4892         Parameters:
4893                 IDOfQuad:   the ID of the quadrangle to be splitted.
4894                 theCriterion:  is a numerical functor, in terms of enum :class:`SMESH.FunctorType`, used to
4895                         choose a diagonal for splitting.
4896                         Note that not all items of :class:`SMESH.FunctorType` corresponds
4897                         to numerical functors.
4898
4899         Returns:
4900             * 1 if 1-3 diagonal is better, 
4901             * 2 if 2-4 diagonal is better, 
4902             * 0 if error occurs.
4903
4904         Note:
4905                 This operation can create gaps in numeration of elements.
4906                 Call :meth:`RenumberElements` to remove the gaps.
4907         """
4908         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
4909
4910     def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
4911         """
4912         Split volumic elements into tetrahedrons
4913
4914         Parameters:
4915                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4916                 method:  flags passing splitting method:
4917                         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
4918                         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
4919
4920         Note:
4921                 This operation can create gaps in numeration of elements.
4922                 Call :meth:`RenumberElements` to remove the gaps.
4923         """
4924         unRegister = genObjUnRegister()
4925         if isinstance( elems, Mesh ):
4926             elems = elems.GetMesh()
4927         if ( isinstance( elems, list )):
4928             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4929             unRegister.set( elems )
4930         self.editor.SplitVolumesIntoTetra(elems, method)
4931         return
4932
4933     def SplitBiQuadraticIntoLinear(self, elems=None):
4934         """
4935         Split bi-quadratic elements into linear ones without creation of additional nodes:
4936
4937             - bi-quadratic triangle will be split into 3 linear quadrangles;
4938             - bi-quadratic quadrangle will be split into 4 linear quadrangles;
4939             - tri-quadratic hexahedron will be split into 8 linear hexahedra.
4940
4941         Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
4942         will be split in order to keep the mesh conformal.
4943
4944         Parameters:
4945             elems: elements to split\: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or element IDs;
4946                 if None (default), all bi-quadratic elements will be split
4947
4948         Note:
4949                 This operation can create gaps in numeration of elements.
4950                 Call :meth:`RenumberElements` to remove the gaps.
4951         """
4952         unRegister = genObjUnRegister()
4953         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
4954             elems = self.editor.MakeIDSource(elems, SMESH.ALL)
4955             unRegister.set( elems )
4956         if elems is None:
4957             elems = [ self.GetMesh() ]
4958         if isinstance( elems, Mesh ):
4959             elems = [ elems.GetMesh() ]
4960         if not isinstance( elems, list ):
4961             elems = [elems]
4962         self.editor.SplitBiQuadraticIntoLinear( elems )
4963
4964     def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
4965                                  method=smeshBuilder.Hex_2Prisms, allDomains=False ):
4966         """
4967         Split hexahedra into prisms
4968
4969         Parameters:
4970                 elems: either a list of elements or a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
4971                 startHexPoint: a point used to find a hexahedron for which *facetNormal*
4972                         gives a normal vector defining facets to split into triangles.
4973                         *startHexPoint* can be either a triple of coordinates or a vertex.
4974                 facetNormal: a normal to a facet to split into triangles of a
4975                         hexahedron found by *startHexPoint*.
4976                         *facetNormal* can be either a triple of coordinates or an edge.
4977                 method:  flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
4978                         smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
4979                 allDomains: if :code:`False`, only hexahedra adjacent to one closest
4980                         to *startHexPoint* are split, else *startHexPoint*
4981                         is used to find the facet to split in all domains present in *elems*.
4982
4983         Note:
4984                 This operation can create gaps in numeration of elements.
4985                 Call :meth:`RenumberElements` to remove the gaps.
4986         """
4987         # IDSource
4988         unRegister = genObjUnRegister()
4989         if isinstance( elems, Mesh ):
4990             elems = elems.GetMesh()
4991         if ( isinstance( elems, list )):
4992             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
4993             unRegister.set( elems )
4994             pass
4995         # axis
4996         if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
4997             startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
4998         elif isinstance( startHexPoint, list ):
4999             startHexPoint = SMESH.PointStruct( startHexPoint[0],
5000                                                startHexPoint[1],
5001                                                startHexPoint[2])
5002         if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
5003             facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
5004         elif isinstance( facetNormal, list ):
5005             facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
5006                                                        facetNormal[1],
5007                                                        facetNormal[2])
5008         self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
5009
5010         self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
5011
5012     def SplitQuadsNearTriangularFacets(self):
5013         """
5014         Split quadrangle faces near triangular facets of volumes
5015
5016         Note:
5017                 This operation can create gaps in numeration of elements.
5018                 Call :meth:`RenumberElements` to remove the gaps.
5019         """
5020         faces_array = self.GetElementsByType(SMESH.FACE)
5021         for face_id in faces_array:
5022             if self.GetElemNbNodes(face_id) == 4: # quadrangle
5023                 quad_nodes = self.mesh.GetElemNodes(face_id)
5024                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
5025                 isVolumeFound = False
5026                 for node1_elem in node1_elems:
5027                     if not isVolumeFound:
5028                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
5029                             nb_nodes = self.GetElemNbNodes(node1_elem)
5030                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
5031                                 volume_elem = node1_elem
5032                                 volume_nodes = self.mesh.GetElemNodes(volume_elem)
5033                                 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
5034                                     if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
5035                                         isVolumeFound = True
5036                                         if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
5037                                             self.SplitQuad([face_id], False) # diagonal 2-4
5038                                     elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
5039                                         isVolumeFound = True
5040                                         self.SplitQuad([face_id], True) # diagonal 1-3
5041                                 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
5042                                     if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
5043                                         isVolumeFound = True
5044                                         self.SplitQuad([face_id], True) # diagonal 1-3
5045
5046     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
5047         """
5048         Split hexahedrons into tetrahedrons.
5049
5050         This operation uses :doc:`pattern_mapping` functionality for splitting.
5051
5052         Parameters:
5053                 theObject: the object from which the list of hexahedrons is taken; 
5054                         this is :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
5055                 theNode000,theNode001: within the range [0,7]; gives the orientation of the
5056                         pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
5057                         will be mapped into *theNode000*-th node of each volume, the (0,0,1)
5058                         key-point will be mapped into *theNode001*-th node of each volume.
5059                         The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
5060
5061         Returns:
5062             True in case of success, False otherwise.
5063
5064         Note:
5065                 This operation can create gaps in numeration of elements.
5066                 Call :meth:`RenumberElements` to remove the gaps.
5067         """
5068 #    Pattern:
5069 #                     5.---------.6
5070 #                    /|#*      /|
5071 #                   / | #*    / |
5072 #                  /  |  # * /  |
5073 #                 /   |   # /*  |
5074 #       (0,0,1) 4.---------.7 * |
5075 #                |#*  |1   | # *|
5076 #                | # *.----|---#.2
5077 #                |  #/ *   |   /
5078 #                |  /#  *  |  /
5079 #                | /   # * | /
5080 #                |/      #*|/
5081 #        (0,0,0) 0.---------.3
5082         pattern_tetra = "!!! Nb of points: \n 8 \n\
5083         !!! Points: \n\
5084         0 0 0  !- 0 \n\
5085         0 1 0  !- 1 \n\
5086         1 1 0  !- 2 \n\
5087         1 0 0  !- 3 \n\
5088         0 0 1  !- 4 \n\
5089         0 1 1  !- 5 \n\
5090         1 1 1  !- 6 \n\
5091         1 0 1  !- 7 \n\
5092         !!! Indices of points of 6 tetras: \n\
5093         0 3 4 1 \n\
5094         7 4 3 1 \n\
5095         4 7 5 1 \n\
5096         6 2 5 7 \n\
5097         1 5 2 7 \n\
5098         2 3 1 7 \n"
5099
5100         pattern = self.smeshpyD.GetPattern()
5101         isDone  = pattern.LoadFromFile(pattern_tetra)
5102         if not isDone:
5103             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5104             return isDone
5105
5106         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5107         isDone = pattern.MakeMesh(self.mesh, False, False)
5108         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5109
5110         # split quafrangle faces near triangular facets of volumes
5111         self.SplitQuadsNearTriangularFacets()
5112
5113         return isDone
5114
5115     def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
5116         """
5117         Split hexahedrons into prisms.
5118
5119         Uses the :doc:`pattern_mapping` functionality for splitting.
5120
5121         Parameters:
5122                 theObject: the object (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`) from where the list of hexahedrons is taken;
5123                 theNode000,theNode001: (within the range [0,7]) gives the orientation of the
5124                         pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
5125                         will be mapped into the *theNode000* -th node of each volume, keypoint (0,0,1)
5126                         will be mapped into the *theNode001* -th node of each volume.
5127                         Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
5128
5129         Returns:
5130             True in case of success, False otherwise.
5131
5132         Note:
5133                 This operation can create gaps in numeration of elements.
5134                 Call :meth:`RenumberElements` to remove the gaps.
5135         """
5136 #        Pattern:     5.---------.6
5137 #                     /|#       /|
5138 #                    / | #     / |
5139 #                   /  |  #   /  |
5140 #                  /   |   # /   |
5141 #        (0,0,1) 4.---------.7   |
5142 #                 |    |    |    |
5143 #                 |   1.----|----.2
5144 #                 |   / *   |   /
5145 #                 |  /   *  |  /
5146 #                 | /     * | /
5147 #                 |/       *|/
5148 #        (0,0,0) 0.---------.3
5149         pattern_prism = "!!! Nb of points: \n 8 \n\
5150         !!! Points: \n\
5151         0 0 0  !- 0 \n\
5152         0 1 0  !- 1 \n\
5153         1 1 0  !- 2 \n\
5154         1 0 0  !- 3 \n\
5155         0 0 1  !- 4 \n\
5156         0 1 1  !- 5 \n\
5157         1 1 1  !- 6 \n\
5158         1 0 1  !- 7 \n\
5159         !!! Indices of points of 2 prisms: \n\
5160         0 1 3 4 5 7 \n\
5161         2 3 1 6 7 5 \n"
5162
5163         pattern = self.smeshpyD.GetPattern()
5164         isDone  = pattern.LoadFromFile(pattern_prism)
5165         if not isDone:
5166             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
5167             return isDone
5168
5169         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
5170         isDone = pattern.MakeMesh(self.mesh, False, False)
5171         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
5172
5173         # Split quafrangle faces near triangular facets of volumes
5174         self.SplitQuadsNearTriangularFacets()
5175
5176         return isDone
5177
5178     def Smooth(self, IDsOfElements, IDsOfFixedNodes,
5179                MaxNbOfIterations, MaxAspectRatio, Method):
5180         """
5181         Smooth elements
5182
5183         Parameters:
5184                 IDsOfElements: the list if ids of elements to smooth
5185                 IDsOfFixedNodes: the list of ids of fixed nodes.
5186                         Note that nodes built on edges and boundary nodes are always fixed.
5187                 MaxNbOfIterations: the maximum number of iterations
5188                 MaxAspectRatio: varies in range [1.0, inf]
5189                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5190                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5191
5192         Returns:
5193             True in case of success, False otherwise.
5194         """
5195
5196         if IDsOfElements == []:
5197             IDsOfElements = self.GetElementsId()
5198         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5199         self.mesh.SetParameters(Parameters)
5200         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
5201                                   MaxNbOfIterations, MaxAspectRatio, Method)
5202
5203     def SmoothObject(self, theObject, IDsOfFixedNodes,
5204                      MaxNbOfIterations, MaxAspectRatio, Method):
5205         """
5206         Smooth elements which belong to the given object
5207
5208         Parameters:
5209                 theObject: the object to smooth
5210                 IDsOfFixedNodes: the list of ids of fixed nodes.
5211                         Note that nodes built on edges and boundary nodes are always fixed.
5212                 MaxNbOfIterations: the maximum number of iterations
5213                 MaxAspectRatio: varies in range [1.0, inf]
5214                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5215                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5216
5217         Returns:
5218             True in case of success, False otherwise.
5219         """
5220
5221         if ( isinstance( theObject, Mesh )):
5222             theObject = theObject.GetMesh()
5223         return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
5224                                         MaxNbOfIterations, MaxAspectRatio, Method)
5225
5226     def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
5227                          MaxNbOfIterations, MaxAspectRatio, Method):
5228         """
5229         Parametrically smooth the given elements
5230
5231         Parameters:
5232                 IDsOfElements: the list if ids of elements to smooth
5233                 IDsOfFixedNodes: the list of ids of fixed nodes.
5234                         Note that nodes built on edges and boundary nodes are always fixed.
5235                 MaxNbOfIterations: the maximum number of iterations
5236                 MaxAspectRatio: varies in range [1.0, inf]
5237                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5238                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5239
5240         Returns:
5241             True in case of success, False otherwise.
5242         """
5243
5244         if IDsOfElements == []:
5245             IDsOfElements = self.GetElementsId()
5246         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
5247         self.mesh.SetParameters(Parameters)
5248         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
5249                                             MaxNbOfIterations, MaxAspectRatio, Method)
5250
5251     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
5252                                MaxNbOfIterations, MaxAspectRatio, Method):
5253         """
5254         Parametrically smooth the elements which belong to the given object
5255
5256         Parameters:
5257                 theObject: the object to smooth
5258                 IDsOfFixedNodes: the list of ids of fixed nodes.
5259                         Note that nodes built on edges and boundary nodes are always fixed.
5260                 MaxNbOfIterations: the maximum number of iterations
5261                 MaxAspectRatio: varies in range [1.0, inf]
5262                 Method: is either Laplacian (smesh.LAPLACIAN_SMOOTH)
5263                         or Centroidal (smesh.CENTROIDAL_SMOOTH)
5264
5265         Returns:
5266             True in case of success, False otherwise.
5267         """
5268
5269         if ( isinstance( theObject, Mesh )):
5270             theObject = theObject.GetMesh()
5271         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
5272                                                   MaxNbOfIterations, MaxAspectRatio, Method)
5273
5274     def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
5275         """
5276         Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
5277         them with quadratic with the same id.
5278
5279         Parameters:
5280                 theForce3d: method of new node creation:
5281
5282                   * False - the medium node lies at the geometrical entity from which the mesh element is built
5283                   * True - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
5284                 theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5285                 theToBiQuad: If True, converts the mesh to bi-quadratic
5286
5287         Returns:
5288             :class:`SMESH.ComputeError` which can hold a warning
5289
5290         Warning:
5291             If *theSubMesh* is provided, the mesh can become non-conformal
5292
5293         Note:
5294                 This operation can create gaps in numeration of nodes or elements.
5295                 Call :meth:`RenumberElements` to remove the gaps.
5296         """
5297
5298         if isinstance( theSubMesh, Mesh ):
5299             theSubMesh = theSubMesh.mesh
5300         if theToBiQuad:
5301             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
5302         else:
5303             if theSubMesh:
5304                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
5305             else:
5306                 self.editor.ConvertToQuadratic(theForce3d)
5307         error = self.editor.GetLastError()
5308         if error and error.comment:
5309             print(error.comment)
5310         return error
5311
5312     def ConvertFromQuadratic(self, theSubMesh=None):
5313         """
5314         Convert the mesh from quadratic to ordinary,
5315         deletes old quadratic elements,
5316         replacing them with ordinary mesh elements with the same id.
5317
5318         Parameters:
5319             theSubMesh: a :class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>` to convert
5320
5321         Warning:
5322             If *theSubMesh* is provided, the mesh can become non-conformal
5323
5324         Note:
5325                 This operation can create gaps in numeration of nodes or elements.
5326                 Call :meth:`RenumberElements` to remove the gaps.
5327         """
5328
5329         if theSubMesh:
5330             self.editor.ConvertFromQuadraticObject(theSubMesh)
5331         else:
5332             return self.editor.ConvertFromQuadratic()
5333
5334     def Make2DMeshFrom3D(self):
5335         """
5336         Create 2D mesh as skin on boundary faces of a 3D mesh
5337
5338         Returns:
5339             True if operation has been completed successfully, False otherwise
5340         """
5341
5342         return self.editor.Make2DMeshFrom3D()
5343
5344     def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5345                          toCopyElements=False, toCopyExistingBondary=False):
5346         """
5347         Create missing boundary elements
5348
5349         Parameters:
5350                 elements: elements whose boundary is to be checked:
5351                         :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` or list of elements.
5352                         If *elements* is mesh, it must be the mesh whose MakeBoundaryMesh() is called
5353                 dimension: defines type of boundary elements to create, either of
5354                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }.
5355                         SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
5356                 groupName: a name of group to store created boundary elements in,
5357                         "" means not to create the group
5358                 meshName: a name of new mesh to store created boundary elements in,
5359                         "" means not to create the new mesh
5360                 toCopyElements: if True, the checked elements will be copied into
5361                         the new mesh else only boundary elements will be copied into the new mesh
5362                 toCopyExistingBondary: if True, not only new but also pre-existing
5363                         boundary elements will be copied into the new mesh
5364
5365         Returns:
5366             tuple (:class:`Mesh`, :class:`group <SMESH.SMESH_Group>`) where boundary elements were added to
5367         """
5368
5369         unRegister = genObjUnRegister()
5370         if isinstance( elements, Mesh ):
5371             elements = elements.GetMesh()
5372         if ( isinstance( elements, list )):
5373             elemType = SMESH.ALL
5374             if elements: elemType = self.GetElementType( elements[0], iselem=True)
5375             elements = self.editor.MakeIDSource(elements, elemType)
5376             unRegister.set( elements )
5377         mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
5378                                                    toCopyElements,toCopyExistingBondary)
5379         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5380         return mesh, group
5381
5382     def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
5383                              toCopyAll=False, groups=[]):
5384         """
5385         Create missing boundary elements around either the whole mesh or
5386         groups of elements
5387
5388         Parameters:
5389                 dimension: defines type of boundary elements to create, either of
5390                         { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
5391                 groupName: a name of group to store all boundary elements in,
5392                         "" means not to create the group
5393                 meshName: a name of a new mesh, which is a copy of the initial
5394                         mesh + created boundary elements; "" means not to create the new mesh
5395                 toCopyAll: if True, the whole initial mesh will be copied into
5396                         the new mesh else only boundary elements will be copied into the new mesh
5397                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
5398
5399         Returns:
5400                 tuple( long, mesh, group )
5401                        - long - number of added boundary elements
5402                        - mesh - the :class:`Mesh` where elements were added to
5403                        - group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
5404         """
5405
5406         nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
5407                                                            toCopyAll,groups)
5408         if mesh: mesh = self.smeshpyD.Mesh(mesh)
5409         return nb, mesh, group
5410
5411     def RenumberNodes(self):
5412         """
5413         Renumber mesh nodes to remove unused node IDs
5414         """
5415         self.editor.RenumberNodes()
5416
5417     def RenumberElements(self):
5418         """
5419         Renumber mesh elements to remove unused element IDs
5420         """
5421         self.editor.RenumberElements()
5422
5423     def _getIdSourceList(self, arg, idType, unRegister):
5424         """
5425         Private method converting *arg* into a list of :class:`SMESH.SMESH_IDSource`
5426         """
5427         if arg and isinstance( arg, list ):
5428             if isinstance( arg[0], int ):
5429                 arg = self.GetIDSource( arg, idType )
5430                 unRegister.set( arg )
5431             elif isinstance( arg[0], Mesh ):
5432                 arg[0] = arg[0].GetMesh()
5433         elif isinstance( arg, Mesh ):
5434             arg = arg.GetMesh()
5435         if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
5436             arg = [arg]
5437         return arg
5438
5439     def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
5440                              MakeGroups=False, TotalAngle=False):
5441         """
5442         Generate new elements by rotation of the given elements and nodes around the axis
5443
5444         Parameters:
5445                 nodes: nodes to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5446                 edges: edges to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5447                 faces: faces to revolve: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5448                 Axis: the axis of rotation: :class:`SMESH.AxisStruct`, line (geom object) or [x,y,z,dx,dy,dz]
5449                 AngleInRadians: the angle of Rotation (in radians) or a name of variable
5450                         which defines angle in degrees
5451                 NbOfSteps: the number of steps
5452                 Tolerance: tolerance
5453                 MakeGroups: forces the generation of new groups from existing ones
5454                 TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5455                         of all steps, else - size of each step
5456
5457         Returns:
5458             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5459         """
5460
5461         unRegister = genObjUnRegister()
5462         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5463         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5464         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5465
5466         if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
5467             Axis = self.smeshpyD.GetAxisStruct( Axis )
5468         if isinstance( Axis, list ):
5469             Axis = SMESH.AxisStruct( *Axis )
5470
5471         AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
5472         NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
5473         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
5474         self.mesh.SetParameters(Parameters)
5475         if TotalAngle and NbOfSteps:
5476             AngleInRadians /= NbOfSteps
5477         return self.editor.RotationSweepObjects( nodes, edges, faces,
5478                                                  Axis, AngleInRadians,
5479                                                  NbOfSteps, Tolerance, MakeGroups)
5480
5481     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
5482                       MakeGroups=False, TotalAngle=False):
5483         """
5484         Generate new elements by rotation of the elements around the axis
5485
5486         Parameters:
5487             IDsOfElements: the list of ids of elements to sweep
5488             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5489             AngleInRadians: the angle of Rotation (in radians) or a name of variable which defines angle in degrees
5490             NbOfSteps: the number of steps
5491             Tolerance: tolerance
5492             MakeGroups: forces the generation of new groups from existing ones
5493             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5494                 of all steps, else - size of each step
5495
5496         Returns:
5497             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5498         """
5499
5500         return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
5501                                          AngleInRadians, NbOfSteps, Tolerance,
5502                                          MakeGroups, TotalAngle)
5503
5504     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5505                             MakeGroups=False, TotalAngle=False):
5506         """
5507         Generate new elements by rotation of the elements of object around the axis
5508         theObject object which elements should be sweeped.
5509         It can be a mesh, a sub mesh or a group.
5510
5511         Parameters:
5512             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5513             AngleInRadians: the angle of Rotation
5514             NbOfSteps: number of steps
5515             Tolerance: tolerance
5516             MakeGroups: forces the generation of new groups from existing ones
5517             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5518                 of all steps, else - size of each step
5519
5520         Returns:
5521             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5522         """
5523
5524         return self.RotationSweepObjects( [], theObject, theObject, Axis,
5525                                           AngleInRadians, NbOfSteps, Tolerance,
5526                                           MakeGroups, TotalAngle )
5527
5528     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5529                               MakeGroups=False, TotalAngle=False):
5530         """
5531         Generate new elements by rotation of the elements of object around the axis
5532         theObject object which elements should be sweeped.
5533         It can be a mesh, a sub mesh or a group.
5534
5535         Parameters:
5536             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5537             AngleInRadians: the angle of Rotation
5538             NbOfSteps: number of steps
5539             Tolerance: tolerance
5540             MakeGroups: forces the generation of new groups from existing ones
5541             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5542                 of all steps, else - size of each step
5543
5544         Returns:
5545             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, 
5546             empty list otherwise
5547         """
5548
5549         return self.RotationSweepObjects([],theObject,[], Axis,
5550                                          AngleInRadians, NbOfSteps, Tolerance,
5551                                          MakeGroups, TotalAngle)
5552
5553     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
5554                               MakeGroups=False, TotalAngle=False):
5555         """
5556         Generate new elements by rotation of the elements of object around the axis
5557         theObject object which elements should be sweeped.
5558         It can be a mesh, a sub mesh or a group.
5559
5560         Parameters:
5561             Axis: the axis of rotation, :class:`SMESH.AxisStruct` or line(geom object)
5562             AngleInRadians: the angle of Rotation
5563             NbOfSteps: number of steps
5564             Tolerance: tolerance
5565             MakeGroups: forces the generation of new groups from existing ones
5566             TotalAngle: gives meaning of AngleInRadians: if True then it is an angular size
5567                 of all steps, else - size of each step
5568
5569         Returns:
5570             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5571         """
5572
5573         return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
5574                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
5575
5576     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
5577                               scaleFactors=[], linearVariation=False, basePoint=[],
5578                               angles=[], anglesVariation=False):
5579         """
5580         Generate new elements by extrusion of the given elements and nodes
5581
5582         Parameters:
5583             nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5584             edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5585             faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5586             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5587                 the direction and value of extrusion for one step (the total extrusion
5588                 length will be NbOfSteps * ||StepVector||)
5589             NbOfSteps: the number of steps
5590             MakeGroups: forces the generation of new groups from existing ones
5591             scaleFactors: optional scale factors to apply during extrusion
5592             linearVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5593                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5594             basePoint: optional scaling and rotation center; if not provided, a gravity center of
5595                 nodes and elements being extruded is used as the scaling center.
5596                 It can be either
5597
5598                         - a list of tree components of the point or
5599                         - a node ID or
5600                         - a GEOM point
5601             angles: list of angles in radians. Nodes at each extrusion step are rotated 
5602                 around *basePoint*, additionally to previous steps.
5603             anglesVariation: forces the computation of rotation angles as linear
5604                 variation of the given *angles* along path steps
5605         Returns:
5606             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5607
5608         Example: :ref:`tui_extrusion`
5609         """
5610         unRegister = genObjUnRegister()
5611         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
5612         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
5613         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
5614
5615         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5616             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5617         if isinstance( StepVector, list ):
5618             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5619
5620         if isinstance( basePoint, int):
5621             xyz = self.GetNodeXYZ( basePoint )
5622             if not xyz:
5623                 raise RuntimeError("Invalid node ID: %s" % basePoint)
5624             basePoint = xyz
5625         if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
5626             basePoint = self.geompyD.PointCoordinates( basePoint )
5627
5628         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
5629         scaleFactors,scaleParameters,hasVars = ParseParameters(scaleFactors)
5630         angles,angleParameters,hasVars = ParseAngles(angles)
5631         Parameters = StepVector.PS.parameters + var_separator + \
5632                      Parameters + var_separator + \
5633                      scaleParameters + var_separator + angleParameters
5634         self.mesh.SetParameters(Parameters)
5635
5636         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
5637                                                   StepVector, NbOfSteps, MakeGroups,
5638                                                   scaleFactors, linearVariation, basePoint,
5639                                                   angles, anglesVariation )
5640
5641
5642     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
5643         """
5644         Generate new elements by extrusion of the elements with given ids
5645
5646         Parameters:
5647             IDsOfElements: the list of ids of elements or nodes for extrusion
5648             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5649                 the direction and value of extrusion for one step (the total extrusion
5650                 length will be NbOfSteps * ||StepVector||)
5651             NbOfSteps: the number of steps
5652             MakeGroups: forces the generation of new groups from existing ones
5653             IsNodes: is True if elements with given ids are nodes
5654
5655         Returns:
5656             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5657
5658         Example: :ref:`tui_extrusion`
5659         """
5660         n,e,f = [],[],[]
5661         if IsNodes: n = IDsOfElements
5662         else      : e,f, = IDsOfElements,IDsOfElements
5663         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5664
5665     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
5666                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
5667         """
5668         Generate new elements by extrusion along the normal to a discretized surface or wire
5669
5670         Parameters:
5671             Elements: elements to extrude - a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`.
5672                 Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
5673             StepSize: length of one extrusion step (the total extrusion
5674                 length will be *NbOfSteps* *StepSize*).
5675             NbOfSteps: number of extrusion steps.
5676             ByAverageNormal: if True each node is translated by *StepSize*
5677                 along the average of the normal vectors to the faces sharing the node;
5678                 else each node is translated along the same average normal till
5679                 intersection with the plane got by translation of the face sharing
5680                 the node along its own normal by *StepSize*.
5681             UseInputElemsOnly: to use only *Elements* when computing extrusion direction
5682                 for every node of *Elements*.
5683             MakeGroups: forces generation of new groups from existing ones.
5684             Dim: dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
5685                 is not yet implemented. This parameter is used if *Elements* contains
5686                 both faces and edges, i.e. *Elements* is a Mesh.
5687
5688         Returns:
5689             the list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
5690             empty list otherwise.
5691         Example: :ref:`tui_extrusion`
5692         """
5693
5694         unRegister = genObjUnRegister()
5695         if isinstance( Elements, Mesh ):
5696             Elements = [ Elements.GetMesh() ]
5697         if isinstance( Elements, list ):
5698             if not Elements:
5699                 raise RuntimeError("Elements empty!")
5700             if isinstance( Elements[0], Mesh ):
5701                 Elements = [ Elements[0].GetMesh() ]
5702             if isinstance( Elements[0], int ):
5703                 Elements = self.GetIDSource( Elements, SMESH.ALL )
5704                 unRegister.set( Elements )
5705         if not isinstance( Elements, list ):
5706             Elements = [ Elements ]
5707         StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
5708         self.mesh.SetParameters(Parameters)
5709         return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
5710                                              ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
5711
5712     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
5713         """
5714         Generate new elements by extrusion of the elements or nodes which belong to the object
5715
5716         Parameters:
5717             theObject: the object whose elements or nodes should be processed.
5718                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5719             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5720                 the direction and value of extrusion for one step (the total extrusion
5721                 length will be NbOfSteps * ||StepVector||)
5722             NbOfSteps: the number of steps
5723             MakeGroups: forces the generation of new groups from existing ones
5724             IsNodes: is True if elements to extrude are nodes
5725
5726         Returns:
5727             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5728         Example: :ref:`tui_extrusion`
5729         """
5730
5731         n,e,f = [],[],[]
5732         if IsNodes: n    = theObject
5733         else      : e,f, = theObject,theObject
5734         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
5735
5736     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5737         """
5738         Generate new elements by extrusion of edges which belong to the object
5739
5740         Parameters:
5741             theObject: object whose 1D elements should be processed.
5742                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5743             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5744                 the direction and value of extrusion for one step (the total extrusion
5745                 length will be NbOfSteps * ||StepVector||)
5746             NbOfSteps: the number of steps
5747             MakeGroups: to generate new groups from existing ones
5748
5749         Returns:
5750             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5751         Example: :ref:`tui_extrusion`
5752         """
5753
5754         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
5755
5756     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
5757         """
5758         Generate new elements by extrusion of faces which belong to the object
5759
5760         Parameters:
5761             theObject: object whose 2D elements should be processed.
5762                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5763             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5764                 the direction and value of extrusion for one step (the total extrusion
5765                 length will be NbOfSteps * ||StepVector||)
5766             NbOfSteps: the number of steps
5767             MakeGroups: forces the generation of new groups from existing ones
5768
5769         Returns:
5770             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5771         Example: :ref:`tui_extrusion`
5772         """
5773
5774         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
5775
5776     def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
5777                           ExtrFlags, SewTolerance, MakeGroups=False):
5778         """
5779         Generate new elements by extrusion of the elements with given ids
5780
5781         Parameters:
5782             IDsOfElements: is ids of elements
5783             StepVector: vector or :class:`SMESH.DirStruct` or 3 vector components, defining
5784                 the direction and value of extrusion for one step (the total extrusion
5785                 length will be NbOfSteps * ||StepVector||)
5786             NbOfSteps: the number of steps
5787             ExtrFlags: sets flags for extrusion
5788             SewTolerance: uses for comparing locations of nodes if flag
5789                 EXTRUSION_FLAG_SEW is set
5790             MakeGroups: forces the generation of new groups from existing ones
5791
5792         Returns:
5793             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
5794         """
5795
5796         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
5797             StepVector = self.smeshpyD.GetDirStruct(StepVector)
5798         if isinstance( StepVector, list ):
5799             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
5800         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
5801                                              ExtrFlags, SewTolerance, MakeGroups)
5802
5803     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathObject, PathShape=None,
5804                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
5805                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5806                                   ScaleFactors=[], ScalesVariation=False):
5807         """
5808         Generate new elements by extrusion of the given elements and nodes along the path.
5809         The path of extrusion must be a meshed edge.
5810
5811         Parameters:
5812             Nodes: nodes to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5813             Edges: edges to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5814             Faces: faces to extrude: a list including ids, :class:`a mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>`
5815             PathObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>` containing edges along which proceeds the extrusion
5816             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
5817             NodeStart: the first or the last node on the path. Defines the direction of extrusion
5818             HasAngles: not used obsolete
5819             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5820                 around *basePoint*, additionally to previous steps.
5821             LinearVariation: forces the computation of rotation angles as linear
5822                 variation of the given Angles along path steps
5823             HasRefPoint: allows using the reference point
5824             RefPoint: optional scaling and rotation center (mass center of the extruded
5825                 elements by default). The User can specify any point as the Reference Point. 
5826                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5827             MakeGroups: forces the generation of new groups from existing ones
5828             ScaleFactors: optional scale factors to apply during extrusion
5829             ScalesVariation: if *True*, *scaleFactors* are spread over all *NbOfSteps*,
5830                 else *scaleFactors* [i] is applied to nodes at the i-th extrusion step
5831
5832         Returns:
5833             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5834             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5835         Example: :ref:`tui_extrusion_along_path`
5836         """
5837
5838         unRegister = genObjUnRegister()
5839         Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
5840         Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
5841         Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
5842
5843         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
5844             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
5845         if isinstance( RefPoint, list ):
5846             if not RefPoint: RefPoint = [0,0,0]
5847             RefPoint = SMESH.PointStruct( *RefPoint )
5848         if isinstance( PathObject, Mesh ):
5849             PathObject = PathObject.GetMesh()
5850         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
5851         ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors)
5852         Parameters = AnglesParameters + var_separator + \
5853                      RefPoint.parameters + var_separator + ScalesParameters 
5854         self.mesh.SetParameters(Parameters)
5855         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
5856                                                      PathObject, PathShape, NodeStart,
5857                                                      HasAngles, Angles, LinearVariation,
5858                                                      HasRefPoint, RefPoint, MakeGroups,
5859                                                      ScaleFactors, ScalesVariation)
5860
5861     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
5862                             HasAngles=False, Angles=[], LinearVariation=False,
5863                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
5864                             ElemType=SMESH.FACE):
5865         """
5866         Generate new elements by extrusion of the given elements.
5867         The path of extrusion must be a meshed edge.
5868
5869         Parameters:
5870             Base: :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>`, or list of ids of elements for extrusion
5871             Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion
5872             NodeStart: the start node from Path. Defines the direction of extrusion
5873             HasAngles: not used obsolete
5874             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5875                 around *basePoint*, additionally to previous steps.
5876             LinearVariation: forces the computation of rotation angles as linear
5877                 variation of the given Angles along path steps
5878             HasRefPoint: allows using the reference point
5879             RefPoint: the reference point around which the elements are rotated (the mass
5880                 center of the elements by default).
5881                 The User can specify any point as the Reference Point.
5882                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5883             MakeGroups: forces the generation of new groups from existing ones
5884             ElemType: type of elements for extrusion (if param Base is a mesh)
5885
5886         Returns:
5887             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5888             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5889             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5890             otherwise
5891         Example: :ref:`tui_extrusion_along_path`
5892         """
5893
5894         n,e,f = [],[],[]
5895         if ElemType == SMESH.NODE: n = Base
5896         if ElemType == SMESH.EDGE: e = Base
5897         if ElemType == SMESH.FACE: f = Base
5898         gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
5899                                                HasAngles, Angles, LinearVariation,
5900                                                HasRefPoint, RefPoint, MakeGroups)
5901         if MakeGroups: return gr,er
5902         return er
5903
5904     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
5905                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5906                            MakeGroups=False, LinearVariation=False):
5907         """
5908         Generate new elements by extrusion of the given elements.
5909         The path of extrusion must be a meshed edge.
5910
5911         Parameters:
5912             IDsOfElements: ids of elements
5913             PathMesh: mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
5914             PathShape: shape (edge) defines the sub-mesh for the path
5915             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5916             HasAngles: not used obsolete
5917             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5918                 around *basePoint*, additionally to previous steps.
5919             HasRefPoint: allows using the reference point
5920             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5921                 The User can specify any point as the Reference Point.
5922                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5923             MakeGroups: forces the generation of new groups from existing ones
5924             LinearVariation: forces the computation of rotation angles as linear
5925                 variation of the given Angles along path steps
5926
5927         Returns:
5928             list of created :class:`groups <SMESH.SMESH_GroupBase>` and
5929             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>`
5930             if *MakeGroups* == True, only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5931         Example: :ref:`tui_extrusion_along_path`
5932         """
5933
5934         if not IDsOfElements:
5935             IDsOfElements = [ self.GetMesh() ]
5936         n,e,f = [],IDsOfElements,IDsOfElements
5937         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
5938                                                NodeStart, HasAngles, Angles,
5939                                                LinearVariation,
5940                                                HasRefPoint, RefPoint, MakeGroups)
5941         if MakeGroups: return gr,er
5942         return er
5943
5944     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
5945                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5946                                  MakeGroups=False, LinearVariation=False):
5947         """
5948         Generate new elements by extrusion of the elements which belong to the object.
5949         The path of extrusion must be a meshed edge.
5950
5951         Parameters:
5952             theObject: the object whose elements should be processed.
5953                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5954             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5955             PathShape: shape (edge) defines the sub-mesh for the path
5956             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5957             HasAngles: not used obsolete
5958             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5959                 around *basePoint*, additionally to previous steps.
5960             HasRefPoint: allows using the reference point
5961             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
5962                 The User can specify any point as the Reference Point.
5963                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
5964             MakeGroups: forces the generation of new groups from existing ones
5965             LinearVariation: forces the computation of rotation angles as linear
5966                 variation of the given Angles along path steps
5967
5968         Returns:
5969             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
5970             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
5971             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
5972         Example: :ref:`tui_extrusion_along_path`
5973         """
5974
5975         n,e,f = [],theObject,theObject
5976         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
5977                                                HasAngles, Angles, LinearVariation,
5978                                                HasRefPoint, RefPoint, MakeGroups)
5979         if MakeGroups: return gr,er
5980         return er
5981
5982     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
5983                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
5984                                    MakeGroups=False, LinearVariation=False):
5985         """
5986         Generate new elements by extrusion of mesh segments which belong to the object.
5987         The path of extrusion must be a meshed edge.
5988
5989         Parameters:
5990             theObject: the object whose 1D elements should be processed.
5991                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
5992             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
5993             PathShape: shape (edge) defines the sub-mesh for the path
5994             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
5995             HasAngles: not used obsolete
5996             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
5997                 around *basePoint*, additionally to previous steps.
5998             HasRefPoint: allows using the reference point
5999             RefPoint:  the reference point around which the shape is rotated (the mass center of the shape by default).
6000                 The User can specify any point as the Reference Point.
6001                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6002             MakeGroups: forces the generation of new groups from existing ones
6003             LinearVariation: forces the computation of rotation angles as linear
6004                 variation of the given Angles along path steps
6005
6006         Returns:
6007             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
6008             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6009             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6010         Example: :ref:`tui_extrusion_along_path`
6011         """
6012
6013         n,e,f = [],theObject,[]
6014         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6015                                                HasAngles, Angles, LinearVariation,
6016                                                HasRefPoint, RefPoint, MakeGroups)
6017         if MakeGroups: return gr,er
6018         return er
6019
6020     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
6021                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
6022                                    MakeGroups=False, LinearVariation=False):
6023         """
6024         Generate new elements by extrusion of faces which belong to the object.
6025         The path of extrusion must be a meshed edge.
6026
6027         Parameters:
6028             theObject: the object whose 2D elements should be processed.
6029                 It can be a :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
6030             PathMesh: mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
6031             PathShape: shape (edge) defines the sub-mesh for the path
6032             NodeStart: the first or the last node on the edge. Defines the direction of extrusion
6033             HasAngles: not used obsolete
6034             Angles: list of angles in radians. Nodes at each extrusion step are rotated 
6035                 around *basePoint*, additionally to previous steps.
6036             HasRefPoint: allows using the reference point
6037             RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default).
6038                 The User can specify any point as the Reference Point.
6039                 *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct`
6040             MakeGroups: forces the generation of new groups from existing ones
6041             LinearVariation: forces the computation of rotation angles as linear
6042                 variation of the given Angles along path steps
6043
6044         Returns:
6045             list of created :class:`groups <SMESH.SMESH_GroupBase>` and 
6046             :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` if *MakeGroups* == True,
6047             only :class:`error code <SMESH.SMESH_MeshEditor.Extrusion_Error>` otherwise
6048         Example: :ref:`tui_extrusion_along_path`
6049         """
6050
6051         n,e,f = [],[],theObject
6052         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
6053                                                HasAngles, Angles, LinearVariation,
6054                                                HasRefPoint, RefPoint, MakeGroups)
6055         if MakeGroups: return gr,er
6056         return er
6057
6058     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6059         """
6060         Create a symmetrical copy of mesh elements
6061
6062         Parameters:
6063             IDsOfElements: list of elements ids
6064             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6065             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6066                 If the *Mirror* is a geom object this parameter is unnecessary
6067             Copy: allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
6068             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6069
6070         Returns:
6071             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6072         """
6073
6074         if IDsOfElements == []:
6075             IDsOfElements = self.GetElementsId()
6076         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6077             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6078             theMirrorType = Mirror._mirrorType
6079         else:
6080             self.mesh.SetParameters(Mirror.parameters)
6081         if Copy and MakeGroups:
6082             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
6083         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
6084         return []
6085
6086     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
6087         """
6088         Create a new mesh by a symmetrical copy of mesh elements
6089
6090         Parameters:
6091             IDsOfElements: the list of elements ids
6092             Mirror: is :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6093             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6094                 If the *Mirror* is a geom object this parameter is unnecessary
6095             MakeGroups: to generate new groups from existing ones
6096             NewMeshName: a name of the new mesh to create
6097
6098         Returns:
6099             instance of class :class:`Mesh`
6100         """
6101
6102         if IDsOfElements == []:
6103             IDsOfElements = self.GetElementsId()
6104         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6105             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6106             theMirrorType = Mirror._mirrorType
6107         else:
6108             self.mesh.SetParameters(Mirror.parameters)
6109         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
6110                                           MakeGroups, NewMeshName)
6111         return Mesh(self.smeshpyD,self.geompyD,mesh)
6112
6113     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
6114         """
6115         Create a symmetrical copy of the object
6116
6117         Parameters:
6118             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6119             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6120             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6121                 If the *Mirror* is a geom object this parameter is unnecessary
6122             Copy: allows copying the element (Copy==True) or replacing it with its mirror (Copy==False)
6123             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6124
6125         Returns:
6126             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6127         """
6128
6129         if ( isinstance( theObject, Mesh )):
6130             theObject = theObject.GetMesh()
6131         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6132             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6133             theMirrorType = Mirror._mirrorType
6134         else:
6135             self.mesh.SetParameters(Mirror.parameters)
6136         if Copy and MakeGroups:
6137             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
6138         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
6139         return []
6140
6141     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
6142         """
6143         Create a new mesh by a symmetrical copy of the object
6144
6145         Parameters:
6146             theObject: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
6147             Mirror: :class:`SMESH.AxisStruct` or geom object (point, line, plane)
6148             theMirrorType: smesh.POINT, smesh.AXIS or smesh.PLANE.
6149                 If the *Mirror* is a geom object this parameter is unnecessary
6150             MakeGroups: forces the generation of new groups from existing ones
6151             NewMeshName: the name of the new mesh to create
6152
6153         Returns:
6154             instance of class :class:`Mesh`
6155         """
6156
6157         if ( isinstance( theObject, Mesh )):
6158             theObject = theObject.GetMesh()
6159         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
6160             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
6161             theMirrorType = Mirror._mirrorType
6162         else:
6163             self.mesh.SetParameters(Mirror.parameters)
6164         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
6165                                                 MakeGroups, NewMeshName)
6166         return Mesh( self.smeshpyD,self.geompyD,mesh )
6167
6168     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
6169         """
6170         Translate the elements
6171
6172         Parameters:
6173             IDsOfElements: list of elements ids
6174             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6175             Copy: allows copying the translated elements
6176             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6177
6178         Returns:
6179             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6180         """
6181
6182         if IDsOfElements == []:
6183             IDsOfElements = self.GetElementsId()
6184         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6185             Vector = self.smeshpyD.GetDirStruct(Vector)
6186         if isinstance( Vector, list ):
6187             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6188         self.mesh.SetParameters(Vector.PS.parameters)
6189         if Copy and MakeGroups:
6190             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
6191         self.editor.Translate(IDsOfElements, Vector, Copy)
6192         return []
6193
6194     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
6195         """
6196         Create a new mesh of translated elements
6197
6198         Parameters:
6199             IDsOfElements: list of elements ids
6200             Vector: the direction of translation (:class:`SMESH.DirStruct` or vector or 3 vector components)
6201             MakeGroups: forces the generation of new groups from existing ones
6202             NewMeshName: the name of the newly created mesh
6203
6204         Returns:
6205             instance of class :class:`Mesh`
6206         """
6207
6208         if IDsOfElements == []:
6209             IDsOfElements = self.GetElementsId()
6210         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6211             Vector = self.smeshpyD.GetDirStruct(Vector)
6212         if isinstance( Vector, list ):
6213             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6214         self.mesh.SetParameters(Vector.PS.parameters)
6215         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
6216         return Mesh ( self.smeshpyD, self.geompyD, mesh )
6217
6218     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
6219         """
6220         Translate the object
6221
6222         Parameters:
6223             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6224             Vector: direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6225             Copy: allows copying the translated elements
6226             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6227
6228         Returns:
6229             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6230         """
6231
6232         if ( isinstance( theObject, Mesh )):
6233             theObject = theObject.GetMesh()
6234         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
6235             Vector = self.smeshpyD.GetDirStruct(Vector)
6236         if isinstance( Vector, list ):
6237             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6238         self.mesh.SetParameters(Vector.PS.parameters)
6239         if Copy and MakeGroups:
6240             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
6241         self.editor.TranslateObject(theObject, Vector, Copy)
6242         return []
6243
6244     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
6245         """
6246         Create a new mesh from the translated object
6247
6248         Parameters:
6249             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6250             Vector: the direction of translation (:class:`SMESH.DirStruct` or geom vector or 3 vector components)
6251             MakeGroups: forces the generation of new groups from existing ones
6252             NewMeshName: the name of the newly created mesh
6253
6254         Returns:
6255             instance of class :class:`Mesh`
6256         """
6257
6258         if isinstance( theObject, Mesh ):
6259             theObject = theObject.GetMesh()
6260         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
6261             Vector = self.smeshpyD.GetDirStruct(Vector)
6262         if isinstance( Vector, list ):
6263             Vector = self.smeshpyD.MakeDirStruct(*Vector)
6264         self.mesh.SetParameters(Vector.PS.parameters)
6265         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
6266         return Mesh( self.smeshpyD, self.geompyD, mesh )
6267
6268
6269
6270     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
6271         """
6272         Scale the object
6273
6274         Parameters:
6275             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6276             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6277             theScaleFact: list of 1-3 scale factors for axises
6278             Copy: allows copying the translated elements
6279             MakeGroups: forces the generation of new groups from existing
6280                 ones (if Copy)
6281
6282         Returns:
6283             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True,
6284             empty list otherwise
6285         """
6286         unRegister = genObjUnRegister()
6287         if ( isinstance( theObject, Mesh )):
6288             theObject = theObject.GetMesh()
6289         if ( isinstance( theObject, list )):
6290             theObject = self.GetIDSource(theObject, SMESH.ALL)
6291             unRegister.set( theObject )
6292         if ( isinstance( thePoint, list )):
6293             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6294         if ( isinstance( theScaleFact, float )):
6295             theScaleFact = [theScaleFact]
6296         if ( isinstance( theScaleFact, int )):
6297             theScaleFact = [ float(theScaleFact)]
6298
6299         self.mesh.SetParameters(thePoint.parameters)
6300
6301         if Copy and MakeGroups:
6302             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
6303         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
6304         return []
6305
6306     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
6307         """
6308         Create a new mesh from the translated object
6309
6310         Parameters:
6311             theObject: the object to translate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6312             thePoint: base point for scale (:class:`SMESH.PointStruct` or list of 3 coordinates)
6313             theScaleFact: list of 1-3 scale factors for axises
6314             MakeGroups: forces the generation of new groups from existing ones
6315             NewMeshName: the name of the newly created mesh
6316
6317         Returns:
6318             instance of class :class:`Mesh`
6319         """
6320         unRegister = genObjUnRegister()
6321         if (isinstance(theObject, Mesh)):
6322             theObject = theObject.GetMesh()
6323         if ( isinstance( theObject, list )):
6324             theObject = self.GetIDSource(theObject,SMESH.ALL)
6325             unRegister.set( theObject )
6326         if ( isinstance( thePoint, list )):
6327             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
6328         if ( isinstance( theScaleFact, float )):
6329             theScaleFact = [theScaleFact]
6330         if ( isinstance( theScaleFact, int )):
6331             theScaleFact = [ float(theScaleFact)]
6332
6333         self.mesh.SetParameters(thePoint.parameters)
6334         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
6335                                          MakeGroups, NewMeshName)
6336         return Mesh( self.smeshpyD, self.geompyD, mesh )
6337
6338
6339
6340     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
6341         """
6342         Rotate the elements
6343
6344         Parameters:
6345             IDsOfElements: list of elements ids
6346             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6347             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6348             Copy: allows copying the rotated elements
6349             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6350
6351         Returns:
6352             list of created :class:`groups <SMESH.SMESH_GroupBase>` if *MakeGroups* == True, empty list otherwise
6353         """
6354
6355
6356         if IDsOfElements == []:
6357             IDsOfElements = self.GetElementsId()
6358         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6359             Axis = self.smeshpyD.GetAxisStruct(Axis)
6360         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6361         Parameters = Axis.parameters + var_separator + Parameters
6362         self.mesh.SetParameters(Parameters)
6363         if Copy and MakeGroups:
6364             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
6365         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
6366         return []
6367
6368     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
6369         """
6370         Create a new mesh of rotated elements
6371
6372         Parameters:
6373             IDsOfElements: list of element ids
6374             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6375             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6376             MakeGroups: forces the generation of new groups from existing ones
6377             NewMeshName: the name of the newly created mesh
6378
6379         Returns:
6380             instance of class :class:`Mesh`
6381         """
6382
6383         if IDsOfElements == []:
6384             IDsOfElements = self.GetElementsId()
6385         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6386             Axis = self.smeshpyD.GetAxisStruct(Axis)
6387         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6388         Parameters = Axis.parameters + var_separator + Parameters
6389         self.mesh.SetParameters(Parameters)
6390         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
6391                                           MakeGroups, NewMeshName)
6392         return Mesh( self.smeshpyD, self.geompyD, mesh )
6393
6394     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
6395         """
6396         Rotate the object
6397
6398         Parameters:
6399             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6400             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6401             AngleInRadians: the angle of rotation (in radians) or a name of variable which defines angle in degrees
6402             Copy: allows copying the rotated elements
6403             MakeGroups: forces the generation of new groups from existing ones (if Copy)
6404
6405         Returns:
6406             list of created :class:`groups <SMESH.SMESH_GroupBase>` if MakeGroups==True, empty list otherwise
6407         """
6408
6409         if (isinstance(theObject, Mesh)):
6410             theObject = theObject.GetMesh()
6411         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6412             Axis = self.smeshpyD.GetAxisStruct(Axis)
6413         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6414         Parameters = Axis.parameters + ":" + Parameters
6415         self.mesh.SetParameters(Parameters)
6416         if Copy and MakeGroups:
6417             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
6418         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
6419         return []
6420
6421     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
6422         """
6423         Create a new mesh from the rotated object
6424
6425         Parameters:
6426             theObject: the object to rotate (:class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`)
6427             Axis: the axis of rotation (:class:`SMESH.AxisStruct` or geom line)
6428             AngleInRadians: the angle of rotation (in radians)  or a name of variable which defines angle in degrees
6429             MakeGroups: forces the generation of new groups from existing ones
6430             NewMeshName: the name of the newly created mesh
6431
6432         Returns:
6433             instance of class :class:`Mesh`
6434         """
6435
6436         if (isinstance( theObject, Mesh )):
6437             theObject = theObject.GetMesh()
6438         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
6439             Axis = self.smeshpyD.GetAxisStruct(Axis)
6440         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
6441         Parameters = Axis.parameters + ":" + Parameters
6442         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
6443                                                        MakeGroups, NewMeshName)
6444         self.mesh.SetParameters(Parameters)
6445         return Mesh( self.smeshpyD, self.geompyD, mesh )
6446
6447     def Offset(self, theObject, Value, MakeGroups=False, CopyElements=False, NewMeshName=''):
6448         """
6449         Create an offset mesh from the given 2D object
6450
6451         Parameters:
6452             theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter)
6453             theValue (float): signed offset size
6454             MakeGroups (boolean): forces the generation of new groups from existing ones
6455             CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, 
6456                           False means to remove original elements.
6457             NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh
6458
6459         Returns:
6460             A tuple (:class:`Mesh`, list of :class:`groups <SMESH.SMESH_Group>`)
6461         """
6462
6463         if isinstance( theObject, Mesh ):
6464             theObject = theObject.GetMesh()
6465         theValue,Parameters,hasVars = ParseParameters(Value)
6466         mesh_groups = self.editor.Offset(theObject, Value, MakeGroups, CopyElements, NewMeshName)
6467         self.mesh.SetParameters(Parameters)
6468         if mesh_groups[0]:
6469             return Mesh( self.smeshpyD, self.geompyD, mesh_groups[0] ), mesh_groups[1]
6470         return mesh_groups
6471
6472     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
6473         """
6474         Find groups of adjacent nodes within Tolerance.
6475
6476         Parameters:
6477             Tolerance (float): the value of tolerance
6478             SeparateCornerAndMediumNodes (boolean): if *True*, in quadratic mesh puts
6479                 corner and medium nodes in separate groups thus preventing
6480                 their further merge.
6481
6482         Returns:
6483             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6484         """
6485
6486         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
6487
6488     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
6489                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
6490         """
6491         Find groups of adjacent nodes within Tolerance.
6492
6493         Parameters:
6494             Tolerance: the value of tolerance
6495             SubMeshOrGroup: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or of node IDs
6496             exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search
6497             SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts
6498                 corner and medium nodes in separate groups thus preventing
6499                 their further merge.
6500
6501         Returns:
6502             the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
6503         """
6504
6505         unRegister = genObjUnRegister()
6506         if not isinstance( SubMeshOrGroup, list ):
6507             SubMeshOrGroup = [ SubMeshOrGroup ]
6508         for i,obj in enumerate( SubMeshOrGroup ):
6509             if isinstance( obj, Mesh ):
6510                 SubMeshOrGroup = [ obj.GetMesh() ]
6511                 break
6512             if isinstance( obj, int ):
6513                 SubMeshOrGroup = [ self.GetIDSource( SubMeshOrGroup, SMESH.NODE )]
6514                 unRegister.set( SubMeshOrGroup )
6515                 break
6516
6517         if not isinstance( exceptNodes, list ):
6518             exceptNodes = [ exceptNodes ]
6519         if exceptNodes and isinstance( exceptNodes[0], int ):
6520             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
6521             unRegister.set( exceptNodes )
6522
6523         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
6524                                                         exceptNodes, SeparateCornerAndMediumNodes)
6525
6526     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
6527         """
6528         Merge nodes
6529
6530         Parameters:
6531             GroupsOfNodes: a list of groups of nodes IDs for merging.
6532                 E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced
6533                 in all elements and mesh groups by nodes 1 and 25 correspondingly
6534             NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
6535                 If *NodesToKeep* does not include a node to keep for some group to merge,
6536                 then the first node in the group is kept.
6537             AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming
6538                 invalid
6539
6540         Note:
6541                 This operation can create gaps in numeration of nodes or elements.
6542                 Call :meth:`RenumberElements` to remove the gaps.
6543         """
6544         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
6545
6546     def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]):
6547         """
6548         Find the elements built on the same nodes.
6549
6550         Parameters:
6551             MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` or element IDs to check for equal elements
6552             exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search
6553
6554
6555         Returns:
6556             the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
6557         """
6558
6559         unRegister = genObjUnRegister()
6560         if MeshOrSubMeshOrGroup is None:
6561             MeshOrSubMeshOrGroup = [ self.mesh ]
6562         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
6563             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ]
6564         elif not isinstance( MeshOrSubMeshOrGroup, list ):
6565             MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ]
6566         if isinstance( MeshOrSubMeshOrGroup[0], int ):
6567             MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )]
6568             unRegister.set( MeshOrSubMeshOrGroup )
6569         for item in MeshOrSubMeshOrGroup:
6570             if isinstance( item, Mesh ):
6571                 MeshOrSubMeshOrGroup = [ item.GetMesh() ]
6572
6573         if not isinstance( exceptElements, list ):
6574             exceptElements = [ exceptElements ]
6575         if exceptElements and isinstance( exceptElements[0], int ):
6576             exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )]
6577             unRegister.set( exceptElements )
6578
6579         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements )
6580
6581     def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]):
6582         """
6583         Merge elements in each given group.
6584
6585         Parameters:
6586             GroupsOfElementsID: a list of groups (lists) of elements IDs for merging
6587                 (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and
6588                 replaced in all mesh groups by elements 1 and 25)
6589             ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs.
6590                 If *ElementsToKeep* does not include an element to keep for some group to merge,
6591                 then the first element in the group is kept.
6592
6593         Note:
6594                 This operation can create gaps in numeration of elements.
6595                 Call :meth:`RenumberElements` to remove the gaps.
6596         """
6597
6598         unRegister = genObjUnRegister()
6599         if ElementsToKeep:
6600             if not isinstance( ElementsToKeep, list ):
6601                 ElementsToKeep = [ ElementsToKeep ]
6602             if isinstance( ElementsToKeep[0], int ):
6603                 ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )]
6604                 unRegister.set( ElementsToKeep )
6605
6606         self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep )
6607
6608     def MergeEqualElements(self):
6609         """
6610         Leave one element and remove all other elements built on the same nodes.
6611
6612         Note:
6613                 This operation can create gaps in numeration of elements.
6614                 Call :meth:`RenumberElements` to remove the gaps.
6615         """
6616
6617         self.editor.MergeEqualElements()
6618
6619     def FindFreeBorders(self, ClosedOnly=True):
6620         """
6621         Returns all or only closed free borders
6622
6623         Returns:
6624             list of SMESH.FreeBorder's
6625         """
6626
6627         return self.editor.FindFreeBorders( ClosedOnly )
6628
6629     def FillHole(self, holeNodes, groupName=""):
6630         """
6631         Fill with 2D elements a hole defined by a SMESH.FreeBorder.
6632
6633         Parameters:
6634             holeNodes: either a SMESH.FreeBorder or a list on node IDs. These nodes
6635                 must describe all sequential nodes of the hole border. The first and the last
6636                 nodes must be the same. Use :meth:`FindFreeBorders` to get nodes of holes.
6637             groupName (string): name of a group to add new faces
6638         Returns:
6639             a :class:`group <SMESH.SMESH_GroupBase>` containing the new faces; or :code:`None` if `groupName` == ""
6640         """
6641
6642
6643         if holeNodes and isinstance( holeNodes, list ) and isinstance( holeNodes[0], int ):
6644             holeNodes = SMESH.FreeBorder(nodeIDs=holeNodes)
6645         if not isinstance( holeNodes, SMESH.FreeBorder ):
6646             raise TypeError("holeNodes must be either SMESH.FreeBorder or list of integer and not %s" % holeNodes)
6647         return self.editor.FillHole( holeNodes, groupName )
6648
6649     def FindCoincidentFreeBorders (self, tolerance=0.):
6650         """
6651         Return groups of FreeBorder's coincident within the given tolerance.
6652
6653         Parameters:
6654             tolerance: the tolerance. If the tolerance <= 0.0 then one tenth of an average
6655                 size of elements adjacent to free borders being compared is used.
6656
6657         Returns:
6658             SMESH.CoincidentFreeBorders structure
6659         """
6660
6661         return self.editor.FindCoincidentFreeBorders( tolerance )
6662
6663     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
6664         """
6665         Sew FreeBorder's of each group
6666
6667         Parameters:
6668             freeBorders: either a SMESH.CoincidentFreeBorders structure or a list of lists
6669                 where each enclosed list contains node IDs of a group of coincident free
6670                 borders such that each consequent triple of IDs within a group describes
6671                 a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
6672                 last node of a border.
6673                 For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
6674                 groups of coincident free borders, each group including two borders.
6675             createPolygons: if :code:`True` faces adjacent to free borders are converted to
6676                 polygons if a node of opposite border falls on a face edge, else such
6677                 faces are split into several ones.
6678             createPolyhedra: if :code:`True` volumes adjacent to free borders are converted to
6679                 polyhedra if a node of opposite border falls on a volume edge, else such
6680                 volumes, if any, remain intact and the mesh becomes non-conformal.
6681
6682         Returns:
6683             a number of successfully sewed groups
6684
6685         Note:
6686                 This operation can create gaps in numeration of nodes or elements.
6687                 Call :meth:`RenumberElements` to remove the gaps.
6688         """
6689
6690         if freeBorders and isinstance( freeBorders, list ):
6691             # construct SMESH.CoincidentFreeBorders
6692             if isinstance( freeBorders[0], int ):
6693                 freeBorders = [freeBorders]
6694             borders = []
6695             coincidentGroups = []
6696             for nodeList in freeBorders:
6697                 if not nodeList or len( nodeList ) % 3:
6698                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
6699                 group = []
6700                 while nodeList:
6701                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
6702                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
6703                     nodeList = nodeList[3:]
6704                     pass
6705                 coincidentGroups.append( group )
6706                 pass
6707             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
6708
6709         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
6710
6711     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6712                         FirstNodeID2, SecondNodeID2, LastNodeID2,
6713                         CreatePolygons, CreatePolyedrs):
6714         """
6715         Sew free borders
6716
6717         Returns:
6718             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6719
6720         Note:
6721                 This operation can create gaps in numeration of nodes or elements.
6722                 Call :meth:`RenumberElements` to remove the gaps.
6723         """
6724
6725         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6726                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
6727                                           CreatePolygons, CreatePolyedrs)
6728
6729     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
6730                                FirstNodeID2, SecondNodeID2):
6731         """
6732         Sew conform free borders
6733
6734         Returns:
6735             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6736
6737         Note:
6738                 This operation can create gaps in numeration of elements.
6739                 Call :meth:`RenumberElements` to remove the gaps.
6740         """
6741
6742         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
6743                                                  FirstNodeID2, SecondNodeID2)
6744
6745     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6746                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
6747         """
6748         Sew border to side
6749
6750         Returns:
6751             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6752
6753         Note:
6754                 This operation can create gaps in numeration of elements.
6755                 Call :meth:`RenumberElements` to remove the gaps.
6756         """
6757
6758         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
6759                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
6760
6761     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
6762                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6763                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
6764         """
6765         Sew two sides of a mesh. The nodes belonging to Side1 are
6766         merged with the nodes of elements of Side2.
6767         The number of elements in theSide1 and in theSide2 must be
6768         equal and they should have similar nodal connectivity.
6769         The nodes to merge should belong to side borders and
6770         the first node should be linked to the second.
6771
6772         Returns:
6773             :class:`error code <SMESH.SMESH_MeshEditor.Sew_Error>`
6774
6775         Note:
6776                 This operation can create gaps in numeration of nodes.
6777                 Call :meth:`RenumberElements` to remove the gaps.
6778         """
6779
6780         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
6781                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
6782                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
6783
6784     def ChangeElemNodes(self, ide, newIDs):
6785         """
6786         Set new nodes for the given element. Number of nodes should be kept.
6787
6788         Parameters:
6789             ide: the element ID
6790             newIDs: nodes IDs
6791
6792         Returns:
6793             False if the number of nodes does not correspond to the type of element
6794         """
6795
6796         return self.editor.ChangeElemNodes(ide, newIDs)
6797
6798     def GetLastCreatedNodes(self):
6799         """
6800         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some nodes were
6801         created, this method return the list of their IDs.
6802         If new nodes were not created - return empty list
6803
6804         Returns:
6805             the list of integer values (can be empty)
6806         """
6807
6808         return self.editor.GetLastCreatedNodes()
6809
6810     def GetLastCreatedElems(self):
6811         """
6812         If during the last operation of :class:`SMESH.SMESH_MeshEditor` some elements were
6813         created this method return the list of their IDs.
6814         If new elements were not created - return empty list
6815
6816         Returns:
6817             the list of integer values (can be empty)
6818         """
6819
6820         return self.editor.GetLastCreatedElems()
6821
6822     def ClearLastCreated(self):
6823         """
6824         Forget what nodes and elements were created by the last mesh edition operation
6825         """
6826
6827         self.editor.ClearLastCreated()
6828
6829     def DoubleElements(self, theElements, theGroupName=""):
6830         """
6831         Create duplicates of given elements, i.e. create new elements based on the
6832         same nodes as the given ones.
6833
6834         Parameters:
6835             theElements: container of elements to duplicate. It can be a
6836                 :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` 
6837                 or a list of element IDs. If *theElements* is
6838                 a :class:`Mesh`, elements of highest dimension are duplicated
6839             theGroupName: a name of group to contain the generated elements.
6840                 If a group with such a name already exists, the new elements
6841                 are added to the existing group, else a new group is created.
6842                 If *theGroupName* is empty, new elements are not added
6843                 in any group.
6844
6845         Returns:
6846                 a :class:`group <SMESH.SMESH_Group>` where the new elements are added. 
6847                 None if *theGroupName* == "".
6848         """
6849
6850         unRegister = genObjUnRegister()
6851         if isinstance( theElements, Mesh ):
6852             theElements = theElements.mesh
6853         elif isinstance( theElements, list ):
6854             theElements = self.GetIDSource( theElements, SMESH.ALL )
6855             unRegister.set( theElements )
6856         return self.editor.DoubleElements(theElements, theGroupName)
6857
6858     def DoubleNodes(self, theNodes, theModifiedElems):
6859         """
6860         Create a hole in a mesh by doubling the nodes of some particular elements
6861
6862         Parameters:
6863             theNodes: IDs of nodes to be doubled
6864             theModifiedElems: IDs of elements to be updated by the new (doubled)
6865                 nodes. If list of element identifiers is empty then nodes are doubled but
6866                 they not assigned to elements
6867
6868         Returns:
6869             True if operation has been completed successfully, False otherwise
6870         """
6871
6872         return self.editor.DoubleNodes(theNodes, theModifiedElems)
6873
6874     def DoubleNode(self, theNodeId, theModifiedElems):
6875         """
6876         Create a hole in a mesh by doubling the nodes of some particular elements.
6877         This method provided for convenience works as :meth:`DoubleNodes`.
6878
6879         Parameters:
6880             theNodeId: IDs of node to double
6881             theModifiedElems: IDs of elements to update
6882
6883         Returns:
6884             True if operation has been completed successfully, False otherwise
6885         """
6886
6887         return self.editor.DoubleNode(theNodeId, theModifiedElems)
6888
6889     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
6890         """
6891         Create a hole in a mesh by doubling the nodes of some particular elements.
6892         This method provided for convenience works as :meth:`DoubleNodes`.
6893
6894         Parameters:
6895             theNodes: group of nodes to double.
6896             theModifiedElems: group of elements to update.
6897             theMakeGroup: forces the generation of a group containing new nodes.
6898
6899         Returns:
6900             True or a created group if operation has been completed successfully,
6901             False or None otherwise
6902         """
6903
6904         if theMakeGroup:
6905             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
6906         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
6907
6908     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
6909         """
6910         Create a hole in a mesh by doubling the nodes of some particular elements.
6911         This method provided for convenience works as :meth:`DoubleNodes`.
6912
6913         Parameters:
6914             theNodes: list of groups of nodes to double.
6915             theModifiedElems: list of groups of elements to update.
6916             theMakeGroup: forces the generation of a group containing new nodes.
6917
6918         Returns:
6919             True if operation has been completed successfully, False otherwise
6920         """
6921
6922         if theMakeGroup:
6923             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
6924         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
6925
6926     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
6927         """
6928         Create a hole in a mesh by doubling the nodes of some particular elements
6929
6930         Parameters:
6931             theElems: the list of elements (edges or faces) to replicate.
6932                 The nodes for duplication could be found from these elements
6933             theNodesNot: list of nodes NOT to replicate
6934             theAffectedElems: the list of elements (cells and edges) to which the
6935                 replicated nodes should be associated to
6936
6937         Returns:
6938             True if operation has been completed successfully, False otherwise
6939         """
6940
6941         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
6942
6943     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
6944         """
6945         Create a hole in a mesh by doubling the nodes of some particular elements
6946
6947         Parameters:
6948             theElems: the list of elements (edges or faces) to replicate.
6949                 The nodes for duplication could be found from these elements
6950             theNodesNot: list of nodes NOT to replicate
6951             theShape: shape to detect affected elements (element which geometric center
6952                 located on or inside shape).
6953                 The replicated nodes should be associated to affected elements.
6954
6955         Returns:
6956             True if operation has been completed successfully, False otherwise
6957         """
6958
6959         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
6960
6961     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
6962                              theMakeGroup=False, theMakeNodeGroup=False):
6963         """
6964         Create a hole in a mesh by doubling the nodes of some particular elements.
6965         This method provided for convenience works as :meth:`DoubleNodes`.
6966
6967         Parameters:
6968             theElems: group of of elements (edges or faces) to replicate.
6969             theNodesNot: group of nodes NOT to replicate.
6970             theAffectedElems: group of elements to which the replicated nodes
6971                 should be associated to.
6972             theMakeGroup: forces the generation of a group containing new elements.
6973             theMakeNodeGroup: forces the generation of a group containing new nodes.
6974
6975         Returns:
6976             True or created groups (one or two) if operation has been completed successfully,
6977             False or None otherwise
6978         """
6979
6980         if theMakeGroup or theMakeNodeGroup:
6981             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
6982                                                             theAffectedElems,
6983                                                             theMakeGroup, theMakeNodeGroup)
6984             if theMakeGroup and theMakeNodeGroup:
6985                 return twoGroups
6986             else:
6987                 return twoGroups[ int(theMakeNodeGroup) ]
6988         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
6989
6990     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
6991         """
6992         Create a hole in a mesh by doubling the nodes of some particular elements.
6993         This method provided for convenience works as :meth:`DoubleNodes`.
6994
6995         Parameters:
6996             theElems: group of of elements (edges or faces) to replicate
6997             theNodesNot: group of nodes not to replicate
6998             theShape: shape to detect affected elements (element which geometric center
6999                 located on or inside shape).
7000                 The replicated nodes should be associated to affected elements
7001         """
7002
7003         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
7004
7005     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
7006                              theMakeGroup=False, theMakeNodeGroup=False):
7007         """
7008         Create a hole in a mesh by doubling the nodes of some particular elements.
7009         This method provided for convenience works as :meth:`DoubleNodes`.
7010
7011         Parameters:
7012             theElems: list of groups of elements (edges or faces) to replicate
7013             theNodesNot: list of groups of nodes NOT to replicate
7014             theAffectedElems: group of elements to which the replicated nodes
7015                 should be associated to
7016             theMakeGroup: forces generation of a group containing new elements.
7017             theMakeNodeGroup: forces generation of a group containing new nodes
7018
7019         Returns:
7020             True or created groups (one or two) if operation has been completed successfully,
7021             False or None otherwise
7022         """
7023
7024         if theMakeGroup or theMakeNodeGroup:
7025             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
7026                                                              theAffectedElems,
7027                                                              theMakeGroup, theMakeNodeGroup)
7028             if theMakeGroup and theMakeNodeGroup:
7029                 return twoGroups
7030             else:
7031                 return twoGroups[ int(theMakeNodeGroup) ]
7032         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
7033
7034     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7035         """
7036         Create a hole in a mesh by doubling the nodes of some particular elements.
7037         This method provided for convenience works as :meth:`DoubleNodes`.
7038
7039         Parameters:
7040             theElems: list of groups of elements (edges or faces) to replicate
7041             theNodesNot: list of groups of nodes NOT to replicate
7042             theShape: shape to detect affected elements (element which geometric center
7043                 located on or inside shape).
7044                 The replicated nodes should be associated to affected elements
7045
7046         Returns:
7047             True if operation has been completed successfully, False otherwise
7048         """
7049
7050         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
7051
7052     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
7053         """
7054         Identify the elements that will be affected by node duplication (actual duplication is not performed).
7055         This method is the first step of :meth:`DoubleNodeElemGroupsInRegion`.
7056
7057         Parameters:
7058             theElems: list of groups of nodes or elements (edges or faces) to replicate
7059             theNodesNot: list of groups of nodes NOT to replicate
7060             theShape: shape to detect affected elements (element which geometric center
7061                 located on or inside shape).
7062                 The replicated nodes should be associated to affected elements
7063
7064         Returns:
7065             groups of affected elements in order: volumes, faces, edges
7066         """
7067
7068         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
7069
7070     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
7071
7072         """
7073         Double nodes on shared faces between groups of volumes and create flat elements on demand.
7074         The list of groups must describe a partition of the mesh volumes.
7075         The nodes of the internal faces at the boundaries of the groups are doubled.
7076         In option, the internal faces are replaced by flat elements.
7077         Triangles are transformed to prisms, and quadrangles to hexahedrons.
7078
7079         Parameters:
7080             theDomains: list of groups of volumes
7081             createJointElems: if True, create the elements
7082             onAllBoundaries: if True, the nodes and elements are also created on
7083                 the boundary between *theDomains* and the rest mesh
7084
7085         Returns:
7086             True if operation has been completed successfully, False otherwise
7087         """
7088
7089         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
7090
7091     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
7092         """
7093         Double nodes on some external faces and create flat elements.
7094         Flat elements are mainly used by some types of mechanic calculations.
7095
7096         Each group of the list must be constituted of faces.
7097         Triangles are transformed in prisms, and quadrangles in hexahedrons.
7098
7099         Parameters:
7100             theGroupsOfFaces: list of groups of faces
7101
7102         Returns:
7103             True if operation has been completed successfully, False otherwise
7104         """
7105
7106         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
7107
7108     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
7109         """
7110         Identify all the elements around a geom shape, get the faces delimiting the hole
7111         """
7112         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
7113
7114     def MakePolyLine(self, segments, groupName='', isPreview=False ):
7115         """    
7116         Create a polyline consisting of 1D mesh elements each lying on a 2D element of
7117         the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the
7118         plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure.
7119         If there are several paths connecting a pair of points, the shortest path is
7120         selected by the module. Position of the cutting plane is defined by the two
7121         points and an optional vector lying on the plane specified by a PolySegment.
7122         By default the vector is defined by Mesh module as following. A middle point
7123         of the two given points is computed. The middle point is projected to the mesh.
7124         The vector goes from the middle point to the projection point. In case of planar
7125         mesh, the vector is normal to the mesh.
7126
7127         In preview mode, *segments* [i].vector returns the used vector which goes from the middle point to its projection.
7128
7129         Parameters:
7130             segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes.
7131             groupName: optional name of a group where created mesh segments will be added.
7132
7133         """    
7134         editor = self.editor
7135         if isPreview:
7136             editor = self.mesh.GetMeshEditPreviewer()
7137         segmentsRes = editor.MakePolyLine( segments, groupName )
7138         for i, seg in enumerate( segmentsRes ):
7139             segments[i].vector = seg.vector
7140         if isPreview:
7141             return editor.GetPreviewData()
7142         return None
7143
7144     def MakeSlot(self, segmentGroup, width ):
7145         """
7146         Create a slot of given width around given 1D elements lying on a triangle mesh.
7147         The slot is constructed by cutting faces by cylindrical surfaces made
7148         around each segment. Segments are expected to be created by MakePolyLine().
7149
7150         Returns:
7151                FaceEdge's located at the slot boundary
7152         """
7153         return self.editor.MakeSlot( segmentGroup, width )
7154
7155     def GetFunctor(self, funcType ):
7156         """
7157         Return a cached numerical functor by its type.
7158
7159         Parameters:
7160             funcType: functor type: an item of :class:`SMESH.FunctorType` enumeration.
7161                 Note that not all items correspond to numerical functors.
7162
7163         Returns:
7164             :class:`SMESH.NumericalFunctor`. The functor is already initialized with a mesh
7165         """
7166
7167         fn = self.functors[ funcType._v ]
7168         if not fn:
7169             fn = self.smeshpyD.GetFunctor(funcType)
7170             fn.SetMesh(self.mesh)
7171             self.functors[ funcType._v ] = fn
7172         return fn
7173
7174     def FunctorValue(self, funcType, elemId, isElem=True):
7175         """
7176         Return value of a functor for a given element
7177
7178         Parameters:
7179             funcType: an item of :class:`SMESH.FunctorType` enum.
7180             elemId: element or node ID
7181             isElem: *elemId* is ID of element or node
7182
7183         Returns:
7184             the functor value or zero in case of invalid arguments
7185         """
7186
7187         fn = self.GetFunctor( funcType )
7188         if fn.GetElementType() == self.GetElementType(elemId, isElem):
7189             val = fn.GetValue(elemId)
7190         else:
7191             val = 0
7192         return val
7193
7194     def GetLength(self, elemId=None):
7195         """
7196         Get length of given 1D elements or of all 1D mesh elements
7197
7198         Parameters:
7199             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.
7200
7201         Returns:
7202             Sum of lengths of given elements
7203         """
7204
7205         length = 0
7206         if elemId == None:
7207             length = self.smeshpyD.GetLength(self)
7208         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7209             length = self.smeshpyD.GetLength(elemId)
7210         elif elemId == []:
7211             length = 0
7212         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7213             for obj in elemId:
7214                 length += self.smeshpyD.GetLength(obj)
7215         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7216             unRegister = genObjUnRegister()
7217             obj = self.GetIDSource( elemId )
7218             unRegister.set( obj )
7219             length = self.smeshpyD.GetLength( obj )
7220         else:
7221             length = self.FunctorValue(SMESH.FT_Length, elemId)
7222         return length
7223
7224     def GetArea(self, elemId=None):
7225         """
7226         Get area of given 2D elements or of all 2D mesh elements
7227
7228         Parameters:
7229             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.
7230
7231         Returns:
7232             Area of given element's if *elemId* is specified or sum of all 2D mesh elements' areas otherwise
7233         """
7234
7235         area = 0
7236         if elemId == None:
7237             area = self.smeshpyD.GetArea(self)
7238         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7239             area = self.smeshpyD.GetArea(elemId)
7240         elif elemId == []:
7241             area = 0
7242         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7243             for obj in elemId:
7244                 area += self.smeshpyD.GetArea(obj)
7245         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7246             unRegister = genObjUnRegister()
7247             obj = self.GetIDSource( elemId )
7248             unRegister.set( obj )
7249             area = self.smeshpyD.GetArea( obj )
7250         else:
7251             area = self.FunctorValue(SMESH.FT_Area, elemId)
7252         return area
7253
7254     def GetVolume(self, elemId=None):
7255         """
7256         Get volume of given 3D elements or of all 3D mesh elements
7257
7258         Parameters:
7259             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.
7260
7261         Returns:
7262             Sum element's volume value if *elemId* is specified or sum of all 3D mesh elements' volumes otherwise
7263         """
7264
7265         volume = 0
7266         if elemId == None:
7267             volume= self.smeshpyD.GetVolume(self)
7268         elif isinstance(elemId, SMESH._objref_SMESH_IDSource):
7269             volume= self.smeshpyD.GetVolume(elemId)
7270         elif elemId == []:
7271             volume = 0
7272         elif isinstance(elemId, list) and isinstance(elemId[0], SMESH._objref_SMESH_IDSource):
7273             for obj in elemId:
7274                 volume+= self.smeshpyD.GetVolume(obj)
7275         elif isinstance(elemId, list) and isinstance(elemId[0], int):
7276             unRegister = genObjUnRegister()
7277             obj = self.GetIDSource( elemId )
7278             unRegister.set( obj )
7279             volume= self.smeshpyD.GetVolume( obj )
7280         else:
7281             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
7282         return volume
7283
7284     def GetAngle(self, node1, node2, node3 ):
7285         """
7286         Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3)
7287
7288         Parameters:            
7289                 node1,node2,node3: IDs of the three nodes
7290
7291         Returns:        
7292             Angle in radians [0,PI]. -1 if failure case.
7293         """
7294         p1 = self.GetNodeXYZ( node1 )
7295         p2 = self.GetNodeXYZ( node2 )
7296         p3 = self.GetNodeXYZ( node3 )
7297         if p1 and p2 and p3:
7298             return self.smeshpyD.GetAngle( p1,p2,p3 )
7299         return -1.
7300
7301
7302     def GetMaxElementLength(self, elemId):
7303         """
7304         Get maximum element length.
7305
7306         Parameters:
7307             elemId: mesh element ID
7308
7309         Returns:
7310             element's maximum length value
7311         """
7312
7313         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7314             ftype = SMESH.FT_MaxElementLength3D
7315         else:
7316             ftype = SMESH.FT_MaxElementLength2D
7317         return self.FunctorValue(ftype, elemId)
7318
7319     def GetAspectRatio(self, elemId):
7320         """
7321         Get aspect ratio of 2D or 3D element.
7322
7323         Parameters:
7324             elemId: mesh element ID
7325
7326         Returns:
7327             element's aspect ratio value
7328         """
7329
7330         if self.GetElementType(elemId, True) == SMESH.VOLUME:
7331             ftype = SMESH.FT_AspectRatio3D
7332         else:
7333             ftype = SMESH.FT_AspectRatio
7334         return self.FunctorValue(ftype, elemId)
7335
7336     def GetWarping(self, elemId):
7337         """
7338         Get warping angle of 2D element.
7339
7340         Parameters:
7341             elemId: mesh element ID
7342
7343         Returns:
7344             element's warping angle value
7345         """
7346
7347         return self.FunctorValue(SMESH.FT_Warping, elemId)
7348
7349     def GetMinimumAngle(self, elemId):
7350         """
7351         Get minimum angle of 2D element.
7352
7353         Parameters:
7354             elemId: mesh element ID
7355
7356         Returns:
7357             element's minimum angle value
7358         """
7359
7360         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
7361
7362     def GetTaper(self, elemId):
7363         """
7364         Get taper of 2D element.
7365
7366         Parameters:
7367             elemId: mesh element ID
7368
7369         Returns:
7370             element's taper value
7371         """
7372
7373         return self.FunctorValue(SMESH.FT_Taper, elemId)
7374
7375     def GetSkew(self, elemId):
7376         """
7377         Get skew of 2D element.
7378
7379         Parameters:
7380             elemId: mesh element ID
7381
7382         Returns:
7383             element's skew value
7384         """
7385
7386         return self.FunctorValue(SMESH.FT_Skew, elemId)
7387
7388     def GetMinMax(self, funType, meshPart=None):
7389         """
7390         Return minimal and maximal value of a given functor.
7391
7392         Parameters:
7393             funType (SMESH.FunctorType): a functor type.
7394                   Note that not all items of :class:`SMESH.FunctorType` corresponds
7395                   to numerical functors.
7396             meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to treat
7397
7398         Returns:
7399             tuple (min,max)
7400         """
7401
7402         unRegister = genObjUnRegister()
7403         if isinstance( meshPart, list ):
7404             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
7405             unRegister.set( meshPart )
7406         if isinstance( meshPart, Mesh ):
7407             meshPart = meshPart.mesh
7408         fun = self.GetFunctor( funType )
7409         if fun:
7410             if meshPart:
7411                 if hasattr( meshPart, "SetMesh" ):
7412                     meshPart.SetMesh( self.mesh ) # set mesh to filter
7413                 hist = fun.GetLocalHistogram( 1, False, meshPart )
7414             else:
7415                 hist = fun.GetHistogram( 1, False )
7416             if hist:
7417                 return hist[0].min, hist[0].max
7418         return None
7419
7420     pass # end of Mesh class
7421
7422
7423 class meshProxy(SMESH._objref_SMESH_Mesh):
7424     """
7425     Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
7426     with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
7427     """
7428     def __init__(self,*args):
7429         SMESH._objref_SMESH_Mesh.__init__(self,*args)
7430     def __deepcopy__(self, memo=None):
7431         new = self.__class__(self)
7432         return new
7433     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
7434         if len( args ) == 3:
7435             args += SMESH.ALL_NODES, True
7436         return SMESH._objref_SMESH_Mesh.CreateDimGroup(self, *args)
7437     def ExportToMEDX(self, *args): # function removed
7438         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
7439         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7440         SMESH._objref_SMESH_Mesh.ExportMED(self, *args)
7441     def ExportToMED(self, *args): # function removed
7442         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
7443         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7444         args2 = list(args)
7445         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7446             args2.append(True)
7447         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7448     def ExportPartToMED(self, *args): # 'version' parameter removed
7449         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7450         SMESH._objref_SMESH_Mesh.ExportPartToMED(self, *args)
7451     def ExportMED(self, *args): # signature of method changed
7452         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]]
7453         args2 = list(args)
7454         while len(args2) < 5:  # !!!! nb of parameters for ExportToMED IDL's method
7455             args2.append(True)
7456         SMESH._objref_SMESH_Mesh.ExportMED(self, *args2)
7457     pass
7458 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
7459
7460
7461 class submeshProxy(SMESH._objref_SMESH_subMesh):
7462
7463     """
7464     Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
7465     """
7466     def __init__(self,*args):
7467         SMESH._objref_SMESH_subMesh.__init__(self,*args)
7468         self.mesh = None
7469     def __deepcopy__(self, memo=None):
7470         new = self.__class__(self)
7471         return new
7472
7473     def Compute(self,refresh=False):
7474         """
7475         Compute the sub-mesh and return the status of the computation
7476
7477         Parameters:
7478             refresh: if *True*, Object Browser is automatically updated (when running in GUI)
7479
7480         Returns:
7481             True or False
7482
7483         This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
7484         :meth:`smeshBuilder.Mesh.GetSubMesh`.
7485         """
7486
7487         if not self.mesh:
7488             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
7489
7490         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
7491
7492         if salome.sg.hasDesktop():
7493             if refresh: salome.sg.updateObjBrowser()
7494             pass
7495
7496         return ok
7497     pass
7498 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
7499
7500
7501 class meshEditor(SMESH._objref_SMESH_MeshEditor):
7502     """
7503     Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
7504     compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
7505     smeshBuilder.Mesh
7506     """
7507     def __init__(self,*args):
7508         SMESH._objref_SMESH_MeshEditor.__init__( self, *args)
7509         self.mesh = None
7510     def __getattr__(self, name ): # method called if an attribute not found
7511         if not self.mesh:         # look for name() method in Mesh class
7512             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
7513         if hasattr( self.mesh, name ):
7514             return getattr( self.mesh, name )
7515         if name == "ExtrusionAlongPathObjX":
7516             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
7517         print("meshEditor: attribute '%s' NOT FOUND" % name)
7518         return None
7519     def __deepcopy__(self, memo=None):
7520         new = self.__class__(self)
7521         return new
7522     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
7523         if len( args ) == 1: args += False,
7524         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
7525     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
7526         if len( args ) == 2: args += False,
7527         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
7528     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
7529         if len( args ) == 1:
7530             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
7531         NodesToKeep = args[1]
7532         AvoidMakingHoles = args[2] if len( args ) == 3 else False
7533         unRegister  = genObjUnRegister()
7534         if NodesToKeep:
7535             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
7536                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
7537             if not isinstance( NodesToKeep, list ):
7538                 NodesToKeep = [ NodesToKeep ]
7539         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
7540     pass
7541 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
7542
7543 class Pattern(SMESH._objref_SMESH_Pattern):
7544     """
7545     Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
7546     variables in some methods
7547     """
7548
7549     def LoadFromFile(self, patternTextOrFile ):
7550         text = patternTextOrFile
7551         if os.path.exists( text ):
7552             text = open( patternTextOrFile ).read()
7553             pass
7554         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
7555
7556     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
7557         decrFun = lambda i: i-1
7558         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
7559         theMesh.SetParameters(Parameters)
7560         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
7561
7562     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
7563         decrFun = lambda i: i-1
7564         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
7565         theMesh.SetParameters(Parameters)
7566         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
7567
7568     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
7569         if isinstance( mesh, Mesh ):
7570             mesh = mesh.GetMesh()
7571         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
7572
7573 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
7574 """
7575 Registering the new proxy for Pattern
7576 """
7577
7578 class algoCreator:
7579     """
7580     Private class used to bind methods creating algorithms to the class Mesh
7581     """
7582
7583     def __init__(self, method):
7584         self.mesh = None
7585         self.defaultAlgoType = ""
7586         self.algoTypeToClass = {}
7587         self.method = method
7588
7589     def add(self, algoClass):
7590         """
7591         Store a python class of algorithm
7592         """
7593         if inspect.isclass(algoClass) and \
7594            hasattr( algoClass, "algoType"):
7595             self.algoTypeToClass[ algoClass.algoType ] = algoClass
7596             if not self.defaultAlgoType and \
7597                hasattr( algoClass, "isDefault") and algoClass.isDefault:
7598                 self.defaultAlgoType = algoClass.algoType
7599             #print("Add",algoClass.algoType, "dflt",self.defaultAlgoType)
7600
7601     def copy(self, mesh):
7602         """
7603         Create a copy of self and assign mesh to the copy
7604         """
7605
7606         other = algoCreator( self.method )
7607         other.defaultAlgoType = self.defaultAlgoType
7608         other.algoTypeToClass = self.algoTypeToClass
7609         other.mesh = mesh
7610         return other
7611
7612     def __call__(self,algo="",geom=0,*args):
7613         """
7614         Create an instance of algorithm
7615         """
7616         algoType = ""
7617         shape = 0
7618         if isinstance( algo, str ):
7619             algoType = algo
7620         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
7621                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
7622             shape = algo
7623         elif algo:
7624             args += (algo,)
7625
7626         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
7627             shape = geom
7628         elif not algoType and isinstance( geom, str ):
7629             algoType = geom
7630         elif geom:
7631             args += (geom,)
7632         for arg in args:
7633             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
7634                 shape = arg
7635             elif isinstance( arg, str ) and not algoType:
7636                 algoType = arg
7637             else:
7638                 import traceback, sys
7639                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
7640                 sys.stderr.write( msg + '\n' )
7641                 tb = traceback.extract_stack(None,2)
7642                 traceback.print_list( [tb[0]] )
7643         if not algoType:
7644             algoType = self.defaultAlgoType
7645         if not algoType and self.algoTypeToClass:
7646             algoType = sorted( self.algoTypeToClass.keys() )[0]
7647         if algoType in self.algoTypeToClass:
7648             #print("Create algo",algoType)
7649             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
7650         raise RuntimeError( "No class found for algo type %s" % algoType)
7651         return None
7652
7653 class hypMethodWrapper:
7654     """
7655     Private class used to substitute and store variable parameters of hypotheses.
7656     """
7657
7658     def __init__(self, hyp, method):
7659         self.hyp    = hyp
7660         self.method = method
7661         #print("REBIND:", method.__name__)
7662         return
7663
7664     def __call__(self,*args):
7665         """
7666         call a method of hypothesis with calling SetVarParameter() before
7667         """
7668
7669         if not args:
7670             return self.method( self.hyp, *args ) # hypothesis method with no args
7671
7672         #print("MethWrapper.__call__", self.method.__name__, args)
7673         try:
7674             parsed = ParseParameters(*args)     # replace variables with their values
7675             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
7676             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
7677         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
7678             # maybe there is a replaced string arg which is not variable
7679             result = self.method( self.hyp, *args )
7680         except ValueError as detail: # raised by ParseParameters()
7681             try:
7682                 result = self.method( self.hyp, *args )
7683             except omniORB.CORBA.BAD_PARAM:
7684                 raise ValueError(detail) # wrong variable name
7685
7686         return result
7687     pass
7688
7689 class genObjUnRegister:
7690     """
7691     A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
7692     """
7693
7694     def __init__(self, genObj=None):
7695         self.genObjList = []
7696         self.set( genObj )
7697         return
7698
7699     def set(self, genObj):
7700         "Store one or a list of of SALOME.GenericObj'es"
7701         if isinstance( genObj, list ):
7702             self.genObjList.extend( genObj )
7703         else:
7704             self.genObjList.append( genObj )
7705         return
7706
7707     def __del__(self):
7708         for genObj in self.genObjList:
7709             if genObj and hasattr( genObj, "UnRegister" ):
7710                 genObj.UnRegister()
7711
7712 for pluginName in os.environ[ "SMESH_MeshersList" ].split( os.pathsep ):
7713     """
7714     Bind methods creating mesher plug-ins to the Mesh class
7715     """
7716
7717     # print("pluginName: ", pluginName)
7718     pluginBuilderName = pluginName + "Builder"
7719     try:
7720         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
7721     except Exception as e:
7722         from salome_utils import verbose
7723         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
7724         continue
7725     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
7726     plugin = eval( pluginBuilderName )
7727     # print("  plugin:" , str(plugin))
7728
7729     # add methods creating algorithms to Mesh
7730     for k in dir( plugin ):
7731         if k[0] == '_': continue
7732         algo = getattr( plugin, k )
7733         #print("             algo:", str(algo))
7734         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
7735             #print("                     meshMethod:" , str(algo.meshMethod))
7736             if not hasattr( Mesh, algo.meshMethod ):
7737                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
7738                 pass
7739             _mmethod = getattr( Mesh, algo.meshMethod )
7740             if hasattr(  _mmethod, "add" ):
7741                 _mmethod.add(algo)
7742             pass
7743         pass
7744     pass
7745 del pluginName