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