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