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