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