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