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