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