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