Salome HOME
f3e83622c0582d6ccf3b58f73774d3a720513b6f
[modules/smesh.git] / src / SMESH_SWIG / smeshBuilder.py
1 # Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 #  File   : smeshBuilder.py
20 #  Author : Francis KLOSS, OCC
21 #  Module : SMESH
22
23 import salome
24 from salome.geom import geomBuilder
25
26 import SMESH # This is necessary for back compatibility
27 import omniORB                                       # back compatibility
28 SMESH.MED_V2_1    = 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
44 import SALOME
45 import SALOMEDS
46 import os
47 import inspect
48
49 # In case the omniORBpy EnumItem class does not fully support Python 3
50 # (for instance in version 4.2.1-2), the comparison ordering methods must be
51 # defined
52 #
53 try:
54     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
55 except TypeError:
56     def enumitem_eq(self, other):
57         try:
58             if isinstance(other, omniORB.EnumItem):
59                 if other._parent_id == self._parent_id:
60                     return self._v == other._v
61                 else:
62                     return self._parent_id == other._parent_id
63             else:
64                 return id(self) == id(other)
65         except:
66             return id(self) == id(other)
67
68     def enumitem_lt(self, other):
69         try:
70             if isinstance(other, omniORB.EnumItem):
71                 if other._parent_id == self._parent_id:
72                     return self._v < other._v
73                 else:
74                     return self._parent_id < other._parent_id
75             else:
76                 return id(self) < id(other)
77         except:
78             return id(self) < id(other)
79
80     def enumitem_le(self, other):
81         try:
82             if isinstance(other, omniORB.EnumItem):
83                 if other._parent_id == self._parent_id:
84                     return self._v <= other._v
85                 else:
86                     return self._parent_id <= other._parent_id
87             else:
88                 return id(self) <= id(other)
89         except:
90             return id(self) <= id(other)
91
92     def enumitem_gt(self, other):
93         try:
94             if isinstance(other, omniORB.EnumItem):
95                 if other._parent_id == self._parent_id:
96                     return self._v > other._v
97                 else:
98                     return self._parent_id > other._parent_id
99             else:
100                 return id(self) > id(other)
101         except:
102             return id(self) > id(other)
103
104     def enumitem_ge(self, other):
105         try:
106             if isinstance(other, omniORB.EnumItem):
107                 if other._parent_id == self._parent_id:
108                     return self._v >= other._v
109                 else:
110                     return self._parent_id >= other._parent_id
111             else:
112                 return id(self) >= id(other)
113         except:
114             return id(self) >= id(other)
115
116     omniORB.EnumItem.__eq__ = enumitem_eq
117     omniORB.EnumItem.__lt__ = enumitem_lt
118     omniORB.EnumItem.__le__ = enumitem_le
119     omniORB.EnumItem.__gt__ = enumitem_gt
120     omniORB.EnumItem.__ge__ = enumitem_ge
121
122
123 class MeshMeta(type):
124     """Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
125     """
126     def __instancecheck__(cls, inst):
127         """Implement isinstance(inst, cls)."""
128         return any(cls.__subclasscheck__(c)
129                    for c in {type(inst), inst.__class__})
130
131     def __subclasscheck__(cls, sub):
132         """Implement issubclass(sub, cls)."""
133         return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
134
135 def DegreesToRadians(AngleInDegrees):
136     """Convert an angle from degrees to radians
137     """
138     from math import pi
139     return AngleInDegrees * pi / 180.0
140
141 import salome_notebook
142 notebook = salome_notebook.notebook
143 # Salome notebook variable separator
144 var_separator = ":"
145
146 def ParseParameters(*args):
147     """
148     Return list of variable values from salome notebook.
149     The last argument, if is callable, is used to modify values got from notebook
150     """
151     Result = []
152     Parameters = ""
153     hasVariables = False
154     varModifFun=None
155     if args and callable(args[-1]):
156         args, varModifFun = args[:-1], args[-1]
157     for parameter in args:
158
159         Parameters += str(parameter) + var_separator
160
161         if isinstance(parameter,str):
162             # check if there is an inexistent variable name
163             if not notebook.isVariable(parameter):
164                 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
165             parameter = notebook.get(parameter)
166             hasVariables = True
167             if varModifFun:
168                 parameter = varModifFun(parameter)
169                 pass
170             pass
171         Result.append(parameter)
172
173         pass
174     Parameters = Parameters[:-1]
175     Result.append( Parameters )
176     Result.append( hasVariables )
177     return Result
178
179 def ParseAngles(*args):
180     """
181     Parse parameters while converting variables to radians
182     """
183     return ParseParameters( *( args + (DegreesToRadians, )))
184
185 def __initPointStruct(point,*args):
186     """
187     Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
188     Parameters are stored in PointStruct.parameters attribute
189     """
190     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
191     pass
192 SMESH.PointStruct.__init__ = __initPointStruct
193
194 def __initAxisStruct(ax,*args):
195     """
196     Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
197     Parameters are stored in AxisStruct.parameters attribute
198     """
199     if len( args ) != 6:
200         raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
201     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
202     pass
203 SMESH.AxisStruct.__init__ = __initAxisStruct
204
205 smeshPrecisionConfusion = 1.e-07
206 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
207     """Compare real values using smeshPrecisionConfusion as tolerance
208     """
209     if abs(val1 - val2) < tol:
210         return True
211     return False
212
213 NO_NAME = "NoName"
214
215 def GetName(obj):
216     """
217     Return a name of an object
218     
219     Returns:
220         object name
221     """
222     if obj:
223         # object not null
224         if isinstance(obj, SALOMEDS._objref_SObject):
225             # study object
226             return obj.GetName()
227         try:
228             ior  = salome.orb.object_to_string(obj)
229         except:
230             ior = None
231         if ior:
232             sobj = salome.myStudy.FindObjectIOR(ior)
233             if sobj:
234                 return sobj.GetName()
235             if hasattr(obj, "GetName"):
236                 # unknown CORBA object, having GetName() method
237                 return obj.GetName()
238             else:
239                 # unknown CORBA object, no GetName() method
240                 return NO_NAME
241             pass
242         if hasattr(obj, "GetName"):
243             # unknown non-CORBA object, having GetName() method
244             return obj.GetName()
245         pass
246     raise RuntimeError("Null or invalid object")
247
248 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
249     """
250     Print error message if a hypothesis was not assigned.
251     """
252     if isAlgo:
253         hypType = "algorithm"
254     else:
255         hypType = "hypothesis"
256         pass
257     reason = ""
258     if hasattr( status, "__getitem__" ):
259         status, reason = status[0], status[1]
260     if status == HYP_UNKNOWN_FATAL:
261         reason = "for unknown reason"
262     elif status == HYP_INCOMPATIBLE:
263         reason = "this hypothesis mismatches the algorithm"
264     elif status == HYP_NOTCONFORM:
265         reason = "a non-conform mesh would be built"
266     elif status == HYP_ALREADY_EXIST:
267         if isAlgo: return # it does not influence anything
268         reason = hypType + " of the same dimension is already assigned to this shape"
269     elif status == HYP_BAD_DIM:
270         reason = hypType + " mismatches the shape"
271     elif status == HYP_CONCURRENT :
272         reason = "there are concurrent hypotheses on sub-shapes"
273     elif status == HYP_BAD_SUBSHAPE:
274         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
275     elif status == HYP_BAD_GEOMETRY:
276         reason = "the algorithm is not applicable to this geometry"
277     elif status == HYP_HIDDEN_ALGO:
278         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
279     elif status == HYP_HIDING_ALGO:
280         reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
281     elif status == HYP_NEED_SHAPE:
282         reason = "algorithm can't work without shape"
283     elif status == HYP_INCOMPAT_HYPS:
284         pass
285     else:
286         return
287     where = geomName
288     if where:
289         where = '"%s"' % geomName
290         if mesh:
291             meshName = GetName( mesh )
292             if meshName and meshName != NO_NAME:
293                 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
294     if status < HYP_UNKNOWN_FATAL and where:
295         print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
296     elif where:
297         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
298     else:
299         print('"%s" was not assigned : %s' %( hypName, reason ))
300         pass
301
302 def AssureGeomPublished(mesh, geom, name=''):
303     """
304     Private method. Add geom (sub-shape of the main shape) into the study if not yet there
305     """
306     if not mesh.smeshpyD.IsEnablePublish():
307         return
308     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
309         return
310     if not geom.GetStudyEntry():
311         ## get a name
312         if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
313             # for all groups SubShapeName() return "Compound_-1"
314             name = mesh.geompyD.SubShapeName(geom, mesh.geom)
315         if not name:
316             name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
317         ## publish
318         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
319     return
320
321 def FirstVertexOnCurve(mesh, edge):
322     """
323     Returns:
324         the first vertex of a geometrical edge by ignoring orientation
325     """
326     vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
327     if not vv:
328         raise TypeError("Given object has no vertices")
329     if len( vv ) == 1: return vv[0]
330     v0   = mesh.geompyD.MakeVertexOnCurve(edge,0.)
331     xyz  = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
332     xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
333     xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
334     dist1, dist2 = 0,0
335     for i in range(3):
336         dist1 += abs( xyz[i] - xyz1[i] )
337         dist2 += abs( xyz[i] - xyz2[i] )
338     if dist1 < dist2:
339         return vv[0]
340     else:
341         return vv[1]
342
343 smeshInst = None
344 """
345 Warning:
346     smeshInst is a singleton
347 """
348 engine = None
349 doLcc = False
350 created = False
351
352 class smeshBuilder( SMESH._objref_SMESH_Gen, object ):
353     """
354     This class allows to create, load or manipulate meshes.
355     It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
356     It also has methods to get infos and measure meshes.
357     """
358
359     # MirrorType enumeration
360     POINT = SMESH_MeshEditor.POINT
361     AXIS =  SMESH_MeshEditor.AXIS
362     PLANE = SMESH_MeshEditor.PLANE
363
364     # Smooth_Method enumeration
365     LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
366     CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
367
368     PrecisionConfusion = smeshPrecisionConfusion
369
370     # TopAbs_State enumeration
371     [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
372
373     # Methods of splitting a hexahedron into tetrahedra
374     Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
375
376     def __new__(cls, *args):
377         global engine
378         global smeshInst
379         global doLcc
380         #print("==== __new__", engine, smeshInst, doLcc)
381
382         if smeshInst is None:
383             # smesh engine is either retrieved from engine, or created
384             smeshInst = engine
385             # Following test avoids a recursive loop
386             if doLcc:
387                 if smeshInst is not None:
388                     # smesh engine not created: existing engine found
389                     doLcc = False
390                 if doLcc:
391                     doLcc = False
392                     # FindOrLoadComponent called:
393                     # 1. CORBA resolution of server
394                     # 2. the __new__ method is called again
395                     #print("==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc)
396                     smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
397             else:
398                 # FindOrLoadComponent not called
399                 if smeshInst is None:
400                     # smeshBuilder instance is created from lcc.FindOrLoadComponent
401                     #print("==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc)
402                     smeshInst = super(smeshBuilder,cls).__new__(cls)
403                 else:
404                     # smesh engine not created: existing engine found
405                     #print("==== existing ", engine, smeshInst, doLcc)
406                     pass
407             #print("====1 ", smeshInst)
408             return smeshInst
409
410         #print("====2 ", smeshInst)
411         return smeshInst
412
413     def __init__(self, *args):
414         global created
415         #print("--------------- smeshbuilder __init__ ---", created)
416         if not created:
417             created = True
418             SMESH._objref_SMESH_Gen.__init__(self, *args)
419
420
421     def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
422         """
423         Dump component to the Python script.
424         This method overrides IDL function to allow default values for the parameters.
425         """
426
427         return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
428
429     def SetDumpPythonHistorical(self, isHistorical):
430         """
431         Set mode of DumpPython(), *historical* or *snapshot*.
432         In the *historical* mode, the Python Dump script includes all commands
433         performed by SMESH engine. In the *snapshot* mode, commands
434         relating to objects removed from the Study are excluded from the script
435         as well as commands not influencing the current state of meshes
436         """
437
438         if isHistorical: val = "true"
439         else:            val = "false"
440         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
441
442     def init_smesh(self,geompyD = None):
443         """
444         Set Geometry component
445         """    
446         #print("init_smesh")
447         self.UpdateStudy(geompyD)
448         notebook.myStudy = salome.myStudy
449
450     def Mesh(self, obj=0, name=0):
451         """
452         Create a mesh. This mesh can be either 
453
454         * an empty mesh not bound to geometry, if *obj* == 0
455         * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object
456         * a mesh wrapping a :class:`CORBA mesh <SMESH.SMESH_Mesh>` given as *obj* parameter.
457
458         Parameters:
459             obj: either 
460
461                    1. a :class:`CORBA mesh <SMESH.SMESH_Mesh>` got by calling e.g.
462                       ::
463
464                         salome.myStudy.FindObjectID("0:1:2:3").GetObject() 
465
466                    2. a geometrical object for meshing
467                    3. none.
468             name: the name for the new mesh.
469
470         Returns:
471             an instance of class :class:`Mesh`.
472         """
473
474         if isinstance(obj,str):
475             obj,name = name,obj
476         return Mesh(self, self.geompyD, obj, name)
477
478     def EnumToLong(self,theItem):
479         """
480         Return a long value from enumeration
481         """
482
483         return theItem._v
484
485     def ColorToString(self,c):
486         """
487         Convert SALOMEDS.Color to string.
488         To be used with filters.
489
490         Parameters:
491             c: color value (SALOMEDS.Color)
492
493         Returns:
494             a string representation of the color.
495         """
496
497         val = ""
498         if isinstance(c, SALOMEDS.Color):
499             val = "%s;%s;%s" % (c.R, c.G, c.B)
500         elif isinstance(c, str):
501             val = c
502         else:
503             raise ValueError("Color value should be of string or SALOMEDS.Color type")
504         return val
505
506     def GetPointStruct(self,theVertex):
507         """
508         Get :class:`SMESH.PointStruct` from vertex
509
510         Parameters:
511                 theVertex (GEOM.GEOM_Object): vertex
512
513         Returns:
514                 :class:`SMESH.PointStruct`
515         """
516
517         [x, y, z] = self.geompyD.PointCoordinates(theVertex)
518         return PointStruct(x,y,z)
519
520     def GetDirStruct(self,theVector):
521         """
522         Get :class:`SMESH.DirStruct` from vector
523
524         Parameters:
525                 theVector (GEOM.GEOM_Object): vector
526
527         Returns:
528                 :class:`SMESH.DirStruct`
529         """
530
531         vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
532         if(len(vertices) != 2):
533             print("Error: vector object is incorrect.")
534             return None
535         p1 = self.geompyD.PointCoordinates(vertices[0])
536         p2 = self.geompyD.PointCoordinates(vertices[1])
537         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
538         dirst = DirStruct(pnt)
539         return dirst
540
541     def MakeDirStruct(self,x,y,z):
542         """
543         Make :class:`SMESH.DirStruct` from a triplet of floats
544
545         Parameters:
546                 x,y,z (float): vector components
547
548         Returns:
549                 :class:`SMESH.DirStruct`
550         """
551
552         pnt = PointStruct(x,y,z)
553         return DirStruct(pnt)
554
555     def GetAxisStruct(self,theObj):
556         """
557         Get :class:`SMESH.AxisStruct` from a geometrical object
558
559         Parameters:
560             theObj (GEOM.GEOM_Object): line or plane
561
562         Returns:
563             :class:`SMESH.AxisStruct`
564         """
565         import GEOM
566         edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
567         axis = None
568         if len(edges) > 1:
569             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
570             vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
571             vertex1 = self.geompyD.PointCoordinates(vertex1)
572             vertex2 = self.geompyD.PointCoordinates(vertex2)
573             vertex3 = self.geompyD.PointCoordinates(vertex3)
574             vertex4 = self.geompyD.PointCoordinates(vertex4)
575             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
576             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
577             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] ]
578             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
579             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
580         elif len(edges) == 1:
581             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
582             p1 = self.geompyD.PointCoordinates( vertex1 )
583             p2 = self.geompyD.PointCoordinates( vertex2 )
584             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
585             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
586         elif theObj.GetShapeType() == GEOM.VERTEX:
587             x,y,z = self.geompyD.PointCoordinates( theObj )
588             axis = AxisStruct( x,y,z, 1,0,0,)
589             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
590         return axis
591
592     # From SMESH_Gen interface:
593     # ------------------------
594
595     def SetName(self, obj, name):
596         """
597         Set the given name to an object
598
599         Parameters:
600                 obj: the object to rename
601                 name: a new object name
602         """
603
604         if isinstance( obj, Mesh ):
605             obj = obj.GetMesh()
606         elif isinstance( obj, Mesh_Algorithm ):
607             obj = obj.GetAlgorithm()
608         ior  = salome.orb.object_to_string(obj)
609         SMESH._objref_SMESH_Gen.SetName(self, ior, name)
610
611     def SetEmbeddedMode( self,theMode ):
612         """
613         Set the current mode
614         """
615
616         SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
617
618     def IsEmbeddedMode(self):
619         """
620         Get the current mode
621         """
622
623         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
624
625     def UpdateStudy( self, geompyD = None  ):
626         """
627         Update the current study. Calling UpdateStudy() allows to
628         update meshes at switching GEOM->SMESH
629         """
630         #self.UpdateStudy()
631         if not geompyD:
632             from salome.geom import geomBuilder
633             geompyD = geomBuilder.geom
634             if not geompyD:
635                 geompyD = geomBuilder.New()
636             pass
637         self.geompyD=geompyD
638         self.SetGeomEngine(geompyD)
639         SMESH._objref_SMESH_Gen.UpdateStudy(self)
640         sb = salome.myStudy.NewBuilder()
641         sc = salome.myStudy.FindComponent("SMESH")
642         if sc:
643             sb.LoadWith(sc, self)
644         pass
645     
646     def SetEnablePublish( self, theIsEnablePublish ):
647         """
648         Set enable publishing in the study. Calling SetEnablePublish( False ) allows to
649         switch **off** publishing in the Study of mesh objects.
650         """
651        #self.SetEnablePublish(theIsEnablePublish)
652         SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
653         global notebook
654         notebook = salome_notebook.NoteBook( theIsEnablePublish )
655
656
657     def CreateMeshesFromUNV( self,theFileName ):
658         """
659         Create a Mesh object importing data from the given UNV file
660
661         Returns:
662                 an instance of class :class:`Mesh`
663         """
664
665         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
666         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
667         return aMesh
668
669     def CreateMeshesFromMED( self,theFileName ):
670         """
671         Create a Mesh object(s) importing data from the given MED file
672
673         Returns:
674                 a tuple ( list of class :class:`Mesh` instances, 
675                 :class:`SMESH.DriverMED_ReadStatus` )
676         """
677
678         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
679         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
680         return aMeshes, aStatus
681
682     def CreateMeshesFromSAUV( self,theFileName ):
683         """
684         Create a Mesh object(s) importing data from the given SAUV file
685
686         Returns:
687                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
688         """
689
690         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
691         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
692         return aMeshes, aStatus
693
694     def CreateMeshesFromSTL( self, theFileName ):
695         """
696         Create a Mesh object importing data from the given STL file
697
698         Returns:
699                 an instance of class :class:`Mesh`
700         """
701
702         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
703         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
704         return aMesh
705
706     def CreateMeshesFromCGNS( self, theFileName ):
707         """
708         Create Mesh objects importing data from the given CGNS file
709
710         Returns:
711                 a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` )
712         """
713
714         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
715         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
716         return aMeshes, aStatus
717
718     def CreateMeshesFromGMF( self, theFileName ):
719         """
720         Create a Mesh object importing data from the given GMF file.
721         GMF files must have .mesh extension for the ASCII format and .meshb for
722         the binary format.
723
724         Returns:
725                 ( an instance of class :class:`Mesh`, :class:`SMESH.ComputeError` )
726         """
727
728         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
729                                                                         theFileName,
730                                                                         True)
731         if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
732         return Mesh(self, self.geompyD, aSmeshMesh), error
733
734     def Concatenate( self, meshes, uniteIdenticalGroups,
735                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
736                      name = "", meshToAppendTo = None):
737         """
738         Concatenate the given meshes into one mesh, optionally to meshToAppendTo.
739         All groups of input meshes will be present in the new mesh.
740
741         Parameters:
742                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to combine into one mesh
743                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
744                 mergeNodesAndElements: if True, equal nodes and elements are merged
745                 mergeTolerance: tolerance for merging nodes
746                 allGroups: forces creation of groups corresponding to every input mesh
747                 name: name of a new mesh
748                 meshToAppendTo a mesh to append all given meshes
749
750         Returns:
751                 an instance of class :class:`Mesh`
752         """
753
754         if not meshes: return None
755         if not isinstance( meshes, list ):
756             meshes = [ meshes ]
757         for i,m in enumerate( meshes ):
758             if isinstance( m, Mesh ):
759                 meshes[i] = m.GetMesh()
760         mergeTolerance,Parameters,hasVars = ParseParameters( mergeTolerance )
761         if hasattr(meshes[0], "SetParameters"):
762             meshes[0].SetParameters( Parameters )
763         else:
764             meshes[0].GetMesh().SetParameters( Parameters )
765         if isinstance( meshToAppendTo, Mesh ):
766             meshToAppendTo = meshToAppendTo.GetMesh()
767         if allGroups:
768             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
769                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
770                 mergeTolerance,meshToAppendTo )
771         else:
772             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
773                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,
774                 mergeTolerance,meshToAppendTo )
775
776         aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name )
777         return aMesh
778
779     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
780         """
781         Create a mesh by copying a part of another mesh.
782
783         Parameters:
784                 meshPart: a part of mesh to copy, either 
785                         :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`.
786                         To copy nodes or elements not forming any mesh object,
787                         pass result of :meth:`Mesh.GetIDSource` as *meshPart*
788                 meshName: a name of the new mesh
789                 toCopyGroups: to create in the new mesh groups the copied elements belongs to
790                 toKeepIDs: to preserve order of the copied elements or not
791
792         Returns:
793                 an instance of class :class:`Mesh`
794         """
795
796         if isinstance( meshPart, Mesh ):
797             meshPart = meshPart.GetMesh()
798         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
799         return Mesh(self, self.geompyD, mesh)
800
801     def CopyMeshWithGeom( self, sourceMesh, newGeom, meshName="", toCopyGroups=True,
802                           toReuseHypotheses=True, toCopyElements=True):
803         """
804         Create a mesh by copying a mesh definition (hypotheses and groups) to a new geometry.
805         It is supposed that the new geometry is a modified geometry of *sourceMesh*.
806         To facilitate and speed up the operation, consider using
807         "Set presentation parameters and sub-shapes from arguments" option in
808         a dialog of geometrical operation used to create the new geometry.
809
810         Parameters:
811                 sourceMesh: the mesh to copy definition of.
812                 newGeom: the new geomtry.
813                 meshName: an optional name of the new mesh. If omitted, the mesh name is kept.
814                 toCopyGroups: to create groups in the new mesh.
815                 toReuseHypotheses: to reuse hypotheses of the *sourceMesh*.
816                 toCopyElements: to copy mesh elements present on non-modified sub-shapes of 
817                                 *sourceMesh*.
818         Returns:
819                 tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries )
820                 *invalidEntries* are study entries of objects whose
821                 counterparts are not found in the *newGeom*, followed by entries
822                 of mesh sub-objects that are invalid because they depend on a not found
823                 preceeding sub-shape
824         """
825         if isinstance( sourceMesh, Mesh ):
826             sourceMesh = sourceMesh.GetMesh()
827
828         ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries = \
829            SMESH._objref_SMESH_Gen.CopyMeshWithGeom( self, sourceMesh, newGeom, meshName,
830                                                      toCopyGroups,
831                                                      toReuseHypotheses,
832                                                      toCopyElements)
833         return ( ok, Mesh(self, self.geompyD, newMesh),
834                  newGroups, newSubMeshes, newHypotheses, invalidEntries )
835
836     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
837         """
838         Return IDs of sub-shapes
839
840         Parameters:
841                 theMainObject (GEOM.GEOM_Object): a shape
842                 theListOfSubObjects: sub-shapes (list of GEOM.GEOM_Object)
843         Returns:
844                 the list of integer values
845         """
846
847         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
848
849     def GetPattern(self):
850         """
851         Create a pattern mapper.
852
853         Returns:
854                 an instance of :class:`SMESH.SMESH_Pattern`
855
856         :ref:`Example of Patterns usage <tui_pattern_mapping>`
857         """
858
859         return SMESH._objref_SMESH_Gen.GetPattern(self)
860
861     def SetBoundaryBoxSegmentation(self, nbSegments):
862         """
863         Set number of segments per diagonal of boundary box of geometry, by which
864         default segment length of appropriate 1D hypotheses is defined in GUI.
865         Default value is 10.
866         """
867
868         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
869
870     # Filtering. Auxiliary functions:
871     # ------------------------------
872
873     def GetEmptyCriterion(self):
874         """
875         Create an empty criterion
876
877         Returns:
878                 :class:`SMESH.Filter.Criterion`
879         """
880
881         Type = self.EnumToLong(FT_Undefined)
882         Compare = self.EnumToLong(FT_Undefined)
883         Threshold = 0
884         ThresholdStr = ""
885         ThresholdID = ""
886         UnaryOp = self.EnumToLong(FT_Undefined)
887         BinaryOp = self.EnumToLong(FT_Undefined)
888         Tolerance = 1e-07
889         TypeOfElement = ALL
890         Precision = -1 ##@1e-07
891         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
892                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
893
894     def GetCriterion(self,elementType,
895                      CritType,
896                      Compare = FT_EqualTo,
897                      Threshold="",
898                      UnaryOp=FT_Undefined,
899                      BinaryOp=FT_Undefined,
900                      Tolerance=1e-07):
901         """
902         Create a criterion by the given parameters
903         Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
904
905         Parameters:
906                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
907                 CritType: the type of criterion :class:`SMESH.FunctorType` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
908                         Note that the items starting from FT_LessThan are not suitable for *CritType*.
909                 Compare:  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
910                 Threshold: the threshold value (range of ids as string, shape, numeric)
911                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
912                 BinaryOp: a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
913                         SMESH.FT_Undefined
914                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
915                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
916
917         Returns:
918                 :class:`SMESH.Filter.Criterion`
919
920         Example: :ref:`combining_filters`
921         """
922
923         if not CritType in SMESH.FunctorType._items:
924             raise TypeError("CritType should be of SMESH.FunctorType")
925         aCriterion               = self.GetEmptyCriterion()
926         aCriterion.TypeOfElement = elementType
927         aCriterion.Type          = self.EnumToLong(CritType)
928         aCriterion.Tolerance     = Tolerance
929
930         aThreshold = Threshold
931
932         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
933             aCriterion.Compare = self.EnumToLong(Compare)
934         elif Compare == "=" or Compare == "==":
935             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
936         elif Compare == "<":
937             aCriterion.Compare = self.EnumToLong(FT_LessThan)
938         elif Compare == ">":
939             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
940         elif Compare != FT_Undefined:
941             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
942             aThreshold = Compare
943
944         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
945                         FT_BelongToCylinder, FT_LyingOnGeom]:
946             # Check that Threshold is GEOM object
947             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
948                 aCriterion.ThresholdStr = GetName(aThreshold)
949                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
950                 if not aCriterion.ThresholdID:
951                     name = aCriterion.ThresholdStr
952                     if not name:
953                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
954                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
955             # or a name of GEOM object
956             elif isinstance( aThreshold, str ):
957                 aCriterion.ThresholdStr = aThreshold
958             else:
959                 raise TypeError("The Threshold should be a shape.")
960             if isinstance(UnaryOp,float):
961                 aCriterion.Tolerance = UnaryOp
962                 UnaryOp = FT_Undefined
963                 pass
964         elif CritType == FT_BelongToMeshGroup:
965             # Check that Threshold is a group
966             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
967                 if aThreshold.GetType() != elementType:
968                     raise ValueError("Group type mismatches Element type")
969                 aCriterion.ThresholdStr = aThreshold.GetName()
970                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
971                 study = salome.myStudy
972                 if study:
973                     so = study.FindObjectIOR( aCriterion.ThresholdID )
974                     if so:
975                         entry = so.GetID()
976                         if entry:
977                             aCriterion.ThresholdID = entry
978             else:
979                 raise TypeError("The Threshold should be a Mesh Group")
980         elif CritType == FT_RangeOfIds:
981             # Check that Threshold is string
982             if isinstance(aThreshold, str):
983                 aCriterion.ThresholdStr = aThreshold
984             else:
985                 raise TypeError("The Threshold should be a string.")
986         elif CritType == FT_CoplanarFaces:
987             # Check the Threshold
988             if isinstance(aThreshold, int):
989                 aCriterion.ThresholdID = str(aThreshold)
990             elif isinstance(aThreshold, str):
991                 ID = int(aThreshold)
992                 if ID < 1:
993                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
994                 aCriterion.ThresholdID = aThreshold
995             else:
996                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
997         elif CritType == FT_ConnectedElements:
998             # Check the Threshold
999             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
1000                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
1001                 if not aCriterion.ThresholdID:
1002                     name = aThreshold.GetName()
1003                     if not name:
1004                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
1005                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
1006             elif isinstance(aThreshold, int): # node id
1007                 aCriterion.Threshold = aThreshold
1008             elif isinstance(aThreshold, list): # 3 point coordinates
1009                 if len( aThreshold ) < 3:
1010                     raise ValueError("too few point coordinates, must be 3")
1011                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
1012             elif isinstance(aThreshold, str):
1013                 if aThreshold.isdigit():
1014                     aCriterion.Threshold = aThreshold # node id
1015                 else:
1016                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
1017             else:
1018                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
1019                       "or a list of point coordinates and not '%s'"%aThreshold)
1020         elif CritType == FT_ElemGeomType:
1021             # Check the Threshold
1022             try:
1023                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1024                 assert( aThreshold in SMESH.GeometryType._items )
1025             except:
1026                 if isinstance(aThreshold, int):
1027                     aCriterion.Threshold = aThreshold
1028                 else:
1029                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
1030                 pass
1031             pass
1032         elif CritType == FT_EntityType:
1033             # Check the Threshold
1034             try:
1035                 aCriterion.Threshold = self.EnumToLong(aThreshold)
1036                 assert( aThreshold in SMESH.EntityType._items )
1037             except:
1038                 if isinstance(aThreshold, int):
1039                     aCriterion.Threshold = aThreshold
1040                 else:
1041                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
1042                 pass
1043             pass
1044
1045         elif CritType == FT_GroupColor:
1046             # Check the Threshold
1047             try:
1048                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
1049             except:
1050                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
1051             pass
1052         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
1053                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
1054                           FT_BareBorderFace, FT_BareBorderVolume,
1055                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
1056                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
1057             # At this point the Threshold is unnecessary
1058             if aThreshold ==  FT_LogicalNOT:
1059                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1060             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
1061                 aCriterion.BinaryOp = aThreshold
1062         else:
1063             # Check Threshold
1064             try:
1065                 aThreshold = float(aThreshold)
1066                 aCriterion.Threshold = aThreshold
1067             except:
1068                 raise TypeError("The Threshold should be a number.")
1069                 return None
1070
1071         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
1072             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
1073
1074         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
1075             aCriterion.BinaryOp = self.EnumToLong(Threshold)
1076
1077         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
1078             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
1079
1080         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
1081             aCriterion.BinaryOp = self.EnumToLong(BinaryOp)
1082
1083         return aCriterion
1084
1085     def GetFilter(self,elementType,
1086                   CritType=FT_Undefined,
1087                   Compare=FT_EqualTo,
1088                   Threshold="",
1089                   UnaryOp=FT_Undefined,
1090                   Tolerance=1e-07,
1091                   mesh=None):
1092         """
1093         Create a filter with the given parameters
1094
1095         Parameters:
1096                 elementType: the :class:`type of elements <SMESH.ElementType>` (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1097                 CritType: the :class:`type of criterion <SMESH.FunctorType>` (SMESH.FT_Taper, SMESH.FT_Area, etc.).
1098                         Note that the items starting from FT_LessThan are not suitable for CritType.
1099                 Compare: belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
1100                 Threshold: the threshold value (range of ids as string, shape, numeric)
1101                 UnaryOp:  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
1102                 Tolerance: the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
1103                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
1104                 mesh: the mesh to initialize the filter with
1105
1106         Returns:
1107                 :class:`SMESH.Filter`
1108
1109         Examples:
1110                See :doc:`Filters usage examples <tui_filters>`
1111         """
1112
1113         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
1114         aFilterMgr = self.CreateFilterManager()
1115         aFilter = aFilterMgr.CreateFilter()
1116         aCriteria = []
1117         aCriteria.append(aCriterion)
1118         aFilter.SetCriteria(aCriteria)
1119         if mesh:
1120             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
1121             else                       : aFilter.SetMesh( mesh )
1122         aFilterMgr.UnRegister()
1123         return aFilter
1124
1125     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
1126         """
1127         Create a filter from criteria
1128
1129         Parameters:
1130                 criteria: a list of :class:`SMESH.Filter.Criterion`
1131                 binOp: binary operator used when binary operator of criteria is undefined
1132
1133         Returns:
1134                 :class:`SMESH.Filter`
1135
1136         Examples:
1137                See :doc:`Filters usage examples <tui_filters>`
1138         """
1139
1140         for i in range( len( criteria ) - 1 ):
1141             if criteria[i].BinaryOp == self.EnumToLong( SMESH.FT_Undefined ):
1142                 criteria[i].BinaryOp = self.EnumToLong( binOp )
1143         aFilterMgr = self.CreateFilterManager()
1144         aFilter = aFilterMgr.CreateFilter()
1145         aFilter.SetCriteria(criteria)
1146         aFilterMgr.UnRegister()
1147         return aFilter
1148
1149     def GetFunctor(self,theCriterion):
1150         """
1151         Create a numerical functor by its type
1152
1153         Parameters:
1154                 theCriterion (SMESH.FunctorType): functor type.
1155                         Note that not all items correspond to numerical functors.
1156
1157         Returns:
1158                 :class:`SMESH.NumericalFunctor`
1159         """
1160
1161         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
1162             return theCriterion
1163         aFilterMgr = self.CreateFilterManager()
1164         functor = None
1165         if theCriterion == FT_AspectRatio:
1166             functor = aFilterMgr.CreateAspectRatio()
1167         elif theCriterion == FT_AspectRatio3D:
1168             functor = aFilterMgr.CreateAspectRatio3D()
1169         elif theCriterion == FT_Warping:
1170             functor = aFilterMgr.CreateWarping()
1171         elif theCriterion == FT_MinimumAngle:
1172             functor = aFilterMgr.CreateMinimumAngle()
1173         elif theCriterion == FT_Taper:
1174             functor = aFilterMgr.CreateTaper()
1175         elif theCriterion == FT_Skew:
1176             functor = aFilterMgr.CreateSkew()
1177         elif theCriterion == FT_Area:
1178             functor = aFilterMgr.CreateArea()
1179         elif theCriterion == FT_Volume3D:
1180             functor = aFilterMgr.CreateVolume3D()
1181         elif theCriterion == FT_MaxElementLength2D:
1182             functor = aFilterMgr.CreateMaxElementLength2D()
1183         elif theCriterion == FT_MaxElementLength3D:
1184             functor = aFilterMgr.CreateMaxElementLength3D()
1185         elif theCriterion == FT_MultiConnection:
1186             functor = aFilterMgr.CreateMultiConnection()
1187         elif theCriterion == FT_MultiConnection2D:
1188             functor = aFilterMgr.CreateMultiConnection2D()
1189         elif theCriterion == FT_Length:
1190             functor = aFilterMgr.CreateLength()
1191         elif theCriterion == FT_Length2D:
1192             functor = aFilterMgr.CreateLength2D()
1193         elif theCriterion == FT_Deflection2D:
1194             functor = aFilterMgr.CreateDeflection2D()
1195         elif theCriterion == FT_NodeConnectivityNumber:
1196             functor = aFilterMgr.CreateNodeConnectivityNumber()
1197         elif theCriterion == FT_BallDiameter:
1198             functor = aFilterMgr.CreateBallDiameter()
1199         else:
1200             print("Error: given parameter is not numerical functor type.")
1201         aFilterMgr.UnRegister()
1202         return functor
1203
1204     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1205         """
1206         Create hypothesis
1207
1208         Parameters:
1209                 theHType (string): mesh hypothesis type
1210                 theLibName (string): mesh plug-in library name
1211
1212         Returns:
1213                 created hypothesis instance
1214         """
1215         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1216
1217         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1218             return hyp
1219
1220         # wrap hypothesis methods
1221         for meth_name in dir( hyp.__class__ ):
1222             if not meth_name.startswith("Get") and \
1223                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1224                 method = getattr ( hyp.__class__, meth_name )
1225                 if callable(method):
1226                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1227
1228         return hyp
1229
1230     def GetMeshInfo(self, obj):
1231         """
1232         Get the mesh statistic.
1233         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
1234         an item of :class:`SMESH.EntityType`.
1235
1236         Returns:
1237                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
1238         """
1239
1240         if isinstance( obj, Mesh ):
1241             obj = obj.GetMesh()
1242         d = {}
1243         if hasattr(obj, "GetMeshInfo"):
1244             values = obj.GetMeshInfo()
1245             for i in range(SMESH.Entity_Last._v):
1246                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1247             pass
1248         return d
1249
1250     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1251         """
1252         Get minimum distance between two objects
1253
1254         * If *src2* is None, and *id2* = 0, distance from *src1* / *id1* to the origin is computed.
1255         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1256
1257         Parameters:
1258                 src1 (SMESH.SMESH_IDSource): first source object
1259                 src2 (SMESH.SMESH_IDSource): second source object
1260                 id1 (int): node/element id from the first source
1261                 id2 (int): node/element id from the second (or first) source
1262                 isElem1 (boolean): *True* if *id1* is element id, *False* if it is node id
1263                 isElem2 (boolean): *True* if *id2* is element id, *False* if it is node id
1264
1265         Returns:
1266                 minimum distance value
1267
1268         See also: 
1269                 :meth:`GetMinDistance`
1270         """
1271
1272         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1273         if result is None:
1274             result = 0.0
1275         else:
1276             result = result.value
1277         return result
1278
1279     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1280         """
1281         Get :class:`SMESH.Measure` structure specifying minimum distance data between two objects
1282
1283         * If *src2* is None, and *id2*  = 0, distance from *src1* / *id1* to the origin is computed.
1284         * If *src2* is None, and *id2* != 0, it is assumed that both *id1* and *id2* belong to *src1*.
1285
1286         Parameters:
1287                 src1 (SMESH.SMESH_IDSource): first source object
1288                 src2 (SMESH.SMESH_IDSource): second source object
1289                 id1 (int): node/element id from the first source
1290                 id2 (int): node/element id from the second (or first) source
1291                 isElem1 (boolean): *True* if **id1** is element id, *False* if it is node id
1292                 isElem2 (boolean): *True* if **id2** is element id, *False* if it is node id
1293
1294         Returns:
1295                 :class:`SMESH.Measure` structure or None if input data is invalid
1296         See also: 
1297                 :meth:`MinDistance`
1298         """
1299
1300         if isinstance(src1, Mesh): src1 = src1.mesh
1301         if isinstance(src2, Mesh): src2 = src2.mesh
1302         if src2 is None and id2 != 0: src2 = src1
1303         if not hasattr(src1, "_narrow"): return None
1304         src1 = src1._narrow(SMESH.SMESH_IDSource)
1305         if not src1: return None
1306         unRegister = genObjUnRegister()
1307         if id1 != 0:
1308             m = src1.GetMesh()
1309             e = m.GetMeshEditor()
1310             if isElem1:
1311                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1312             else:
1313                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1314             unRegister.set( src1 )
1315             pass
1316         if hasattr(src2, "_narrow"):
1317             src2 = src2._narrow(SMESH.SMESH_IDSource)
1318             if src2 and id2 != 0:
1319                 m = src2.GetMesh()
1320                 e = m.GetMeshEditor()
1321                 if isElem2:
1322                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1323                 else:
1324                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1325                 unRegister.set( src2 )
1326                 pass
1327             pass
1328         aMeasurements = self.CreateMeasurements()
1329         unRegister.set( aMeasurements )
1330         result = aMeasurements.MinDistance(src1, src2)
1331         return result
1332
1333     def BoundingBox(self, objects):
1334         """
1335         Get bounding box of the specified object(s)
1336
1337         Parameters:
1338                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1339
1340         Returns:
1341                 tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1342
1343         See also: 
1344                :meth:`GetBoundingBox`
1345         """
1346
1347         result = self.GetBoundingBox(objects)
1348         if result is None:
1349             result = (0.0,)*6
1350         else:
1351             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1352         return result
1353
1354     def GetBoundingBox(self, objects):
1355         """
1356         Get :class:`SMESH.Measure` structure specifying bounding box data of the specified object(s)
1357
1358         Parameters:
1359                 objects (SMESH.SMESH_IDSource): single source object or list of source objects
1360
1361         Returns:
1362                 :class:`SMESH.Measure` structure
1363
1364         See also: 
1365                 :meth:`BoundingBox`
1366         """
1367
1368         if isinstance(objects, tuple):
1369             objects = list(objects)
1370         if not isinstance(objects, list):
1371             objects = [objects]
1372         srclist = []
1373         for o in objects:
1374             if isinstance(o, Mesh):
1375                 srclist.append(o.mesh)
1376             elif hasattr(o, "_narrow"):
1377                 src = o._narrow(SMESH.SMESH_IDSource)
1378                 if src: srclist.append(src)
1379                 pass
1380             pass
1381         aMeasurements = self.CreateMeasurements()
1382         result = aMeasurements.BoundingBox(srclist)
1383         aMeasurements.UnRegister()
1384         return result
1385
1386     def GetLength(self, obj):
1387         """
1388         Get sum of lengths of all 1D elements in the mesh object.
1389
1390         Parameters:
1391                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1392
1393         Returns:
1394                 sum of lengths of all 1D elements
1395         """
1396
1397         if isinstance(obj, Mesh): obj = obj.mesh
1398         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1399         aMeasurements = self.CreateMeasurements()
1400         value = aMeasurements.Length(obj)
1401         aMeasurements.UnRegister()
1402         return value
1403
1404     def GetArea(self, obj):
1405         """
1406         Get sum of areas of all 2D elements in the mesh object.
1407
1408         Parameters:
1409                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1410
1411         Returns:
1412                 sum of areas of all 2D elements
1413         """
1414
1415         if isinstance(obj, Mesh): obj = obj.mesh
1416         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1417         aMeasurements = self.CreateMeasurements()
1418         value = aMeasurements.Area(obj)
1419         aMeasurements.UnRegister()
1420         return value
1421
1422     def GetVolume(self, obj):
1423         """
1424         Get sum of volumes of all 3D elements in the mesh object.
1425
1426         Parameters:
1427                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1428
1429         Returns:
1430                 sum of volumes of all 3D elements
1431         """
1432
1433         if isinstance(obj, Mesh): obj = obj.mesh
1434         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1435         aMeasurements = self.CreateMeasurements()
1436         value = aMeasurements.Volume(obj)
1437         aMeasurements.UnRegister()
1438         return value
1439
1440     def GetGravityCenter(self, obj):
1441         """
1442         Get gravity center of all nodes of a mesh object.
1443         
1444         Parameters:            
1445                 obj: :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
1446
1447         Returns:        
1448                 Three components of the gravity center (x,y,z)
1449
1450         See also: 
1451                 :meth:`Mesh.BaryCenter`
1452         """
1453         if isinstance(obj, Mesh): obj = obj.mesh
1454         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1455         aMeasurements = self.CreateMeasurements()
1456         pointStruct = aMeasurements.GravityCenter(obj)
1457         aMeasurements.UnRegister()
1458         return pointStruct.x, pointStruct.y, pointStruct.z
1459
1460     def GetAngle(self, p1, p2, p3 ):
1461         """
1462         Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3)
1463
1464         Parameters:            
1465                 p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct 
1466                           or list [x,y,z]
1467
1468         Returns:        
1469             Angle in radians
1470         """
1471         if isinstance( p1, list ): p1 = PointStruct(*p1)
1472         if isinstance( p2, list ): p2 = PointStruct(*p2)
1473         if isinstance( p3, list ): p3 = PointStruct(*p3)
1474
1475         aMeasurements = self.CreateMeasurements()
1476         angle = aMeasurements.Angle(p1,p2,p3)
1477         aMeasurements.UnRegister()
1478
1479         return angle
1480
1481
1482     pass # end of class smeshBuilder
1483
1484 import omniORB
1485 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1486 """Registering the new proxy for SMESH.SMESH_Gen"""
1487
1488
1489 def New( instance=None, instanceGeom=None):
1490     """
1491     Create a new smeshBuilder instance. The smeshBuilder class provides the Python
1492     interface to create or load meshes.
1493
1494     Typical use is::
1495
1496         import salome
1497         salome.salome_init()
1498         from salome.smesh import smeshBuilder
1499         smesh = smeshBuilder.New()
1500
1501     Parameters:
1502         instance:      CORBA proxy of SMESH Engine. If None, the default Engine is used.
1503         instanceGeom:  CORBA proxy of GEOM  Engine. If None, the default Engine is used.
1504     Returns:
1505         :class:`smeshBuilder` instance
1506     """
1507     global engine
1508     global smeshInst
1509     global doLcc
1510     if instance and isinstance( instance, SALOMEDS._objref_Study ):
1511         import sys
1512         sys.stderr.write("Warning: 'study' argument is no more needed in smeshBuilder.New(). Consider updating your script!!!\n\n")
1513         instance = None
1514     engine = instance
1515     if engine is None:
1516         doLcc = True
1517     smeshInst = smeshBuilder()
1518     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1519     smeshInst.init_smesh(instanceGeom)
1520     return smeshInst
1521
1522
1523 # Public class: Mesh
1524 # ==================
1525
1526
1527 class Mesh(metaclass = MeshMeta):
1528     """
1529     This class allows defining and managing a mesh.
1530     It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1531     It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1532     new nodes and elements and by changing the existing entities), to get information
1533     about a mesh and to export a mesh in different formats.
1534     """    
1535
1536     geom = 0
1537     mesh = 0
1538     editor = 0
1539
1540     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1541
1542         """
1543         Constructor
1544
1545         Create a mesh on the shape *obj* (or an empty mesh if *obj* is equal to 0) and
1546         sets the GUI name of this mesh to *name*.
1547
1548         Parameters:
1549                 smeshpyD: an instance of smeshBuilder class
1550                 geompyD: an instance of geomBuilder class
1551                 obj: Shape to be meshed or :class:`SMESH.SMESH_Mesh` object
1552                 name: Study name of the mesh
1553         """
1554
1555         self.smeshpyD = smeshpyD
1556         self.geompyD = geompyD
1557         if obj is None:
1558             obj = 0
1559         objHasName = False
1560         if obj != 0:
1561             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1562                 self.geom = obj
1563                 objHasName = True
1564                 # publish geom of mesh (issue 0021122)
1565                 if not self.geom.GetStudyEntry():
1566                     objHasName = False
1567                     geompyD.init_geom()
1568                     if name:
1569                         geo_name = name + " shape"
1570                     else:
1571                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1572                     geompyD.addToStudy( self.geom, geo_name )
1573                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1574
1575             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1576                 self.SetMesh(obj)
1577         else:
1578             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1579         if name:
1580             self.smeshpyD.SetName(self.mesh, name)
1581         elif objHasName:
1582             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1583
1584         if not self.geom:
1585             self.geom = self.mesh.GetShapeToMesh()
1586
1587         self.editor   = self.mesh.GetMeshEditor()
1588         self.functors = [None] * SMESH.FT_Undefined._v
1589
1590         # set self to algoCreator's
1591         for attrName in dir(self):
1592             attr = getattr( self, attrName )
1593             if isinstance( attr, algoCreator ):
1594                 setattr( self, attrName, attr.copy( self ))
1595                 pass
1596             pass
1597         pass
1598
1599     def __del__(self):
1600         """
1601         Destructor. Clean-up resources
1602         """
1603         if self.mesh:
1604             #self.mesh.UnRegister()
1605             pass
1606         pass
1607
1608     def SetMesh(self, theMesh):
1609         """
1610         Initialize the Mesh object from an instance of :class:`SMESH.SMESH_Mesh` interface
1611
1612         Parameters:
1613                 theMesh: a :class:`SMESH.SMESH_Mesh` object
1614         """
1615
1616
1617         # do not call Register() as this prevents mesh servant deletion at closing study
1618         #if self.mesh: self.mesh.UnRegister()
1619         self.mesh = theMesh
1620         if self.mesh:
1621             #self.mesh.Register()
1622             self.geom = self.mesh.GetShapeToMesh()
1623         pass
1624
1625     def GetMesh(self):
1626         """
1627         Return the mesh, that is an encapsulated instance of :class:`SMESH.SMESH_Mesh` interface
1628
1629         Returns:
1630                 a :class:`SMESH.SMESH_Mesh` object
1631         """
1632
1633         return self.mesh
1634
1635     def GetEngine(self):
1636         """
1637         Return a smeshBuilder instance created this mesh
1638         """
1639         return self.smeshpyD
1640
1641     def GetGeomEngine(self):
1642         """
1643         Return a geomBuilder instance
1644         """
1645         return self.geompyD
1646
1647     def GetName(self):
1648         """
1649         Get the name of the mesh
1650
1651         Returns:
1652                 the name of the mesh as a string
1653         """
1654
1655         name = GetName(self.GetMesh())
1656         return name
1657
1658     def SetName(self, name):
1659         """
1660         Set a name to the mesh
1661
1662         Parameters:
1663                 name: a new name of the mesh
1664         """
1665
1666         self.smeshpyD.SetName(self.GetMesh(), name)
1667
1668     def GetSubMesh(self, geom, name):
1669         """
1670         Get a sub-mesh object associated to a *geom* geometrical object.
1671
1672         Parameters:
1673                 geom: a geometrical object (shape)
1674                 name: a name for the sub-mesh in the Object Browser
1675
1676         Returns:
1677                 an object of type :class:`SMESH.SMESH_subMesh`, representing a part of mesh,
1678                 which lies on the given shape
1679
1680         Note:
1681                 A sub-mesh is implicitly created when a sub-shape is specified at
1682                 creating an algorithm, for example::
1683
1684                    algo1D = mesh.Segment(geom=Edge_1)
1685
1686                 create a sub-mesh on *Edge_1* and assign Wire Discretization algorithm to it.
1687                 The created sub-mesh can be retrieved from the algorithm::
1688
1689                    submesh = algo1D.GetSubMesh()
1690         """
1691
1692         AssureGeomPublished( self, geom, name )
1693         submesh = self.mesh.GetSubMesh( geom, name )
1694         return submesh
1695
1696     def GetShape(self):
1697         """
1698         Return the shape associated to the mesh
1699
1700         Returns:
1701                 a GEOM_Object
1702         """
1703
1704         return self.geom
1705
1706     def SetShape(self, geom):
1707         """
1708         Associate the given shape to the mesh (entails the recreation of the mesh)
1709
1710         Parameters:
1711                 geom: the shape to be meshed (GEOM_Object)
1712         """
1713
1714         self.mesh = self.smeshpyD.CreateMesh(geom)
1715
1716     def HasShapeToMesh(self):
1717         """
1718         Return ``True`` if this mesh is based on geometry
1719         """
1720         return self.mesh.HasShapeToMesh()
1721
1722     def Load(self):
1723         """
1724         Load mesh from the study after opening the study
1725         """
1726         self.mesh.Load()
1727
1728     def IsReadyToCompute(self, theSubObject):
1729         """
1730         Return true if the hypotheses are defined well
1731
1732         Parameters:
1733                 theSubObject: a sub-shape of a mesh shape
1734
1735         Returns:
1736                 True or False
1737         """
1738
1739         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1740
1741     def GetAlgoState(self, theSubObject):
1742         """
1743         Return errors of hypotheses definition.
1744         The list of errors is empty if everything is OK.
1745
1746         Parameters:
1747                 theSubObject: a sub-shape of a mesh shape
1748
1749         Returns:
1750                 a list of errors
1751         """
1752
1753         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1754
1755     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1756         """
1757         Return a geometrical object on which the given element was built.
1758         The returned geometrical object, if not nil, is either found in the
1759         study or published by this method with the given name
1760
1761         Parameters:
1762             theElementID: the id of the mesh element
1763             theGeomName: the user-defined name of the geometrical object
1764
1765         Returns:
1766             GEOM.GEOM_Object instance
1767         """
1768
1769         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1770
1771     def MeshDimension(self):
1772         """
1773         Return the mesh dimension depending on the dimension of the underlying shape
1774         or, if the mesh is not based on any shape, basing on deimension of elements
1775
1776         Returns:
1777                 mesh dimension as an integer value [0,3]
1778         """
1779
1780         if self.mesh.HasShapeToMesh():
1781             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1782             if len( shells ) > 0 :
1783                 return 3
1784             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1785                 return 2
1786             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1787                 return 1
1788             else:
1789                 return 0;
1790         else:
1791             if self.NbVolumes() > 0: return 3
1792             if self.NbFaces()   > 0: return 2
1793             if self.NbEdges()   > 0: return 1
1794         return 0
1795
1796     def Evaluate(self, geom=0):
1797         """
1798         Evaluate size of prospective mesh on a shape
1799
1800         Returns:
1801                 a list where i-th element is a number of elements of i-th :class:`SMESH.EntityType`.
1802                 To know predicted number of e.g. edges, inquire it this way::
1803
1804                    Evaluate()[ smesh.EnumToLong( SMESH.Entity_Edge )]
1805         """
1806
1807         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1808             if self.geom == 0:
1809                 geom = self.mesh.GetShapeToMesh()
1810             else:
1811                 geom = self.geom
1812         return self.smeshpyD.Evaluate(self.mesh, geom)
1813
1814
1815     def Compute(self, geom=0, discardModifs=False, refresh=False):
1816         """
1817         Compute the mesh and return the status of the computation
1818
1819         Parameters:
1820                 geom: geomtrical shape on which mesh data should be computed
1821                 discardModifs: if True and the mesh has been edited since
1822                         a last total re-compute and that may prevent successful partial re-compute,
1823                         then the mesh is cleaned before Compute()
1824                 refresh: if *True*, Object Browser is automatically updated (when running in GUI)
1825
1826         Returns:
1827                 True or False
1828         """
1829
1830         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1831             if self.geom == 0:
1832                 geom = self.mesh.GetShapeToMesh()
1833             else:
1834                 geom = self.geom
1835         ok = False
1836         try:
1837             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1838                 self.mesh.Clear()
1839             ok = self.smeshpyD.Compute(self.mesh, geom)
1840         except SALOME.SALOME_Exception as ex:
1841             print("Mesh computation failed, exception caught:")
1842             print("    ", ex.details.text)
1843         except:
1844             import traceback
1845             print("Mesh computation failed, exception caught:")
1846             traceback.print_exc()
1847         if True:#not ok:
1848             allReasons = ""
1849
1850             # Treat compute errors
1851             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1852             shapeText = ""
1853             for err in computeErrors:
1854                 if self.mesh.HasShapeToMesh():
1855                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1856                 errText = ""
1857                 stdErrors = ["OK",                   #COMPERR_OK
1858                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1859                              "std::exception",       #COMPERR_STD_EXCEPTION
1860                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1861                              "..",                   #COMPERR_SLM_EXCEPTION
1862                              "Unknown exception",    #COMPERR_EXCEPTION
1863                              "Memory allocation problem", #COMPERR_MEMORY_PB
1864                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1865                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1866                              "Warning",              #COMPERR_WARNING
1867                              "Computation cancelled",#COMPERR_CANCELED
1868                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1869                 if err.code > 0:
1870                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1871                 else:
1872                     errText = "code %s" % -err.code
1873                 if errText: errText += ". "
1874                 errText += err.comment
1875                 if allReasons: allReasons += "\n"
1876                 if ok:
1877                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1878                 else:
1879                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1880                 pass
1881
1882             # Treat hyp errors
1883             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1884             for err in errors:
1885                 if err.isGlobalAlgo:
1886                     glob = "global"
1887                 else:
1888                     glob = "local"
1889                     pass
1890                 dim = err.algoDim
1891                 name = err.algoName
1892                 if len(name) == 0:
1893                     reason = '%s %sD algorithm is missing' % (glob, dim)
1894                 elif err.state == HYP_MISSING:
1895                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1896                               % (glob, dim, name, dim))
1897                 elif err.state == HYP_NOTCONFORM:
1898                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1899                 elif err.state == HYP_BAD_PARAMETER:
1900                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1901                               % ( glob, dim, name ))
1902                 elif err.state == HYP_BAD_GEOMETRY:
1903                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1904                               'geometry' % ( glob, dim, name ))
1905                 elif err.state == HYP_HIDDEN_ALGO:
1906                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1907                               'algorithm of upper dimension generating %sD mesh'
1908                               % ( glob, dim, name, glob, dim ))
1909                 else:
1910                     reason = ("For unknown reason. "
1911                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1912                     pass
1913                 if allReasons: allReasons += "\n"
1914                 allReasons += "-  " + reason
1915                 pass
1916             if not ok or allReasons != "":
1917                 msg = '"' + GetName(self.mesh) + '"'
1918                 if ok: msg += " has been computed with warnings"
1919                 else:  msg += " has not been computed"
1920                 if allReasons != "": msg += ":"
1921                 else:                msg += "."
1922                 print(msg)
1923                 print(allReasons)
1924             pass
1925         if salome.sg.hasDesktop():
1926             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1927                 if refresh: salome.sg.updateObjBrowser()
1928
1929         return ok
1930
1931     def GetComputeErrors(self, shape=0 ):
1932         """
1933         Return a list of error messages (:class:`SMESH.ComputeError`) of the last :meth:`Compute`
1934         """
1935
1936         if shape == 0:
1937             shape = self.mesh.GetShapeToMesh()
1938         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1939
1940     def GetSubShapeName(self, subShapeID ):
1941         """
1942         Return a name of a sub-shape by its ID.
1943         Possible variants (for *subShapeID* == 3):
1944
1945                 - **"Face_12"** - published sub-shape
1946                 - **FACE #3** - not published sub-shape
1947                 - **sub-shape #3** - invalid sub-shape ID
1948                 - **#3** - error in this function
1949
1950         Parameters:
1951                 subShapeID: a unique ID of a sub-shape
1952
1953         Returns:
1954                 a string describing the sub-shape
1955
1956         """
1957
1958         if not self.mesh.HasShapeToMesh():
1959             return ""
1960         try:
1961             shapeText = ""
1962             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1963             s = salome.myStudy
1964             mainSO = s.FindObjectIOR(mainIOR)
1965             if mainSO:
1966                 if subShapeID == 1:
1967                     shapeText = '"%s"' % mainSO.GetName()
1968                 subIt = s.NewChildIterator(mainSO)
1969                 while subIt.More():
1970                     subSO = subIt.Value()
1971                     subIt.Next()
1972                     obj = subSO.GetObject()
1973                     if not obj: continue
1974                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1975                     if not go: continue
1976                     try:
1977                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1978                     except:
1979                         continue
1980                     if ids == subShapeID:
1981                         shapeText = '"%s"' % subSO.GetName()
1982                         break
1983             if not shapeText:
1984                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1985                 if shape:
1986                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1987                 else:
1988                     shapeText = 'sub-shape #%s' % (subShapeID)
1989         except:
1990             shapeText = "#%s" % (subShapeID)
1991         return shapeText
1992
1993     def GetFailedShapes(self, publish=False):
1994         """
1995         Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1996         error of an algorithm
1997
1998         Parameters:
1999                 publish: if *True*, the returned groups will be published in the study
2000
2001         Returns:
2002                 a list of GEOM groups each named after a failed algorithm
2003         """
2004
2005
2006         algo2shapes = {}
2007         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
2008         for err in computeErrors:
2009             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
2010             if not shape: continue
2011             if err.algoName in algo2shapes:
2012                 algo2shapes[ err.algoName ].append( shape )
2013             else:
2014                 algo2shapes[ err.algoName ] = [ shape ]
2015             pass
2016
2017         groups = []
2018         for algoName, shapes in list(algo2shapes.items()):
2019             while shapes:
2020                 groupType = self.smeshpyD.EnumToLong( shapes[0].GetShapeType() )
2021                 otherTypeShapes = []
2022                 sameTypeShapes  = []
2023                 group = self.geompyD.CreateGroup( self.geom, groupType )
2024                 for shape in shapes:
2025                     if shape.GetShapeType() == shapes[0].GetShapeType():
2026                         sameTypeShapes.append( shape )
2027                     else:
2028                         otherTypeShapes.append( shape )
2029                 self.geompyD.UnionList( group, sameTypeShapes )
2030                 if otherTypeShapes:
2031                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
2032                 else:
2033                     group.SetName( algoName )
2034                 groups.append( group )
2035                 shapes = otherTypeShapes
2036             pass
2037         if publish:
2038             for group in groups:
2039                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
2040         return groups
2041
2042     def GetMeshOrder(self):
2043         """
2044         Return sub-mesh objects list in meshing order
2045
2046         Returns:
2047                 list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2048         """
2049
2050         return self.mesh.GetMeshOrder()
2051
2052     def SetMeshOrder(self, submeshes):
2053         """
2054         Set order in which concurrent sub-meshes should be meshed
2055
2056         Parameters:
2057                 submeshes: list of lists of :class:`sub-meshes <SMESH.SMESH_subMesh>`
2058         """
2059
2060         return self.mesh.SetMeshOrder(submeshes)
2061
2062     def Clear(self, refresh=False):
2063         """
2064         Remove all nodes and elements generated on geometry. Imported elements remain.
2065
2066         Parameters:
2067                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2068         """
2069
2070         self.mesh.Clear()
2071         if ( salome.sg.hasDesktop() ):
2072             if refresh: salome.sg.updateObjBrowser()
2073
2074     def ClearSubMesh(self, geomId, refresh=False):
2075         """
2076         Remove all nodes and elements of indicated shape
2077
2078         Parameters:
2079                 geomId: the ID of a sub-shape to remove elements on
2080                 refresh: if *True*, Object browser is automatically updated (when running in GUI)
2081         """
2082
2083         self.mesh.ClearSubMesh(geomId)
2084         if salome.sg.hasDesktop():
2085             if refresh: salome.sg.updateObjBrowser()
2086
2087     def AutomaticTetrahedralization(self, fineness=0):
2088         """
2089         Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
2090
2091         Parameters:
2092                 fineness: [0.0,1.0] defines mesh fineness
2093
2094         Returns:
2095                 True or False
2096         """
2097
2098         dim = self.MeshDimension()
2099         # assign hypotheses
2100         self.RemoveGlobalHypotheses()
2101         self.Segment().AutomaticLength(fineness)
2102         if dim > 1 :
2103             self.Triangle().LengthFromEdges()
2104             pass
2105         if dim > 2 :
2106             self.Tetrahedron()
2107             pass
2108         return self.Compute()
2109
2110     def AutomaticHexahedralization(self, fineness=0):
2111         """
2112         Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
2113
2114         Parameters:
2115                 fineness: [0.0, 1.0] defines mesh fineness
2116
2117         Returns:
2118                 True or False
2119         """
2120
2121         dim = self.MeshDimension()
2122         # assign the hypotheses
2123         self.RemoveGlobalHypotheses()
2124         self.Segment().AutomaticLength(fineness)
2125         if dim > 1 :
2126             self.Quadrangle()
2127             pass
2128         if dim > 2 :
2129             self.Hexahedron()
2130             pass
2131         return self.Compute()
2132
2133     def AddHypothesis(self, hyp, geom=0):
2134         """
2135         Assign a hypothesis
2136
2137         Parameters:
2138                 hyp: a hypothesis to assign
2139                 geom: a subhape of mesh geometry
2140
2141         Returns:
2142                 :class:`SMESH.Hypothesis_Status`
2143         """
2144
2145         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
2146             hyp, geom = geom, hyp
2147         if isinstance( hyp, Mesh_Algorithm ):
2148             hyp = hyp.GetAlgorithm()
2149             pass
2150         if not geom:
2151             geom = self.geom
2152             if not geom:
2153                 geom = self.mesh.GetShapeToMesh()
2154             pass
2155         isApplicable = True
2156         if self.mesh.HasShapeToMesh():
2157             hyp_type     = hyp.GetName()
2158             lib_name     = hyp.GetLibName()
2159             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
2160             # if checkAll and geom:
2161             #     checkAll = geom.GetType() == 37
2162             checkAll     = False
2163             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
2164         if isApplicable:
2165             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
2166             status = self.mesh.AddHypothesis(geom, hyp)
2167         else:
2168             status = HYP_BAD_GEOMETRY, ""
2169         hyp_name = GetName( hyp )
2170         geom_name = ""
2171         if geom:
2172             geom_name = geom.GetName()
2173         isAlgo = hyp._narrow( SMESH_Algo )
2174         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
2175         return status
2176
2177     def IsUsedHypothesis(self, hyp, geom):
2178         """
2179         Return True if an algorithm or hypothesis is assigned to a given shape
2180
2181         Parameters:
2182                 hyp: an algorithm or hypothesis to check
2183                 geom: a subhape of mesh geometry
2184
2185         Returns:
2186                 True of False
2187         """
2188
2189         if not hyp: # or not geom
2190             return False
2191         if isinstance( hyp, Mesh_Algorithm ):
2192             hyp = hyp.GetAlgorithm()
2193             pass
2194         hyps = self.GetHypothesisList(geom)
2195         for h in hyps:
2196             if h.GetId() == hyp.GetId():
2197                 return True
2198         return False
2199
2200     def RemoveHypothesis(self, hyp, geom=0):
2201         """
2202         Unassign a hypothesis
2203
2204         Parameters:
2205                 hyp (SMESH.SMESH_Hypothesis): a hypothesis to unassign
2206                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2207
2208         Returns:
2209                 :class:`SMESH.Hypothesis_Status`
2210         """
2211
2212         if not hyp:
2213             return None
2214         if isinstance( hyp, Mesh_Algorithm ):
2215             hyp = hyp.GetAlgorithm()
2216             pass
2217         shape = geom
2218         if not shape:
2219             shape = self.geom
2220             pass
2221         if self.IsUsedHypothesis( hyp, shape ):
2222             return self.mesh.RemoveHypothesis( shape, hyp )
2223         hypName = GetName( hyp )
2224         geoName = GetName( shape )
2225         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
2226         return None
2227
2228     def GetHypothesisList(self, geom):
2229         """
2230         Get the list of hypotheses added on a geometry
2231
2232         Parameters:
2233                 geom (GEOM.GEOM_Object): a sub-shape of mesh geometry
2234
2235         Returns:
2236                 the sequence of :class:`SMESH.SMESH_Hypothesis`
2237         """
2238
2239         return self.mesh.GetHypothesisList( geom )
2240
2241     def RemoveGlobalHypotheses(self):
2242         """
2243         Remove all global hypotheses
2244         """
2245
2246         current_hyps = self.mesh.GetHypothesisList( self.geom )
2247         for hyp in current_hyps:
2248             self.mesh.RemoveHypothesis( self.geom, hyp )
2249             pass
2250         pass
2251     def ExportMED(self, *args, **kwargs):
2252         """
2253         Export the mesh in a file in MED format
2254         allowing to overwrite the file if it exists or add the exported data to its contents
2255
2256         Parameters:
2257                 fileName: is the file name
2258                 auto_groups (boolean): parameter for creating/not creating
2259                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2260                         the typical use is auto_groups=False.
2261                 minor (int): define the minor version (y, where version is x.y.z) of MED file format.
2262                         The minor must be between 0 and the current minor version of MED file library.
2263                         If minor is equal to -1, the minor version is not changed (default).
2264                         The major version (x, where version is x.y.z) cannot be changed.
2265                 overwrite (boolean): parameter for overwriting/not overwriting the file
2266                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2267                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2268
2269                         - 1D if all mesh nodes lie on OX coordinate axis, or
2270                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2271                         - 3D in the rest cases.
2272
2273                         If *autoDimension* is *False*, the space dimension is always 3.
2274                 fields: list of GEOM fields defined on the shape to mesh.
2275                 geomAssocFields: each character of this string means a need to export a 
2276                         corresponding field; correspondence between fields and characters 
2277                         is following:
2278
2279                         - 'v' stands for "_vertices_" field;
2280                         - 'e' stands for "_edges_" field;
2281                         - 'f' stands for "_faces_" field;
2282                         - 's' stands for "_solids_" field.
2283
2284                 zTolerance (float): tolerance in Z direction. If Z coordinate of a node is 
2285                              close to zero within a given tolerance, the coordinate is set to zero.
2286                              If *ZTolerance* is negative (default), the node coordinates are kept as is.
2287         """
2288         # process positional arguments
2289         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2290         fileName        = args[0]
2291         auto_groups     = args[1] if len(args) > 1 else False
2292         minor           = args[2] if len(args) > 2 else -1
2293         overwrite       = args[3] if len(args) > 3 else True
2294         meshPart        = args[4] if len(args) > 4 else None
2295         autoDimension   = args[5] if len(args) > 5 else True
2296         fields          = args[6] if len(args) > 6 else []
2297         geomAssocFields = args[7] if len(args) > 7 else ''
2298         z_tolerance     = args[8] if len(args) > 8 else -1.
2299         # process keywords arguments
2300         auto_groups     = kwargs.get("auto_groups", auto_groups)
2301         minor           = kwargs.get("minor", minor)
2302         overwrite       = kwargs.get("overwrite", overwrite)
2303         meshPart        = kwargs.get("meshPart", meshPart)
2304         autoDimension   = kwargs.get("autoDimension", autoDimension)
2305         fields          = kwargs.get("fields", fields)
2306         geomAssocFields = kwargs.get("geomAssocFields", geomAssocFields)
2307         z_tolerance     = kwargs.get("zTolerance", z_tolerance)
2308
2309         # invoke engine's function
2310         if meshPart or fields or geomAssocFields or z_tolerance > 0:
2311             unRegister = genObjUnRegister()
2312             if isinstance( meshPart, list ):
2313                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2314                 unRegister.set( meshPart )
2315
2316             z_tolerance,Parameters,hasVars = ParseParameters(z_tolerance)
2317             self.mesh.SetParameters(Parameters)
2318
2319             self.mesh.ExportPartToMED( meshPart, fileName, auto_groups, minor, overwrite, autoDimension,
2320                                        fields, geomAssocFields, z_tolerance)
2321         else:
2322             self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2323
2324     def ExportSAUV(self, f, auto_groups=0):
2325         """
2326         Export the mesh in a file in SAUV format
2327
2328
2329         Parameters:
2330                 f: is the file name
2331                 auto_groups: boolean parameter for creating/not creating
2332                         the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
2333                         the typical use is auto_groups=False.
2334         """
2335
2336         self.mesh.ExportSAUV(f, auto_groups)
2337
2338     def ExportDAT(self, f, meshPart=None):
2339         """
2340         Export the mesh in a file in DAT format
2341
2342         Parameters:
2343                 f: the file name
2344                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2345         """
2346
2347         if meshPart:
2348             unRegister = genObjUnRegister()
2349             if isinstance( meshPart, list ):
2350                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2351                 unRegister.set( meshPart )
2352             self.mesh.ExportPartToDAT( meshPart, f )
2353         else:
2354             self.mesh.ExportDAT(f)
2355
2356     def ExportUNV(self, f, meshPart=None):
2357         """
2358         Export the mesh in a file in UNV format
2359
2360         Parameters:
2361                 f: the file name
2362                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2363         """
2364
2365         if meshPart:
2366             unRegister = genObjUnRegister()
2367             if isinstance( meshPart, list ):
2368                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2369                 unRegister.set( meshPart )
2370             self.mesh.ExportPartToUNV( meshPart, f )
2371         else:
2372             self.mesh.ExportUNV(f)
2373
2374     def ExportSTL(self, f, ascii=1, meshPart=None):
2375         """
2376         Export the mesh in a file in STL format
2377
2378         Parameters:
2379                 f: the file name
2380                 ascii: defines the file encoding
2381                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2382         """
2383
2384         if meshPart:
2385             unRegister = genObjUnRegister()
2386             if isinstance( meshPart, list ):
2387                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2388                 unRegister.set( meshPart )
2389             self.mesh.ExportPartToSTL( meshPart, f, ascii )
2390         else:
2391             self.mesh.ExportSTL(f, ascii)
2392
2393     def ExportCGNS(self, f, overwrite=1, meshPart=None, groupElemsByType=False):
2394         """
2395         Export the mesh in a file in CGNS format
2396
2397         Parameters:
2398                 f: is the file name
2399                 overwrite: boolean parameter for overwriting/not overwriting the file
2400                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2401                 groupElemsByType: if True all elements of same entity type are exported at ones,
2402                         else elements are exported in order of their IDs which can cause creation
2403                         of multiple cgns sections
2404         """
2405
2406         unRegister = genObjUnRegister()
2407         if isinstance( meshPart, list ):
2408             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2409             unRegister.set( meshPart )
2410         if isinstance( meshPart, Mesh ):
2411             meshPart = meshPart.mesh
2412         elif not meshPart:
2413             meshPart = self.mesh
2414         self.mesh.ExportCGNS(meshPart, f, overwrite, groupElemsByType)
2415
2416     def ExportGMF(self, f, meshPart=None):
2417         """
2418         Export the mesh in a file in GMF format.
2419         GMF files must have .mesh extension for the ASCII format and .meshb for
2420         the bynary format. Other extensions are not allowed.
2421
2422         Parameters:
2423                 f: is the file name
2424                 meshPart: a part of mesh (:class:`sub-mesh, group or filter <SMESH.SMESH_IDSource>`) to export instead of the mesh
2425         """
2426
2427         unRegister = genObjUnRegister()
2428         if isinstance( meshPart, list ):
2429             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
2430             unRegister.set( meshPart )
2431         if isinstance( meshPart, Mesh ):
2432             meshPart = meshPart.mesh
2433         elif not meshPart:
2434             meshPart = self.mesh
2435         self.mesh.ExportGMF(meshPart, f, True)
2436
2437     def ExportToMED(self, *args, **kwargs):
2438         """
2439         Deprecated, used only for compatibility! Please, use :meth:`ExportMED` method instead.
2440         Export the mesh in a file in MED format
2441         allowing to overwrite the file if it exists or add the exported data to its contents
2442
2443         Parameters:
2444                 fileName: the file name
2445                 opt (boolean): parameter for creating/not creating
2446                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2447                 overwrite: boolean parameter for overwriting/not overwriting the file
2448                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2449
2450                         - 1D if all mesh nodes lie on OX coordinate axis, or
2451                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2452                         - 3D in the rest cases.
2453
2454                         If **autoDimension** is *False*, the space dimension is always 3.
2455         """
2456     
2457         print("WARNING: ExportToMED() is deprecated, use ExportMED() instead")
2458         # process positional arguments
2459         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2460         fileName      = args[0]
2461         auto_groups   = args[1] if len(args) > 1 else False
2462         overwrite     = args[2] if len(args) > 2 else True
2463         autoDimension = args[3] if len(args) > 3 else True
2464         # process keywords arguments
2465         auto_groups   = kwargs.get("opt", auto_groups)         # old keyword name
2466         auto_groups   = kwargs.get("auto_groups", auto_groups) # new keyword name
2467         overwrite     = kwargs.get("overwrite", overwrite)
2468         autoDimension = kwargs.get("autoDimension", autoDimension)
2469         minor = -1
2470         # invoke engine's function
2471         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2472
2473     def ExportToMEDX(self, *args, **kwargs):
2474         """
2475         Deprecated, used only for compatibility! Please, use ExportMED() method instead.
2476         Export the mesh in a file in MED format
2477
2478         Parameters:
2479                 fileName: the file name
2480                 opt (boolean): parameter for creating/not creating
2481                         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
2482                 overwrite: boolean parameter for overwriting/not overwriting the file
2483                 autoDimension: if *True* (default), a space dimension of a MED mesh can be either
2484
2485                         - 1D if all mesh nodes lie on OX coordinate axis, or
2486                         - 2D if all mesh nodes lie on XOY coordinate plane, or
2487                         - 3D in the rest cases.
2488
2489                         If **autoDimension** is *False*, the space dimension is always 3.
2490                 """
2491
2492         print("WARNING: ExportToMEDX() is deprecated, use ExportMED() instead")
2493         # process positional arguments
2494         #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility
2495         fileName      = args[0]
2496         auto_groups   = args[1] if len(args) > 1 else False
2497         overwrite     = args[2] if len(args) > 2 else True
2498         autoDimension = args[3] if len(args) > 3 else True
2499         # process keywords arguments
2500         auto_groups   = kwargs.get("auto_groups", auto_groups)
2501         overwrite     = kwargs.get("overwrite", overwrite)
2502         autoDimension = kwargs.get("autoDimension", autoDimension)
2503         minor = -1
2504         # invoke engine's function
2505         self.mesh.ExportMED(fileName, auto_groups, minor, overwrite, autoDimension)
2506         return
2507
2508
2509     def Append(self, meshes, uniteIdenticalGroups = True,
2510                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
2511         """
2512         Append given meshes into this mesh.
2513         All groups of input meshes will be created in this mesh.
2514
2515         Parameters:
2516                 meshes: :class:`meshes, sub-meshes, groups or filters <SMESH.SMESH_IDSource>` to append
2517                 uniteIdenticalGroups: if True, groups with same names are united, else they are renamed
2518                 mergeNodesAndElements: if True, equal nodes and elements are merged
2519                 mergeTolerance: tolerance for merging nodes
2520                 allGroups: forces creation of groups corresponding to every input mesh
2521         """
2522         self.smeshpyD.Concatenate( meshes, uniteIdenticalGroups,
2523                                    mergeNodesAndElements, mergeTolerance, allGroups,
2524                                    meshToAppendTo = self.GetMesh() )
2525
2526     # Operations with groups:
2527     # ----------------------
2528     def CreateEmptyGroup(self, elementType, name):
2529         """
2530         Create an empty standalone mesh group
2531
2532         Parameters:
2533                 elementType: the :class:`type <SMESH.ElementType>` of elements in the group; 
2534                         either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2535                 name: the name of the mesh group
2536
2537         Returns:
2538                 :class:`SMESH.SMESH_Group`
2539         """
2540
2541         return self.mesh.CreateGroup(elementType, name)
2542
2543     def Group(self, grp, name=""):
2544         """
2545         Create a mesh group based on the geometric object *grp*
2546         and give it a *name*.
2547         If *name* is not defined the name of the geometric group is used
2548
2549         Note:
2550                 Works like :meth:`GroupOnGeom`.
2551
2552         Parameters:
2553                 grp:  a geometric group, a vertex, an edge, a face or a solid
2554                 name: the name of the mesh group
2555
2556         Returns:
2557                 :class:`SMESH.SMESH_GroupOnGeom`
2558         """
2559
2560         return self.GroupOnGeom(grp, name)
2561
2562     def GroupOnGeom(self, grp, name="", typ=None):
2563         """
2564         Create a mesh group based on the geometrical object *grp*
2565         and give it a *name*.
2566         if *name* is not defined the name of the geometric group is used
2567
2568         Parameters:
2569                 grp:  a geometrical group, a vertex, an edge, a face or a solid
2570                 name: the name of the mesh group
2571                 typ:  the type of elements in the group; either of
2572                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2573                         automatically detected by the type of the geometry
2574
2575         Returns:
2576                 :class:`SMESH.SMESH_GroupOnGeom`
2577         """
2578
2579         AssureGeomPublished( self, grp, name )
2580         if name == "":
2581             name = grp.GetName()
2582         if not typ:
2583             typ = self._groupTypeFromShape( grp )
2584         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2585
2586     def _groupTypeFromShape( self, shape ):
2587         """
2588         Pivate method to get a type of group on geometry
2589         """
2590         tgeo = str(shape.GetShapeType())
2591         if tgeo == "VERTEX":
2592             typ = NODE
2593         elif tgeo == "EDGE":
2594             typ = EDGE
2595         elif tgeo == "FACE" or tgeo == "SHELL":
2596             typ = FACE
2597         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2598             typ = VOLUME
2599         elif tgeo == "COMPOUND":
2600             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2601             if not sub:
2602                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2603             return self._groupTypeFromShape( sub[0] )
2604         else:
2605             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2606         return typ
2607
2608     def GroupOnFilter(self, typ, name, filter):
2609         """
2610         Create a mesh group with given *name* based on the *filter*.
2611         It is a special type of group dynamically updating it's contents during
2612         mesh modification
2613
2614         Parameters:
2615                 typ: the type of elements in the group; either of
2616                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2617                 name: the name of the mesh group
2618                 filter (SMESH.Filter): the filter defining group contents
2619
2620         Returns:
2621                 :class:`SMESH.SMESH_GroupOnFilter`
2622         """
2623
2624         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2625
2626     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2627         """
2628         Create a mesh group by the given ids of elements
2629
2630         Parameters:
2631                 groupName: the name of the mesh group
2632                 elementType: the type of elements in the group; either of
2633                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2634                 elemIDs: either the list of ids, :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
2635
2636         Returns:
2637                 :class:`SMESH.SMESH_Group`
2638         """
2639
2640         group = self.mesh.CreateGroup(elementType, groupName)
2641         if isinstance( elemIDs, Mesh ):
2642             elemIDs = elemIDs.GetMesh()
2643         if hasattr( elemIDs, "GetIDs" ):
2644             if hasattr( elemIDs, "SetMesh" ):
2645                 elemIDs.SetMesh( self.GetMesh() )
2646             group.AddFrom( elemIDs )
2647         else:
2648             group.Add(elemIDs)
2649         return group
2650
2651     def MakeGroup(self,
2652                   groupName,
2653                   elementType,
2654                   CritType=FT_Undefined,
2655                   Compare=FT_EqualTo,
2656                   Threshold="",
2657                   UnaryOp=FT_Undefined,
2658                   Tolerance=1e-07):
2659         """
2660         Create a mesh group by the given conditions
2661
2662         Parameters:
2663                 groupName: the name of the mesh group
2664                 elementType (SMESH.ElementType): the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2665                 CritType (SMESH.FunctorType): the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.).
2666                         Note that the items starting from FT_LessThan are not suitable for CritType.
2667                 Compare (SMESH.FunctorType): belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2668                 Threshold: the threshold value (range of ids as string, shape, numeric, depending on *CritType*)
2669                 UnaryOp (SMESH.FunctorType):  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2670                 Tolerance (float): the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2671                         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2672
2673         Returns:
2674                 :class:`SMESH.SMESH_GroupOnFilter`
2675         """
2676
2677         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2678         group = self.MakeGroupByCriterion(groupName, aCriterion)
2679         return group
2680
2681     def MakeGroupByCriterion(self, groupName, Criterion):
2682         """
2683         Create a mesh group by the given criterion
2684
2685         Parameters:
2686                 groupName: the name of the mesh group
2687                 Criterion: the instance of :class:`SMESH.Filter.Criterion` class
2688
2689         Returns:
2690                 :class:`SMESH.SMESH_GroupOnFilter`
2691
2692         See Also:
2693                 :meth:`smeshBuilder.GetCriterion`
2694         """
2695
2696         return self.MakeGroupByCriteria( groupName, [Criterion] )
2697
2698     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2699         """
2700         Create a mesh group by the given criteria (list of :class:`SMESH.Filter.Criterion`)
2701
2702         Parameters:
2703                 groupName: the name of the mesh group
2704                 theCriteria: the list of :class:`SMESH.Filter.Criterion`
2705                 binOp: binary operator (SMESH.FT_LogicalAND or SMESH.FT_LogicalOR ) used when binary operator of criteria is undefined
2706
2707         Returns:
2708                 :class:`SMESH.SMESH_GroupOnFilter`
2709
2710         See Also:
2711                 :meth:`smeshBuilder.GetCriterion`
2712         """
2713
2714         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2715         group = self.MakeGroupByFilter(groupName, aFilter)
2716         return group
2717
2718     def MakeGroupByFilter(self, groupName, theFilter):
2719         """
2720         Create a mesh group by the given filter
2721
2722         Parameters:
2723                 groupName (string): the name of the mesh group
2724                 theFilter (SMESH.Filter): the filter
2725
2726         Returns:
2727                 :class:`SMESH.SMESH_GroupOnFilter`
2728
2729         See Also:
2730                 :meth:`smeshBuilder.GetFilter`
2731         """
2732
2733         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2734         #theFilter.SetMesh( self.mesh )
2735         #group.AddFrom( theFilter )
2736         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2737         return group
2738
2739     def RemoveGroup(self, group):
2740         """
2741         Remove a group
2742
2743         Parameters:
2744                 group (SMESH.SMESH_GroupBase): group to remove
2745         """
2746
2747         self.mesh.RemoveGroup(group)
2748
2749     def RemoveGroupWithContents(self, group):
2750         """
2751         Remove a group with its contents
2752
2753         Parameters:
2754                 group (SMESH.SMESH_GroupBase): group to remove
2755         """
2756
2757         self.mesh.RemoveGroupWithContents(group)
2758
2759     def GetGroups(self, elemType = SMESH.ALL):
2760         """
2761         Get the list of groups existing in the mesh in the order of creation 
2762         (starting from the oldest one)
2763
2764         Parameters:
2765                 elemType (SMESH.ElementType): type of elements the groups contain;
2766                         by default groups of elements of all types are returned
2767
2768         Returns:
2769                 a list of :class:`SMESH.SMESH_GroupBase`
2770         """
2771
2772         groups = self.mesh.GetGroups()
2773         if elemType == SMESH.ALL:
2774             return groups
2775         typedGroups = []
2776         for g in groups:
2777             if g.GetType() == elemType:
2778                 typedGroups.append( g )
2779                 pass
2780             pass
2781         return typedGroups
2782
2783     def NbGroups(self):
2784         """
2785         Get the number of groups existing in the mesh
2786
2787         Returns:
2788                 the quantity of groups as an integer value
2789         """
2790
2791         return self.mesh.NbGroups()
2792
2793     def GetGroupNames(self):
2794         """
2795         Get the list of names of groups existing in the mesh
2796
2797         Returns:
2798                 list of strings
2799         """
2800
2801         groups = self.GetGroups()
2802         names = []
2803         for group in groups:
2804             names.append(group.GetName())
2805         return names
2806
2807     def GetGroupByName(self, name, elemType = None):
2808         """
2809         Find groups by name and type
2810
2811         Parameters:
2812                 name (string): name of the group of interest
2813                 elemType (SMESH.ElementType): type of elements the groups contain;
2814                         by default one group of any type is returned;
2815                         if elemType == SMESH.ALL then all groups of any type are returned
2816
2817         Returns:
2818                 a list of :class:`SMESH.SMESH_GroupBase`
2819         """
2820
2821         groups = []
2822         for group in self.GetGroups():
2823             if group.GetName() == name:
2824                 if elemType is None:
2825                     return [group]
2826                 if ( elemType == SMESH.ALL or
2827                      group.GetType() == elemType ):
2828                     groups.append( group )
2829         return groups
2830
2831     def UnionGroups(self, group1, group2, name):
2832         """
2833         Produce a union of two groups.
2834         A new group is created. All mesh elements that are
2835         present in the initial groups are added to the new one
2836
2837         Parameters:
2838            group1 (SMESH.SMESH_GroupBase): a group
2839            group2 (SMESH.SMESH_GroupBase): another group
2840
2841         Returns:
2842                 instance of :class:`SMESH.SMESH_Group`
2843         """
2844
2845         return self.mesh.UnionGroups(group1, group2, name)
2846
2847     def UnionListOfGroups(self, groups, name):
2848         """
2849         Produce a union list of groups.
2850         New group is created. All mesh elements that are present in
2851         initial groups are added to the new one
2852
2853         Parameters:
2854            groups: list of :class:`SMESH.SMESH_GroupBase`
2855
2856         Returns:
2857                 instance of :class:`SMESH.SMESH_Group`
2858         """
2859         return self.mesh.UnionListOfGroups(groups, name)
2860
2861     def IntersectGroups(self, group1, group2, name):
2862         """
2863         Prodice an intersection of two groups.
2864         A new group is created. All mesh elements that are common
2865         for the two initial groups are added to the new one.
2866
2867         Parameters:
2868            group1 (SMESH.SMESH_GroupBase): a group
2869            group2 (SMESH.SMESH_GroupBase): another group
2870
2871         Returns:
2872                 instance of :class:`SMESH.SMESH_Group`
2873         """
2874
2875         return self.mesh.IntersectGroups(group1, group2, name)
2876
2877     def IntersectListOfGroups(self, groups, name):
2878         """
2879         Produce an intersection of groups.
2880         New group is created. All mesh elements that are present in all
2881         initial groups simultaneously are added to the new one
2882
2883         Parameters:
2884            groups: a list of :class:`SMESH.SMESH_GroupBase`
2885
2886         Returns:
2887                 instance of :class:`SMESH.SMESH_Group`
2888         """
2889         return self.mesh.IntersectListOfGroups(groups, name)
2890
2891     def CutGroups(self, main_group, tool_group, name):
2892         """
2893         Produce a cut of two groups.
2894         A new group is created. All mesh elements that are present in
2895         the main group but are not present in the tool group are added to the new one
2896
2897         Parameters:
2898            main_group (SMESH.SMESH_GroupBase): a group to cut from
2899            tool_group (SMESH.SMESH_GroupBase): a group to cut by
2900
2901         Returns:
2902                 an instance of :class:`SMESH.SMESH_Group`
2903         """
2904
2905         return self.mesh.CutGroups(main_group, tool_group, name)
2906
2907     def CutListOfGroups(self, main_groups, tool_groups, name):
2908         """
2909         Produce a cut of groups.
2910         A new group is created. All mesh elements that are present in main groups
2911         but do not present in tool groups are added to the new one
2912
2913         Parameters:
2914            main_group: groups to cut from  (list of :class:`SMESH.SMESH_GroupBase`)
2915            tool_group: groups to cut by    (list of :class:`SMESH.SMESH_GroupBase`)
2916
2917         Returns:
2918                 an instance of :class:`SMESH.SMESH_Group`
2919         """
2920
2921         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2922
2923     def CreateDimGroup(self, groups, elemType, name,
2924                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2925         """
2926         Create a standalone group of entities basing on nodes of other groups.
2927
2928         Parameters:
2929                 groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>`, of any type.
2930                 elemType: a type of elements to include to the new group; either of
2931                         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2932                 name: a name of the new group.
2933                 nbCommonNodes: a criterion of inclusion of an element to the new group
2934                         basing on number of element nodes common with reference *groups*.
2935                         Meaning of possible values are:
2936
2937                                 - SMESH.ALL_NODES - include if all nodes are common,
2938                                 - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2939                                 - SMESH.AT_LEAST_ONE - include if one or more node is common,
2940                                 - SMEHS.MAJORITY - include if half of nodes or more are common.
2941                 underlyingOnly: if *True* (default), an element is included to the
2942                         new group provided that it is based on nodes of an element of *groups*;
2943                         in this case the reference *groups* are supposed to be of higher dimension
2944                         than *elemType*, which can be useful for example to get all faces lying on
2945                         volumes of the reference *groups*.
2946
2947         Returns:
2948                 an instance of :class:`SMESH.SMESH_Group`
2949         """
2950
2951         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2952             groups = [groups]
2953         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2954
2955     def FaceGroupsSeparatedByEdges( self, sharpAngle, createEdges=False, useExistingEdges=False ):
2956         """
2957         Distribute all faces of the mesh among groups using sharp edges and optionally
2958         existing 1D elements as group boundaries.
2959
2960         Parameters:
2961                 sharpAngle: edge is considered sharp if an angle between normals of
2962                             adjacent faces is more than \a sharpAngle in degrees.
2963                 createEdges (boolean): to create 1D elements for detected sharp edges.
2964                 useExistingEdges (boolean): to use existing edges as group boundaries
2965         Returns:
2966                 ListOfGroups - the created :class:`groups <SMESH.SMESH_Group>`
2967         """
2968         sharpAngle,Parameters,hasVars = ParseParameters( sharpAngle )
2969         self.mesh.SetParameters(Parameters)
2970         return self.mesh.FaceGroupsSeparatedByEdges( sharpAngle, createEdges, useExistingEdges );
2971
2972     def ConvertToStandalone(self, group):
2973         """
2974         Convert group on geom into standalone group
2975         """
2976
2977         return self.mesh.ConvertToStandalone(group)
2978
2979     # Get some info about mesh:
2980     # ------------------------
2981
2982     def GetLog(self, clearAfterGet):
2983         """
2984         Return the log of nodes and elements added or removed
2985         since the previous clear of the log.
2986
2987         Parameters:
2988                 clearAfterGet: log is emptied after Get (safe if concurrents access)
2989
2990         Returns:
2991                 list of SMESH.log_block structures { commandType, number, coords, indexes }
2992         """
2993
2994         return self.mesh.GetLog(clearAfterGet)
2995
2996     def ClearLog(self):
2997         """
2998         Clear the log of nodes and elements added or removed since the previous
2999         clear. Must be used immediately after :meth:`GetLog` if clearAfterGet is false.
3000         """
3001
3002         self.mesh.ClearLog()
3003
3004     def SetAutoColor(self, theAutoColor):
3005         """
3006         Toggle auto color mode on the object.
3007         If switched on, a default color of a new group in Create Group dialog is chosen randomly.
3008
3009         Parameters:
3010                 theAutoColor (boolean): the flag which toggles auto color mode.
3011         """
3012
3013         self.mesh.SetAutoColor(theAutoColor)
3014
3015     def GetAutoColor(self):
3016         """
3017         Get flag of object auto color mode.
3018
3019         Returns:
3020                 True or False
3021         """
3022
3023         return self.mesh.GetAutoColor()
3024
3025     def GetId(self):
3026         """
3027         Get the internal ID
3028
3029         Returns:
3030             integer value, which is the internal Id of the mesh
3031         """
3032
3033         return self.mesh.GetId()
3034
3035     def HasDuplicatedGroupNamesMED(self):
3036         """
3037         Check the group names for duplications.
3038         Consider the maximum group name length stored in MED file.
3039
3040         Returns:
3041             True or False
3042         """
3043
3044         return self.mesh.HasDuplicatedGroupNamesMED()
3045
3046     def GetMeshEditor(self):
3047         """
3048         Obtain the mesh editor tool
3049
3050         Returns:
3051             an instance of :class:`SMESH.SMESH_MeshEditor`
3052         """
3053
3054         return self.editor
3055
3056     def GetIDSource(self, ids, elemType = SMESH.ALL):
3057         """
3058         Wrap a list of IDs of elements or nodes into :class:`SMESH.SMESH_IDSource` which
3059         can be passed as argument to a method accepting :class:`mesh, sub-mesh, group or filter <SMESH.SMESH_IDSource>`
3060
3061         Parameters:
3062                 ids: list of IDs
3063                 elemType: type of elements; this parameter is used to distinguish
3064                         IDs of nodes from IDs of elements; by default ids are treated as
3065                         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
3066
3067         Returns:
3068             an instance of :class:`SMESH.SMESH_IDSource`
3069
3070         Warning:
3071                 call UnRegister() for the returned object as soon as it is no more useful::
3072
3073                         idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
3074                         mesh.DoSomething( idSrc )
3075                         idSrc.UnRegister()
3076         """
3077
3078         if isinstance( ids, int ):
3079             ids = [ids]
3080         return self.editor.MakeIDSource(ids, elemType)
3081
3082
3083     # Get information about mesh contents:
3084     # ------------------------------------
3085
3086     def GetMeshInfo(self, obj = None):
3087         """
3088         Get the mesh statistic.
3089         Use :meth:`smeshBuilder.EnumToLong` to get an integer from 
3090         an item of :class:`SMESH.EntityType`.
3091
3092         Returns:
3093                 dictionary { :class:`SMESH.EntityType` - "count of elements" }
3094         """
3095
3096         if not obj: obj = self.mesh
3097         return self.smeshpyD.GetMeshInfo(obj)
3098
3099     def NbNodes(self):
3100         """
3101         Return the number of nodes in the mesh
3102
3103         Returns:
3104             an integer value
3105         """
3106
3107         return self.mesh.NbNodes()
3108
3109     def NbElements(self):
3110         """
3111         Return the number of elements in the mesh
3112
3113         Returns:
3114             an integer value
3115         """
3116
3117         return self.mesh.NbElements()
3118
3119     def Nb0DElements(self):
3120         """
3121         Return the number of 0d elements in the mesh
3122
3123         Returns:
3124             an integer value
3125         """
3126
3127         return self.mesh.Nb0DElements()
3128
3129     def NbBalls(self):
3130         """
3131         Return the number of ball discrete elements in the mesh
3132
3133         Returns:
3134             an integer value
3135         """
3136
3137         return self.mesh.NbBalls()
3138
3139     def NbEdges(self):
3140         """
3141         Return the number of edges in the mesh
3142
3143         Returns:
3144             an integer value
3145         """
3146
3147         return self.mesh.NbEdges()
3148
3149     def NbEdgesOfOrder(self, elementOrder):
3150         """
3151         Return the number of edges with the given order in the mesh
3152
3153         Parameters:
3154                 elementOrder: the order of elements
3155                      (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3156
3157         Returns:
3158             an integer value
3159         """
3160
3161         return self.mesh.NbEdgesOfOrder(elementOrder)
3162
3163     def NbFaces(self):
3164         """
3165         Return the number of faces in the mesh
3166
3167         Returns:
3168             an integer value
3169         """
3170
3171         return self.mesh.NbFaces()
3172
3173     def NbFacesOfOrder(self, elementOrder):
3174         """
3175         Return the number of faces with the given order in the mesh
3176
3177         Parameters:
3178                 elementOrder: the order of elements
3179                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3180
3181         Returns:
3182             an integer value
3183         """
3184
3185         return self.mesh.NbFacesOfOrder(elementOrder)
3186
3187     def NbTriangles(self):
3188         """
3189         Return the number of triangles in the mesh
3190
3191         Returns:
3192             an integer value
3193         """
3194
3195         return self.mesh.NbTriangles()
3196
3197     def NbTrianglesOfOrder(self, elementOrder):
3198         """
3199         Return the number of triangles with the given order in the mesh
3200
3201         Parameters:
3202                 elementOrder: is the order of elements
3203                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3204
3205         Returns:
3206             an integer value
3207         """
3208
3209         return self.mesh.NbTrianglesOfOrder(elementOrder)
3210
3211     def NbBiQuadTriangles(self):
3212         """
3213         Return the number of biquadratic triangles in the mesh
3214
3215         Returns:
3216             an integer value
3217         """
3218
3219         return self.mesh.NbBiQuadTriangles()
3220
3221     def NbQuadrangles(self):
3222         """
3223         Return the number of quadrangles in the mesh
3224
3225         Returns:
3226             an integer value
3227         """
3228
3229         return self.mesh.NbQuadrangles()
3230
3231     def NbQuadranglesOfOrder(self, elementOrder):
3232         """
3233         Return the number of quadrangles with the given order in the mesh
3234
3235         Parameters:
3236                 elementOrder: the order of elements
3237                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3238
3239         Returns:
3240             an integer value
3241         """
3242
3243         return self.mesh.NbQuadranglesOfOrder(elementOrder)
3244
3245     def NbBiQuadQuadrangles(self):
3246         """
3247         Return the number of biquadratic quadrangles in the mesh
3248
3249         Returns:
3250             an integer value
3251         """
3252
3253         return self.mesh.NbBiQuadQuadrangles()
3254
3255     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
3256         """
3257         Return the number of polygons of given order in the mesh
3258
3259         Parameters:
3260                 elementOrder: the order of elements
3261                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3262
3263         Returns:
3264             an integer value
3265         """
3266
3267         return self.mesh.NbPolygonsOfOrder(elementOrder)
3268
3269     def NbVolumes(self):
3270         """
3271         Return the number of volumes in the mesh
3272
3273         Returns:
3274             an integer value
3275         """
3276
3277         return self.mesh.NbVolumes()
3278
3279
3280     def NbVolumesOfOrder(self, elementOrder):
3281         """
3282         Return the number of volumes with the given order in the mesh
3283
3284         Parameters:
3285                 elementOrder:  the order of elements
3286                     (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3287
3288         Returns:
3289             an integer value
3290         """
3291
3292         return self.mesh.NbVolumesOfOrder(elementOrder)
3293
3294     def NbTetras(self):
3295         """
3296         Return the number of tetrahedrons in the mesh
3297
3298         Returns:
3299             an integer value
3300         """
3301
3302         return self.mesh.NbTetras()
3303
3304     def NbTetrasOfOrder(self, elementOrder):
3305         """
3306         Return the number of tetrahedrons with the given order in the mesh
3307
3308         Parameters:
3309                 elementOrder:  the order of elements
3310                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3311
3312         Returns:
3313             an integer value
3314         """
3315
3316         return self.mesh.NbTetrasOfOrder(elementOrder)
3317
3318     def NbHexas(self):
3319         """
3320         Return the number of hexahedrons in the mesh
3321
3322         Returns:
3323             an integer value
3324         """
3325
3326         return self.mesh.NbHexas()
3327
3328     def NbHexasOfOrder(self, elementOrder):
3329         """
3330         Return the number of hexahedrons with the given order in the mesh
3331
3332         Parameters:
3333                 elementOrder:  the order of elements
3334                         (SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC)
3335
3336         Returns:
3337             an integer value
3338         """
3339
3340