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