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