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