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