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