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