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