Salome HOME
Merge branch 'master' into V9_dev
[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 ## @package smeshBuilder
24 #  Python API for SALOME %Mesh module
25
26 ## @defgroup l1_auxiliary Auxiliary methods and structures
27 ## @defgroup l1_creating  Creating meshes
28 ## @{
29 ##   @defgroup l2_impexp     Importing and exporting meshes
30 ##   @{
31 ##     @details
32 ##     These are methods of class \ref smeshBuilder.smeshBuilder "smeshBuilder"
33 ##   @}
34 ##   @defgroup l2_construct  Constructing meshes
35 ##   @defgroup l2_algorithms Defining Algorithms
36 ##   @{
37 ##     @defgroup l3_algos_basic   Basic meshing algorithms
38 ##     @defgroup l3_algos_proj    Projection Algorithms
39 ##     @defgroup l3_algos_segmarv Segments around Vertex
40 ##     @defgroup l3_algos_3dextr  3D extrusion meshing algorithm
41
42 ##   @}
43 ##   @defgroup l2_hypotheses Defining hypotheses
44 ##   @{
45 ##     @defgroup l3_hypos_1dhyps 1D Meshing Hypotheses
46 ##     @defgroup l3_hypos_2dhyps 2D Meshing Hypotheses
47 ##     @defgroup l3_hypos_maxvol Max Element Volume hypothesis
48 ##     @defgroup l3_hypos_quad Quadrangle Parameters hypothesis
49 ##     @defgroup l3_hypos_additi Additional Hypotheses
50
51 ##   @}
52 ##   @defgroup l2_submeshes Constructing sub-meshes
53 ##   @defgroup l2_editing   Editing Meshes
54
55 ## @}
56 ## @defgroup l1_meshinfo  Mesh Information
57 ## @defgroup l1_controls  Quality controls and Filtering
58 ## @defgroup l1_grouping  Grouping elements
59 ## @{
60 ##   @defgroup l2_grps_create Creating groups
61 ##   @defgroup l2_grps_operon Using operations on groups
62 ##   @defgroup l2_grps_delete Deleting Groups
63
64 ## @}
65 ## @defgroup l1_modifying Modifying meshes
66 ## @{
67 ##   @defgroup l2_modif_add      Adding nodes and elements
68 ##   @defgroup l2_modif_del      Removing nodes and elements
69 ##   @defgroup l2_modif_edit     Modifying nodes and elements
70 ##   @defgroup l2_modif_renumber Renumbering nodes and elements
71 ##   @defgroup l2_modif_trsf     Transforming meshes (Translation, Rotation, Symmetry, Sewing, Merging)
72 ##   @defgroup l2_modif_unitetri Uniting triangles
73 ##   @defgroup l2_modif_cutquadr Cutting elements
74 ##   @defgroup l2_modif_changori Changing orientation of elements
75 ##   @defgroup l2_modif_smooth   Smoothing
76 ##   @defgroup l2_modif_extrurev Extrusion and Revolution
77 ##   @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh
78 ##   @defgroup l2_modif_duplicat Duplication of nodes and elements (to emulate cracks)
79
80 ## @}
81 ## @defgroup l1_measurements Measurements
82
83 import salome
84 from salome.geom import geomBuilder
85
86 import SMESH # This is necessary for back compatibility
87 from   SMESH import *
88 from   salome.smesh.smesh_algorithm import Mesh_Algorithm
89
90 import SALOME
91 import SALOMEDS
92 import os
93 import inspect
94
95 # In case the omniORBpy EnumItem class does not fully support Python 3
96 # (for instance in version 4.2.1-2), the comparison ordering methods must be
97 # defined
98 #
99 try:
100     SMESH.Entity_Triangle < SMESH.Entity_Quadrangle
101 except TypeError:
102     def enumitem_eq(self, other):
103         try:
104             if isinstance(other, omniORB.EnumItem):
105                 if other._parent_id == self._parent_id:
106                     return self._v == other._v
107                 else:
108                     return self._parent_id == other._parent_id
109             else:
110                 return id(self) == id(other)
111         except:
112             return id(self) == id(other)
113
114     def enumitem_lt(self, other):
115         try:
116             if isinstance(other, omniORB.EnumItem):
117                 if other._parent_id == self._parent_id:
118                     return self._v < other._v
119                 else:
120                     return self._parent_id < other._parent_id
121             else:
122                 return id(self) < id(other)
123         except:
124             return id(self) < id(other)
125
126     def enumitem_le(self, other):
127         try:
128             if isinstance(other, omniORB.EnumItem):
129                 if other._parent_id == self._parent_id:
130                     return self._v <= other._v
131                 else:
132                     return self._parent_id <= other._parent_id
133             else:
134                 return id(self) <= id(other)
135         except:
136             return id(self) <= id(other)
137
138     def enumitem_gt(self, other):
139         try:
140             if isinstance(other, omniORB.EnumItem):
141                 if other._parent_id == self._parent_id:
142                     return self._v > other._v
143                 else:
144                     return self._parent_id > other._parent_id
145             else:
146                 return id(self) > id(other)
147         except:
148             return id(self) > id(other)
149
150     def enumitem_ge(self, other):
151         try:
152             if isinstance(other, omniORB.EnumItem):
153                 if other._parent_id == self._parent_id:
154                     return self._v >= other._v
155                 else:
156                     return self._parent_id >= other._parent_id
157             else:
158                 return id(self) >= id(other)
159         except:
160             return id(self) >= id(other)
161
162     omniORB.EnumItem.__eq__ = enumitem_eq
163     omniORB.EnumItem.__lt__ = enumitem_lt
164     omniORB.EnumItem.__le__ = enumitem_le
165     omniORB.EnumItem.__gt__ = enumitem_gt
166     omniORB.EnumItem.__ge__ = enumitem_ge
167
168
169 ## Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False
170 #
171 class MeshMeta(type):
172     def __instancecheck__(cls, inst):
173         """Implement isinstance(inst, cls)."""
174         return any(cls.__subclasscheck__(c)
175                    for c in {type(inst), inst.__class__})
176
177     def __subclasscheck__(cls, sub):
178         """Implement issubclass(sub, cls)."""
179         return type.__subclasscheck__(cls, sub) or (cls.__name__ == sub.__name__ and cls.__module__ == sub.__module__)
180
181 ## @addtogroup l1_auxiliary
182 ## @{
183
184 ## Convert an angle from degrees to radians
185 def DegreesToRadians(AngleInDegrees):
186     from math import pi
187     return AngleInDegrees * pi / 180.0
188
189 import salome_notebook
190 notebook = salome_notebook.notebook
191 # Salome notebook variable separator
192 var_separator = ":"
193
194 ## Return list of variable values from salome notebook.
195 #  The last argument, if is callable, is used to modify values got from notebook
196 def ParseParameters(*args):
197     Result = []
198     Parameters = ""
199     hasVariables = False
200     varModifFun=None
201     if args and callable(args[-1]):
202         args, varModifFun = args[:-1], args[-1]
203     for parameter in args:
204
205         Parameters += str(parameter) + var_separator
206
207         if isinstance(parameter,str):
208             # check if there is an inexistent variable name
209             if not notebook.isVariable(parameter):
210                 raise ValueError("Variable with name '" + parameter + "' doesn't exist!!!")
211             parameter = notebook.get(parameter)
212             hasVariables = True
213             if varModifFun:
214                 parameter = varModifFun(parameter)
215                 pass
216             pass
217         Result.append(parameter)
218
219         pass
220     Parameters = Parameters[:-1]
221     Result.append( Parameters )
222     Result.append( hasVariables )
223     return Result
224
225 ## Parse parameters while converting variables to radians
226 def ParseAngles(*args):
227     return ParseParameters( *( args + (DegreesToRadians, )))
228
229 ## Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
230 #  Parameters are stored in PointStruct.parameters attribute
231 def __initPointStruct(point,*args):
232     point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
233     pass
234 SMESH.PointStruct.__init__ = __initPointStruct
235
236 ## Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
237 #  Parameters are stored in AxisStruct.parameters attribute
238 def __initAxisStruct(ax,*args):
239     if len( args ) != 6:
240         raise RuntimeError("Bad nb args (%s) passed in SMESH.AxisStruct(x,y,z,dx,dy,dz)"%(len( args )))
241     ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
242     pass
243 SMESH.AxisStruct.__init__ = __initAxisStruct
244
245 smeshPrecisionConfusion = 1.e-07
246 ## Compare real values using smeshPrecisionConfusion as tolerance
247 def IsEqual(val1, val2, tol=smeshPrecisionConfusion):
248     if abs(val1 - val2) < tol:
249         return True
250     return False
251
252 NO_NAME = "NoName"
253
254 ## Return object name
255 def GetName(obj):
256     if obj:
257         # object not null
258         if isinstance(obj, SALOMEDS._objref_SObject):
259             # study object
260             return obj.GetName()
261         try:
262             ior  = salome.orb.object_to_string(obj)
263         except:
264             ior = None
265         if ior:
266             sobj = salome.myStudy.FindObjectIOR(ior)
267             if sobj:
268                 return sobj.GetName()
269             if hasattr(obj, "GetName"):
270                 # unknown CORBA object, having GetName() method
271                 return obj.GetName()
272             else:
273                 # unknown CORBA object, no GetName() method
274                 return NO_NAME
275             pass
276         if hasattr(obj, "GetName"):
277             # unknown non-CORBA object, having GetName() method
278             return obj.GetName()
279         pass
280     raise RuntimeError("Null or invalid object")
281
282 ## Print error message if a hypothesis was not assigned.
283 def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh):
284     if isAlgo:
285         hypType = "algorithm"
286     else:
287         hypType = "hypothesis"
288         pass
289     reason = ""
290     if hasattr( status, "__getitem__" ):
291         status, reason = status[0], status[1]
292     if status == HYP_UNKNOWN_FATAL:
293         reason = "for unknown reason"
294     elif status == HYP_INCOMPATIBLE:
295         reason = "this hypothesis mismatches the algorithm"
296     elif status == HYP_NOTCONFORM:
297         reason = "a non-conform mesh would be built"
298     elif status == HYP_ALREADY_EXIST:
299         if isAlgo: return # it does not influence anything
300         reason = hypType + " of the same dimension is already assigned to this shape"
301     elif status == HYP_BAD_DIM:
302         reason = hypType + " mismatches the shape"
303     elif status == HYP_CONCURENT:
304         reason = "there are concurrent hypotheses on sub-shapes"
305     elif status == HYP_BAD_SUBSHAPE:
306         reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
307     elif status == HYP_BAD_GEOMETRY:
308         reason = "the algorithm is not applicable to this geometry"
309     elif status == HYP_HIDDEN_ALGO:
310         reason = "it is hidden by an algorithm of an upper dimension, which generates elements of all dimensions"
311     elif status == HYP_HIDING_ALGO:
312         reason = "it hides algorithms of lower dimensions by generating elements of all dimensions"
313     elif status == HYP_NEED_SHAPE:
314         reason = "algorithm can't work without shape"
315     elif status == HYP_INCOMPAT_HYPS:
316         pass
317     else:
318         return
319     where = geomName
320     if where:
321         where = '"%s"' % geomName
322         if mesh:
323             meshName = GetName( mesh )
324             if meshName and meshName != NO_NAME:
325                 where = '"%s" shape in "%s" mesh ' % ( geomName, meshName )
326     if status < HYP_UNKNOWN_FATAL and where:
327         print('"%s" was assigned to %s but %s' %( hypName, where, reason ))
328     elif where:
329         print('"%s" was not assigned to %s : %s' %( hypName, where, reason ))
330     else:
331         print('"%s" was not assigned : %s' %( hypName, reason ))
332         pass
333
334 ## Private method. Add geom (sub-shape of the main shape) into the study if not yet there
335 def AssureGeomPublished(mesh, geom, name=''):
336     if not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
337         return
338     if not geom.GetStudyEntry():
339         ## get a name
340         if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND:
341             # for all groups SubShapeName() return "Compound_-1"
342             name = mesh.geompyD.SubShapeName(geom, mesh.geom)
343         if not name:
344             name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
345         ## publish
346         mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
347     return
348
349 ## Return the first vertex of a geometrical edge by ignoring orientation
350 def FirstVertexOnCurve(mesh, edge):
351     vv = mesh.geompyD.SubShapeAll( edge, geomBuilder.geomBuilder.ShapeType["VERTEX"])
352     if not vv:
353         raise TypeError("Given object has no vertices")
354     if len( vv ) == 1: return vv[0]
355     v0   = mesh.geompyD.MakeVertexOnCurve(edge,0.)
356     xyz  = mesh.geompyD.PointCoordinates( v0 ) # coords of the first vertex
357     xyz1 = mesh.geompyD.PointCoordinates( vv[0] )
358     xyz2 = mesh.geompyD.PointCoordinates( vv[1] )
359     dist1, dist2 = 0,0
360     for i in range(3):
361         dist1 += abs( xyz[i] - xyz1[i] )
362         dist2 += abs( xyz[i] - xyz2[i] )
363     if dist1 < dist2:
364         return vv[0]
365     else:
366         return vv[1]
367
368 ## Return a long value from enumeration
369 def EnumToLong(theItem):
370     return theItem._v
371
372 # end of l1_auxiliary
373 ## @}
374
375
376 # Warning: smeshInst is a singleton
377 smeshInst = None
378 engine = None
379 doLcc = False
380 created = False
381
382 ## This class allows to create, load or manipulate meshes.
383 #  It has a set of methods to create, load or copy meshes, to combine several meshes, etc.
384 #  It also has methods to get infos and measure meshes.
385 class smeshBuilder(SMESH._objref_SMESH_Gen):
386
387     # MirrorType enumeration
388     POINT = SMESH_MeshEditor.POINT
389     AXIS =  SMESH_MeshEditor.AXIS
390     PLANE = SMESH_MeshEditor.PLANE
391
392     # Smooth_Method enumeration
393     LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
394     CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
395
396     PrecisionConfusion = smeshPrecisionConfusion
397
398     # TopAbs_State enumeration
399     [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = list(range(4))
400
401     # Methods of splitting a hexahedron into tetrahedra
402     Hex_5Tet, Hex_6Tet, Hex_24Tet, Hex_2Prisms, Hex_4Prisms = 1, 2, 3, 1, 2
403
404     def __new__(cls, *args):
405         global engine
406         global smeshInst
407         global doLcc
408         #print "==== __new__", engine, smeshInst, doLcc
409
410         if smeshInst is None:
411             # smesh engine is either retrieved from engine, or created
412             smeshInst = engine
413             # Following test avoids a recursive loop
414             if doLcc:
415                 if smeshInst is not None:
416                     # smesh engine not created: existing engine found
417                     doLcc = False
418                 if doLcc:
419                     doLcc = False
420                     # FindOrLoadComponent called:
421                     # 1. CORBA resolution of server
422                     # 2. the __new__ method is called again
423                     #print "==== smeshInst = lcc.FindOrLoadComponent ", engine, smeshInst, doLcc
424                     smeshInst = salome.lcc.FindOrLoadComponent( "FactoryServer", "SMESH" )
425             else:
426                 # FindOrLoadComponent not called
427                 if smeshInst is None:
428                     # smeshBuilder instance is created from lcc.FindOrLoadComponent
429                     #print "==== smeshInst = super(smeshBuilder,cls).__new__(cls) ", engine, smeshInst, doLcc
430                     smeshInst = super(smeshBuilder,cls).__new__(cls)
431                 else:
432                     # smesh engine not created: existing engine found
433                     #print "==== existing ", engine, smeshInst, doLcc
434                     pass
435             #print "====1 ", smeshInst
436             return smeshInst
437
438         #print "====2 ", smeshInst
439         return smeshInst
440
441     def __init__(self, *args):
442         global created
443         #print "--------------- smeshbuilder __init__ ---", created
444         if not created:
445             created = True
446             SMESH._objref_SMESH_Gen.__init__(self, *args)
447
448     ## Dump component to the Python script
449     #  This method overrides IDL function to allow default values for the parameters.
450     #  @ingroup l1_auxiliary
451     def DumpPython(self, theIsPublished=True, theIsMultiFile=True):
452         return SMESH._objref_SMESH_Gen.DumpPython(self, theIsPublished, theIsMultiFile)
453
454     ## Set mode of DumpPython(), \a historical or \a snapshot.
455     #  In the \a historical mode, the Python Dump script includes all commands
456     #  performed by SMESH engine. In the \a snapshot mode, commands
457     #  relating to objects removed from the Study are excluded from the script
458     #  as well as commands not influencing the current state of meshes
459     #  @ingroup l1_auxiliary
460     def SetDumpPythonHistorical(self, isHistorical):
461         if isHistorical: val = "true"
462         else:            val = "false"
463         SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
464
465     ## Set Geometry component
466     #  @ingroup l1_auxiliary
467     def init_smesh(self,isPublished = True,geompyD = None):
468         #print "init_smesh"
469         self.UpdateStudy(geompyD)
470         if isPublished:
471             global notebook
472             notebook.myStudy = salome.myStudy
473
474     ## Create a mesh. This can be either an empty mesh, possibly having an underlying geometry,
475     #  or a mesh wrapping a CORBA mesh given as a parameter.
476     #  @param obj either (1) a CORBA mesh (SMESH._objref_SMESH_Mesh) got e.g. by calling
477     #         salome.myStudy.FindObjectID("0:1:2:3").GetObject() or
478     #         (2) a Geometrical object for meshing or
479     #         (3) none.
480     #  @param name the name for the new mesh.
481     #  @return an instance of Mesh class.
482     #  @ingroup l2_construct
483     def Mesh(self, obj=0, name=0):
484         if isinstance(obj,str):
485             obj,name = name,obj
486         return Mesh(self,self.geompyD,obj,name)
487
488     ## Return a string representation of the color.
489     #  To be used with filters.
490     #  @param c color value (SALOMEDS.Color)
491     #  @ingroup l1_auxiliary
492     def ColorToString(self,c):
493         val = ""
494         if isinstance(c, SALOMEDS.Color):
495             val = "%s;%s;%s" % (c.R, c.G, c.B)
496         elif isinstance(c, str):
497             val = c
498         else:
499             raise ValueError("Color value should be of string or SALOMEDS.Color type")
500         return val
501
502     ## Get PointStruct from vertex
503     #  @param theVertex a GEOM object(vertex)
504     #  @return SMESH.PointStruct
505     #  @ingroup l1_auxiliary
506     def GetPointStruct(self,theVertex):
507         [x, y, z] = self.geompyD.PointCoordinates(theVertex)
508         return PointStruct(x,y,z)
509
510     ## Get DirStruct from vector
511     #  @param theVector a GEOM object(vector)
512     #  @return SMESH.DirStruct
513     #  @ingroup l1_auxiliary
514     def GetDirStruct(self,theVector):
515         vertices = self.geompyD.SubShapeAll( theVector, geomBuilder.geomBuilder.ShapeType["VERTEX"] )
516         if(len(vertices) != 2):
517             print("Error: vector object is incorrect.")
518             return None
519         p1 = self.geompyD.PointCoordinates(vertices[0])
520         p2 = self.geompyD.PointCoordinates(vertices[1])
521         pnt = PointStruct(p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
522         dirst = DirStruct(pnt)
523         return dirst
524
525     ## Make DirStruct from a triplet
526     #  @param x,y,z vector components
527     #  @return SMESH.DirStruct
528     #  @ingroup l1_auxiliary
529     def MakeDirStruct(self,x,y,z):
530         pnt = PointStruct(x,y,z)
531         return DirStruct(pnt)
532
533     ## Get AxisStruct from object
534     #  @param theObj a GEOM object (line or plane)
535     #  @return SMESH.AxisStruct
536     #  @ingroup l1_auxiliary
537     def GetAxisStruct(self,theObj):
538         import GEOM
539         edges = self.geompyD.SubShapeAll( theObj, geomBuilder.geomBuilder.ShapeType["EDGE"] )
540         axis = None
541         if len(edges) > 1:
542             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
543             vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
544             vertex1 = self.geompyD.PointCoordinates(vertex1)
545             vertex2 = self.geompyD.PointCoordinates(vertex2)
546             vertex3 = self.geompyD.PointCoordinates(vertex3)
547             vertex4 = self.geompyD.PointCoordinates(vertex4)
548             v1 = [vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2]]
549             v2 = [vertex4[0]-vertex3[0], vertex4[1]-vertex3[1], vertex4[2]-vertex3[2]]
550             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] ]
551             axis = AxisStruct(vertex1[0], vertex1[1], vertex1[2], normal[0], normal[1], normal[2])
552             axis._mirrorType = SMESH.SMESH_MeshEditor.PLANE
553         elif len(edges) == 1:
554             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geomBuilder.geomBuilder.ShapeType["VERTEX"] )
555             p1 = self.geompyD.PointCoordinates( vertex1 )
556             p2 = self.geompyD.PointCoordinates( vertex2 )
557             axis = AxisStruct(p1[0], p1[1], p1[2], p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
558             axis._mirrorType = SMESH.SMESH_MeshEditor.AXIS
559         elif theObj.GetShapeType() == GEOM.VERTEX:
560             x,y,z = self.geompyD.PointCoordinates( theObj )
561             axis = AxisStruct( x,y,z, 1,0,0,)
562             axis._mirrorType = SMESH.SMESH_MeshEditor.POINT
563         return axis
564
565     # From SMESH_Gen interface:
566     # ------------------------
567
568     ## Set the given name to the object
569     #  @param obj the object to rename
570     #  @param name a new object name
571     #  @ingroup l1_auxiliary
572     def SetName(self, obj, name):
573         if isinstance( obj, Mesh ):
574             obj = obj.GetMesh()
575         elif isinstance( obj, Mesh_Algorithm ):
576             obj = obj.GetAlgorithm()
577         ior  = salome.orb.object_to_string(obj)
578         SMESH._objref_SMESH_Gen.SetName(self, ior, name)
579
580     ## Set the current mode
581     #  @ingroup l1_auxiliary
582     def SetEmbeddedMode( self,theMode ):
583         SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode)
584
585     ## Get the current mode
586     #  @ingroup l1_auxiliary
587     def IsEmbeddedMode(self):
588         return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self)
589     
590     ## Update the current study. Calling UpdateStudy() allows to 
591     #  update meshes at switching GEOM->SMESH
592     #  @ingroup l1_auxiliary
593     def UpdateStudy( self, geompyD = None  ):
594         #self.UpdateStudy()
595         if not geompyD:
596             from salome.geom import geomBuilder
597             geompyD = geomBuilder.geom
598             pass
599         self.geompyD=geompyD
600         self.SetGeomEngine(geompyD)
601         SMESH._objref_SMESH_Gen.UpdateStudy(self)
602         sb = salome.myStudy.NewBuilder()
603         sc = salome.myStudy.FindComponent("SMESH")
604         if sc: sb.LoadWith(sc, self)
605         pass
606         
607     ## Sets enable publishing in the study. Calling SetEnablePublish( false ) allows to
608     #  switch OFF publishing in the Study of mesh objects.
609     #  @ingroup l1_auxiliary
610     def SetEnablePublish( self, theIsEnablePublish ):
611         #self.SetEnablePublish(theIsEnablePublish)
612         SMESH._objref_SMESH_Gen.SetEnablePublish(self,theIsEnablePublish)
613         global notebook
614         notebook = salome_notebook.NoteBook( theIsEnablePublish )
615
616     ## Create a Mesh object importing data from the given UNV file
617     #  @return an instance of Mesh class
618     #  @ingroup l2_impexp
619     def CreateMeshesFromUNV( self,theFileName ):
620         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromUNV(self,theFileName)
621         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
622         return aMesh
623
624     ## Create a Mesh object(s) importing data from the given MED file
625     #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
626     #  @ingroup l2_impexp
627     def CreateMeshesFromMED( self,theFileName ):
628         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromMED(self,theFileName)
629         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
630         return aMeshes, aStatus
631
632     ## Create a Mesh object(s) importing data from the given SAUV file
633     #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
634     #  @ingroup l2_impexp
635     def CreateMeshesFromSAUV( self,theFileName ):
636         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
637         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
638         return aMeshes, aStatus
639
640     ## Create a Mesh object importing data from the given STL file
641     #  @return an instance of Mesh class
642     #  @ingroup l2_impexp
643     def CreateMeshesFromSTL( self, theFileName ):
644         aSmeshMesh = SMESH._objref_SMESH_Gen.CreateMeshesFromSTL(self,theFileName)
645         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
646         return aMesh
647
648     ## Create Mesh objects importing data from the given CGNS file
649     #  @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus )
650     #  @ingroup l2_impexp
651     def CreateMeshesFromCGNS( self, theFileName ):
652         aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
653         aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ]
654         return aMeshes, aStatus
655
656     ## Create a Mesh object importing data from the given GMF file.
657     #  GMF files must have .mesh extension for the ASCII format and .meshb for
658     #  the binary format.
659     #  @return [ an instance of Mesh class, SMESH.ComputeError ]
660     #  @ingroup l2_impexp
661     def CreateMeshesFromGMF( self, theFileName ):
662         aSmeshMesh, error = SMESH._objref_SMESH_Gen.CreateMeshesFromGMF(self,
663                                                                         theFileName,
664                                                                         True)
665         if error.comment: print("*** CreateMeshesFromGMF() errors:\n", error.comment)
666         return Mesh(self, self.geompyD, aSmeshMesh), error
667
668     ## Concatenate the given meshes into one mesh. All groups of input meshes will be
669     #  present in the new mesh.
670     #  @param meshes the meshes, sub-meshes and groups to combine into one mesh
671     #  @param uniteIdenticalGroups if true, groups with same names are united, else they are renamed
672     #  @param mergeNodesAndElements if true, equal nodes and elements are merged
673     #  @param mergeTolerance tolerance for merging nodes
674     #  @param allGroups forces creation of groups corresponding to every input mesh
675     #  @param name name of a new mesh
676     #  @return an instance of Mesh class
677     #  @ingroup l1_creating
678     def Concatenate( self, meshes, uniteIdenticalGroups,
679                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False,
680                      name = ""):
681         if not meshes: return None
682         for i,m in enumerate(meshes):
683             if isinstance(m, Mesh):
684                 meshes[i] = m.GetMesh()
685         mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
686         meshes[0].SetParameters(Parameters)
687         if allGroups:
688             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
689                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
690         else:
691             aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
692                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
693         aMesh = Mesh(self, self.geompyD, aSmeshMesh, name=name)
694         return aMesh
695
696     ## Create a mesh by copying a part of another mesh.
697     #  @param meshPart a part of mesh to copy, either a Mesh, a sub-mesh or a group;
698     #                  to copy nodes or elements not contained in any mesh object,
699     #                  pass result of Mesh.GetIDSource( list_of_ids, type ) as meshPart
700     #  @param meshName a name of the new mesh
701     #  @param toCopyGroups to create in the new mesh groups the copied elements belongs to
702     #  @param toKeepIDs to preserve order of the copied elements or not
703     #  @return an instance of Mesh class
704     #  @ingroup l1_creating
705     def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
706         if (isinstance( meshPart, Mesh )):
707             meshPart = meshPart.GetMesh()
708         mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
709         return Mesh(self, self.geompyD, mesh)
710
711     ## Return IDs of sub-shapes
712     #  @return the list of integer values
713     #  @ingroup l1_auxiliary
714     def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
715         return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
716
717     ## Create a pattern mapper.
718     #  @return an instance of SMESH_Pattern
719     #
720     #  <a href="../tui_modifying_meshes_page.html#tui_pattern_mapping">Example of Patterns usage</a>
721     #  @ingroup l1_modifying
722     def GetPattern(self):
723         return SMESH._objref_SMESH_Gen.GetPattern(self)
724
725     ## Set number of segments per diagonal of boundary box of geometry, by which
726     #  default segment length of appropriate 1D hypotheses is defined in GUI.
727     #  Default value is 10.
728     #  @ingroup l1_auxiliary
729     def SetBoundaryBoxSegmentation(self, nbSegments):
730         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
731
732     # Filtering. Auxiliary functions:
733     # ------------------------------
734
735     ## Create an empty criterion
736     #  @return SMESH.Filter.Criterion
737     #  @ingroup l1_controls
738     def GetEmptyCriterion(self):
739         Type = EnumToLong(FT_Undefined)
740         Compare = EnumToLong(FT_Undefined)
741         Threshold = 0
742         ThresholdStr = ""
743         ThresholdID = ""
744         UnaryOp = EnumToLong(FT_Undefined)
745         BinaryOp = EnumToLong(FT_Undefined)
746         Tolerance = 1e-07
747         TypeOfElement = ALL
748         Precision = -1 ##@1e-07
749         return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID,
750                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
751
752     ## Create a criterion by the given parameters
753     #  \n Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
754     #  @param elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
755     #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
756     #          Type SMESH.FunctorType._items in the Python Console to see all values.
757     #          Note that the items starting from FT_LessThan are not suitable for CritType.
758     #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
759     #  @param Threshold the threshold value (range of ids as string, shape, numeric)
760     #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
761     #  @param BinaryOp a binary logical operation SMESH.FT_LogicalAND, SMESH.FT_LogicalOR or
762     #                  SMESH.FT_Undefined
763     #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
764     #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
765     #  @return SMESH.Filter.Criterion
766     #
767     #  <a href="../tui_filters_page.html#combining_filters">Example of Criteria usage</a>
768     #  @ingroup l1_controls
769     def GetCriterion(self,elementType,
770                      CritType,
771                      Compare = FT_EqualTo,
772                      Threshold="",
773                      UnaryOp=FT_Undefined,
774                      BinaryOp=FT_Undefined,
775                      Tolerance=1e-07):
776         if not CritType in SMESH.FunctorType._items:
777             raise TypeError("CritType should be of SMESH.FunctorType")
778         aCriterion               = self.GetEmptyCriterion()
779         aCriterion.TypeOfElement = elementType
780         aCriterion.Type          = EnumToLong(CritType)
781         aCriterion.Tolerance     = Tolerance
782
783         aThreshold = Threshold
784
785         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
786             aCriterion.Compare = EnumToLong(Compare)
787         elif Compare == "=" or Compare == "==":
788             aCriterion.Compare = EnumToLong(FT_EqualTo)
789         elif Compare == "<":
790             aCriterion.Compare = EnumToLong(FT_LessThan)
791         elif Compare == ">":
792             aCriterion.Compare = EnumToLong(FT_MoreThan)
793         elif Compare != FT_Undefined:
794             aCriterion.Compare = EnumToLong(FT_EqualTo)
795             aThreshold = Compare
796
797         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
798                         FT_BelongToCylinder, FT_LyingOnGeom]:
799             # Check that Threshold is GEOM object
800             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
801                 aCriterion.ThresholdStr = GetName(aThreshold)
802                 aCriterion.ThresholdID  = aThreshold.GetStudyEntry()
803                 if not aCriterion.ThresholdID:
804                     name = aCriterion.ThresholdStr
805                     if not name:
806                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
807                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
808             # or a name of GEOM object
809             elif isinstance( aThreshold, str ):
810                 aCriterion.ThresholdStr = aThreshold
811             else:
812                 raise TypeError("The Threshold should be a shape.")
813             if isinstance(UnaryOp,float):
814                 aCriterion.Tolerance = UnaryOp
815                 UnaryOp = FT_Undefined
816                 pass
817         elif CritType == FT_BelongToMeshGroup:
818             # Check that Threshold is a group
819             if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
820                 if aThreshold.GetType() != elementType:
821                     raise ValueError("Group type mismatches Element type")
822                 aCriterion.ThresholdStr = aThreshold.GetName()
823                 aCriterion.ThresholdID  = salome.orb.object_to_string( aThreshold )
824                 study = salome.myStudy
825                 if study:
826                     so = study.FindObjectIOR( aCriterion.ThresholdID )
827                     if so:
828                         entry = so.GetID()
829                         if entry:
830                             aCriterion.ThresholdID = entry
831             else:
832                 raise TypeError("The Threshold should be a Mesh Group")
833         elif CritType == FT_RangeOfIds:
834             # Check that Threshold is string
835             if isinstance(aThreshold, str):
836                 aCriterion.ThresholdStr = aThreshold
837             else:
838                 raise TypeError("The Threshold should be a string.")
839         elif CritType == FT_CoplanarFaces:
840             # Check the Threshold
841             if isinstance(aThreshold, int):
842                 aCriterion.ThresholdID = str(aThreshold)
843             elif isinstance(aThreshold, str):
844                 ID = int(aThreshold)
845                 if ID < 1:
846                     raise ValueError("Invalid ID of mesh face: '%s'"%aThreshold)
847                 aCriterion.ThresholdID = aThreshold
848             else:
849                 raise TypeError("The Threshold should be an ID of mesh face and not '%s'"%aThreshold)
850         elif CritType == FT_ConnectedElements:
851             # Check the Threshold
852             if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
853                 aCriterion.ThresholdID = aThreshold.GetStudyEntry()
854                 if not aCriterion.ThresholdID:
855                     name = aThreshold.GetName()
856                     if not name:
857                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
858                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
859             elif isinstance(aThreshold, int): # node id
860                 aCriterion.Threshold = aThreshold
861             elif isinstance(aThreshold, list): # 3 point coordinates
862                 if len( aThreshold ) < 3:
863                     raise ValueError("too few point coordinates, must be 3")
864                 aCriterion.ThresholdStr = " ".join( [str(c) for c in aThreshold[:3]] )
865             elif isinstance(aThreshold, str):
866                 if aThreshold.isdigit():
867                     aCriterion.Threshold = aThreshold # node id
868                 else:
869                     aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
870             else:
871                 raise TypeError("The Threshold should either a VERTEX, or a node ID, "\
872                       "or a list of point coordinates and not '%s'"%aThreshold)
873         elif CritType == FT_ElemGeomType:
874             # Check the Threshold
875             try:
876                 aCriterion.Threshold = EnumToLong(aThreshold)
877                 assert( aThreshold in SMESH.GeometryType._items )
878             except:
879                 if isinstance(aThreshold, int):
880                     aCriterion.Threshold = aThreshold
881                 else:
882                     raise TypeError("The Threshold should be an integer or SMESH.GeometryType.")
883                 pass
884             pass
885         elif CritType == FT_EntityType:
886             # Check the Threshold
887             try:
888                 aCriterion.Threshold = EnumToLong(aThreshold)
889                 assert( aThreshold in SMESH.EntityType._items )
890             except:
891                 if isinstance(aThreshold, int):
892                     aCriterion.Threshold = aThreshold
893                 else:
894                     raise TypeError("The Threshold should be an integer or SMESH.EntityType.")
895                 pass
896             pass
897
898         elif CritType == FT_GroupColor:
899             # Check the Threshold
900             try:
901                 aCriterion.ThresholdStr = self.ColorToString(aThreshold)
902             except:
903                 raise TypeError("The threshold value should be of SALOMEDS.Color type")
904             pass
905         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
906                           FT_LinearOrQuadratic, FT_BadOrientedVolume,
907                           FT_BareBorderFace, FT_BareBorderVolume,
908                           FT_OverConstrainedFace, FT_OverConstrainedVolume,
909                           FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
910             # At this point the Threshold is unnecessary
911             if aThreshold ==  FT_LogicalNOT:
912                 aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT)
913             elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
914                 aCriterion.BinaryOp = aThreshold
915         else:
916             # Check Threshold
917             try:
918                 aThreshold = float(aThreshold)
919                 aCriterion.Threshold = aThreshold
920             except:
921                 raise TypeError("The Threshold should be a number.")
922                 return None
923
924         if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
925             aCriterion.UnaryOp = EnumToLong(FT_LogicalNOT)
926
927         if Threshold in [FT_LogicalAND, FT_LogicalOR]:
928             aCriterion.BinaryOp = EnumToLong(Threshold)
929
930         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
931             aCriterion.BinaryOp = EnumToLong(UnaryOp)
932
933         if BinaryOp in [FT_LogicalAND, FT_LogicalOR]:
934             aCriterion.BinaryOp = EnumToLong(BinaryOp)
935
936         return aCriterion
937
938     ## Create a filter with the given parameters
939     #  @param elementType the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
940     #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
941     #          Type SMESH.FunctorType._items in the Python Console to see all values.
942     #          Note that the items starting from FT_LessThan are not suitable for CritType.
943     #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
944     #  @param Threshold the threshold value (range of ids as string, shape, numeric)
945     #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
946     #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
947     #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces and SMESH.FT_EqualNodes criteria
948     #  @param mesh the mesh to initialize the filter with
949     #  @return SMESH_Filter
950     #
951     #  <a href="../tui_filters_page.html#tui_filters">Example of Filters usage</a>
952     #  @ingroup l1_controls
953     def GetFilter(self,elementType,
954                   CritType=FT_Undefined,
955                   Compare=FT_EqualTo,
956                   Threshold="",
957                   UnaryOp=FT_Undefined,
958                   Tolerance=1e-07,
959                   mesh=None):
960         aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
961         aFilterMgr = self.CreateFilterManager()
962         aFilter = aFilterMgr.CreateFilter()
963         aCriteria = []
964         aCriteria.append(aCriterion)
965         aFilter.SetCriteria(aCriteria)
966         if mesh:
967             if isinstance( mesh, Mesh ): aFilter.SetMesh( mesh.GetMesh() )
968             else                       : aFilter.SetMesh( mesh )
969         aFilterMgr.UnRegister()
970         return aFilter
971
972     ## Create a filter from criteria
973     #  @param criteria a list of criteria
974     #  @param binOp binary operator used when binary operator of criteria is undefined
975     #  @return SMESH_Filter
976     #
977     #  <a href="../tui_filters_page.html#tui_filters">Example of Filters usage</a>
978     #  @ingroup l1_controls
979     def GetFilterFromCriteria(self,criteria, binOp=SMESH.FT_LogicalAND):
980         for i in range( len( criteria ) - 1 ):
981             if criteria[i].BinaryOp == EnumToLong( SMESH.FT_Undefined ):
982                 criteria[i].BinaryOp = EnumToLong( binOp )
983         aFilterMgr = self.CreateFilterManager()
984         aFilter = aFilterMgr.CreateFilter()
985         aFilter.SetCriteria(criteria)
986         aFilterMgr.UnRegister()
987         return aFilter
988
989     ## Create a numerical functor by its type
990     #  @param theCriterion functor type - an item of SMESH.FunctorType enumeration.
991     #          Type SMESH.FunctorType._items in the Python Console to see all items.
992     #          Note that not all items correspond to numerical functors.
993     #  @return SMESH_NumericalFunctor
994     #  @ingroup l1_controls
995     def GetFunctor(self,theCriterion):
996         if isinstance( theCriterion, SMESH._objref_NumericalFunctor ):
997             return theCriterion
998         aFilterMgr = self.CreateFilterManager()
999         functor = None
1000         if theCriterion == FT_AspectRatio:
1001             functor = aFilterMgr.CreateAspectRatio()
1002         elif theCriterion == FT_AspectRatio3D:
1003             functor = aFilterMgr.CreateAspectRatio3D()
1004         elif theCriterion == FT_Warping:
1005             functor = aFilterMgr.CreateWarping()
1006         elif theCriterion == FT_MinimumAngle:
1007             functor = aFilterMgr.CreateMinimumAngle()
1008         elif theCriterion == FT_Taper:
1009             functor = aFilterMgr.CreateTaper()
1010         elif theCriterion == FT_Skew:
1011             functor = aFilterMgr.CreateSkew()
1012         elif theCriterion == FT_Area:
1013             functor = aFilterMgr.CreateArea()
1014         elif theCriterion == FT_Volume3D:
1015             functor = aFilterMgr.CreateVolume3D()
1016         elif theCriterion == FT_MaxElementLength2D:
1017             functor = aFilterMgr.CreateMaxElementLength2D()
1018         elif theCriterion == FT_MaxElementLength3D:
1019             functor = aFilterMgr.CreateMaxElementLength3D()
1020         elif theCriterion == FT_MultiConnection:
1021             functor = aFilterMgr.CreateMultiConnection()
1022         elif theCriterion == FT_MultiConnection2D:
1023             functor = aFilterMgr.CreateMultiConnection2D()
1024         elif theCriterion == FT_Length:
1025             functor = aFilterMgr.CreateLength()
1026         elif theCriterion == FT_Length2D:
1027             functor = aFilterMgr.CreateLength2D()
1028         elif theCriterion == FT_NodeConnectivityNumber:
1029             functor = aFilterMgr.CreateNodeConnectivityNumber()
1030         elif theCriterion == FT_BallDiameter:
1031             functor = aFilterMgr.CreateBallDiameter()
1032         else:
1033             print("Error: given parameter is not numerical functor type.")
1034         aFilterMgr.UnRegister()
1035         return functor
1036
1037     ## Create hypothesis
1038     #  @param theHType mesh hypothesis type (string)
1039     #  @param theLibName mesh plug-in library name
1040     #  @return created hypothesis instance
1041     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
1042         hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
1043
1044         if isinstance( hyp, SMESH._objref_SMESH_Algo ):
1045             return hyp
1046
1047         # wrap hypothesis methods
1048         #print "HYPOTHESIS", theHType
1049         for meth_name in dir( hyp.__class__ ):
1050             if not meth_name.startswith("Get") and \
1051                not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
1052                 method = getattr ( hyp.__class__, meth_name )
1053                 if callable(method):
1054                     setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
1055
1056         return hyp
1057
1058     ## Get the mesh statistic
1059     #  @return dictionary "element type" - "count of elements"
1060     #  @ingroup l1_meshinfo
1061     def GetMeshInfo(self, obj):
1062         if isinstance( obj, Mesh ):
1063             obj = obj.GetMesh()
1064         d = {}
1065         if hasattr(obj, "GetMeshInfo"):
1066             values = obj.GetMeshInfo()
1067             for i in range(EnumToLong(SMESH.Entity_Last)):
1068                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
1069             pass
1070         return d
1071
1072     ## Get minimum distance between two objects
1073     #
1074     #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
1075     #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
1076     #
1077     #  @param src1 first source object
1078     #  @param src2 second source object
1079     #  @param id1 node/element id from the first source
1080     #  @param id2 node/element id from the second (or first) source
1081     #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
1082     #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
1083     #  @return minimum distance value
1084     #  @sa GetMinDistance()
1085     #  @ingroup l1_measurements
1086     def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1087         result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
1088         if result is None:
1089             result = 0.0
1090         else:
1091             result = result.value
1092         return result
1093
1094     ## Get measure structure specifying minimum distance data between two objects
1095     #
1096     #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
1097     #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
1098     #
1099     #  @param src1 first source object
1100     #  @param src2 second source object
1101     #  @param id1 node/element id from the first source
1102     #  @param id2 node/element id from the second (or first) source
1103     #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
1104     #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
1105     #  @return Measure structure or None if input data is invalid
1106     #  @sa MinDistance()
1107     #  @ingroup l1_measurements
1108     def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
1109         if isinstance(src1, Mesh): src1 = src1.mesh
1110         if isinstance(src2, Mesh): src2 = src2.mesh
1111         if src2 is None and id2 != 0: src2 = src1
1112         if not hasattr(src1, "_narrow"): return None
1113         src1 = src1._narrow(SMESH.SMESH_IDSource)
1114         if not src1: return None
1115         unRegister = genObjUnRegister()
1116         if id1 != 0:
1117             m = src1.GetMesh()
1118             e = m.GetMeshEditor()
1119             if isElem1:
1120                 src1 = e.MakeIDSource([id1], SMESH.FACE)
1121             else:
1122                 src1 = e.MakeIDSource([id1], SMESH.NODE)
1123             unRegister.set( src1 )
1124             pass
1125         if hasattr(src2, "_narrow"):
1126             src2 = src2._narrow(SMESH.SMESH_IDSource)
1127             if src2 and id2 != 0:
1128                 m = src2.GetMesh()
1129                 e = m.GetMeshEditor()
1130                 if isElem2:
1131                     src2 = e.MakeIDSource([id2], SMESH.FACE)
1132                 else:
1133                     src2 = e.MakeIDSource([id2], SMESH.NODE)
1134                 unRegister.set( src2 )
1135                 pass
1136             pass
1137         aMeasurements = self.CreateMeasurements()
1138         unRegister.set( aMeasurements )
1139         result = aMeasurements.MinDistance(src1, src2)
1140         return result
1141
1142     ## Get bounding box of the specified object(s)
1143     #  @param objects single source object or list of source objects
1144     #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
1145     #  @sa GetBoundingBox()
1146     #  @ingroup l1_measurements
1147     def BoundingBox(self, objects):
1148         result = self.GetBoundingBox(objects)
1149         if result is None:
1150             result = (0.0,)*6
1151         else:
1152             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
1153         return result
1154
1155     ## Get measure structure specifying bounding box data of the specified object(s)
1156     #  @param objects single source object or list of source objects
1157     #  @return Measure structure
1158     #  @sa BoundingBox()
1159     #  @ingroup l1_measurements
1160     def GetBoundingBox(self, objects):
1161         if isinstance(objects, tuple):
1162             objects = list(objects)
1163         if not isinstance(objects, list):
1164             objects = [objects]
1165         srclist = []
1166         for o in objects:
1167             if isinstance(o, Mesh):
1168                 srclist.append(o.mesh)
1169             elif hasattr(o, "_narrow"):
1170                 src = o._narrow(SMESH.SMESH_IDSource)
1171                 if src: srclist.append(src)
1172                 pass
1173             pass
1174         aMeasurements = self.CreateMeasurements()
1175         result = aMeasurements.BoundingBox(srclist)
1176         aMeasurements.UnRegister()
1177         return result
1178
1179     ## Get sum of lengths of all 1D elements in the mesh object.
1180     #  @param obj mesh, submesh or group
1181     #  @return sum of lengths of all 1D elements
1182     #  @ingroup l1_measurements
1183     def GetLength(self, obj):
1184         if isinstance(obj, Mesh): obj = obj.mesh
1185         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1186         aMeasurements = self.CreateMeasurements()
1187         value = aMeasurements.Length(obj)
1188         aMeasurements.UnRegister()
1189         return value
1190
1191     ## Get sum of areas of all 2D elements in the mesh object.
1192     #  @param obj mesh, submesh or group
1193     #  @return sum of areas of all 2D elements
1194     #  @ingroup l1_measurements
1195     def GetArea(self, obj):
1196         if isinstance(obj, Mesh): obj = obj.mesh
1197         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1198         aMeasurements = self.CreateMeasurements()
1199         value = aMeasurements.Area(obj)
1200         aMeasurements.UnRegister()
1201         return value
1202
1203     ## Get sum of volumes of all 3D elements in the mesh object.
1204     #  @param obj mesh, submesh or group
1205     #  @return sum of volumes of all 3D elements
1206     #  @ingroup l1_measurements
1207     def GetVolume(self, obj):
1208         if isinstance(obj, Mesh): obj = obj.mesh
1209         if isinstance(obj, Mesh_Algorithm): obj = obj.GetSubMesh()
1210         aMeasurements = self.CreateMeasurements()
1211         value = aMeasurements.Volume(obj)
1212         aMeasurements.UnRegister()
1213         return value
1214
1215     pass # end of class smeshBuilder
1216
1217 import omniORB
1218 #Registering the new proxy for SMESH_Gen
1219 omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshBuilder)
1220
1221 ## Create a new smeshBuilder instance.The smeshBuilder class provides the Python
1222 #  interface to create or load meshes.
1223 #
1224 #  Typical use is:
1225 #  \code
1226 #    import salome
1227 #    salome.salome_init()
1228 #    from salome.smesh import smeshBuilder
1229 #    smesh = smeshBuilder.New()
1230 #  \endcode
1231 #  @param  isPublished If False, the notebool will not be used.
1232 #  @param  instance  CORBA proxy of SMESH Engine. If None, the default Engine is used.
1233 #  @return smeshBuilder instance
1234
1235 def New( isPublished = True, instance=None):
1236     """
1237     Create a new smeshBuilder instance.The smeshBuilder class provides the Python
1238     interface to create or load meshes.
1239
1240     Typical use is:
1241         import salome
1242         salome.salome_init()
1243         from salome.smesh import smeshBuilder
1244         smesh = smeshBuilder.New()
1245
1246     Parameters:
1247         isPublished If False, the notebool will not be used.
1248         instance  CORBA proxy of SMESH Engine. If None, the default Engine is used.
1249     Returns:
1250         smeshBuilder instance
1251     """
1252     global engine
1253     global smeshInst
1254     global doLcc
1255     engine = instance
1256     if engine is None:
1257         doLcc = True
1258     smeshInst = smeshBuilder()
1259     assert isinstance(smeshInst,smeshBuilder), "Smesh engine class is %s but should be smeshBuilder.smeshBuilder. Import salome.smesh.smeshBuilder before creating the instance."%smeshInst.__class__
1260     smeshInst.init_smesh(isPublished)
1261     return smeshInst
1262
1263
1264 # Public class: Mesh
1265 # ==================
1266
1267 ## This class allows defining and managing a mesh.
1268 #  It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes.
1269 #  It also has methods to define groups of mesh elements, to modify a mesh (by addition of
1270 #  new nodes and elements and by changing the existing entities), to get information
1271 #  about a mesh and to export a mesh in different formats.
1272 class Mesh(metaclass=MeshMeta):
1273     geom = 0
1274     mesh = 0
1275     editor = 0
1276
1277     ## Constructor
1278     #
1279     #  Create a mesh on the shape \a obj (or an empty mesh if \a obj is equal to 0) and
1280     #  sets the GUI name of this mesh to \a name.
1281     #  @param smeshpyD an instance of smeshBuilder class
1282     #  @param geompyD an instance of geomBuilder class
1283     #  @param obj Shape to be meshed or SMESH_Mesh object
1284     #  @param name Study name of the mesh
1285     #  @ingroup l2_construct
1286     def __init__(self, smeshpyD, geompyD, obj=0, name=0):
1287         self.smeshpyD = smeshpyD
1288         self.geompyD = geompyD
1289         if obj is None:
1290             obj = 0
1291         objHasName = False
1292         if obj != 0:
1293             if isinstance(obj, geomBuilder.GEOM._objref_GEOM_Object):
1294                 self.geom = obj
1295                 objHasName = True
1296                 # publish geom of mesh (issue 0021122)
1297                 if not self.geom.GetStudyEntry():
1298                     objHasName = False
1299                     geompyD.init_geom()
1300                     if name:
1301                         geo_name = name + " shape"
1302                     else:
1303                         geo_name = "%s_%s to mesh"%(self.geom.GetShapeType(), id(self.geom)%100)
1304                     geompyD.addToStudy( self.geom, geo_name )
1305                 self.SetMesh( self.smeshpyD.CreateMesh(self.geom) )
1306
1307             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
1308                 self.SetMesh(obj)
1309         else:
1310             self.SetMesh( self.smeshpyD.CreateEmptyMesh() )
1311         if name:
1312             self.smeshpyD.SetName(self.mesh, name)
1313         elif objHasName:
1314             self.smeshpyD.SetName(self.mesh, GetName(obj)) # + " mesh"
1315
1316         if not self.geom:
1317             self.geom = self.mesh.GetShapeToMesh()
1318
1319         self.editor   = self.mesh.GetMeshEditor()
1320         self.functors = [None] * EnumToLong(SMESH.FT_Undefined)
1321
1322         # set self to algoCreator's
1323         for attrName in dir(self):
1324             attr = getattr( self, attrName )
1325             if isinstance( attr, algoCreator ):
1326                 setattr( self, attrName, attr.copy( self ))
1327                 pass
1328             pass
1329         pass
1330
1331     ## Destructor. Clean-up resources
1332     def __del__(self):
1333         if self.mesh:
1334             #self.mesh.UnRegister()
1335             pass
1336         pass
1337
1338     ## Initialize the Mesh object from an instance of SMESH_Mesh interface
1339     #  @param theMesh a SMESH_Mesh object
1340     #  @ingroup l2_construct
1341     def SetMesh(self, theMesh):
1342         # do not call Register() as this prevents mesh servant deletion at closing study
1343         #if self.mesh: self.mesh.UnRegister()
1344         self.mesh = theMesh
1345         if self.mesh:
1346             #self.mesh.Register()
1347             self.geom = self.mesh.GetShapeToMesh()
1348         pass
1349
1350     ## Return the mesh, that is an instance of SMESH_Mesh interface
1351     #  @return a SMESH_Mesh object
1352     #  @ingroup l2_construct
1353     def GetMesh(self):
1354         return self.mesh
1355
1356     ## Get the name of the mesh
1357     #  @return the name of the mesh as a string
1358     #  @ingroup l2_construct
1359     def GetName(self):
1360         name = GetName(self.GetMesh())
1361         return name
1362
1363     ## Set a name to the mesh
1364     #  @param name a new name of the mesh
1365     #  @ingroup l2_construct
1366     def SetName(self, name):
1367         self.smeshpyD.SetName(self.GetMesh(), name)
1368
1369     ## Get a sub-mesh object associated to a \a geom geometrical object.
1370     #  @param geom a geometrical object (shape)
1371     #  @param name a name for the sub-mesh in the Object Browser
1372     #  @return an object of type SMESH.SMESH_subMesh, representing a part of mesh,
1373     #          which lies on the given shape
1374     #
1375     #  The sub-mesh object gives access to the IDs of nodes and elements.
1376     #  The sub-mesh object has the following methods:
1377     #  - SMESH.SMESH_subMesh.GetNumberOfElements()
1378     #  - SMESH.SMESH_subMesh.GetNumberOfNodes( all )
1379     #  - SMESH.SMESH_subMesh.GetElementsId()
1380     #  - SMESH.SMESH_subMesh.GetElementsByType( ElementType )
1381     #  - SMESH.SMESH_subMesh.GetNodesId()
1382     #  - SMESH.SMESH_subMesh.GetSubShape()
1383     #  - SMESH.SMESH_subMesh.GetFather()
1384     #  - SMESH.SMESH_subMesh.GetId()
1385     #  @note A sub-mesh is implicitly created when a sub-shape is specified at
1386     #  creating an algorithm, for example: <code>algo1D = mesh.Segment(geom=Edge_1) </code>
1387     #  creates a sub-mesh on @c Edge_1 and assign Wire Discretization algorithm to it.
1388     #  The created sub-mesh can be retrieved from the algorithm:
1389     #  <code>submesh = algo1D.GetSubMesh()</code>
1390     #  @ingroup l2_submeshes
1391     def GetSubMesh(self, geom, name):
1392         AssureGeomPublished( self, geom, name )
1393         submesh = self.mesh.GetSubMesh( geom, name )
1394         return submesh
1395
1396     ## Return the shape associated to the mesh
1397     #  @return a GEOM_Object
1398     #  @ingroup l2_construct
1399     def GetShape(self):
1400         return self.geom
1401
1402     ## Associate the given shape to the mesh (entails the recreation of the mesh)
1403     #  @param geom the shape to be meshed (GEOM_Object)
1404     #  @ingroup l2_construct
1405     def SetShape(self, geom):
1406         self.mesh = self.smeshpyD.CreateMesh(geom)
1407
1408     ## Load mesh from the study after opening the study
1409     def Load(self):
1410         self.mesh.Load()
1411
1412     ## Return true if the hypotheses are defined well
1413     #  @param theSubObject a sub-shape of a mesh shape
1414     #  @return True or False
1415     #  @ingroup l2_construct
1416     def IsReadyToCompute(self, theSubObject):
1417         return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject)
1418
1419     ## Return errors of hypotheses definition.
1420     #  The list of errors is empty if everything is OK.
1421     #  @param theSubObject a sub-shape of a mesh shape
1422     #  @return a list of errors
1423     #  @ingroup l2_construct
1424     def GetAlgoState(self, theSubObject):
1425         return self.smeshpyD.GetAlgoState(self.mesh, theSubObject)
1426
1427     ## Return a geometrical object on which the given element was built.
1428     #  The returned geometrical object, if not nil, is either found in the
1429     #  study or published by this method with the given name
1430     #  @param theElementID the id of the mesh element
1431     #  @param theGeomName the user-defined name of the geometrical object
1432     #  @return GEOM::GEOM_Object instance
1433     #  @ingroup l1_meshinfo
1434     def GetGeometryByMeshElement(self, theElementID, theGeomName):
1435         return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName )
1436
1437     ## Return the mesh dimension depending on the dimension of the underlying shape
1438     #  or, if the mesh is not based on any shape, basing on deimension of elements
1439     #  @return mesh dimension as an integer value [0,3]
1440     #  @ingroup l1_meshinfo
1441     def MeshDimension(self):
1442         if self.mesh.HasShapeToMesh():
1443             shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] )
1444             if len( shells ) > 0 :
1445                 return 3
1446             elif self.geompyD.NumberOfFaces( self.geom ) > 0 :
1447                 return 2
1448             elif self.geompyD.NumberOfEdges( self.geom ) > 0 :
1449                 return 1
1450             else:
1451                 return 0;
1452         else:
1453             if self.NbVolumes() > 0: return 3
1454             if self.NbFaces()   > 0: return 2
1455             if self.NbEdges()   > 0: return 1
1456         return 0
1457
1458     ## Evaluate size of prospective mesh on a shape
1459     #  @return a list where i-th element is a number of elements of i-th SMESH.EntityType
1460     #  To know predicted number of e.g. edges, inquire it this way
1461     #  Evaluate()[ EnumToLong( Entity_Edge )]
1462     #  @ingroup l2_construct
1463     def Evaluate(self, geom=0):
1464         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1465             if self.geom == 0:
1466                 geom = self.mesh.GetShapeToMesh()
1467             else:
1468                 geom = self.geom
1469         return self.smeshpyD.Evaluate(self.mesh, geom)
1470
1471
1472     ## Compute the mesh and return the status of the computation
1473     #  @param geom geomtrical shape on which mesh data should be computed
1474     #  @param discardModifs if True and the mesh has been edited since
1475     #         a last total re-compute and that may prevent successful partial re-compute,
1476     #         then the mesh is cleaned before Compute()
1477     #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
1478     #  @return True or False
1479     #  @ingroup l2_construct
1480     def Compute(self, geom=0, discardModifs=False, refresh=False):
1481         if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object):
1482             if self.geom == 0:
1483                 geom = self.mesh.GetShapeToMesh()
1484             else:
1485                 geom = self.geom
1486         ok = False
1487         try:
1488             if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
1489                 self.mesh.Clear()
1490             ok = self.smeshpyD.Compute(self.mesh, geom)
1491         except SALOME.SALOME_Exception as ex:
1492             print("Mesh computation failed, exception caught:")
1493             print("    ", ex.details.text)
1494         except:
1495             import traceback
1496             print("Mesh computation failed, exception caught:")
1497             traceback.print_exc()
1498         if True:#not ok:
1499             allReasons = ""
1500
1501             # Treat compute errors
1502             computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
1503             shapeText = ""
1504             for err in computeErrors:
1505                 if self.mesh.HasShapeToMesh():
1506                     shapeText = " on %s" % self.GetSubShapeName( err.subShapeID )
1507                 errText = ""
1508                 stdErrors = ["OK",                   #COMPERR_OK
1509                              "Invalid input mesh",   #COMPERR_BAD_INPUT_MESH
1510                              "std::exception",       #COMPERR_STD_EXCEPTION
1511                              "OCC exception",        #COMPERR_OCC_EXCEPTION
1512                              "..",                   #COMPERR_SLM_EXCEPTION
1513                              "Unknown exception",    #COMPERR_EXCEPTION
1514                              "Memory allocation problem", #COMPERR_MEMORY_PB
1515                              "Algorithm failed",     #COMPERR_ALGO_FAILED
1516                              "Unexpected geometry",  #COMPERR_BAD_SHAPE
1517                              "Warning",              #COMPERR_WARNING
1518                              "Computation cancelled",#COMPERR_CANCELED
1519                              "No mesh on sub-shape"] #COMPERR_NO_MESH_ON_SHAPE
1520                 if err.code > 0:
1521                     if err.code < len(stdErrors): errText = stdErrors[err.code]
1522                 else:
1523                     errText = "code %s" % -err.code
1524                 if errText: errText += ". "
1525                 errText += err.comment
1526                 if allReasons: allReasons += "\n"
1527                 if ok:
1528                     allReasons += '-  "%s"%s - %s' %(err.algoName, shapeText, errText)
1529                 else:
1530                     allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
1531                 pass
1532
1533             # Treat hyp errors
1534             errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
1535             for err in errors:
1536                 if err.isGlobalAlgo:
1537                     glob = "global"
1538                 else:
1539                     glob = "local"
1540                     pass
1541                 dim = err.algoDim
1542                 name = err.algoName
1543                 if len(name) == 0:
1544                     reason = '%s %sD algorithm is missing' % (glob, dim)
1545                 elif err.state == HYP_MISSING:
1546                     reason = ('%s %sD algorithm "%s" misses %sD hypothesis'
1547                               % (glob, dim, name, dim))
1548                 elif err.state == HYP_NOTCONFORM:
1549                     reason = 'Global "Not Conform mesh allowed" hypothesis is missing'
1550                 elif err.state == HYP_BAD_PARAMETER:
1551                     reason = ('Hypothesis of %s %sD algorithm "%s" has a bad parameter value'
1552                               % ( glob, dim, name ))
1553                 elif err.state == HYP_BAD_GEOMETRY:
1554                     reason = ('%s %sD algorithm "%s" is assigned to mismatching'
1555                               'geometry' % ( glob, dim, name ))
1556                 elif err.state == HYP_HIDDEN_ALGO:
1557                     reason = ('%s %sD algorithm "%s" is ignored due to presence of a %s '
1558                               'algorithm of upper dimension generating %sD mesh'
1559                               % ( glob, dim, name, glob, dim ))
1560                 else:
1561                     reason = ("For unknown reason. "
1562                               "Developer, revise Mesh.Compute() implementation in smeshBuilder.py!")
1563                     pass
1564                 if allReasons: allReasons += "\n"
1565                 allReasons += "-  " + reason
1566                 pass
1567             if not ok or allReasons != "":
1568                 msg = '"' + GetName(self.mesh) + '"'
1569                 if ok: msg += " has been computed with warnings"
1570                 else:  msg += " has not been computed"
1571                 if allReasons != "": msg += ":"
1572                 else:                msg += "."
1573                 print(msg)
1574                 print(allReasons)
1575             pass
1576         if salome.sg.hasDesktop():
1577             if not isinstance( refresh, list): # not a call from subMesh.Compute()
1578                 smeshgui = salome.ImportComponentGUI("SMESH")
1579                 smeshgui.Init()
1580                 smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
1581                 if refresh: salome.sg.updateObjBrowser()
1582
1583         return ok
1584
1585     ## Return a list of error messages (SMESH.ComputeError) of the last Compute()
1586     #  @ingroup l2_construct
1587     def GetComputeErrors(self, shape=0 ):
1588         if shape == 0:
1589             shape = self.mesh.GetShapeToMesh()
1590         return self.smeshpyD.GetComputeErrors( self.mesh, shape )
1591
1592     ## Return a name of a sub-shape by its ID
1593     #  @param subShapeID a unique ID of a sub-shape
1594     #  @return a string describing the sub-shape; possible variants:
1595     #  - "Face_12"    (published sub-shape)
1596     #  - FACE #3      (not published sub-shape)
1597     #  - sub-shape #3 (invalid sub-shape ID)
1598     #  - #3           (error in this function)
1599     #  @ingroup l1_auxiliary
1600     def GetSubShapeName(self, subShapeID ):
1601         if not self.mesh.HasShapeToMesh():
1602             return ""
1603         try:
1604             shapeText = ""
1605             mainIOR  = salome.orb.object_to_string( self.GetShape() )
1606             s = salome.myStudy
1607             mainSO = s.FindObjectIOR(mainIOR)
1608             if mainSO:
1609                 if subShapeID == 1:
1610                     shapeText = '"%s"' % mainSO.GetName()
1611                 subIt = s.NewChildIterator(mainSO)
1612                 while subIt.More():
1613                     subSO = subIt.Value()
1614                     subIt.Next()
1615                     obj = subSO.GetObject()
1616                     if not obj: continue
1617                     go = obj._narrow( geomBuilder.GEOM._objref_GEOM_Object )
1618                     if not go: continue
1619                     try:
1620                         ids = self.geompyD.GetSubShapeID( self.GetShape(), go )
1621                     except:
1622                         continue
1623                     if ids == subShapeID:
1624                         shapeText = '"%s"' % subSO.GetName()
1625             if not shapeText:
1626                 shape = self.geompyD.GetSubShape( self.GetShape(), [subShapeID])
1627                 if shape:
1628                     shapeText = '%s #%s' % (shape.GetShapeType(), subShapeID)
1629                 else:
1630                     shapeText = 'sub-shape #%s' % (subShapeID)
1631         except:
1632             shapeText = "#%s" % (subShapeID)
1633         return shapeText
1634
1635     ## Return a list of sub-shapes meshing of which failed, grouped into GEOM groups by
1636     #  error of an algorithm
1637     #  @param publish if @c True, the returned groups will be published in the study
1638     #  @return a list of GEOM groups each named after a failed algorithm
1639     #  @ingroup l2_construct
1640     def GetFailedShapes(self, publish=False):
1641
1642         algo2shapes = {}
1643         computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, self.GetShape() )
1644         for err in computeErrors:
1645             shape = self.geompyD.GetSubShape( self.GetShape(), [err.subShapeID])
1646             if not shape: continue
1647             if err.algoName in algo2shapes:
1648                 algo2shapes[ err.algoName ].append( shape )
1649             else:
1650                 algo2shapes[ err.algoName ] = [ shape ]
1651             pass
1652
1653         groups = []
1654         for algoName, shapes in list(algo2shapes.items()):
1655             while shapes:
1656                 groupType = EnumToLong( shapes[0].GetShapeType() )
1657                 otherTypeShapes = []
1658                 sameTypeShapes  = []
1659                 group = self.geompyD.CreateGroup( self.geom, groupType )
1660                 for shape in shapes:
1661                     if shape.GetShapeType() == shapes[0].GetShapeType():
1662                         sameTypeShapes.append( shape )
1663                     else:
1664                         otherTypeShapes.append( shape )
1665                 self.geompyD.UnionList( group, sameTypeShapes )
1666                 if otherTypeShapes:
1667                     group.SetName( "%s %s" % ( algoName, shapes[0].GetShapeType() ))
1668                 else:
1669                     group.SetName( algoName )
1670                 groups.append( group )
1671                 shapes = otherTypeShapes
1672             pass
1673         if publish:
1674             for group in groups:
1675                 self.geompyD.addToStudyInFather( self.geom, group, group.GetName() )
1676         return groups
1677
1678     ## Return sub-mesh objects list in meshing order
1679     #  @return list of lists of sub-meshes
1680     #  @ingroup l2_construct
1681     def GetMeshOrder(self):
1682         return self.mesh.GetMeshOrder()
1683
1684     ## Set order in which concurrent sub-meshes should be meshed
1685     #  @param submeshes list of lists of sub-meshes
1686     #  @ingroup l2_construct
1687     def SetMeshOrder(self, submeshes):
1688         return self.mesh.SetMeshOrder(submeshes)
1689
1690     ## Remove all nodes and elements generated on geometry. Imported elements remain.
1691     #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
1692     #  @ingroup l2_construct
1693     def Clear(self, refresh=False):
1694         self.mesh.Clear()
1695         if ( salome.sg.hasDesktop() ):
1696             smeshgui = salome.ImportComponentGUI("SMESH")
1697             smeshgui.Init()
1698             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1699             if refresh: salome.sg.updateObjBrowser()
1700
1701     ## Remove all nodes and elements of indicated shape
1702     #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
1703     #  @param geomId the ID of a sub-shape to remove elements on
1704     #  @ingroup l2_submeshes
1705     def ClearSubMesh(self, geomId, refresh=False):
1706         self.mesh.ClearSubMesh(geomId)
1707         if salome.sg.hasDesktop():
1708             smeshgui = salome.ImportComponentGUI("SMESH")
1709             smeshgui.Init()
1710             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
1711             if refresh: salome.sg.updateObjBrowser()
1712
1713     ## Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron
1714     #  @param fineness [0.0,1.0] defines mesh fineness
1715     #  @return True or False
1716     #  @ingroup l3_algos_basic
1717     def AutomaticTetrahedralization(self, fineness=0):
1718         dim = self.MeshDimension()
1719         # assign hypotheses
1720         self.RemoveGlobalHypotheses()
1721         self.Segment().AutomaticLength(fineness)
1722         if dim > 1 :
1723             self.Triangle().LengthFromEdges()
1724             pass
1725         if dim > 2 :
1726             self.Tetrahedron()
1727             pass
1728         return self.Compute()
1729
1730     ## Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
1731     #  @param fineness [0.0, 1.0] defines mesh fineness
1732     #  @return True or False
1733     #  @ingroup l3_algos_basic
1734     def AutomaticHexahedralization(self, fineness=0):
1735         dim = self.MeshDimension()
1736         # assign the hypotheses
1737         self.RemoveGlobalHypotheses()
1738         self.Segment().AutomaticLength(fineness)
1739         if dim > 1 :
1740             self.Quadrangle()
1741             pass
1742         if dim > 2 :
1743             self.Hexahedron()
1744             pass
1745         return self.Compute()
1746
1747     ## Assign a hypothesis
1748     #  @param hyp a hypothesis to assign
1749     #  @param geom a subhape of mesh geometry
1750     #  @return SMESH.Hypothesis_Status
1751     #  @ingroup l2_editing
1752     def AddHypothesis(self, hyp, geom=0):
1753         if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
1754             hyp, geom = geom, hyp
1755         if isinstance( hyp, Mesh_Algorithm ):
1756             hyp = hyp.GetAlgorithm()
1757             pass
1758         if not geom:
1759             geom = self.geom
1760             if not geom:
1761                 geom = self.mesh.GetShapeToMesh()
1762             pass
1763         isApplicable = True
1764         if self.mesh.HasShapeToMesh():
1765             hyp_type     = hyp.GetName()
1766             lib_name     = hyp.GetLibName()
1767             # checkAll    = ( not geom.IsSame( self.mesh.GetShapeToMesh() ))
1768             # if checkAll and geom:
1769             #     checkAll = geom.GetType() == 37
1770             checkAll     = False
1771             isApplicable = self.smeshpyD.IsApplicable(hyp_type, lib_name, geom, checkAll)
1772         if isApplicable:
1773             AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
1774             status = self.mesh.AddHypothesis(geom, hyp)
1775         else:
1776             status = HYP_BAD_GEOMETRY, ""
1777         hyp_name = GetName( hyp )
1778         geom_name = ""
1779         if geom:
1780             geom_name = geom.GetName()
1781         isAlgo = hyp._narrow( SMESH_Algo )
1782         TreatHypoStatus( status, hyp_name, geom_name, isAlgo, self )
1783         return status
1784
1785     ## Return True if an algorithm of hypothesis is assigned to a given shape
1786     #  @param hyp a hypothesis to check
1787     #  @param geom a subhape of mesh geometry
1788     #  @return True of False
1789     #  @ingroup l2_editing
1790     def IsUsedHypothesis(self, hyp, geom):
1791         if not hyp: # or not geom
1792             return False
1793         if isinstance( hyp, Mesh_Algorithm ):
1794             hyp = hyp.GetAlgorithm()
1795             pass
1796         hyps = self.GetHypothesisList(geom)
1797         for h in hyps:
1798             if h.GetId() == hyp.GetId():
1799                 return True
1800         return False
1801
1802     ## Unassign a hypothesis
1803     #  @param hyp a hypothesis to unassign
1804     #  @param geom a sub-shape of mesh geometry
1805     #  @return SMESH.Hypothesis_Status
1806     #  @ingroup l2_editing
1807     def RemoveHypothesis(self, hyp, geom=0):
1808         if not hyp:
1809             return None
1810         if isinstance( hyp, Mesh_Algorithm ):
1811             hyp = hyp.GetAlgorithm()
1812             pass
1813         shape = geom
1814         if not shape:
1815             shape = self.geom
1816             pass
1817         if self.IsUsedHypothesis( hyp, shape ):
1818             return self.mesh.RemoveHypothesis( shape, hyp )
1819         hypName = GetName( hyp )
1820         geoName = GetName( shape )
1821         print("WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ))
1822         return None
1823
1824     ## Get the list of hypotheses added on a geometry
1825     #  @param geom a sub-shape of mesh geometry
1826     #  @return the sequence of SMESH_Hypothesis
1827     #  @ingroup l2_editing
1828     def GetHypothesisList(self, geom):
1829         return self.mesh.GetHypothesisList( geom )
1830
1831     ## Remove all global hypotheses
1832     #  @ingroup l2_editing
1833     def RemoveGlobalHypotheses(self):
1834         current_hyps = self.mesh.GetHypothesisList( self.geom )
1835         for hyp in current_hyps:
1836             self.mesh.RemoveHypothesis( self.geom, hyp )
1837             pass
1838         pass
1839
1840     ## Export the mesh in a file in MED format
1841     ## allowing to overwrite the file if it exists or add the exported data to its contents
1842     #  @param f is the file name
1843     #  @param auto_groups boolean parameter for creating/not creating
1844     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
1845     #  the typical use is auto_groups=False.
1846     #  @param version MED format version (MED_V2_1 or MED_V2_2,
1847     #                 the latter meaning any current version). The parameter is
1848     #                 obsolete since MED_V2_1 is no longer supported.
1849     #  @param overwrite boolean parameter for overwriting/not overwriting the file
1850     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1851     #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
1852     #         - 1D if all mesh nodes lie on OX coordinate axis, or
1853     #         - 2D if all mesh nodes lie on XOY coordinate plane, or
1854     #         - 3D in the rest cases.<br>
1855     #         If @a autoDimension is @c False, the space dimension is always 3.
1856     #  @param fields list of GEOM fields defined on the shape to mesh.
1857     #  @param geomAssocFields each character of this string means a need to export a
1858     #         corresponding field; correspondence between fields and characters is following:
1859     #         - 'v' stands for "_vertices _" field;
1860     #         - 'e' stands for "_edges _" field;
1861     #         - 'f' stands for "_faces _" field;
1862     #         - 's' stands for "_solids _" field.
1863     #  @ingroup l2_impexp
1864     def ExportMED(self, f, auto_groups=0, version=MED_V2_2,
1865                   overwrite=1, meshPart=None, autoDimension=True, fields=[], geomAssocFields=''):
1866         if meshPart or fields or geomAssocFields:
1867             unRegister = genObjUnRegister()
1868             if isinstance( meshPart, list ):
1869                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1870                 unRegister.set( meshPart )
1871             self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite, autoDimension,
1872                                        fields, geomAssocFields)
1873         else:
1874             self.mesh.ExportToMEDX(f, auto_groups, version, overwrite, autoDimension)
1875
1876     ## Export the mesh in a file in SAUV format
1877     #  @param f is the file name
1878     #  @param auto_groups boolean parameter for creating/not creating
1879     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
1880     #  the typical use is auto_groups=false.
1881     #  @ingroup l2_impexp
1882     def ExportSAUV(self, f, auto_groups=0):
1883         self.mesh.ExportSAUV(f, auto_groups)
1884
1885     ## Export the mesh in a file in DAT format
1886     #  @param f the file name
1887     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1888     #  @ingroup l2_impexp
1889     def ExportDAT(self, f, meshPart=None):
1890         if meshPart:
1891             unRegister = genObjUnRegister()
1892             if isinstance( meshPart, list ):
1893                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1894                 unRegister.set( meshPart )
1895             self.mesh.ExportPartToDAT( meshPart, f )
1896         else:
1897             self.mesh.ExportDAT(f)
1898
1899     ## Export the mesh in a file in UNV format
1900     #  @param f the file name
1901     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1902     #  @ingroup l2_impexp
1903     def ExportUNV(self, f, meshPart=None):
1904         if meshPart:
1905             unRegister = genObjUnRegister()
1906             if isinstance( meshPart, list ):
1907                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1908                 unRegister.set( meshPart )
1909             self.mesh.ExportPartToUNV( meshPart, f )
1910         else:
1911             self.mesh.ExportUNV(f)
1912
1913     ## Export the mesh in a file in STL format
1914     #  @param f the file name
1915     #  @param ascii defines the file encoding
1916     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1917     #  @ingroup l2_impexp
1918     def ExportSTL(self, f, ascii=1, meshPart=None):
1919         if meshPart:
1920             unRegister = genObjUnRegister()
1921             if isinstance( meshPart, list ):
1922                 meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1923                 unRegister.set( meshPart )
1924             self.mesh.ExportPartToSTL( meshPart, f, ascii )
1925         else:
1926             self.mesh.ExportSTL(f, ascii)
1927
1928     ## Export the mesh in a file in CGNS format
1929     #  @param f is the file name
1930     #  @param overwrite boolean parameter for overwriting/not overwriting the file
1931     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1932     #  @ingroup l2_impexp
1933     def ExportCGNS(self, f, overwrite=1, meshPart=None):
1934         unRegister = genObjUnRegister()
1935         if isinstance( meshPart, list ):
1936             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1937             unRegister.set( meshPart )
1938         if isinstance( meshPart, Mesh ):
1939             meshPart = meshPart.mesh
1940         elif not meshPart:
1941             meshPart = self.mesh
1942         self.mesh.ExportCGNS(meshPart, f, overwrite)
1943
1944     ## Export the mesh in a file in GMF format.
1945     #  GMF files must have .mesh extension for the ASCII format and .meshb for
1946     #  the bynary format. Other extensions are not allowed.
1947     #  @param f is the file name
1948     #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
1949     #  @ingroup l2_impexp
1950     def ExportGMF(self, f, meshPart=None):
1951         unRegister = genObjUnRegister()
1952         if isinstance( meshPart, list ):
1953             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
1954             unRegister.set( meshPart )
1955         if isinstance( meshPart, Mesh ):
1956             meshPart = meshPart.mesh
1957         elif not meshPart:
1958             meshPart = self.mesh
1959         self.mesh.ExportGMF(meshPart, f, True)
1960
1961     ## Deprecated, used only for compatibility! Please, use ExportMED() method instead.
1962     #  Export the mesh in a file in MED format
1963     #  allowing to overwrite the file if it exists or add the exported data to its contents
1964     #  @param f the file name
1965     #  @param version MED format version (MED_V2_1 or MED_V2_2,
1966     #                 the latter meaning any current version). The parameter is
1967     #                 obsolete since MED_V2_1 is no longer supported.
1968     #  @param opt boolean parameter for creating/not creating
1969     #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
1970     #  @param overwrite boolean parameter for overwriting/not overwriting the file
1971     #  @param autoDimension if @c True (default), a space dimension of a MED mesh can be either
1972     #         - 1D if all mesh nodes lie on OX coordinate axis, or
1973     #         - 2D if all mesh nodes lie on XOY coordinate plane, or
1974     #         - 3D in the rest cases.<br>
1975     #         If @a autoDimension is @c False, the space dimension is always 3.
1976     #  @ingroup l2_impexp
1977     def ExportToMED(self, f, version=MED_V2_2, opt=0, overwrite=1, autoDimension=True):
1978         self.mesh.ExportToMEDX(f, opt, version, overwrite, autoDimension)
1979
1980     # Operations with groups:
1981     # ----------------------
1982
1983     ## Create an empty mesh group
1984     #  @param elementType the type of elements in the group; either of
1985     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
1986     #  @param name the name of the mesh group
1987     #  @return SMESH_Group
1988     #  @ingroup l2_grps_create
1989     def CreateEmptyGroup(self, elementType, name):
1990         return self.mesh.CreateGroup(elementType, name)
1991
1992     ## Create a mesh group based on the geometric object \a grp
1993     #  and gives a \a name, \n if this parameter is not defined
1994     #  the name is the same as the geometric group name \n
1995     #  Note: Works like GroupOnGeom().
1996     #  @param grp  a geometric group, a vertex, an edge, a face or a solid
1997     #  @param name the name of the mesh group
1998     #  @return SMESH_GroupOnGeom
1999     #  @ingroup l2_grps_create
2000     def Group(self, grp, name=""):
2001         return self.GroupOnGeom(grp, name)
2002
2003     ## Create a mesh group based on the geometrical object \a grp
2004     #  and gives a \a name, \n if this parameter is not defined
2005     #  the name is the same as the geometrical group name
2006     #  @param grp  a geometrical group, a vertex, an edge, a face or a solid
2007     #  @param name the name of the mesh group
2008     #  @param typ  the type of elements in the group; either of
2009     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). If not set, it is
2010     #         automatically detected by the type of the geometry
2011     #  @return SMESH_GroupOnGeom
2012     #  @ingroup l2_grps_create
2013     def GroupOnGeom(self, grp, name="", typ=None):
2014         AssureGeomPublished( self, grp, name )
2015         if name == "":
2016             name = grp.GetName()
2017         if not typ:
2018             typ = self._groupTypeFromShape( grp )
2019         return self.mesh.CreateGroupFromGEOM(typ, name, grp)
2020
2021     ## Pivate method to get a type of group on geometry
2022     def _groupTypeFromShape( self, shape ):
2023         tgeo = str(shape.GetShapeType())
2024         if tgeo == "VERTEX":
2025             typ = NODE
2026         elif tgeo == "EDGE":
2027             typ = EDGE
2028         elif tgeo == "FACE" or tgeo == "SHELL":
2029             typ = FACE
2030         elif tgeo == "SOLID" or tgeo == "COMPSOLID":
2031             typ = VOLUME
2032         elif tgeo == "COMPOUND":
2033             sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"])
2034             if not sub:
2035                 raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape))
2036             return self._groupTypeFromShape( sub[0] )
2037         else:
2038             raise ValueError("_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape))
2039         return typ
2040
2041     ## Create a mesh group with given \a name based on the \a filter which
2042     ## is a special type of group dynamically updating it's contents during
2043     ## mesh modification
2044     #  @param typ  the type of elements in the group; either of
2045     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2046     #  @param name the name of the mesh group
2047     #  @param filter the filter defining group contents
2048     #  @return SMESH_GroupOnFilter
2049     #  @ingroup l2_grps_create
2050     def GroupOnFilter(self, typ, name, filter):
2051         return self.mesh.CreateGroupFromFilter(typ, name, filter)
2052
2053     ## Create a mesh group by the given ids of elements
2054     #  @param groupName the name of the mesh group
2055     #  @param elementType the type of elements in the group; either of
2056     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2057     #  @param elemIDs either the list of ids, group, sub-mesh, or filter
2058     #  @return SMESH_Group
2059     #  @ingroup l2_grps_create
2060     def MakeGroupByIds(self, groupName, elementType, elemIDs):
2061         group = self.mesh.CreateGroup(elementType, groupName)
2062         if hasattr( elemIDs, "GetIDs" ):
2063             if hasattr( elemIDs, "SetMesh" ):
2064                 elemIDs.SetMesh( self.GetMesh() )
2065             group.AddFrom( elemIDs )
2066         else:
2067             group.Add(elemIDs)
2068         return group
2069
2070     ## Create a mesh group by the given conditions
2071     #  @param groupName the name of the mesh group
2072     #  @param elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME)
2073     #  @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.)
2074     #          Type SMESH.FunctorType._items in the Python Console to see all values.
2075     #          Note that the items starting from FT_LessThan are not suitable for CritType.
2076     #  @param Compare  belongs to {SMESH.FT_LessThan, SMESH.FT_MoreThan, SMESH.FT_EqualTo}
2077     #  @param Threshold the threshold value (range of ids as string, shape, numeric)
2078     #  @param UnaryOp  SMESH.FT_LogicalNOT or SMESH.FT_Undefined
2079     #  @param Tolerance the tolerance used by SMESH.FT_BelongToGeom, SMESH.FT_BelongToSurface,
2080     #         SMESH.FT_LyingOnGeom, SMESH.FT_CoplanarFaces criteria
2081     #  @return SMESH_GroupOnFilter
2082     #  @ingroup l2_grps_create
2083     def MakeGroup(self,
2084                   groupName,
2085                   elementType,
2086                   CritType=FT_Undefined,
2087                   Compare=FT_EqualTo,
2088                   Threshold="",
2089                   UnaryOp=FT_Undefined,
2090                   Tolerance=1e-07):
2091         aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
2092         group = self.MakeGroupByCriterion(groupName, aCriterion)
2093         return group
2094
2095     ## Create a mesh group by the given criterion
2096     #  @param groupName the name of the mesh group
2097     #  @param Criterion the instance of Criterion class
2098     #  @return SMESH_GroupOnFilter
2099     #  @ingroup l2_grps_create
2100     def MakeGroupByCriterion(self, groupName, Criterion):
2101         return self.MakeGroupByCriteria( groupName, [Criterion] )
2102
2103     ## Create a mesh group by the given criteria (list of criteria)
2104     #  @param groupName the name of the mesh group
2105     #  @param theCriteria the list of criteria
2106     #  @param binOp binary operator used when binary operator of criteria is undefined
2107     #  @return SMESH_GroupOnFilter
2108     #  @ingroup l2_grps_create
2109     def MakeGroupByCriteria(self, groupName, theCriteria, binOp=SMESH.FT_LogicalAND):
2110         aFilter = self.smeshpyD.GetFilterFromCriteria( theCriteria, binOp )
2111         group = self.MakeGroupByFilter(groupName, aFilter)
2112         return group
2113
2114     ## Create a mesh group by the given filter
2115     #  @param groupName the name of the mesh group
2116     #  @param theFilter the instance of Filter class
2117     #  @return SMESH_GroupOnFilter
2118     #  @ingroup l2_grps_create
2119     def MakeGroupByFilter(self, groupName, theFilter):
2120         #group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
2121         #theFilter.SetMesh( self.mesh )
2122         #group.AddFrom( theFilter )
2123         group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter )
2124         return group
2125
2126     ## Remove a group
2127     #  @ingroup l2_grps_delete
2128     def RemoveGroup(self, group):
2129         self.mesh.RemoveGroup(group)
2130
2131     ## Remove a group with its contents
2132     #  @ingroup l2_grps_delete
2133     def RemoveGroupWithContents(self, group):
2134         self.mesh.RemoveGroupWithContents(group)
2135
2136     ## Get the list of groups existing in the mesh in the order
2137     #  of creation (starting from the oldest one)
2138     #  @param elemType type of elements the groups contain; either of
2139     #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME);
2140     #         by default groups of elements of all types are returned
2141     #  @return a sequence of SMESH_GroupBase
2142     #  @ingroup l2_grps_create
2143     def GetGroups(self, elemType = SMESH.ALL):
2144         groups = self.mesh.GetGroups()
2145         if elemType == SMESH.ALL:
2146             return groups
2147         typedGroups = []
2148         for g in groups:
2149             if g.GetType() == elemType:
2150                 typedGroups.append( g )
2151                 pass
2152             pass
2153         return typedGroups
2154
2155     ## Get the number of groups existing in the mesh
2156     #  @return the quantity of groups as an integer value
2157     #  @ingroup l2_grps_create
2158     def NbGroups(self):
2159         return self.mesh.NbGroups()
2160
2161     ## Get the list of names of groups existing in the mesh
2162     #  @return list of strings
2163     #  @ingroup l2_grps_create
2164     def GetGroupNames(self):
2165         groups = self.GetGroups()
2166         names = []
2167         for group in groups:
2168             names.append(group.GetName())
2169         return names
2170
2171     ## Find groups by name and type
2172     #  @param name name of the group of interest
2173     #  @param elemType type of elements the groups contain; either of
2174     #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME);
2175     #         by default one group of any type of elements is returned
2176     #         if elemType == SMESH.ALL then all groups of any type are returned
2177     #  @return a list of SMESH_GroupBase's
2178     #  @ingroup l2_grps_create
2179     def GetGroupByName(self, name, elemType = None):
2180         groups = []
2181         for group in self.GetGroups():
2182             if group.GetName() == name:
2183                 if elemType is None:
2184                     return [group]
2185                 if ( elemType == SMESH.ALL or
2186                      group.GetType() == elemType ):
2187                     groups.append( group )
2188         return groups
2189
2190     ## Produce a union of two groups.
2191     #  A new group is created. All mesh elements that are
2192     #  present in the initial groups are added to the new one
2193     #  @return an instance of SMESH_Group
2194     #  @ingroup l2_grps_operon
2195     def UnionGroups(self, group1, group2, name):
2196         return self.mesh.UnionGroups(group1, group2, name)
2197
2198     ## Produce a union list of groups.
2199     #  New group is created. All mesh elements that are present in
2200     #  initial groups are added to the new one
2201     #  @return an instance of SMESH_Group
2202     #  @ingroup l2_grps_operon
2203     def UnionListOfGroups(self, groups, name):
2204         return self.mesh.UnionListOfGroups(groups, name)
2205
2206     ## Prodice an intersection of two groups.
2207     #  A new group is created. All mesh elements that are common
2208     #  for the two initial groups are added to the new one.
2209     #  @return an instance of SMESH_Group
2210     #  @ingroup l2_grps_operon
2211     def IntersectGroups(self, group1, group2, name):
2212         return self.mesh.IntersectGroups(group1, group2, name)
2213
2214     ## Produce an intersection of groups.
2215     #  New group is created. All mesh elements that are present in all
2216     #  initial groups simultaneously are added to the new one
2217     #  @return an instance of SMESH_Group
2218     #  @ingroup l2_grps_operon
2219     def IntersectListOfGroups(self, groups, name):
2220         return self.mesh.IntersectListOfGroups(groups, name)
2221
2222     ## Produce a cut of two groups.
2223     #  A new group is created. All mesh elements that are present in
2224     #  the main group but are not present in the tool group are added to the new one
2225     #  @return an instance of SMESH_Group
2226     #  @ingroup l2_grps_operon
2227     def CutGroups(self, main_group, tool_group, name):
2228         return self.mesh.CutGroups(main_group, tool_group, name)
2229
2230     ## Produce a cut of groups.
2231     #  A new group is created. All mesh elements that are present in main groups
2232     #  but do not present in tool groups are added to the new one
2233     #  @return an instance of SMESH_Group
2234     #  @ingroup l2_grps_operon
2235     def CutListOfGroups(self, main_groups, tool_groups, name):
2236         return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
2237
2238     ##
2239     #  Create a standalone group of entities basing on nodes of other groups.
2240     #  \param groups - list of reference groups, sub-meshes or filters, of any type.
2241     #  \param elemType - a type of elements to include to the new group; either of
2242     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME).
2243     #  \param name - a name of the new group.
2244     #  \param nbCommonNodes - a criterion of inclusion of an element to the new group
2245     #         basing on number of element nodes common with reference \a groups.
2246     #         Meaning of possible values are:
2247     #         - SMESH.ALL_NODES - include if all nodes are common,
2248     #         - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
2249     #         - SMESH.AT_LEAST_ONE - include if one or more node is common,
2250     #         - SMEHS.MAJORITY - include if half of nodes or more are common.
2251     #  \param underlyingOnly - if \c True (default), an element is included to the
2252     #         new group provided that it is based on nodes of an element of \a groups;
2253     #         in this case the reference \a groups are supposed to be of higher dimension
2254     #         than \a elemType, which can be useful for example to get all faces lying on
2255     #         volumes of the reference \a groups.
2256     #  @return an instance of SMESH_Group
2257     #  @ingroup l2_grps_operon
2258     def CreateDimGroup(self, groups, elemType, name,
2259                        nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
2260         if isinstance( groups, SMESH._objref_SMESH_IDSource ):
2261             groups = [groups]
2262         return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
2263
2264
2265     ## Convert group on geom into standalone group
2266     #  @ingroup l2_grps_operon
2267     def ConvertToStandalone(self, group):
2268         return self.mesh.ConvertToStandalone(group)
2269
2270     # Get some info about mesh:
2271     # ------------------------
2272
2273     ## Return the log of nodes and elements added or removed
2274     #  since the previous clear of the log.
2275     #  @param clearAfterGet log is emptied after Get (safe if concurrents access)
2276     #  @return list of log_block structures:
2277     #                                        commandType
2278     #                                        number
2279     #                                        coords
2280     #                                        indexes
2281     #  @ingroup l1_auxiliary
2282     def GetLog(self, clearAfterGet):
2283         return self.mesh.GetLog(clearAfterGet)
2284
2285     ## Clear the log of nodes and elements added or removed since the previous
2286     #  clear. Must be used immediately after GetLog if clearAfterGet is false.
2287     #  @ingroup l1_auxiliary
2288     def ClearLog(self):
2289         self.mesh.ClearLog()
2290
2291     ## Toggle auto color mode on the object.
2292     #  @param theAutoColor the flag which toggles auto color mode.
2293     #
2294     #  If switched on, a default color of a new group in Create Group dialog is chosen randomly.
2295     #  @ingroup l1_grouping
2296     def SetAutoColor(self, theAutoColor):
2297         self.mesh.SetAutoColor(theAutoColor)
2298
2299     ## Get flag of object auto color mode.
2300     #  @return True or False
2301     #  @ingroup l1_grouping
2302     def GetAutoColor(self):
2303         return self.mesh.GetAutoColor()
2304
2305     ## Get the internal ID
2306     #  @return integer value, which is the internal Id of the mesh
2307     #  @ingroup l1_auxiliary
2308     def GetId(self):
2309         return self.mesh.GetId()
2310
2311     ## Check the group names for duplications.
2312     #  Consider the maximum group name length stored in MED file.
2313     #  @return True or False
2314     #  @ingroup l1_grouping
2315     def HasDuplicatedGroupNamesMED(self):
2316         return self.mesh.HasDuplicatedGroupNamesMED()
2317
2318     ## Obtain the mesh editor tool
2319     #  @return an instance of SMESH_MeshEditor
2320     #  @ingroup l1_modifying
2321     def GetMeshEditor(self):
2322         return self.editor
2323
2324     ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
2325     #  can be passed as argument to a method accepting mesh, group or sub-mesh
2326     #  @param ids list of IDs
2327     #  @param elemType type of elements; this parameter is used to distinguish
2328     #         IDs of nodes from IDs of elements; by default ids are treated as
2329     #         IDs of elements; use SMESH.NODE if ids are IDs of nodes.
2330     #  @return an instance of SMESH_IDSource
2331     #  @warning call UnRegister() for the returned object as soon as it is no more useful:
2332     #          idSrc = mesh.GetIDSource( [1,3,5], SMESH.NODE )
2333     #          mesh.DoSomething( idSrc )
2334     #          idSrc.UnRegister()
2335     #  @ingroup l1_auxiliary
2336     def GetIDSource(self, ids, elemType = SMESH.ALL):
2337         if isinstance( ids, int ):
2338             ids = [ids]
2339         return self.editor.MakeIDSource(ids, elemType)
2340
2341
2342     # Get informations about mesh contents:
2343     # ------------------------------------
2344
2345     ## Get the mesh stattistic
2346     #  @return dictionary type element - count of elements
2347     #  @ingroup l1_meshinfo
2348     def GetMeshInfo(self, obj = None):
2349         if not obj: obj = self.mesh
2350         return self.smeshpyD.GetMeshInfo(obj)
2351
2352     ## Return the number of nodes in the mesh
2353     #  @return an integer value
2354     #  @ingroup l1_meshinfo
2355     def NbNodes(self):
2356         return self.mesh.NbNodes()
2357
2358     ## Return the number of elements in the mesh
2359     #  @return an integer value
2360     #  @ingroup l1_meshinfo
2361     def NbElements(self):
2362         return self.mesh.NbElements()
2363
2364     ## Return the number of 0d elements in the mesh
2365     #  @return an integer value
2366     #  @ingroup l1_meshinfo
2367     def Nb0DElements(self):
2368         return self.mesh.Nb0DElements()
2369
2370     ## Return the number of ball discrete elements in the mesh
2371     #  @return an integer value
2372     #  @ingroup l1_meshinfo
2373     def NbBalls(self):
2374         return self.mesh.NbBalls()
2375
2376     ## Return the number of edges in the mesh
2377     #  @return an integer value
2378     #  @ingroup l1_meshinfo
2379     def NbEdges(self):
2380         return self.mesh.NbEdges()
2381
2382     ## Return the number of edges with the given order in the mesh
2383     #  @param elementOrder the order of elements:
2384     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2385     #  @return an integer value
2386     #  @ingroup l1_meshinfo
2387     def NbEdgesOfOrder(self, elementOrder):
2388         return self.mesh.NbEdgesOfOrder(elementOrder)
2389
2390     ## Return the number of faces in the mesh
2391     #  @return an integer value
2392     #  @ingroup l1_meshinfo
2393     def NbFaces(self):
2394         return self.mesh.NbFaces()
2395
2396     ## Return the number of faces with the given order in the mesh
2397     #  @param elementOrder the order of elements:
2398     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2399     #  @return an integer value
2400     #  @ingroup l1_meshinfo
2401     def NbFacesOfOrder(self, elementOrder):
2402         return self.mesh.NbFacesOfOrder(elementOrder)
2403
2404     ## Return the number of triangles in the mesh
2405     #  @return an integer value
2406     #  @ingroup l1_meshinfo
2407     def NbTriangles(self):
2408         return self.mesh.NbTriangles()
2409
2410     ## Return the number of triangles with the given order in the mesh
2411     #  @param elementOrder is the order of elements:
2412     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2413     #  @return an integer value
2414     #  @ingroup l1_meshinfo
2415     def NbTrianglesOfOrder(self, elementOrder):
2416         return self.mesh.NbTrianglesOfOrder(elementOrder)
2417
2418     ## Return the number of biquadratic triangles in the mesh
2419     #  @return an integer value
2420     #  @ingroup l1_meshinfo
2421     def NbBiQuadTriangles(self):
2422         return self.mesh.NbBiQuadTriangles()
2423
2424     ## Return the number of quadrangles in the mesh
2425     #  @return an integer value
2426     #  @ingroup l1_meshinfo
2427     def NbQuadrangles(self):
2428         return self.mesh.NbQuadrangles()
2429
2430     ## Return the number of quadrangles with the given order in the mesh
2431     #  @param elementOrder the order of elements:
2432     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2433     #  @return an integer value
2434     #  @ingroup l1_meshinfo
2435     def NbQuadranglesOfOrder(self, elementOrder):
2436         return self.mesh.NbQuadranglesOfOrder(elementOrder)
2437
2438     ## Return the number of biquadratic quadrangles in the mesh
2439     #  @return an integer value
2440     #  @ingroup l1_meshinfo
2441     def NbBiQuadQuadrangles(self):
2442         return self.mesh.NbBiQuadQuadrangles()
2443
2444     ## Return the number of polygons of given order in the mesh
2445     #  @param elementOrder the order of elements:
2446     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2447     #  @return an integer value
2448     #  @ingroup l1_meshinfo
2449     def NbPolygons(self, elementOrder = SMESH.ORDER_ANY):
2450         return self.mesh.NbPolygonsOfOrder(elementOrder)
2451
2452     ## Return the number of volumes in the mesh
2453     #  @return an integer value
2454     #  @ingroup l1_meshinfo
2455     def NbVolumes(self):
2456         return self.mesh.NbVolumes()
2457
2458     ## Return the number of volumes with the given order in the mesh
2459     #  @param elementOrder  the order of elements:
2460     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2461     #  @return an integer value
2462     #  @ingroup l1_meshinfo
2463     def NbVolumesOfOrder(self, elementOrder):
2464         return self.mesh.NbVolumesOfOrder(elementOrder)
2465
2466     ## Return the number of tetrahedrons in the mesh
2467     #  @return an integer value
2468     #  @ingroup l1_meshinfo
2469     def NbTetras(self):
2470         return self.mesh.NbTetras()
2471
2472     ## Return the number of tetrahedrons with the given order in the mesh
2473     #  @param elementOrder  the order of elements:
2474     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2475     #  @return an integer value
2476     #  @ingroup l1_meshinfo
2477     def NbTetrasOfOrder(self, elementOrder):
2478         return self.mesh.NbTetrasOfOrder(elementOrder)
2479
2480     ## Return the number of hexahedrons in the mesh
2481     #  @return an integer value
2482     #  @ingroup l1_meshinfo
2483     def NbHexas(self):
2484         return self.mesh.NbHexas()
2485
2486     ## Return the number of hexahedrons with the given order in the mesh
2487     #  @param elementOrder  the order of elements:
2488     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2489     #  @return an integer value
2490     #  @ingroup l1_meshinfo
2491     def NbHexasOfOrder(self, elementOrder):
2492         return self.mesh.NbHexasOfOrder(elementOrder)
2493
2494     ## Return the number of triquadratic hexahedrons in the mesh
2495     #  @return an integer value
2496     #  @ingroup l1_meshinfo
2497     def NbTriQuadraticHexas(self):
2498         return self.mesh.NbTriQuadraticHexas()
2499
2500     ## Return the number of pyramids in the mesh
2501     #  @return an integer value
2502     #  @ingroup l1_meshinfo
2503     def NbPyramids(self):
2504         return self.mesh.NbPyramids()
2505
2506     ## Return the number of pyramids with the given order in the mesh
2507     #  @param elementOrder  the order of elements:
2508     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2509     #  @return an integer value
2510     #  @ingroup l1_meshinfo
2511     def NbPyramidsOfOrder(self, elementOrder):
2512         return self.mesh.NbPyramidsOfOrder(elementOrder)
2513
2514     ## Return the number of prisms in the mesh
2515     #  @return an integer value
2516     #  @ingroup l1_meshinfo
2517     def NbPrisms(self):
2518         return self.mesh.NbPrisms()
2519
2520     ## Return the number of prisms with the given order in the mesh
2521     #  @param elementOrder  the order of elements:
2522     #         SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC
2523     #  @return an integer value
2524     #  @ingroup l1_meshinfo
2525     def NbPrismsOfOrder(self, elementOrder):
2526         return self.mesh.NbPrismsOfOrder(elementOrder)
2527
2528     ## Return the number of hexagonal prisms in the mesh
2529     #  @return an integer value
2530     #  @ingroup l1_meshinfo
2531     def NbHexagonalPrisms(self):
2532         return self.mesh.NbHexagonalPrisms()
2533
2534     ## Return the number of polyhedrons in the mesh
2535     #  @return an integer value
2536     #  @ingroup l1_meshinfo
2537     def NbPolyhedrons(self):
2538         return self.mesh.NbPolyhedrons()
2539
2540     ## Return the number of submeshes in the mesh
2541     #  @return an integer value
2542     #  @ingroup l1_meshinfo
2543     def NbSubMesh(self):
2544         return self.mesh.NbSubMesh()
2545
2546     ## Return the list of mesh elements IDs
2547     #  @return the list of integer values
2548     #  @ingroup l1_meshinfo
2549     def GetElementsId(self):
2550         return self.mesh.GetElementsId()
2551
2552     ## Return the list of IDs of mesh elements with the given type
2553     #  @param elementType  the required type of elements, either of
2554     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
2555     #  @return list of integer values
2556     #  @ingroup l1_meshinfo
2557     def GetElementsByType(self, elementType):
2558         return self.mesh.GetElementsByType(elementType)
2559
2560     ## Return the list of mesh nodes IDs
2561     #  @return the list of integer values
2562     #  @ingroup l1_meshinfo
2563     def GetNodesId(self):
2564         return self.mesh.GetNodesId()
2565
2566     # Get the information about mesh elements:
2567     # ------------------------------------
2568
2569     ## Return the type of mesh element
2570     #  @return the value from SMESH::ElementType enumeration
2571     #          Type SMESH.ElementType._items in the Python Console to see all possible values.
2572     #  @ingroup l1_meshinfo
2573     def GetElementType(self, id, iselem=True):
2574         return self.mesh.GetElementType(id, iselem)
2575
2576     ## Return the geometric type of mesh element
2577     #  @return the value from SMESH::EntityType enumeration
2578     #          Type SMESH.EntityType._items in the Python Console to see all possible values.
2579     #  @ingroup l1_meshinfo
2580     def GetElementGeomType(self, id):
2581         return self.mesh.GetElementGeomType(id)
2582
2583     ## Return the shape type of mesh element
2584     #  @return the value from SMESH::GeometryType enumeration.
2585     #          Type SMESH.GeometryType._items in the Python Console to see all possible values.
2586     #  @ingroup l1_meshinfo
2587     def GetElementShape(self, id):
2588         return self.mesh.GetElementShape(id)
2589
2590     ## Return the list of submesh elements IDs
2591     #  @param Shape a geom object(sub-shape)
2592     #         Shape must be the sub-shape of a ShapeToMesh()
2593     #  @return the list of integer values
2594     #  @ingroup l1_meshinfo
2595     def GetSubMeshElementsId(self, Shape):
2596         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
2597             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
2598         else:
2599             ShapeID = Shape
2600         return self.mesh.GetSubMeshElementsId(ShapeID)
2601
2602     ## Return the list of submesh nodes IDs
2603     #  @param Shape a geom object(sub-shape)
2604     #         Shape must be the sub-shape of a ShapeToMesh()
2605     #  @param all If true, gives all nodes of submesh elements, otherwise gives only submesh nodes
2606     #  @return the list of integer values
2607     #  @ingroup l1_meshinfo
2608     def GetSubMeshNodesId(self, Shape, all):
2609         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
2610             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
2611         else:
2612             ShapeID = Shape
2613         return self.mesh.GetSubMeshNodesId(ShapeID, all)
2614
2615     ## Return type of elements on given shape
2616     #  @param Shape a geom object(sub-shape)
2617     #         Shape must be a sub-shape of a ShapeToMesh()
2618     #  @return element type
2619     #  @ingroup l1_meshinfo
2620     def GetSubMeshElementType(self, Shape):
2621         if isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object):
2622             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
2623         else:
2624             ShapeID = Shape
2625         return self.mesh.GetSubMeshElementType(ShapeID)
2626
2627     ## Get the mesh description
2628     #  @return string value
2629     #  @ingroup l1_meshinfo
2630     def Dump(self):
2631         return self.mesh.Dump()
2632
2633
2634     # Get the information about nodes and elements of a mesh by its IDs:
2635     # -----------------------------------------------------------
2636
2637     ## Get XYZ coordinates of a node
2638     #  \n If there is no nodes for the given ID - return an empty list
2639     #  @return a list of double precision values
2640     #  @ingroup l1_meshinfo
2641     def GetNodeXYZ(self, id):
2642         return self.mesh.GetNodeXYZ(id)
2643
2644     ## Return list of IDs of inverse elements for the given node
2645     #  \n If there is no node for the given ID - return an empty list
2646     #  @return a list of integer values
2647     #  @ingroup l1_meshinfo
2648     def GetNodeInverseElements(self, id):
2649         return self.mesh.GetNodeInverseElements(id)
2650
2651     ## Return the position of a node on the shape
2652     #  @return SMESH::NodePosition
2653     #  @ingroup l1_meshinfo
2654     def GetNodePosition(self,NodeID):
2655         return self.mesh.GetNodePosition(NodeID)
2656
2657     ## Return the position of an element on the shape
2658     #  @return SMESH::ElementPosition
2659     #  @ingroup l1_meshinfo
2660     def GetElementPosition(self,ElemID):
2661         return self.mesh.GetElementPosition(ElemID)
2662
2663     ## Return the ID of the shape, on which the given node was generated.
2664     #  @return an integer value > 0 or -1 if there is no node for the given
2665     #          ID or the node is not assigned to any geometry
2666     #  @ingroup l1_meshinfo
2667     def GetShapeID(self, id):
2668         return self.mesh.GetShapeID(id)
2669
2670     ## Return the ID of the shape, on which the given element was generated.
2671     #  @return an integer value > 0 or -1 if there is no element for the given
2672     #          ID or the element is not assigned to any geometry
2673     #  @ingroup l1_meshinfo
2674     def GetShapeIDForElem(self,id):
2675         return self.mesh.GetShapeIDForElem(id)
2676
2677     ## Return the number of nodes of the given element
2678     #  @return an integer value > 0 or -1 if there is no element for the given ID
2679     #  @ingroup l1_meshinfo
2680     def GetElemNbNodes(self, id):
2681         return self.mesh.GetElemNbNodes(id)
2682
2683     ## Return the node ID the given (zero based) index for the given element
2684     #  \n If there is no element for the given ID - return -1
2685     #  \n If there is no node for the given index - return -2
2686     #  @return an integer value
2687     #  @ingroup l1_meshinfo
2688     def GetElemNode(self, id, index):
2689         return self.mesh.GetElemNode(id, index)
2690
2691     ## Return the IDs of nodes of the given element
2692     #  @return a list of integer values
2693     #  @ingroup l1_meshinfo
2694     def GetElemNodes(self, id):
2695         return self.mesh.GetElemNodes(id)
2696
2697     ## Return true if the given node is the medium node in the given quadratic element
2698     #  @ingroup l1_meshinfo
2699     def IsMediumNode(self, elementID, nodeID):
2700         return self.mesh.IsMediumNode(elementID, nodeID)
2701
2702     ## Return true if the given node is the medium node in one of quadratic elements
2703     #  @param nodeID ID of the node
2704     #  @param elementType  the type of elements to check a state of the node, either of
2705     #         (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
2706     #  @ingroup l1_meshinfo
2707     def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ):
2708         return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType)
2709
2710     ## Return the number of edges for the given element
2711     #  @ingroup l1_meshinfo
2712     def ElemNbEdges(self, id):
2713         return self.mesh.ElemNbEdges(id)
2714
2715     ## Return the number of faces for the given element
2716     #  @ingroup l1_meshinfo
2717     def ElemNbFaces(self, id):
2718         return self.mesh.ElemNbFaces(id)
2719
2720     ## Return nodes of given face (counted from zero) for given volumic element.
2721     #  @ingroup l1_meshinfo
2722     def GetElemFaceNodes(self,elemId, faceIndex):
2723         return self.mesh.GetElemFaceNodes(elemId, faceIndex)
2724
2725     ## Return three components of normal of given mesh face
2726     #  (or an empty array in KO case)
2727     #  @ingroup l1_meshinfo
2728     def GetFaceNormal(self, faceId, normalized=False):
2729         return self.mesh.GetFaceNormal(faceId,normalized)
2730
2731     ## Return an element based on all given nodes.
2732     #  @ingroup l1_meshinfo
2733     def FindElementByNodes(self, nodes):
2734         return self.mesh.FindElementByNodes(nodes)
2735
2736     ## Return elements including all given nodes.
2737     #  @ingroup l1_meshinfo
2738     def GetElementsByNodes(self, nodes, elemType=SMESH.ALL):
2739         return self.mesh.GetElementsByNodes( nodes, elemType )
2740
2741     ## Return true if the given element is a polygon
2742     #  @ingroup l1_meshinfo
2743     def IsPoly(self, id):
2744         return self.mesh.IsPoly(id)
2745
2746     ## Return true if the given element is quadratic
2747     #  @ingroup l1_meshinfo
2748     def IsQuadratic(self, id):
2749         return self.mesh.IsQuadratic(id)
2750
2751     ## Return diameter of a ball discrete element or zero in case of an invalid \a id
2752     #  @ingroup l1_meshinfo
2753     def GetBallDiameter(self, id):
2754         return self.mesh.GetBallDiameter(id)
2755
2756     ## Return XYZ coordinates of the barycenter of the given element
2757     #  \n If there is no element for the given ID - return an empty list
2758     #  @return a list of three double values
2759     #  @ingroup l1_meshinfo
2760     def BaryCenter(self, id):
2761         return self.mesh.BaryCenter(id)
2762
2763     ## Pass mesh elements through the given filter and return IDs of fitting elements
2764     #  @param theFilter SMESH_Filter
2765     #  @return a list of ids
2766     #  @ingroup l1_controls
2767     def GetIdsFromFilter(self, theFilter):
2768         theFilter.SetMesh( self.mesh )
2769         return theFilter.GetIDs()
2770
2771     # Get mesh measurements information:
2772     # ------------------------------------
2773
2774     ## Verify whether a 2D mesh element has free edges (edges connected to one face only)\n
2775     #  Return a list of special structures (borders).
2776     #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
2777     #  @ingroup l1_measurements
2778     def GetFreeBorders(self):
2779         aFilterMgr = self.smeshpyD.CreateFilterManager()
2780         aPredicate = aFilterMgr.CreateFreeEdges()
2781         aPredicate.SetMesh(self.mesh)
2782         aBorders = aPredicate.GetBorders()
2783         aFilterMgr.UnRegister()
2784         return aBorders
2785
2786     ## Get minimum distance between two nodes, elements or distance to the origin
2787     #  @param id1 first node/element id
2788     #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
2789     #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
2790     #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
2791     #  @return minimum distance value
2792     #  @sa GetMinDistance()
2793     #  @ingroup l1_measurements
2794     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
2795         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
2796         return aMeasure.value
2797
2798     ## Get measure structure specifying minimum distance data between two objects
2799     #  @param id1 first node/element id
2800     #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
2801     #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
2802     #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
2803     #  @return Measure structure
2804     #  @sa MinDistance()
2805     #  @ingroup l1_measurements
2806     def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
2807         if isElem1:
2808             id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
2809         else:
2810             id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
2811         if id2 != 0:
2812             if isElem2:
2813                 id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
2814             else:
2815                 id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
2816             pass
2817         else:
2818             id2 = None
2819
2820         aMeasurements = self.smeshpyD.CreateMeasurements()
2821         aMeasure = aMeasurements.MinDistance(id1, id2)
2822         genObjUnRegister([aMeasurements,id1, id2])
2823         return aMeasure
2824
2825     ## Get bounding box of the specified object(s)
2826     #  @param objects single source object or list of source objects or list of nodes/elements IDs
2827     #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
2828     #  @c False specifies that @a objects are nodes
2829     #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
2830     #  @sa GetBoundingBox()
2831     #  @ingroup l1_measurements
2832     def BoundingBox(self, objects=None, isElem=False):
2833         result = self.GetBoundingBox(objects, isElem)
2834         if result is None:
2835             result = (0.0,)*6
2836         else:
2837             result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
2838         return result
2839
2840     ## Get measure structure specifying bounding box data of the specified object(s)
2841     #  @param IDs single source object or list of source objects or list of nodes/elements IDs
2842     #  @param isElem if @a IDs is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
2843     #  @c False specifies that @a objects are nodes
2844     #  @return Measure structure
2845     #  @sa BoundingBox()
2846     #  @ingroup l1_measurements
2847     def GetBoundingBox(self, IDs=None, isElem=False):
2848         if IDs is None:
2849             IDs = [self.mesh]
2850         elif isinstance(IDs, tuple):
2851             IDs = list(IDs)
2852         if not isinstance(IDs, list):
2853             IDs = [IDs]
2854         if len(IDs) > 0 and isinstance(IDs[0], int):
2855             IDs = [IDs]
2856         srclist = []
2857         unRegister = genObjUnRegister()
2858         for o in IDs:
2859             if isinstance(o, Mesh):
2860                 srclist.append(o.mesh)
2861             elif hasattr(o, "_narrow"):
2862                 src = o._narrow(SMESH.SMESH_IDSource)
2863                 if src: srclist.append(src)
2864                 pass
2865             elif isinstance(o, list):
2866                 if isElem:
2867                     srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
2868                 else:
2869                     srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
2870                 unRegister.set( srclist[-1] )
2871                 pass
2872             pass
2873         aMeasurements = self.smeshpyD.CreateMeasurements()
2874         unRegister.set( aMeasurements )
2875         aMeasure = aMeasurements.BoundingBox(srclist)
2876         return aMeasure
2877
2878     # Mesh edition (SMESH_MeshEditor functionality):
2879     # ---------------------------------------------
2880
2881     ## Remove the elements from the mesh by ids
2882     #  @param IDsOfElements is a list of ids of elements to remove
2883     #  @return True or False
2884     #  @ingroup l2_modif_del
2885     def RemoveElements(self, IDsOfElements):
2886         return self.editor.RemoveElements(IDsOfElements)
2887
2888     ## Remove nodes from mesh by ids
2889     #  @param IDsOfNodes is a list of ids of nodes to remove
2890     #  @return True or False
2891     #  @ingroup l2_modif_del
2892     def RemoveNodes(self, IDsOfNodes):
2893         return self.editor.RemoveNodes(IDsOfNodes)
2894
2895     ## Remove all orphan (free) nodes from mesh
2896     #  @return number of the removed nodes
2897     #  @ingroup l2_modif_del
2898     def RemoveOrphanNodes(self):
2899         return self.editor.RemoveOrphanNodes()
2900
2901     ## Add a node to the mesh by coordinates
2902     #  @return Id of the new node
2903     #  @ingroup l2_modif_add
2904     def AddNode(self, x, y, z):
2905         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
2906         if hasVars: self.mesh.SetParameters(Parameters)
2907         return self.editor.AddNode( x, y, z)
2908
2909     ## Create a 0D element on a node with given number.
2910     #  @param IDOfNode the ID of node for creation of the element.
2911     #  @param DuplicateElements to add one more 0D element to a node or not
2912     #  @return the Id of the new 0D element
2913     #  @ingroup l2_modif_add
2914     def Add0DElement( self, IDOfNode, DuplicateElements=True ):
2915         return self.editor.Add0DElement( IDOfNode, DuplicateElements )
2916
2917     ## Create 0D elements on all nodes of the given elements except those
2918     #  nodes on which a 0D element already exists.
2919     #  @param theObject an object on whose nodes 0D elements will be created.
2920     #         It can be mesh, sub-mesh, group, list of element IDs or a holder
2921     #         of nodes IDs created by calling mesh.GetIDSource( nodes, SMESH.NODE )
2922     #  @param theGroupName optional name of a group to add 0D elements created
2923     #         and/or found on nodes of \a theObject.
2924     #  @param DuplicateElements to add one more 0D element to a node or not
2925     #  @return an object (a new group or a temporary SMESH_IDSource) holding
2926     #          IDs of new and/or found 0D elements. IDs of 0D elements
2927     #          can be retrieved from the returned object by calling GetIDs()
2928     #  @ingroup l2_modif_add
2929     def Add0DElementsToAllNodes(self, theObject, theGroupName="", DuplicateElements=False):
2930         unRegister = genObjUnRegister()
2931         if isinstance( theObject, Mesh ):
2932             theObject = theObject.GetMesh()
2933         elif isinstance( theObject, list ):
2934             theObject = self.GetIDSource( theObject, SMESH.ALL )
2935             unRegister.set( theObject )
2936         return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements )
2937
2938     ## Create a ball element on a node with given ID.
2939     #  @param IDOfNode the ID of node for creation of the element.
2940     #  @param diameter the bal diameter.
2941     #  @return the Id of the new ball element
2942     #  @ingroup l2_modif_add
2943     def AddBall(self, IDOfNode, diameter):
2944         return self.editor.AddBall( IDOfNode, diameter )
2945
2946     ## Create a linear or quadratic edge (this is determined
2947     #  by the number of given nodes).
2948     #  @param IDsOfNodes the list of node IDs for creation of the element.
2949     #  The order of nodes in this list should correspond to the description
2950     #  of MED. \n This description is located by the following link:
2951     #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
2952     #  @return the Id of the new edge
2953     #  @ingroup l2_modif_add
2954     def AddEdge(self, IDsOfNodes):
2955         return self.editor.AddEdge(IDsOfNodes)
2956
2957     ## Create a linear or quadratic face (this is determined
2958     #  by the number of given nodes).
2959     #  @param IDsOfNodes the list of node IDs for creation of the element.
2960     #  The order of nodes in this list should correspond to the description
2961     #  of MED. \n This description is located by the following link:
2962     #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
2963     #  @return the Id of the new face
2964     #  @ingroup l2_modif_add
2965     def AddFace(self, IDsOfNodes):
2966         return self.editor.AddFace(IDsOfNodes)
2967
2968     ## Add a polygonal face to the mesh by the list of node IDs
2969     #  @param IdsOfNodes the list of node IDs for creation of the element.
2970     #  @return the Id of the new face
2971     #  @ingroup l2_modif_add
2972     def AddPolygonalFace(self, IdsOfNodes):
2973         return self.editor.AddPolygonalFace(IdsOfNodes)
2974
2975     ## Add a quadratic polygonal face to the mesh by the list of node IDs
2976     #  @param IdsOfNodes the list of node IDs for creation of the element;
2977     #         corner nodes follow first.
2978     #  @return the Id of the new face
2979     #  @ingroup l2_modif_add
2980     def AddQuadPolygonalFace(self, IdsOfNodes):
2981         return self.editor.AddQuadPolygonalFace(IdsOfNodes)
2982
2983     ## Create both simple and quadratic volume (this is determined
2984     #  by the number of given nodes).
2985     #  @param IDsOfNodes the list of node IDs for creation of the element.
2986     #  The order of nodes in this list should correspond to the description
2987     #  of MED. \n This description is located by the following link:
2988     #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
2989     #  @return the Id of the new volumic element
2990     #  @ingroup l2_modif_add
2991     def AddVolume(self, IDsOfNodes):
2992         return self.editor.AddVolume(IDsOfNodes)
2993
2994     ## Create a volume of many faces, giving nodes for each face.
2995     #  @param IdsOfNodes the list of node IDs for volume creation face by face.
2996     #  @param Quantities the list of integer values, Quantities[i]
2997     #         gives the quantity of nodes in face number i.
2998     #  @return the Id of the new volumic element
2999     #  @ingroup l2_modif_add
3000     def AddPolyhedralVolume (self, IdsOfNodes, Quantities):
3001         return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities)
3002
3003     ## Create a volume of many faces, giving the IDs of the existing faces.
3004     #  @param IdsOfFaces the list of face IDs for volume creation.
3005     #
3006     #  Note:  The created volume will refer only to the nodes
3007     #         of the given faces, not to the faces themselves.
3008     #  @return the Id of the new volumic element
3009     #  @ingroup l2_modif_add
3010     def AddPolyhedralVolumeByFaces (self, IdsOfFaces):
3011         return self.editor.AddPolyhedralVolumeByFaces(IdsOfFaces)
3012
3013
3014     ## @brief Binds a node to a vertex
3015     #  @param NodeID a node ID
3016     #  @param Vertex a vertex or vertex ID
3017     #  @return True if succeed else raises an exception
3018     #  @ingroup l2_modif_add
3019     def SetNodeOnVertex(self, NodeID, Vertex):
3020         if ( isinstance( Vertex, geomBuilder.GEOM._objref_GEOM_Object)):
3021             VertexID = self.geompyD.GetSubShapeID( self.geom, Vertex )
3022         else:
3023             VertexID = Vertex
3024         try:
3025             self.editor.SetNodeOnVertex(NodeID, VertexID)
3026         except SALOME.SALOME_Exception as inst:
3027             raise ValueError(inst.details.text)
3028         return True
3029
3030
3031     ## @brief Stores the node position on an edge
3032     #  @param NodeID a node ID
3033     #  @param Edge an edge or edge ID
3034     #  @param paramOnEdge a parameter on the edge where the node is located
3035     #  @return True if succeed else raises an exception
3036     #  @ingroup l2_modif_add
3037     def SetNodeOnEdge(self, NodeID, Edge, paramOnEdge):
3038         if ( isinstance( Edge, geomBuilder.GEOM._objref_GEOM_Object)):
3039             EdgeID = self.geompyD.GetSubShapeID( self.geom, Edge )
3040         else:
3041             EdgeID = Edge
3042         try:
3043             self.editor.SetNodeOnEdge(NodeID, EdgeID, paramOnEdge)
3044         except SALOME.SALOME_Exception as inst:
3045             raise ValueError(inst.details.text)
3046         return True
3047
3048     ## @brief Stores node position on a face
3049     #  @param NodeID a node ID
3050     #  @param Face a face or face ID
3051     #  @param u U parameter on the face where the node is located
3052     #  @param v V parameter on the face where the node is located
3053     #  @return True if succeed else raises an exception
3054     #  @ingroup l2_modif_add
3055     def SetNodeOnFace(self, NodeID, Face, u, v):
3056         if ( isinstance( Face, geomBuilder.GEOM._objref_GEOM_Object)):
3057             FaceID = self.geompyD.GetSubShapeID( self.geom, Face )
3058         else:
3059             FaceID = Face
3060         try:
3061             self.editor.SetNodeOnFace(NodeID, FaceID, u, v)
3062         except SALOME.SALOME_Exception as inst:
3063             raise ValueError(inst.details.text)
3064         return True
3065
3066     ## @brief Binds a node to a solid
3067     #  @param NodeID a node ID
3068     #  @param Solid  a solid or solid ID
3069     #  @return True if succeed else raises an exception
3070     #  @ingroup l2_modif_add
3071     def SetNodeInVolume(self, NodeID, Solid):
3072         if ( isinstance( Solid, geomBuilder.GEOM._objref_GEOM_Object)):
3073             SolidID = self.geompyD.GetSubShapeID( self.geom, Solid )
3074         else:
3075             SolidID = Solid
3076         try:
3077             self.editor.SetNodeInVolume(NodeID, SolidID)
3078         except SALOME.SALOME_Exception as inst:
3079             raise ValueError(inst.details.text)
3080         return True
3081
3082     ## @brief Bind an element to a shape
3083     #  @param ElementID an element ID
3084     #  @param Shape a shape or shape ID
3085     #  @return True if succeed else raises an exception
3086     #  @ingroup l2_modif_add
3087     def SetMeshElementOnShape(self, ElementID, Shape):
3088         if ( isinstance( Shape, geomBuilder.GEOM._objref_GEOM_Object)):
3089             ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
3090         else:
3091             ShapeID = Shape
3092         try:
3093             self.editor.SetMeshElementOnShape(ElementID, ShapeID)
3094         except SALOME.SALOME_Exception as inst:
3095             raise ValueError(inst.details.text)
3096         return True
3097
3098
3099     ## Move the node with the given id
3100     #  @param NodeID the id of the node
3101     #  @param x  a new X coordinate
3102     #  @param y  a new Y coordinate
3103     #  @param z  a new Z coordinate
3104     #  @return True if succeed else False
3105     #  @ingroup l2_modif_edit
3106     def MoveNode(self, NodeID, x, y, z):
3107         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3108         if hasVars: self.mesh.SetParameters(Parameters)
3109         return self.editor.MoveNode(NodeID, x, y, z)
3110
3111     ## Find the node closest to a point and moves it to a point location
3112     #  @param x  the X coordinate of a point
3113     #  @param y  the Y coordinate of a point
3114     #  @param z  the Z coordinate of a point
3115     #  @param NodeID if specified (>0), the node with this ID is moved,
3116     #  otherwise, the node closest to point (@a x,@a y,@a z) is moved
3117     #  @return the ID of a node
3118     #  @ingroup l2_modif_edit
3119     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
3120         x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
3121         if hasVars: self.mesh.SetParameters(Parameters)
3122         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
3123
3124     ## Find the node closest to a point
3125     #  @param x  the X coordinate of a point
3126     #  @param y  the Y coordinate of a point
3127     #  @param z  the Z coordinate of a point
3128     #  @return the ID of a node
3129     #  @ingroup l1_meshinfo
3130     def FindNodeClosestTo(self, x, y, z):
3131         #preview = self.mesh.GetMeshEditPreviewer()
3132         #return preview.MoveClosestNodeToPoint(x, y, z, -1)
3133         return self.editor.FindNodeClosestTo(x, y, z)
3134
3135     ## Find the elements where a point lays IN or ON
3136     #  @param x  the X coordinate of a point
3137     #  @param y  the Y coordinate of a point
3138     #  @param z  the Z coordinate of a point
3139     #  @param elementType type of elements to find; either of
3140     #         (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); SMESH.ALL type
3141     #         means elements of any type excluding nodes, discrete and 0D elements.
3142     #  @param meshPart a part of mesh (group, sub-mesh) to search within
3143     #  @return list of IDs of found elements
3144     #  @ingroup l1_meshinfo
3145     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
3146         if meshPart:
3147             return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
3148         else:
3149             return self.editor.FindElementsByPoint(x, y, z, elementType)
3150
3151     ## Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
3152     #  0-IN, 1-OUT, 2-ON, 3-UNKNOWN
3153     #  UNKNOWN state means that either mesh is wrong or the analysis fails.
3154     #  @ingroup l1_meshinfo
3155     def GetPointState(self, x, y, z):
3156         return self.editor.GetPointState(x, y, z)
3157
3158     ## Find the node closest to a point and moves it to a point location
3159     #  @param x  the X coordinate of a point
3160     #  @param y  the Y coordinate of a point
3161     #  @param z  the Z coordinate of a point
3162     #  @return the ID of a moved node
3163     #  @ingroup l2_modif_edit
3164     def MeshToPassThroughAPoint(self, x, y, z):
3165         return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
3166
3167     ## Replace two neighbour triangles sharing Node1-Node2 link
3168     #  with the triangles built on the same 4 nodes but having other common link.
3169     #  @param NodeID1  the ID of the first node
3170     #  @param NodeID2  the ID of the second node
3171     #  @return false if proper faces were not found
3172     #  @ingroup l2_modif_cutquadr
3173     def InverseDiag(self, NodeID1, NodeID2):
3174         return self.editor.InverseDiag(NodeID1, NodeID2)
3175
3176     ## Replace two neighbour triangles sharing Node1-Node2 link
3177     #  with a quadrangle built on the same 4 nodes.
3178     #  @param NodeID1  the ID of the first node
3179     #  @param NodeID2  the ID of the second node
3180     #  @return false if proper faces were not found
3181     #  @ingroup l2_modif_unitetri
3182     def DeleteDiag(self, NodeID1, NodeID2):
3183         return self.editor.DeleteDiag(NodeID1, NodeID2)
3184
3185     ## Reorient elements by ids
3186     #  @param IDsOfElements if undefined reorients all mesh elements
3187     #  @return True if succeed else False
3188     #  @ingroup l2_modif_changori
3189     def Reorient(self, IDsOfElements=None):
3190         if IDsOfElements == None:
3191             IDsOfElements = self.GetElementsId()
3192         return self.editor.Reorient(IDsOfElements)
3193
3194     ## Reorient all elements of the object
3195     #  @param theObject mesh, submesh or group
3196     #  @return True if succeed else False
3197     #  @ingroup l2_modif_changori
3198     def ReorientObject(self, theObject):
3199         if ( isinstance( theObject, Mesh )):
3200             theObject = theObject.GetMesh()
3201         return self.editor.ReorientObject(theObject)
3202
3203     ## Reorient faces contained in \a the2DObject.
3204     #  @param the2DObject is a mesh, sub-mesh, group or list of IDs of 2D elements
3205     #  @param theDirection is a desired direction of normal of \a theFace.
3206     #         It can be either a GEOM vector or a list of coordinates [x,y,z].
3207     #  @param theFaceOrPoint defines a face of \a the2DObject whose normal will be
3208     #         compared with theDirection. It can be either ID of face or a point
3209     #         by which the face will be found. The point can be given as either
3210     #         a GEOM vertex or a list of point coordinates.
3211     #  @return number of reoriented faces
3212     #  @ingroup l2_modif_changori
3213     def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
3214         unRegister = genObjUnRegister()
3215         # check the2DObject
3216         if isinstance( the2DObject, Mesh ):
3217             the2DObject = the2DObject.GetMesh()
3218         if isinstance( the2DObject, list ):
3219             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
3220             unRegister.set( the2DObject )
3221         # check theDirection
3222         if isinstance( theDirection, geomBuilder.GEOM._objref_GEOM_Object):
3223             theDirection = self.smeshpyD.GetDirStruct( theDirection )
3224         if isinstance( theDirection, list ):
3225             theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
3226         # prepare theFace and thePoint
3227         theFace = theFaceOrPoint
3228         thePoint = PointStruct(0,0,0)
3229         if isinstance( theFaceOrPoint, geomBuilder.GEOM._objref_GEOM_Object):
3230             thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
3231             theFace = -1
3232         if isinstance( theFaceOrPoint, list ):
3233             thePoint = PointStruct( *theFaceOrPoint )
3234             theFace = -1
3235         if isinstance( theFaceOrPoint, PointStruct ):
3236             thePoint = theFaceOrPoint
3237             theFace = -1
3238         return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
3239
3240     ## Reorient faces according to adjacent volumes.
3241     #  @param the2DObject is a mesh, sub-mesh, group or list of
3242     #         either IDs of faces or face groups.
3243     #  @param the3DObject is a mesh, sub-mesh, group or list of IDs of volumes.
3244     #  @param theOutsideNormal to orient faces to have their normals
3245     #         pointing either \a outside or \a inside the adjacent volumes.
3246     #  @return number of reoriented faces.
3247     #  @ingroup l2_modif_changori
3248     def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
3249         unRegister = genObjUnRegister()
3250         # check the2DObject
3251         if not isinstance( the2DObject, list ):
3252             the2DObject = [ the2DObject ]
3253         elif the2DObject and isinstance( the2DObject[0], int ):
3254             the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
3255             unRegister.set( the2DObject )
3256             the2DObject = [ the2DObject ]
3257         for i,obj2D in enumerate( the2DObject ):
3258             if isinstance( obj2D, Mesh ):
3259                 the2DObject[i] = obj2D.GetMesh()
3260             if isinstance( obj2D, list ):
3261                 the2DObject[i] = self.GetIDSource( obj2D, SMESH.FACE )
3262                 unRegister.set( the2DObject[i] )
3263         # check the3DObject
3264         if isinstance( the3DObject, Mesh ):
3265             the3DObject = the3DObject.GetMesh()
3266         if isinstance( the3DObject, list ):
3267             the3DObject = self.GetIDSource( the3DObject, SMESH.VOLUME )
3268             unRegister.set( the3DObject )
3269         return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal )
3270
3271     ## Fuse the neighbouring triangles into quadrangles.
3272     #  @param IDsOfElements The triangles to be fused.
3273     #  @param theCriterion  a numerical functor, in terms of enum SMESH.FunctorType, used to
3274     #          applied to possible quadrangles to choose a neighbour to fuse with.
3275     #          Type SMESH.FunctorType._items in the Python Console to see all items.
3276     #          Note that not all items correspond to numerical functors.
3277     #  @param MaxAngle      is the maximum angle between element normals at which the fusion
3278     #          is still performed; theMaxAngle is mesured in radians.
3279     #          Also it could be a name of variable which defines angle in degrees.
3280     #  @return TRUE in case of success, FALSE otherwise.
3281     #  @ingroup l2_modif_unitetri
3282     def TriToQuad(self, IDsOfElements, theCriterion, MaxAngle):
3283         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
3284         self.mesh.SetParameters(Parameters)
3285         if not IDsOfElements:
3286             IDsOfElements = self.GetElementsId()
3287         Functor = self.smeshpyD.GetFunctor(theCriterion)
3288         return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle)
3289
3290     ## Fuse the neighbouring triangles of the object into quadrangles
3291     #  @param theObject is mesh, submesh or group
3292     #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType,
3293     #          applied to possible quadrangles to choose a neighbour to fuse with.
3294     #          Type SMESH.FunctorType._items in the Python Console to see all items.
3295     #          Note that not all items correspond to numerical functors.
3296     #  @param MaxAngle   a max angle between element normals at which the fusion
3297     #          is still performed; theMaxAngle is mesured in radians.
3298     #  @return TRUE in case of success, FALSE otherwise.
3299     #  @ingroup l2_modif_unitetri
3300     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
3301         MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
3302         self.mesh.SetParameters(Parameters)
3303         if isinstance( theObject, Mesh ):
3304             theObject = theObject.GetMesh()
3305         Functor = self.smeshpyD.GetFunctor(theCriterion)
3306         return self.editor.TriToQuadObject(theObject, Functor, MaxAngle)
3307
3308     ## Split quadrangles into triangles.
3309     #  @param IDsOfElements the faces to be splitted.
3310     #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
3311     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
3312     #         value, then quadrangles will be split by the smallest diagonal.
3313     #         Type SMESH.FunctorType._items in the Python Console to see all items.
3314     #         Note that not all items correspond to numerical functors.
3315     #  @return TRUE in case of success, FALSE otherwise.
3316     #  @ingroup l2_modif_cutquadr
3317     def QuadToTri (self, IDsOfElements, theCriterion = None):
3318         if IDsOfElements == []:
3319             IDsOfElements = self.GetElementsId()
3320         if theCriterion is None:
3321             theCriterion = FT_MaxElementLength2D
3322         Functor = self.smeshpyD.GetFunctor(theCriterion)
3323         return self.editor.QuadToTri(IDsOfElements, Functor)
3324
3325     ## Split quadrangles into triangles.
3326     #  @param theObject the object from which the list of elements is taken,
3327     #         this is mesh, submesh or group
3328     #  @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to
3329     #         choose a diagonal for splitting. If @a theCriterion is None, which is a default
3330     #         value, then quadrangles will be split by the smallest diagonal.
3331     #         Type SMESH.FunctorType._items in the Python Console to see all items.
3332     #         Note that not all items correspond to numerical functors.
3333     #  @return TRUE in case of success, FALSE otherwise.
3334     #  @ingroup l2_modif_cutquadr
3335     def QuadToTriObject (self, theObject, theCriterion = None):
3336         if ( isinstance( theObject, Mesh )):
3337             theObject = theObject.GetMesh()
3338         if theCriterion is None:
3339             theCriterion = FT_MaxElementLength2D
3340         Functor = self.smeshpyD.GetFunctor(theCriterion)
3341         return self.editor.QuadToTriObject(theObject, Functor)
3342
3343     ## Split each of given quadrangles into 4 triangles. A node is added at the center of
3344     #  a quadrangle.
3345     #  @param theElements the faces to be splitted. This can be either mesh, sub-mesh,
3346     #         group or a list of face IDs. By default all quadrangles are split
3347     #  @ingroup l2_modif_cutquadr
3348     def QuadTo4Tri (self, theElements=[]):
3349         unRegister = genObjUnRegister()
3350         if isinstance( theElements, Mesh ):
3351             theElements = theElements.mesh
3352         elif not theElements:
3353             theElements = self.mesh
3354         elif isinstance( theElements, list ):
3355             theElements = self.GetIDSource( theElements, SMESH.FACE )
3356             unRegister.set( theElements )
3357         return self.editor.QuadTo4Tri( theElements )
3358
3359     ## Split quadrangles into triangles.
3360     #  @param IDsOfElements the faces to be splitted
3361     #  @param Diag13        is used to choose a diagonal for splitting.
3362     #  @return TRUE in case of success, FALSE otherwise.
3363     #  @ingroup l2_modif_cutquadr
3364     def SplitQuad (self, IDsOfElements, Diag13):
3365         if IDsOfElements == []:
3366             IDsOfElements = self.GetElementsId()
3367         return self.editor.SplitQuad(IDsOfElements, Diag13)
3368
3369     ## Split quadrangles into triangles.
3370     #  @param theObject the object from which the list of elements is taken,
3371     #         this is mesh, submesh or group
3372     #  @param Diag13    is used to choose a diagonal for splitting.
3373     #  @return TRUE in case of success, FALSE otherwise.
3374     #  @ingroup l2_modif_cutquadr
3375     def SplitQuadObject (self, theObject, Diag13):
3376         if ( isinstance( theObject, Mesh )):
3377             theObject = theObject.GetMesh()
3378         return self.editor.SplitQuadObject(theObject, Diag13)
3379
3380     ## Find a better splitting of the given quadrangle.
3381     #  @param IDOfQuad   the ID of the quadrangle to be splitted.
3382     #  @param theCriterion  is a numerical functor, in terms of enum SMESH.FunctorType, used to
3383     #         choose a diagonal for splitting.
3384     #         Type SMESH.FunctorType._items in the Python Console to see all items.
3385     #         Note that not all items correspond to numerical functors.
3386     #  @return 1 if 1-3 diagonal is better, 2 if 2-4
3387     #          diagonal is better, 0 if error occurs.
3388     #  @ingroup l2_modif_cutquadr
3389     def BestSplit (self, IDOfQuad, theCriterion):
3390         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
3391
3392     ## Split volumic elements into tetrahedrons
3393     #  @param elems either a list of elements or a mesh or a group or a submesh or a filter
3394     #  @param method  flags passing splitting method:
3395     #         smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet.
3396     #         smesh.Hex_5Tet - to split the hexahedron into 5 tetrahedrons, etc.
3397     #  @ingroup l2_modif_cutquadr
3398     def SplitVolumesIntoTetra(self, elems, method=smeshBuilder.Hex_5Tet ):
3399         unRegister = genObjUnRegister()
3400         if isinstance( elems, Mesh ):
3401             elems = elems.GetMesh()
3402         if ( isinstance( elems, list )):
3403             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
3404             unRegister.set( elems )
3405         self.editor.SplitVolumesIntoTetra(elems, method)
3406         return
3407
3408     ## Split bi-quadratic elements into linear ones without creation of additional nodes:
3409     #   - bi-quadratic triangle will be split into 3 linear quadrangles;
3410     #   - bi-quadratic quadrangle will be split into 4 linear quadrangles;
3411     #   - tri-quadratic hexahedron will be split into 8 linear hexahedra.
3412     #   Quadratic elements of lower dimension  adjacent to the split bi-quadratic element
3413     #   will be split in order to keep the mesh conformal.
3414     #  @param elems - elements to split: sub-meshes, groups, filters or element IDs;
3415     #         if None (default), all bi-quadratic elements will be split
3416     #  @ingroup l2_modif_cutquadr
3417     def SplitBiQuadraticIntoLinear(self, elems=None):
3418         unRegister = genObjUnRegister()
3419         if elems and isinstance( elems, list ) and isinstance( elems[0], int ):
3420             elems = self.editor.MakeIDSource(elems, SMESH.ALL)
3421             unRegister.set( elems )
3422         if elems is None:
3423             elems = [ self.GetMesh() ]
3424         if isinstance( elems, Mesh ):
3425             elems = [ elems.GetMesh() ]
3426         if not isinstance( elems, list ):
3427             elems = [elems]
3428         self.editor.SplitBiQuadraticIntoLinear( elems )
3429
3430     ## Split hexahedra into prisms
3431     #  @param elems either a list of elements or a mesh or a group or a submesh or a filter
3432     #  @param startHexPoint a point used to find a hexahedron for which @a facetNormal
3433     #         gives a normal vector defining facets to split into triangles.
3434     #         @a startHexPoint can be either a triple of coordinates or a vertex.
3435     #  @param facetNormal a normal to a facet to split into triangles of a
3436     #         hexahedron found by @a startHexPoint.
3437     #         @a facetNormal can be either a triple of coordinates or an edge.
3438     #  @param method  flags passing splitting method: smesh.Hex_2Prisms, smesh.Hex_4Prisms.
3439     #         smesh.Hex_2Prisms - to split the hexahedron into 2 prisms, etc.
3440     #  @param allDomains if @c False, only hexahedra adjacent to one closest
3441     #         to @a startHexPoint are split, else @a startHexPoint
3442     #         is used to find the facet to split in all domains present in @a elems.
3443     #  @ingroup l2_modif_cutquadr
3444     def SplitHexahedraIntoPrisms(self, elems, startHexPoint, facetNormal,
3445                                  method=smeshBuilder.Hex_2Prisms, allDomains=False ):
3446         # IDSource
3447         unRegister = genObjUnRegister()
3448         if isinstance( elems, Mesh ):
3449             elems = elems.GetMesh()
3450         if ( isinstance( elems, list )):
3451             elems = self.editor.MakeIDSource(elems, SMESH.VOLUME)
3452             unRegister.set( elems )
3453             pass
3454         # axis
3455         if isinstance( startHexPoint, geomBuilder.GEOM._objref_GEOM_Object):
3456             startHexPoint = self.smeshpyD.GetPointStruct( startHexPoint )
3457         elif isinstance( startHexPoint, list ):
3458             startHexPoint = SMESH.PointStruct( startHexPoint[0],
3459                                                startHexPoint[1],
3460                                                startHexPoint[2])
3461         if isinstance( facetNormal, geomBuilder.GEOM._objref_GEOM_Object):
3462             facetNormal = self.smeshpyD.GetDirStruct( facetNormal )
3463         elif isinstance( facetNormal, list ):
3464             facetNormal = self.smeshpyD.MakeDirStruct( facetNormal[0],
3465                                                        facetNormal[1],
3466                                                        facetNormal[2])
3467         self.mesh.SetParameters( startHexPoint.parameters + facetNormal.PS.parameters )
3468
3469         self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains)
3470
3471     ## Split quadrangle faces near triangular facets of volumes
3472     #
3473     #  @ingroup l2_modif_cutquadr
3474     def SplitQuadsNearTriangularFacets(self):
3475         faces_array = self.GetElementsByType(SMESH.FACE)
3476         for face_id in faces_array:
3477             if self.GetElemNbNodes(face_id) == 4: # quadrangle
3478                 quad_nodes = self.mesh.GetElemNodes(face_id)
3479                 node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
3480                 isVolumeFound = False
3481                 for node1_elem in node1_elems:
3482                     if not isVolumeFound:
3483                         if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
3484                             nb_nodes = self.GetElemNbNodes(node1_elem)
3485                             if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
3486                                 volume_elem = node1_elem
3487                                 volume_nodes = self.mesh.GetElemNodes(volume_elem)
3488                                 if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
3489                                     if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
3490                                         isVolumeFound = True
3491                                         if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
3492                                             self.SplitQuad([face_id], False) # diagonal 2-4
3493                                     elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
3494                                         isVolumeFound = True
3495                                         self.SplitQuad([face_id], True) # diagonal 1-3
3496                                 elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
3497                                     if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
3498                                         isVolumeFound = True
3499                                         self.SplitQuad([face_id], True) # diagonal 1-3
3500
3501     ## @brief Splits hexahedrons into tetrahedrons.
3502     #
3503     #  This operation uses pattern mapping functionality for splitting.
3504     #  @param theObject the object from which the list of hexahedrons is taken; this is mesh, submesh or group.
3505     #  @param theNode000,theNode001 within the range [0,7]; gives the orientation of the
3506     #         pattern relatively each hexahedron: the (0,0,0) key-point of the pattern
3507     #         will be mapped into <VAR>theNode000</VAR>-th node of each volume, the (0,0,1)
3508     #         key-point will be mapped into <VAR>theNode001</VAR>-th node of each volume.
3509     #         The (0,0,0) key-point of the used pattern corresponds to a non-split corner.
3510     #  @return TRUE in case of success, FALSE otherwise.
3511     #  @ingroup l2_modif_cutquadr
3512     def SplitHexaToTetras (self, theObject, theNode000, theNode001):
3513         # Pattern:     5.---------.6
3514         #              /|#*      /|
3515         #             / | #*    / |
3516         #            /  |  # * /  |
3517         #           /   |   # /*  |
3518         # (0,0,1) 4.---------.7 * |
3519         #          |#*  |1   | # *|
3520         #          | # *.----|---#.2
3521         #          |  #/ *   |   /
3522         #          |  /#  *  |  /
3523         #          | /   # * | /
3524         #          |/      #*|/
3525         # (0,0,0) 0.---------.3
3526         pattern_tetra = "!!! Nb of points: \n 8 \n\
3527         !!! Points: \n\
3528         0 0 0  !- 0 \n\
3529         0 1 0  !- 1 \n\
3530         1 1 0  !- 2 \n\
3531         1 0 0  !- 3 \n\
3532         0 0 1  !- 4 \n\
3533         0 1 1  !- 5 \n\
3534         1 1 1  !- 6 \n\
3535         1 0 1  !- 7 \n\
3536         !!! Indices of points of 6 tetras: \n\
3537         0 3 4 1 \n\
3538         7 4 3 1 \n\
3539         4 7 5 1 \n\
3540         6 2 5 7 \n\
3541         1 5 2 7 \n\
3542         2 3 1 7 \n"
3543
3544         pattern = self.smeshpyD.GetPattern()
3545         isDone  = pattern.LoadFromFile(pattern_tetra)
3546         if not isDone:
3547             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
3548             return isDone
3549
3550         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
3551         isDone = pattern.MakeMesh(self.mesh, False, False)
3552         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
3553
3554         # split quafrangle faces near triangular facets of volumes
3555         self.SplitQuadsNearTriangularFacets()
3556
3557         return isDone
3558
3559     ## @brief Split hexahedrons into prisms.
3560     #
3561     #  Uses the pattern mapping functionality for splitting.
3562     #  @param theObject the object (mesh, submesh or group) from where the list of hexahedrons is taken;
3563     #  @param theNode000,theNode001 (within the range [0,7]) gives the orientation of the
3564     #         pattern relatively each hexahedron: keypoint (0,0,0) of the pattern
3565     #         will be mapped into the <VAR>theNode000</VAR>-th node of each volume, keypoint (0,0,1)
3566     #         will be mapped into the <VAR>theNode001</VAR>-th node of each volume.
3567     #         Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
3568     #  @return TRUE in case of success, FALSE otherwise.
3569     #  @ingroup l2_modif_cutquadr
3570     def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
3571         # Pattern:     5.---------.6
3572         #              /|#       /|
3573         #             / | #     / |
3574         #            /  |  #   /  |
3575         #           /   |   # /   |
3576         # (0,0,1) 4.---------.7   |
3577         #          |    |    |    |
3578         #          |   1.----|----.2
3579         #          |   / *   |   /
3580         #          |  /   *  |  /
3581         #          | /     * | /
3582         #          |/       *|/
3583         # (0,0,0) 0.---------.3
3584         pattern_prism = "!!! Nb of points: \n 8 \n\
3585         !!! Points: \n\
3586         0 0 0  !- 0 \n\
3587         0 1 0  !- 1 \n\
3588         1 1 0  !- 2 \n\
3589         1 0 0  !- 3 \n\
3590         0 0 1  !- 4 \n\
3591         0 1 1  !- 5 \n\
3592         1 1 1  !- 6 \n\
3593         1 0 1  !- 7 \n\
3594         !!! Indices of points of 2 prisms: \n\
3595         0 1 3 4 5 7 \n\
3596         2 3 1 6 7 5 \n"
3597
3598         pattern = self.smeshpyD.GetPattern()
3599         isDone  = pattern.LoadFromFile(pattern_prism)
3600         if not isDone:
3601             print('Pattern.LoadFromFile :', pattern.GetErrorCode())
3602             return isDone
3603
3604         pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
3605         isDone = pattern.MakeMesh(self.mesh, False, False)
3606         if not isDone: print('Pattern.MakeMesh :', pattern.GetErrorCode())
3607
3608         # Split quafrangle faces near triangular facets of volumes
3609         self.SplitQuadsNearTriangularFacets()
3610
3611         return isDone
3612
3613     ## Smooth elements
3614     #  @param IDsOfElements the list if ids of elements to smooth
3615     #  @param IDsOfFixedNodes the list of ids of fixed nodes.
3616     #  Note that nodes built on edges and boundary nodes are always fixed.
3617     #  @param MaxNbOfIterations the maximum number of iterations
3618     #  @param MaxAspectRatio varies in range [1.0, inf]
3619     #  @param Method is either Laplacian (smesh.LAPLACIAN_SMOOTH)
3620     #         or Centroidal (smesh.CENTROIDAL_SMOOTH)
3621     #  @return TRUE in case of success, FALSE otherwise.
3622     #  @ingroup l2_modif_smooth
3623     def Smooth(self, IDsOfElements, IDsOfFixedNodes,
3624                MaxNbOfIterations, MaxAspectRatio, Method):
3625         if IDsOfElements == []:
3626             IDsOfElements = self.GetElementsId()
3627         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
3628         self.mesh.SetParameters(Parameters)
3629         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
3630                                   MaxNbOfIterations, MaxAspectRatio, Method)
3631
3632     ## Smooth elements which belong to the given object
3633     #  @param theObject the object to smooth
3634     #  @param IDsOfFixedNodes the list of ids of fixed nodes.
3635     #  Note that nodes built on edges and boundary nodes are always fixed.
3636     #  @param MaxNbOfIterations the maximum number of iterations
3637     #  @param MaxAspectRatio varies in range [1.0, inf]
3638     #  @param Method is either Laplacian (smesh.LAPLACIAN_SMOOTH)
3639     #         or Centroidal (smesh.CENTROIDAL_SMOOTH)
3640     #  @return TRUE in case of success, FALSE otherwise.
3641     #  @ingroup l2_modif_smooth
3642     def SmoothObject(self, theObject, IDsOfFixedNodes,
3643                      MaxNbOfIterations, MaxAspectRatio, Method):
3644         if ( isinstance( theObject, Mesh )):
3645             theObject = theObject.GetMesh()
3646         return self.editor.SmoothObject(theObject, IDsOfFixedNodes,
3647                                         MaxNbOfIterations, MaxAspectRatio, Method)
3648
3649     ## Parametrically smooth the given elements
3650     #  @param IDsOfElements the list if ids of elements to smooth
3651     #  @param IDsOfFixedNodes the list of ids of fixed nodes.
3652     #  Note that nodes built on edges and boundary nodes are always fixed.
3653     #  @param MaxNbOfIterations the maximum number of iterations
3654     #  @param MaxAspectRatio varies in range [1.0, inf]
3655     #  @param Method is either Laplacian (smesh.LAPLACIAN_SMOOTH)
3656     #         or Centroidal (smesh.CENTROIDAL_SMOOTH)
3657     #  @return TRUE in case of success, FALSE otherwise.
3658     #  @ingroup l2_modif_smooth
3659     def SmoothParametric(self, IDsOfElements, IDsOfFixedNodes,
3660                          MaxNbOfIterations, MaxAspectRatio, Method):
3661         if IDsOfElements == []:
3662             IDsOfElements = self.GetElementsId()
3663         MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
3664         self.mesh.SetParameters(Parameters)
3665         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
3666                                             MaxNbOfIterations, MaxAspectRatio, Method)
3667
3668     ## Parametrically smooth the elements which belong to the given object
3669     #  @param theObject the object to smooth
3670     #  @param IDsOfFixedNodes the list of ids of fixed nodes.
3671     #  Note that nodes built on edges and boundary nodes are always fixed.
3672     #  @param MaxNbOfIterations the maximum number of iterations
3673     #  @param MaxAspectRatio varies in range [1.0, inf]
3674     #  @param Method is either Laplacian (smesh.LAPLACIAN_SMOOTH)
3675     #         or Centroidal (smesh.CENTROIDAL_SMOOTH)
3676     #  @return TRUE in case of success, FALSE otherwise.
3677     #  @ingroup l2_modif_smooth
3678     def SmoothParametricObject(self, theObject, IDsOfFixedNodes,
3679                                MaxNbOfIterations, MaxAspectRatio, Method):
3680         if ( isinstance( theObject, Mesh )):
3681             theObject = theObject.GetMesh()
3682         return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes,
3683                                                   MaxNbOfIterations, MaxAspectRatio, Method)
3684
3685     ## Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing
3686     #  them with quadratic with the same id.
3687     #  @param theForce3d new node creation method:
3688     #         0 - the medium node lies at the geometrical entity from which the mesh element is built
3689     #         1 - the medium node lies at the middle of the line segments connecting two nodes of a mesh element
3690     #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
3691     #  @param theToBiQuad If True, converts the mesh to bi-quadratic
3692     #  @return SMESH.ComputeError which can hold a warning
3693     #  @ingroup l2_modif_tofromqu
3694     def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
3695         if isinstance( theSubMesh, Mesh ):
3696             theSubMesh = theSubMesh.mesh
3697         if theToBiQuad:
3698             self.editor.ConvertToBiQuadratic(theForce3d,theSubMesh)
3699         else:
3700             if theSubMesh:
3701                 self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
3702             else:
3703                 self.editor.ConvertToQuadratic(theForce3d)
3704         error = self.editor.GetLastError()
3705         if error and error.comment:
3706             print(error.comment)
3707         return error
3708
3709     ## Convert the mesh from quadratic to ordinary,
3710     #  deletes old quadratic elements, \n replacing
3711     #  them with ordinary mesh elements with the same id.
3712     #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
3713     #  @ingroup l2_modif_tofromqu
3714     def ConvertFromQuadratic(self, theSubMesh=None):
3715         if theSubMesh:
3716             self.editor.ConvertFromQuadraticObject(theSubMesh)
3717         else:
3718             return self.editor.ConvertFromQuadratic()
3719
3720     ## Create 2D mesh as skin on boundary faces of a 3D mesh
3721     #  @return TRUE if operation has been completed successfully, FALSE otherwise
3722     #  @ingroup l2_modif_add
3723     def Make2DMeshFrom3D(self):
3724         return self.editor.Make2DMeshFrom3D()
3725
3726     ## Create missing boundary elements
3727     #  @param elements - elements whose boundary is to be checked:
3728     #                    mesh, group, sub-mesh or list of elements
3729     #   if elements is mesh, it must be the mesh whose MakeBoundaryMesh() is called
3730     #  @param dimension - defines type of boundary elements to create, either of
3731     #                     { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
3732     #    SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells
3733     #  @param groupName - a name of group to store created boundary elements in,
3734     #                     "" means not to create the group
3735     #  @param meshName - a name of new mesh to store created boundary elements in,
3736     #                     "" means not to create the new mesh
3737     #  @param toCopyElements - if true, the checked elements will be copied into
3738     #     the new mesh else only boundary elements will be copied into the new mesh
3739     #  @param toCopyExistingBondary - if true, not only new but also pre-existing
3740     #     boundary elements will be copied into the new mesh
3741     #  @return tuple (mesh, group) where boundary elements were added to
3742     #  @ingroup l2_modif_add
3743     def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
3744                          toCopyElements=False, toCopyExistingBondary=False):
3745         unRegister = genObjUnRegister()
3746         if isinstance( elements, Mesh ):
3747             elements = elements.GetMesh()
3748         if ( isinstance( elements, list )):
3749             elemType = SMESH.ALL
3750             if elements: elemType = self.GetElementType( elements[0], iselem=True)
3751             elements = self.editor.MakeIDSource(elements, elemType)
3752             unRegister.set( elements )
3753         mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
3754                                                    toCopyElements,toCopyExistingBondary)
3755         if mesh: mesh = self.smeshpyD.Mesh(mesh)
3756         return mesh, group
3757
3758     ##
3759     # @brief Create missing boundary elements around either the whole mesh or
3760     #    groups of elements
3761     #  @param dimension - defines type of boundary elements to create, either of
3762     #                     { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D }
3763     #  @param groupName - a name of group to store all boundary elements in,
3764     #    "" means not to create the group
3765     #  @param meshName - a name of a new mesh, which is a copy of the initial
3766     #    mesh + created boundary elements; "" means not to create the new mesh
3767     #  @param toCopyAll - if true, the whole initial mesh will be copied into
3768     #    the new mesh else only boundary elements will be copied into the new mesh
3769     #  @param groups - groups of elements to make boundary around
3770     #  @retval tuple( long, mesh, groups )
3771     #                 long - number of added boundary elements
3772     #                 mesh - the mesh where elements were added to
3773     #                 group - the group of boundary elements or None
3774     #
3775     #  @ingroup l2_modif_add
3776     def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
3777                              toCopyAll=False, groups=[]):
3778         nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
3779                                                            toCopyAll,groups)
3780         if mesh: mesh = self.smeshpyD.Mesh(mesh)
3781         return nb, mesh, group
3782
3783     ## Renumber mesh nodes (Obsolete, does nothing)
3784     #  @ingroup l2_modif_renumber
3785     def RenumberNodes(self):
3786         self.editor.RenumberNodes()
3787
3788     ## Renumber mesh elements (Obsole, does nothing)
3789     #  @ingroup l2_modif_renumber
3790     def RenumberElements(self):
3791         self.editor.RenumberElements()
3792
3793     ## Private method converting \a arg into a list of SMESH_IdSource's
3794     def _getIdSourceList(self, arg, idType, unRegister):
3795         if arg and isinstance( arg, list ):
3796             if isinstance( arg[0], int ):
3797                 arg = self.GetIDSource( arg, idType )
3798                 unRegister.set( arg )
3799             elif isinstance( arg[0], Mesh ):
3800                 arg[0] = arg[0].GetMesh()
3801         elif isinstance( arg, Mesh ):
3802             arg = arg.GetMesh()
3803         if arg and isinstance( arg, SMESH._objref_SMESH_IDSource ):
3804             arg = [arg]
3805         return arg
3806
3807     ## Generate new elements by rotation of the given elements and nodes around the axis
3808     #  @param nodes - nodes to revolve: a list including ids, groups, sub-meshes or a mesh
3809     #  @param edges - edges to revolve: a list including ids, groups, sub-meshes or a mesh
3810     #  @param faces - faces to revolve: a list including ids, groups, sub-meshes or a mesh
3811     #  @param Axis the axis of rotation: AxisStruct, line (geom object) or [x,y,z,dx,dy,dz]
3812     #  @param AngleInRadians the angle of Rotation (in radians) or a name of variable
3813     #         which defines angle in degrees
3814     #  @param NbOfSteps the number of steps
3815     #  @param Tolerance tolerance
3816     #  @param MakeGroups forces the generation of new groups from existing ones
3817     #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
3818     #                    of all steps, else - size of each step
3819     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3820     #  @ingroup l2_modif_extrurev
3821     def RotationSweepObjects(self, nodes, edges, faces, Axis, AngleInRadians, NbOfSteps, Tolerance,
3822                              MakeGroups=False, TotalAngle=False):
3823         unRegister = genObjUnRegister()
3824         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
3825         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
3826         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
3827
3828         if isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object):
3829             Axis = self.smeshpyD.GetAxisStruct( Axis )
3830         if isinstance( Axis, list ):
3831             Axis = SMESH.AxisStruct( *Axis )
3832
3833         AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
3834         NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
3835         Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
3836         self.mesh.SetParameters(Parameters)
3837         if TotalAngle and NbOfSteps:
3838             AngleInRadians /= NbOfSteps
3839         return self.editor.RotationSweepObjects( nodes, edges, faces,
3840                                                  Axis, AngleInRadians,
3841                                                  NbOfSteps, Tolerance, MakeGroups)
3842
3843     ## Generate new elements by rotation of the elements around the axis
3844     #  @param IDsOfElements the list of ids of elements to sweep
3845     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
3846     #  @param AngleInRadians the angle of Rotation (in radians) or a name of variable which defines angle in degrees
3847     #  @param NbOfSteps the number of steps
3848     #  @param Tolerance tolerance
3849     #  @param MakeGroups forces the generation of new groups from existing ones
3850     #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
3851     #                    of all steps, else - size of each step
3852     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3853     #  @ingroup l2_modif_extrurev
3854     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
3855                       MakeGroups=False, TotalAngle=False):
3856         return self.RotationSweepObjects([], IDsOfElements, IDsOfElements, Axis,
3857                                          AngleInRadians, NbOfSteps, Tolerance,
3858                                          MakeGroups, TotalAngle)
3859
3860     ## Generate new elements by rotation of the elements of object around the axis
3861     #  @param theObject object which elements should be sweeped.
3862     #                   It can be a mesh, a sub mesh or a group.
3863     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
3864     #  @param AngleInRadians the angle of Rotation
3865     #  @param NbOfSteps number of steps
3866     #  @param Tolerance tolerance
3867     #  @param MakeGroups forces the generation of new groups from existing ones
3868     #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
3869     #                    of all steps, else - size of each step
3870     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3871     #  @ingroup l2_modif_extrurev
3872     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
3873                             MakeGroups=False, TotalAngle=False):
3874         return self.RotationSweepObjects( [], theObject, theObject, Axis,
3875                                           AngleInRadians, NbOfSteps, Tolerance,
3876                                           MakeGroups, TotalAngle )
3877
3878     ## Generate new elements by rotation of the elements of object around the axis
3879     #  @param theObject object which elements should be sweeped.
3880     #                   It can be a mesh, a sub mesh or a group.
3881     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
3882     #  @param AngleInRadians the angle of Rotation
3883     #  @param NbOfSteps number of steps
3884     #  @param Tolerance tolerance
3885     #  @param MakeGroups forces the generation of new groups from existing ones
3886     #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
3887     #                    of all steps, else - size of each step
3888     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3889     #  @ingroup l2_modif_extrurev
3890     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
3891                               MakeGroups=False, TotalAngle=False):
3892         return self.RotationSweepObjects([],theObject,[], Axis,
3893                                          AngleInRadians, NbOfSteps, Tolerance,
3894                                          MakeGroups, TotalAngle)
3895
3896     ## Generate new elements by rotation of the elements of object around the axis
3897     #  @param theObject object which elements should be sweeped.
3898     #                   It can be a mesh, a sub mesh or a group.
3899     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
3900     #  @param AngleInRadians the angle of Rotation
3901     #  @param NbOfSteps number of steps
3902     #  @param Tolerance tolerance
3903     #  @param MakeGroups forces the generation of new groups from existing ones
3904     #  @param TotalAngle gives meaning of AngleInRadians: if True then it is an angular size
3905     #                    of all steps, else - size of each step
3906     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3907     #  @ingroup l2_modif_extrurev
3908     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
3909                               MakeGroups=False, TotalAngle=False):
3910         return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians,
3911                                          NbOfSteps, Tolerance, MakeGroups, TotalAngle)
3912
3913     ## Generate new elements by extrusion of the given elements and nodes
3914     #  @param nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh
3915     #  @param edges edges to extrude: a list including ids, groups, sub-meshes or a mesh
3916     #  @param faces faces to extrude: a list including ids, groups, sub-meshes or a mesh
3917     #  @param StepVector vector or DirStruct or 3 vector components, defining
3918     #         the direction and value of extrusion for one step (the total extrusion
3919     #         length will be NbOfSteps * ||StepVector||)
3920     #  @param NbOfSteps the number of steps
3921     #  @param MakeGroups forces the generation of new groups from existing ones
3922     #  @param scaleFactors optional scale factors to apply during extrusion
3923     #  @param linearVariation if @c True, scaleFactors are spread over all @a scaleFactors,
3924     #         else scaleFactors[i] is applied to nodes at the i-th extrusion step
3925     #  @param basePoint optional scaling center; if not provided, a gravity center of
3926     #         nodes and elements being extruded is used as the scaling center.
3927     #         It can be either
3928     #         - a list of tree components of the point or
3929     #         - a node ID or
3930     #         - a GEOM point
3931     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3932     #  @ingroup l2_modif_extrurev
3933     #  @ref tui_extrusion example
3934     def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
3935                               scaleFactors=[], linearVariation=False, basePoint=[] ):
3936         unRegister = genObjUnRegister()
3937         nodes = self._getIdSourceList( nodes, SMESH.NODE, unRegister )
3938         edges = self._getIdSourceList( edges, SMESH.EDGE, unRegister )
3939         faces = self._getIdSourceList( faces, SMESH.FACE, unRegister )
3940
3941         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
3942             StepVector = self.smeshpyD.GetDirStruct(StepVector)
3943         if isinstance( StepVector, list ):
3944             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
3945
3946         if isinstance( basePoint, int):
3947             xyz = self.GetNodeXYZ( basePoint )
3948             if not xyz:
3949                 raise RuntimeError("Invalid node ID: %s" % basePoint)
3950             basePoint = xyz
3951         if isinstance( basePoint, geomBuilder.GEOM._objref_GEOM_Object ):
3952             basePoint = self.geompyD.PointCoordinates( basePoint )
3953
3954         NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
3955         Parameters = StepVector.PS.parameters + var_separator + Parameters
3956         self.mesh.SetParameters(Parameters)
3957
3958         return self.editor.ExtrusionSweepObjects( nodes, edges, faces,
3959                                                   StepVector, NbOfSteps,
3960                                                   scaleFactors, linearVariation, basePoint,
3961                                                   MakeGroups)
3962
3963
3964     ## Generate new elements by extrusion of the elements with given ids
3965     #  @param IDsOfElements the list of ids of elements or nodes for extrusion
3966     #  @param StepVector vector or DirStruct or 3 vector components, defining
3967     #         the direction and value of extrusion for one step (the total extrusion
3968     #         length will be NbOfSteps * ||StepVector||)
3969     #  @param NbOfSteps the number of steps
3970     #  @param MakeGroups forces the generation of new groups from existing ones
3971     #  @param IsNodes is True if elements with given ids are nodes
3972     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
3973     #  @ingroup l2_modif_extrurev
3974     #  @ref tui_extrusion example
3975     def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
3976         n,e,f = [],[],[]
3977         if IsNodes: n = IDsOfElements
3978         else      : e,f, = IDsOfElements,IDsOfElements
3979         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
3980
3981     ## Generate new elements by extrusion along the normal to a discretized surface or wire
3982     #  @param Elements elements to extrude - a list including ids, groups, sub-meshes or a mesh.
3983     #         Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
3984     #  @param StepSize length of one extrusion step (the total extrusion
3985     #         length will be \a NbOfSteps * \a StepSize ).
3986     #  @param NbOfSteps number of extrusion steps.
3987     #  @param ByAverageNormal if True each node is translated by \a StepSize
3988     #         along the average of the normal vectors to the faces sharing the node;
3989     #         else each node is translated along the same average normal till
3990     #         intersection with the plane got by translation of the face sharing
3991     #         the node along its own normal by \a StepSize.
3992     #  @param UseInputElemsOnly to use only \a Elements when computing extrusion direction
3993     #         for every node of \a Elements.
3994     #  @param MakeGroups forces generation of new groups from existing ones.
3995     #  @param Dim dimension of elements to extrude: 2 - faces or 1 - edges. Extrusion of edges
3996     #         is not yet implemented. This parameter is used if \a Elements contains
3997     #         both faces and edges, i.e. \a Elements is a Mesh.
3998     #  @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
3999     #          empty list otherwise.
4000     #  @ingroup l2_modif_extrurev
4001     #  @ref tui_extrusion example
4002     def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
4003                           ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
4004         unRegister = genObjUnRegister()
4005         if isinstance( Elements, Mesh ):
4006             Elements = [ Elements.GetMesh() ]
4007         if isinstance( Elements, list ):
4008             if not Elements:
4009                 raise RuntimeError("Elements empty!")
4010             if isinstance( Elements[0], int ):
4011                 Elements = self.GetIDSource( Elements, SMESH.ALL )
4012                 unRegister.set( Elements )
4013         if not isinstance( Elements, list ):
4014             Elements = [ Elements ]
4015         StepSize,NbOfSteps,Parameters,hasVars = ParseParameters(StepSize,NbOfSteps)
4016         self.mesh.SetParameters(Parameters)
4017         return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
4018                                              ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
4019
4020     ## Generate new elements by extrusion of the elements or nodes which belong to the object
4021     #  @param theObject the object whose elements or nodes should be processed.
4022     #                   It can be a mesh, a sub-mesh or a group.
4023     #  @param StepVector vector or DirStruct or 3 vector components, defining
4024     #         the direction and value of extrusion for one step (the total extrusion
4025     #         length will be NbOfSteps * ||StepVector||)
4026     #  @param NbOfSteps the number of steps
4027     #  @param MakeGroups forces the generation of new groups from existing ones
4028     #  @param IsNodes is True if elements to extrude are nodes
4029     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4030     #  @ingroup l2_modif_extrurev
4031     #  @ref tui_extrusion example
4032     def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
4033         n,e,f = [],[],[]
4034         if IsNodes: n    = theObject
4035         else      : e,f, = theObject,theObject
4036         return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
4037
4038     ## Generate new elements by extrusion of edges which belong to the object
4039     #  @param theObject object whose 1D elements should be processed.
4040     #                   It can be a mesh, a sub-mesh or a group.
4041     #  @param StepVector vector or DirStruct or 3 vector components, defining
4042     #         the direction and value of extrusion for one step (the total extrusion
4043     #         length will be NbOfSteps * ||StepVector||)
4044     #  @param NbOfSteps the number of steps
4045     #  @param MakeGroups to generate new groups from existing ones
4046     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4047     #  @ingroup l2_modif_extrurev
4048     #  @ref tui_extrusion example
4049     def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
4050         return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
4051
4052     ## Generate new elements by extrusion of faces which belong to the object
4053     #  @param theObject object whose 2D elements should be processed.
4054     #                   It can be a mesh, a sub-mesh or a group.
4055     #  @param StepVector vector or DirStruct or 3 vector components, defining
4056     #         the direction and value of extrusion for one step (the total extrusion
4057     #         length will be NbOfSteps * ||StepVector||)
4058     #  @param NbOfSteps the number of steps
4059     #  @param MakeGroups forces the generation of new groups from existing ones
4060     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4061     #  @ingroup l2_modif_extrurev
4062     #  @ref tui_extrusion example
4063     def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
4064         return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
4065
4066     ## Generate new elements by extrusion of the elements with given ids
4067     #  @param IDsOfElements is ids of elements
4068     #  @param StepVector vector or DirStruct or 3 vector components, defining
4069     #         the direction and value of extrusion for one step (the total extrusion
4070     #         length will be NbOfSteps * ||StepVector||)
4071     #  @param NbOfSteps the number of steps
4072     #  @param ExtrFlags sets flags for extrusion
4073     #  @param SewTolerance uses for comparing locations of nodes if flag
4074     #         EXTRUSION_FLAG_SEW is set
4075     #  @param MakeGroups forces the generation of new groups from existing ones
4076     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4077     #  @ingroup l2_modif_extrurev
4078     def AdvancedExtrusion(self, IDsOfElements, StepVector, NbOfSteps,
4079                           ExtrFlags, SewTolerance, MakeGroups=False):
4080         if isinstance( StepVector, geomBuilder.GEOM._objref_GEOM_Object):
4081             StepVector = self.smeshpyD.GetDirStruct(StepVector)
4082         if isinstance( StepVector, list ):
4083             StepVector = self.smeshpyD.MakeDirStruct(*StepVector)
4084         return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps,
4085                                              ExtrFlags, SewTolerance, MakeGroups)
4086
4087     ## Generate new elements by extrusion of the given elements and nodes along the path.
4088     #  The path of extrusion must be a meshed edge.
4089     #  @param Nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh
4090     #  @param Edges edges to extrude: a list including ids, groups, sub-meshes or a mesh
4091     #  @param Faces faces to extrude: a list including ids, groups, sub-meshes or a mesh
4092     #  @param PathMesh 1D mesh or 1D sub-mesh, along which proceeds the extrusion
4093     #  @param PathShape shape (edge) defines the sub-mesh of PathMesh if PathMesh
4094     #         contains not only path segments, else it can be None
4095     #  @param NodeStart the first or the last node on the path. Defines the direction of extrusion
4096     #  @param HasAngles allows the shape to be rotated around the path
4097     #                   to get the resulting mesh in a helical fashion
4098     #  @param Angles list of angles
4099     #  @param LinearVariation forces the computation of rotation angles as linear
4100     #                         variation of the given Angles along path steps
4101     #  @param HasRefPoint allows using the reference point
4102     #  @param RefPoint the point around which the shape is rotated (the mass center of the
4103     #         shape by default). The User can specify any point as the Reference Point.
4104     #  @param MakeGroups forces the generation of new groups from existing ones
4105     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
4106     #  @ingroup l2_modif_extrurev
4107     #  @ref tui_extrusion_along_path example
4108     def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
4109                                   NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
4110                                   HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
4111         unRegister = genObjUnRegister()
4112         Nodes = self._getIdSourceList( Nodes, SMESH.NODE, unRegister )
4113         Edges = self._getIdSourceList( Edges, SMESH.EDGE, unRegister )
4114         Faces = self._getIdSourceList( Faces, SMESH.FACE, unRegister )
4115
4116         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
4117             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
4118         if isinstance( RefPoint, list ):
4119             if not RefPoint: RefPoint = [0,0,0]
4120             RefPoint = SMESH.PointStruct( *RefPoint )
4121         if isinstance( PathMesh, Mesh ):
4122             PathMesh = PathMesh.GetMesh()
4123         Angles,AnglesParameters,hasVars = ParseAngles(Angles)
4124         Parameters = AnglesParameters + var_separator + RefPoint.parameters
4125         self.mesh.SetParameters(Parameters)
4126         return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces,
4127                                                      PathMesh, PathShape, NodeStart,
4128                                                      HasAngles, Angles, LinearVariation,
4129                                                      HasRefPoint, RefPoint, MakeGroups)
4130
4131     ## Generate new elements by extrusion of the given elements
4132     #  The path of extrusion must be a meshed edge.
4133     #  @param Base mesh or group, or sub-mesh, or list of ids of elements for extrusion
4134     #  @param Path - 1D mesh or 1D sub-mesh, along which proceeds the extrusion
4135     #  @param NodeStart the start node from Path. Defines the direction of extrusion
4136     #  @param HasAngles allows the shape to be rotated around the path
4137     #                   to get the resulting mesh in a helical fashion
4138     #  @param Angles list of angles in radians
4139     #  @param LinearVariation forces the computation of rotation angles as linear
4140     #                         variation of the given Angles along path steps
4141     #  @param HasRefPoint allows using the reference point
4142     #  @param RefPoint the point around which the elements are rotated (the mass
4143     #         center of the elements by default).
4144     #         The User can specify any point as the Reference Point.
4145     #         RefPoint can be either GEOM Vertex, [x,y,z] or SMESH.PointStruct
4146     #  @param MakeGroups forces the generation of new groups from existing ones
4147     #  @param ElemType type of elements for extrusion (if param Base is a mesh)
4148     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
4149     #          only SMESH::Extrusion_Error otherwise
4150     #  @ingroup l2_modif_extrurev
4151     #  @ref tui_extrusion_along_path example
4152     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
4153                             HasAngles=False, Angles=[], LinearVariation=False,
4154                             HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
4155                             ElemType=SMESH.FACE):
4156         n,e,f = [],[],[]
4157         if ElemType == SMESH.NODE: n = Base
4158         if ElemType == SMESH.EDGE: e = Base
4159         if ElemType == SMESH.FACE: f = Base
4160         gr,er = self.ExtrusionAlongPathObjects(n,e,f, Path, None, NodeStart,
4161                                                HasAngles, Angles, LinearVariation,
4162                                                HasRefPoint, RefPoint, MakeGroups)
4163         if MakeGroups: return gr,er
4164         return er
4165
4166     ## Generate new elements by extrusion of the given elements
4167     #  The path of extrusion must be a meshed edge.
4168     #  @param IDsOfElements ids of elements
4169     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion
4170     #  @param PathShape shape(edge) defines the sub-mesh for the path
4171     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
4172     #  @param HasAngles allows the shape to be rotated around the path
4173     #                   to get the resulting mesh in a helical fashion
4174     #  @param Angles list of angles in radians
4175     #  @param HasRefPoint allows using the reference point
4176     #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
4177     #         The User can specify any point as the Reference Point.
4178     #  @param MakeGroups forces the generation of new groups from existing ones
4179     #  @param LinearVariation forces the computation of rotation angles as linear
4180     #                         variation of the given Angles along path steps
4181     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
4182     #          only SMESH::Extrusion_Error otherwise
4183     #  @ingroup l2_modif_extrurev
4184     #  @ref tui_extrusion_along_path example
4185     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
4186                            HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
4187                            MakeGroups=False, LinearVariation=False):
4188         n,e,f = [],IDsOfElements,IDsOfElements
4189         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
4190                                                NodeStart, HasAngles, Angles,
4191                                                LinearVariation,
4192                                                HasRefPoint, RefPoint, MakeGroups)
4193         if MakeGroups: return gr,er
4194         return er
4195
4196     ## Generate new elements by extrusion of the elements which belong to the object
4197     #  The path of extrusion must be a meshed edge.
4198     #  @param theObject the object whose elements should be processed.
4199     #                   It can be a mesh, a sub-mesh or a group.
4200     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
4201     #  @param PathShape shape(edge) defines the sub-mesh for the path
4202     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
4203     #  @param HasAngles allows the shape to be rotated around the path
4204     #                   to get the resulting mesh in a helical fashion
4205     #  @param Angles list of angles
4206     #  @param HasRefPoint allows using the reference point
4207     #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
4208     #         The User can specify any point as the Reference Point.
4209     #  @param MakeGroups forces the generation of new groups from existing ones
4210     #  @param LinearVariation forces the computation of rotation angles as linear
4211     #                         variation of the given Angles along path steps
4212     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
4213     #          only SMESH::Extrusion_Error otherwise
4214     #  @ingroup l2_modif_extrurev
4215     #  @ref tui_extrusion_along_path example
4216     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
4217                                  HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
4218                                  MakeGroups=False, LinearVariation=False):
4219         n,e,f = [],theObject,theObject
4220         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
4221                                                HasAngles, Angles, LinearVariation,
4222                                                HasRefPoint, RefPoint, MakeGroups)
4223         if MakeGroups: return gr,er
4224         return er
4225
4226     ## Generate new elements by extrusion of mesh segments which belong to the object
4227     #  The path of extrusion must be a meshed edge.
4228     #  @param theObject the object whose 1D elements should be processed.
4229     #                   It can be a mesh, a sub-mesh or a group.
4230     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
4231     #  @param PathShape shape(edge) defines the sub-mesh for the path
4232     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
4233     #  @param HasAngles allows the shape to be rotated around the path
4234     #                   to get the resulting mesh in a helical fashion
4235     #  @param Angles list of angles
4236     #  @param HasRefPoint allows using the reference point
4237     #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
4238     #         The User can specify any point as the Reference Point.
4239     #  @param MakeGroups forces the generation of new groups from existing ones
4240     #  @param LinearVariation forces the computation of rotation angles as linear
4241     #                         variation of the given Angles along path steps
4242     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
4243     #          only SMESH::Extrusion_Error otherwise
4244     #  @ingroup l2_modif_extrurev
4245     #  @ref tui_extrusion_along_path example
4246     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
4247                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
4248                                    MakeGroups=False, LinearVariation=False):
4249         n,e,f = [],theObject,[]
4250         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
4251                                                HasAngles, Angles, LinearVariation,
4252                                                HasRefPoint, RefPoint, MakeGroups)
4253         if MakeGroups: return gr,er
4254         return er
4255
4256     ## Generate new elements by extrusion of faces which belong to the object
4257     #  The path of extrusion must be a meshed edge.
4258     #  @param theObject the object whose 2D elements should be processed.
4259     #                   It can be a mesh, a sub-mesh or a group.
4260     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
4261     #  @param PathShape shape(edge) defines the sub-mesh for the path
4262     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
4263     #  @param HasAngles allows the shape to be rotated around the path
4264     #                   to get the resulting mesh in a helical fashion
4265     #  @param Angles list of angles
4266     #  @param HasRefPoint allows using the reference point
4267     #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
4268     #         The User can specify any point as the Reference Point.
4269     #  @param MakeGroups forces the generation of new groups from existing ones
4270     #  @param LinearVariation forces the computation of rotation angles as linear
4271     #                         variation of the given Angles along path steps
4272     #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
4273     #          only SMESH::Extrusion_Error otherwise
4274     #  @ingroup l2_modif_extrurev
4275     #  @ref tui_extrusion_along_path example
4276     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
4277                                    HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
4278                                    MakeGroups=False, LinearVariation=False):
4279         n,e,f = [],[],theObject
4280         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
4281                                                HasAngles, Angles, LinearVariation,
4282                                                HasRefPoint, RefPoint, MakeGroups)
4283         if MakeGroups: return gr,er
4284         return er
4285
4286     ## Create a symmetrical copy of mesh elements
4287     #  @param IDsOfElements list of elements ids
4288     #  @param Mirror is AxisStruct or geom object(point, line, plane)
4289     #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
4290     #         If the Mirror is a geom object this parameter is unnecessary
4291     #  @param Copy allows to copy element (Copy is 1) or to replace with its mirroring (Copy is 0)
4292     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4293     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4294     #  @ingroup l2_modif_trsf
4295     def Mirror(self, IDsOfElements, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
4296         if IDsOfElements == []:
4297             IDsOfElements = self.GetElementsId()
4298         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
4299             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
4300             theMirrorType = Mirror._mirrorType
4301         else:
4302             self.mesh.SetParameters(Mirror.parameters)
4303         if Copy and MakeGroups:
4304             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
4305         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
4306         return []
4307
4308     ## Create a new mesh by a symmetrical copy of mesh elements
4309     #  @param IDsOfElements the list of elements ids
4310     #  @param Mirror is AxisStruct or geom object (point, line, plane)
4311     #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
4312     #         If the Mirror is a geom object this parameter is unnecessary
4313     #  @param MakeGroups to generate new groups from existing ones
4314     #  @param NewMeshName a name of the new mesh to create
4315     #  @return instance of Mesh class
4316     #  @ingroup l2_modif_trsf
4317     def MirrorMakeMesh(self, IDsOfElements, Mirror, theMirrorType=0, MakeGroups=0, NewMeshName=""):
4318         if IDsOfElements == []:
4319             IDsOfElements = self.GetElementsId()
4320         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
4321             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
4322             theMirrorType = Mirror._mirrorType
4323         else:
4324             self.mesh.SetParameters(Mirror.parameters)
4325         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
4326                                           MakeGroups, NewMeshName)
4327         return Mesh(self.smeshpyD,self.geompyD,mesh)
4328
4329     ## Create a symmetrical copy of the object
4330     #  @param theObject mesh, submesh or group
4331     #  @param Mirror AxisStruct or geom object (point, line, plane)
4332     #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
4333     #         If the Mirror is a geom object this parameter is unnecessary
4334     #  @param Copy allows copying the element (Copy is 1) or replacing it with its mirror (Copy is 0)
4335     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4336     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4337     #  @ingroup l2_modif_trsf
4338     def MirrorObject (self, theObject, Mirror, theMirrorType=None, Copy=0, MakeGroups=False):
4339         if ( isinstance( theObject, Mesh )):
4340             theObject = theObject.GetMesh()
4341         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
4342             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
4343             theMirrorType = Mirror._mirrorType
4344         else:
4345             self.mesh.SetParameters(Mirror.parameters)
4346         if Copy and MakeGroups:
4347             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
4348         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
4349         return []
4350
4351     ## Create a new mesh by a symmetrical copy of the object
4352     #  @param theObject mesh, submesh or group
4353     #  @param Mirror AxisStruct or geom object (point, line, plane)
4354     #  @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE
4355     #         If the Mirror is a geom object this parameter is unnecessary
4356     #  @param MakeGroups forces the generation of new groups from existing ones
4357     #  @param NewMeshName the name of the new mesh to create
4358     #  @return instance of Mesh class
4359     #  @ingroup l2_modif_trsf
4360     def MirrorObjectMakeMesh (self, theObject, Mirror, theMirrorType=0,MakeGroups=0,NewMeshName=""):
4361         if ( isinstance( theObject, Mesh )):
4362             theObject = theObject.GetMesh()
4363         if ( isinstance( Mirror, geomBuilder.GEOM._objref_GEOM_Object)):
4364             Mirror        = self.smeshpyD.GetAxisStruct(Mirror)
4365             theMirrorType = Mirror._mirrorType
4366         else:
4367             self.mesh.SetParameters(Mirror.parameters)
4368         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
4369                                                 MakeGroups, NewMeshName)
4370         return Mesh( self.smeshpyD,self.geompyD,mesh )
4371
4372     ## Translate the elements
4373     #  @param IDsOfElements list of elements ids
4374     #  @param Vector the direction of translation (DirStruct or vector or 3 vector components)
4375     #  @param Copy allows copying the translated elements
4376     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4377     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4378     #  @ingroup l2_modif_trsf
4379     def Translate(self, IDsOfElements, Vector, Copy, MakeGroups=False):
4380         if IDsOfElements == []:
4381             IDsOfElements = self.GetElementsId()
4382         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
4383             Vector = self.smeshpyD.GetDirStruct(Vector)
4384         if isinstance( Vector, list ):
4385             Vector = self.smeshpyD.MakeDirStruct(*Vector)
4386         self.mesh.SetParameters(Vector.PS.parameters)
4387         if Copy and MakeGroups:
4388             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
4389         self.editor.Translate(IDsOfElements, Vector, Copy)
4390         return []
4391
4392     ## Create a new mesh of translated elements
4393     #  @param IDsOfElements list of elements ids
4394     #  @param Vector the direction of translation (DirStruct or vector or 3 vector components)
4395     #  @param MakeGroups forces the generation of new groups from existing ones
4396     #  @param NewMeshName the name of the newly created mesh
4397     #  @return instance of Mesh class
4398     #  @ingroup l2_modif_trsf
4399     def TranslateMakeMesh(self, IDsOfElements, Vector, MakeGroups=False, NewMeshName=""):
4400         if IDsOfElements == []:
4401             IDsOfElements = self.GetElementsId()
4402         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
4403             Vector = self.smeshpyD.GetDirStruct(Vector)
4404         if isinstance( Vector, list ):
4405             Vector = self.smeshpyD.MakeDirStruct(*Vector)
4406         self.mesh.SetParameters(Vector.PS.parameters)
4407         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
4408         return Mesh ( self.smeshpyD, self.geompyD, mesh )
4409
4410     ## Translate the object
4411     #  @param theObject the object to translate (mesh, submesh, or group)
4412     #  @param Vector direction of translation (DirStruct or geom vector or 3 vector components)
4413     #  @param Copy allows copying the translated elements
4414     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4415     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4416     #  @ingroup l2_modif_trsf
4417     def TranslateObject(self, theObject, Vector, Copy, MakeGroups=False):
4418         if ( isinstance( theObject, Mesh )):
4419             theObject = theObject.GetMesh()
4420         if ( isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object)):
4421             Vector = self.smeshpyD.GetDirStruct(Vector)
4422         if isinstance( Vector, list ):
4423             Vector = self.smeshpyD.MakeDirStruct(*Vector)
4424         self.mesh.SetParameters(Vector.PS.parameters)
4425         if Copy and MakeGroups:
4426             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
4427         self.editor.TranslateObject(theObject, Vector, Copy)
4428         return []
4429
4430     ## Create a new mesh from the translated object
4431     #  @param theObject the object to translate (mesh, submesh, or group)
4432     #  @param Vector the direction of translation (DirStruct or geom vector or 3 vector components)
4433     #  @param MakeGroups forces the generation of new groups from existing ones
4434     #  @param NewMeshName the name of the newly created mesh
4435     #  @return instance of Mesh class
4436     #  @ingroup l2_modif_trsf
4437     def TranslateObjectMakeMesh(self, theObject, Vector, MakeGroups=False, NewMeshName=""):
4438         if isinstance( theObject, Mesh ):
4439             theObject = theObject.GetMesh()
4440         if isinstance( Vector, geomBuilder.GEOM._objref_GEOM_Object ):
4441             Vector = self.smeshpyD.GetDirStruct(Vector)
4442         if isinstance( Vector, list ):
4443             Vector = self.smeshpyD.MakeDirStruct(*Vector)
4444         self.mesh.SetParameters(Vector.PS.parameters)
4445         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
4446         return Mesh( self.smeshpyD, self.geompyD, mesh )
4447
4448
4449
4450     ## Scale the object
4451     #  @param theObject - the object to translate (mesh, submesh, or group)
4452     #  @param thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates)
4453     #  @param theScaleFact - list of 1-3 scale factors for axises
4454     #  @param Copy - allows copying the translated elements
4455     #  @param MakeGroups - forces the generation of new groups from existing
4456     #                      ones (if Copy)
4457     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True,
4458     #          empty list otherwise
4459     def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
4460         unRegister = genObjUnRegister()
4461         if ( isinstance( theObject, Mesh )):
4462             theObject = theObject.GetMesh()
4463         if ( isinstance( theObject, list )):
4464             theObject = self.GetIDSource(theObject, SMESH.ALL)
4465             unRegister.set( theObject )
4466         if ( isinstance( thePoint, list )):
4467             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
4468         if ( isinstance( theScaleFact, float )):
4469             theScaleFact = [theScaleFact]
4470         if ( isinstance( theScaleFact, int )):
4471             theScaleFact = [ float(theScaleFact)]
4472
4473         self.mesh.SetParameters(thePoint.parameters)
4474
4475         if Copy and MakeGroups:
4476             return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
4477         self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
4478         return []
4479
4480     ## Create a new mesh from the translated object
4481     #  @param theObject - the object to translate (mesh, submesh, or group)
4482     #  @param thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates)
4483     #  @param theScaleFact - list of 1-3 scale factors for axises
4484     #  @param MakeGroups - forces the generation of new groups from existing ones
4485     #  @param NewMeshName - the name of the newly created mesh
4486     #  @return instance of Mesh class
4487     def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
4488         unRegister = genObjUnRegister()
4489         if (isinstance(theObject, Mesh)):
4490             theObject = theObject.GetMesh()
4491         if ( isinstance( theObject, list )):
4492             theObject = self.GetIDSource(theObject,SMESH.ALL)
4493             unRegister.set( theObject )
4494         if ( isinstance( thePoint, list )):
4495             thePoint = PointStruct( thePoint[0], thePoint[1], thePoint[2] )
4496         if ( isinstance( theScaleFact, float )):
4497             theScaleFact = [theScaleFact]
4498         if ( isinstance( theScaleFact, int )):
4499             theScaleFact = [ float(theScaleFact)]
4500
4501         self.mesh.SetParameters(thePoint.parameters)
4502         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
4503                                          MakeGroups, NewMeshName)
4504         return Mesh( self.smeshpyD, self.geompyD, mesh )
4505
4506
4507
4508     ## Rotate the elements
4509     #  @param IDsOfElements list of elements ids
4510     #  @param Axis the axis of rotation (AxisStruct or geom line)
4511     #  @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees
4512     #  @param Copy allows copying the rotated elements
4513     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4514     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4515     #  @ingroup l2_modif_trsf
4516     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
4517         if IDsOfElements == []:
4518             IDsOfElements = self.GetElementsId()
4519         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
4520             Axis = self.smeshpyD.GetAxisStruct(Axis)
4521         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
4522         Parameters = Axis.parameters + var_separator + Parameters
4523         self.mesh.SetParameters(Parameters)
4524         if Copy and MakeGroups:
4525             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
4526         self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy)
4527         return []
4528
4529     ## Create a new mesh of rotated elements
4530     #  @param IDsOfElements list of element ids
4531     #  @param Axis the axis of rotation (AxisStruct or geom line)
4532     #  @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees
4533     #  @param MakeGroups forces the generation of new groups from existing ones
4534     #  @param NewMeshName the name of the newly created mesh
4535     #  @return instance of Mesh class
4536     #  @ingroup l2_modif_trsf
4537     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
4538         if IDsOfElements == []:
4539             IDsOfElements = self.GetElementsId()
4540         if ( isinstance( Axis, geomBuilder.GEOM._objref_GEOM_Object)):
4541             Axis = self.smeshpyD.GetAxisStruct(Axis)
4542         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
4543         Parameters = Axis.parameters + var_separator + Parameters
4544         self.mesh.SetParameters(Parameters)
4545         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
4546                                           MakeGroups, NewMeshName)
4547         return Mesh( self.smeshpyD, self.geompyD, mesh )
4548
4549     ## Rotate the object
4550     #  @param theObject the object to rotate( mesh, submesh, or group)
4551     #  @param Axis the axis of rotation (AxisStruct or geom line)
4552     #  @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees
4553     #  @param Copy allows copying the rotated elements
4554     #  @param MakeGroups forces the generation of new groups from existing ones (if Copy)
4555     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
4556     #  @ingroup l2_modif_trsf
4557     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
4558         if (isinstance(theObject, Mesh)):
4559             theObject = theObject.GetMesh()
4560         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
4561             Axis = self.smeshpyD.GetAxisStruct(Axis)
4562         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
4563         Parameters = Axis.parameters + ":" + Parameters
4564         self.mesh.SetParameters(Parameters)
4565         if Copy and MakeGroups:
4566             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
4567         self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy)
4568         return []
4569
4570     ## Create a new mesh from the rotated object
4571     #  @param theObject the object to rotate (mesh, submesh, or group)
4572     #  @param Axis the axis of rotation (AxisStruct or geom line)
4573     #  @param AngleInRadians the angle of rotation (in radians)  or a name of variable which defines angle in degrees
4574     #  @param MakeGroups forces the generation of new groups from existing ones
4575     #  @param NewMeshName the name of the newly created mesh
4576     #  @return instance of Mesh class
4577     #  @ingroup l2_modif_trsf
4578     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
4579         if (isinstance( theObject, Mesh )):
4580             theObject = theObject.GetMesh()
4581         if (isinstance(Axis, geomBuilder.GEOM._objref_GEOM_Object)):
4582             Axis = self.smeshpyD.GetAxisStruct(Axis)
4583         AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
4584         Parameters = Axis.parameters + ":" + Parameters
4585         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
4586                                                        MakeGroups, NewMeshName)
4587         self.mesh.SetParameters(Parameters)
4588         return Mesh( self.smeshpyD, self.geompyD, mesh )
4589
4590     ## Find groups of adjacent nodes within Tolerance.
4591     #  @param Tolerance the value of tolerance
4592     #  @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
4593     #         corner and medium nodes in separate groups thus preventing
4594     #         their further merge.
4595     #  @return the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
4596     #  @ingroup l2_modif_trsf
4597     def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False):
4598         return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes )
4599
4600     ## Find groups of ajacent nodes within Tolerance.
4601     #  @param Tolerance the value of tolerance
4602     #  @param SubMeshOrGroup SubMesh, Group or Filter
4603     #  @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search
4604     #  @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
4605     #         corner and medium nodes in separate groups thus preventing
4606     #         their further merge.
4607     #  @return the list of groups of nodes IDs (e.g. [[1,12,13],[4,25]])
4608     #  @ingroup l2_modif_trsf
4609     def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance,
4610                                    exceptNodes=[], SeparateCornerAndMediumNodes=False):
4611         unRegister = genObjUnRegister()
4612         if (isinstance( SubMeshOrGroup, Mesh )):
4613             SubMeshOrGroup = SubMeshOrGroup.GetMesh()
4614         if not isinstance( exceptNodes, list ):
4615             exceptNodes = [ exceptNodes ]
4616         if exceptNodes and isinstance( exceptNodes[0], int ):
4617             exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE )]
4618             unRegister.set( exceptNodes )
4619         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,
4620                                                         exceptNodes, SeparateCornerAndMediumNodes)
4621
4622     ## Merge nodes
4623     #  @param GroupsOfNodes a list of groups of nodes IDs for merging
4624     #         (e.g. [[1,12,13],[25,4]], then nodes 12, 13 and 4 will be removed and replaced
4625     #         by nodes 1 and 25 correspondingly in all elements and groups
4626     #  @param NodesToKeep nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
4627     #         If @a NodesToKeep does not include a node to keep for some group to merge,
4628     #         then the first node in the group is kept.
4629     #  @param AvoidMakingHoles prevent merging nodes which cause removal of elements becoming
4630     #         invalid
4631     #  @ingroup l2_modif_trsf
4632     def MergeNodes (self, GroupsOfNodes, NodesToKeep=[], AvoidMakingHoles=False):
4633         # NodesToKeep are converted to SMESH_IDSource in meshEditor.MergeNodes()
4634         self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles )
4635
4636     ## Find the elements built on the same nodes.
4637     #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
4638     #  @return the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]])
4639     #  @ingroup l2_modif_trsf
4640     def FindEqualElements (self, MeshOrSubMeshOrGroup=None):
4641         if not MeshOrSubMeshOrGroup:
4642             MeshOrSubMeshOrGroup=self.mesh
4643         elif isinstance( MeshOrSubMeshOrGroup, Mesh ):
4644             MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
4645         return self.editor.FindEqualElements( MeshOrSubMeshOrGroup )
4646
4647     ## Merge elements in each given group.
4648     #  @param GroupsOfElementsID a list of groups of elements IDs for merging
4649     #        (e.g. [[1,12,13],[25,4]], then elements 12, 13 and 4 will be removed and
4650     #        replaced by elements 1 and 25 in all groups)
4651     #  @ingroup l2_modif_trsf
4652     def MergeElements(self, GroupsOfElementsID):
4653         self.editor.MergeElements(GroupsOfElementsID)
4654
4655     ## Leave one element and remove all other elements built on the same nodes.
4656     #  @ingroup l2_modif_trsf
4657     def MergeEqualElements(self):
4658         self.editor.MergeEqualElements()
4659
4660     ## Return groups of FreeBorder's coincident within the given tolerance.
4661     #  @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average
4662     #         size of elements adjacent to free borders being compared is used.
4663     #  @return SMESH.CoincidentFreeBorders structure
4664     #  @ingroup l2_modif_trsf
4665     def FindCoincidentFreeBorders (self, tolerance=0.):
4666         return self.editor.FindCoincidentFreeBorders( tolerance )
4667
4668     ## Sew FreeBorder's of each group
4669     #  @param freeBorders either a SMESH.CoincidentFreeBorders structure or a list of lists
4670     #         where each enclosed list contains node IDs of a group of coincident free
4671     #         borders such that each consequent triple of IDs within a group describes
4672     #         a free border in a usual way: n1, n2, nLast - i.e. 1st node, 2nd node and
4673     #         last node of a border.
4674     #         For example [[1, 2, 10, 20, 21, 40], [11, 12, 15, 55, 54, 41]] describes two
4675     #         groups of coincident free borders, each group including two borders.
4676     #  @param createPolygons if @c True faces adjacent to free borders are converted to
4677     #         polygons if a node of opposite border falls on a face edge, else such
4678     #         faces are split into several ones.
4679     #  @param createPolyhedra if @c True volumes adjacent to free borders are converted to
4680     #         polyhedra if a node of opposite border falls on a volume edge, else such
4681     #         volumes, if any, remain intact and the mesh becomes non-conformal.
4682     #  @return a number of successfully sewed groups
4683     #  @ingroup l2_modif_trsf
4684     def SewCoincidentFreeBorders (self, freeBorders, createPolygons=False, createPolyhedra=False):
4685         if freeBorders and isinstance( freeBorders, list ):
4686             # construct SMESH.CoincidentFreeBorders
4687             if isinstance( freeBorders[0], int ):
4688                 freeBorders = [freeBorders]
4689             borders = []
4690             coincidentGroups = []
4691             for nodeList in freeBorders:
4692                 if not nodeList or len( nodeList ) % 3:
4693                     raise ValueError("Wrong number of nodes in this group: %s" % nodeList)
4694                 group = []
4695                 while nodeList:
4696                     group.append  ( SMESH.FreeBorderPart( len(borders), 0, 1, 2 ))
4697                     borders.append( SMESH.FreeBorder( nodeList[:3] ))
4698                     nodeList = nodeList[3:]
4699                     pass
4700                 coincidentGroups.append( group )
4701                 pass
4702             freeBorders = SMESH.CoincidentFreeBorders( borders, coincidentGroups )
4703
4704         return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra )
4705
4706     ## Sew free borders
4707     #  @return SMESH::Sew_Error
4708     #  @ingroup l2_modif_trsf
4709     def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
4710                         FirstNodeID2, SecondNodeID2, LastNodeID2,
4711                         CreatePolygons, CreatePolyedrs):
4712         return self.editor.SewFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
4713                                           FirstNodeID2, SecondNodeID2, LastNodeID2,
4714                                           CreatePolygons, CreatePolyedrs)
4715
4716     ## Sew conform free borders
4717     #  @return SMESH::Sew_Error
4718     #  @ingroup l2_modif_trsf
4719     def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1,
4720                                FirstNodeID2, SecondNodeID2):
4721         return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1,
4722                                                  FirstNodeID2, SecondNodeID2)
4723
4724     ## Sew border to side
4725     #  @return SMESH::Sew_Error
4726     #  @ingroup l2_modif_trsf
4727     def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
4728                          FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs):
4729         return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder,
4730                                            FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs)
4731
4732     ## Sew two sides of a mesh. The nodes belonging to Side1 are
4733     #  merged with the nodes of elements of Side2.
4734     #  The number of elements in theSide1 and in theSide2 must be
4735     #  equal and they should have similar nodal connectivity.
4736     #  The nodes to merge should belong to side borders and
4737     #  the first node should be linked to the second.
4738     #  @return SMESH::Sew_Error
4739     #  @ingroup l2_modif_trsf
4740     def SewSideElements (self, IDsOfSide1Elements, IDsOfSide2Elements,
4741                          NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
4742                          NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge):
4743         return self.editor.SewSideElements(IDsOfSide1Elements, IDsOfSide2Elements,
4744                                            NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge,
4745                                            NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge)
4746
4747     ## Set new nodes for the given element.
4748     #  @param ide the element id
4749     #  @param newIDs nodes ids
4750     #  @return If the number of nodes does not correspond to the type of element - return false
4751     #  @ingroup l2_modif_edit
4752     def ChangeElemNodes(self, ide, newIDs):
4753         return self.editor.ChangeElemNodes(ide, newIDs)
4754
4755     ## If during the last operation of MeshEditor some nodes were
4756     #  created, this method return the list of their IDs, \n
4757     #  if new nodes were not created - return empty list
4758     #  @return the list of integer values (can be empty)
4759     #  @ingroup l2_modif_add
4760     def GetLastCreatedNodes(self):
4761         return self.editor.GetLastCreatedNodes()
4762
4763     ## If during the last operation of MeshEditor some elements were
4764     #  created this method return the list of their IDs, \n
4765     #  if new elements were not created - return empty list
4766     #  @return the list of integer values (can be empty)
4767     #  @ingroup l2_modif_add
4768     def GetLastCreatedElems(self):
4769         return self.editor.GetLastCreatedElems()
4770
4771     ## Forget what nodes and elements were created by the last mesh edition operation
4772     #  @ingroup l2_modif_add
4773     def ClearLastCreated(self):
4774         self.editor.ClearLastCreated()
4775
4776     ## Create duplicates of given elements, i.e. create new elements based on the
4777     #  same nodes as the given ones.
4778     #  @param theElements - container of elements to duplicate. It can be a Mesh,
4779     #         sub-mesh, group, filter or a list of element IDs. If \a theElements is
4780     #         a Mesh, elements of highest dimension are duplicated
4781     #  @param theGroupName - a name of group to contain the generated elements.
4782     #                    If a group with such a name already exists, the new elements
4783     #                    are added to the existng group, else a new group is created.
4784     #                    If \a theGroupName is empty, new elements are not added
4785     #                    in any group.
4786     # @return a group where the new elements are added. None if theGroupName == "".
4787     #  @ingroup l2_modif_duplicat
4788     def DoubleElements(self, theElements, theGroupName=""):
4789         unRegister = genObjUnRegister()
4790         if isinstance( theElements, Mesh ):
4791             theElements = theElements.mesh
4792         elif isinstance( theElements, list ):
4793             theElements = self.GetIDSource( theElements, SMESH.ALL )
4794             unRegister.set( theElements )
4795         return self.editor.DoubleElements(theElements, theGroupName)
4796
4797     ## Create a hole in a mesh by doubling the nodes of some particular elements
4798     #  @param theNodes identifiers of nodes to be doubled
4799     #  @param theModifiedElems identifiers of elements to be updated by the new (doubled)
4800     #         nodes. If list of element identifiers is empty then nodes are doubled but
4801     #         they not assigned to elements
4802     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4803     #  @ingroup l2_modif_duplicat
4804     def DoubleNodes(self, theNodes, theModifiedElems):
4805         return self.editor.DoubleNodes(theNodes, theModifiedElems)
4806
4807     ## Create a hole in a mesh by doubling the nodes of some particular elements
4808     #  This method provided for convenience works as DoubleNodes() described above.
4809     #  @param theNodeId identifiers of node to be doubled
4810     #  @param theModifiedElems identifiers of elements to be updated
4811     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4812     #  @ingroup l2_modif_duplicat
4813     def DoubleNode(self, theNodeId, theModifiedElems):
4814         return self.editor.DoubleNode(theNodeId, theModifiedElems)
4815
4816     ## Create a hole in a mesh by doubling the nodes of some particular elements
4817     #  This method provided for convenience works as DoubleNodes() described above.
4818     #  @param theNodes group of nodes to be doubled
4819     #  @param theModifiedElems group of elements to be updated.
4820     #  @param theMakeGroup forces the generation of a group containing new nodes.
4821     #  @return TRUE or a created group if operation has been completed successfully,
4822     #          FALSE or None otherwise
4823     #  @ingroup l2_modif_duplicat
4824     def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
4825         if theMakeGroup:
4826             return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
4827         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
4828
4829     ## Create a hole in a mesh by doubling the nodes of some particular elements
4830     #  This method provided for convenience works as DoubleNodes() described above.
4831     #  @param theNodes list of groups of nodes to be doubled
4832     #  @param theModifiedElems list of groups of elements to be updated.
4833     #  @param theMakeGroup forces the generation of a group containing new nodes.
4834     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4835     #  @ingroup l2_modif_duplicat
4836     def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
4837         if theMakeGroup:
4838             return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
4839         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
4840
4841     ## Create a hole in a mesh by doubling the nodes of some particular elements
4842     #  @param theElems - the list of elements (edges or faces) to be replicated
4843     #         The nodes for duplication could be found from these elements
4844     #  @param theNodesNot - list of nodes to NOT replicate
4845     #  @param theAffectedElems - the list of elements (cells and edges) to which the
4846     #         replicated nodes should be associated to.
4847     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4848     #  @ingroup l2_modif_duplicat
4849     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
4850         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
4851
4852     ## Create a hole in a mesh by doubling the nodes of some particular elements
4853     #  @param theElems - the list of elements (edges or faces) to be replicated
4854     #         The nodes for duplication could be found from these elements
4855     #  @param theNodesNot - list of nodes to NOT replicate
4856     #  @param theShape - shape to detect affected elements (element which geometric center
4857     #         located on or inside shape).
4858     #         The replicated nodes should be associated to affected elements.
4859     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4860     #  @ingroup l2_modif_duplicat
4861     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
4862         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
4863
4864     ## Create a hole in a mesh by doubling the nodes of some particular elements
4865     #  This method provided for convenience works as DoubleNodes() described above.
4866     #  @param theElems - group of of elements (edges or faces) to be replicated
4867     #  @param theNodesNot - group of nodes not to replicated
4868     #  @param theAffectedElems - group of elements to which the replicated nodes
4869     #         should be associated to.
4870     #  @param theMakeGroup forces the generation of a group containing new elements.
4871     #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
4872     #  @return TRUE or created groups (one or two) if operation has been completed successfully,
4873     #          FALSE or None otherwise
4874     #  @ingroup l2_modif_duplicat
4875     def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
4876                              theMakeGroup=False, theMakeNodeGroup=False):
4877         if theMakeGroup or theMakeNodeGroup:
4878             twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
4879                                                             theAffectedElems,
4880                                                             theMakeGroup, theMakeNodeGroup)
4881             if theMakeGroup and theMakeNodeGroup:
4882                 return twoGroups
4883             else:
4884                 return twoGroups[ int(theMakeNodeGroup) ]
4885         return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
4886
4887     ## Create a hole in a mesh by doubling the nodes of some particular elements
4888     #  This method provided for convenience works as DoubleNodes() described above.
4889     #  @param theElems - group of of elements (edges or faces) to be replicated
4890     #  @param theNodesNot - group of nodes not to replicated
4891     #  @param theShape - shape to detect affected elements (element which geometric center
4892     #         located on or inside shape).
4893     #         The replicated nodes should be associated to affected elements.
4894     #  @ingroup l2_modif_duplicat
4895     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
4896         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
4897
4898     ## Create a hole in a mesh by doubling the nodes of some particular elements
4899     #  This method provided for convenience works as DoubleNodes() described above.
4900     #  @param theElems - list of groups of elements (edges or faces) to be replicated
4901     #  @param theNodesNot - list of groups of nodes not to replicated
4902     #  @param theAffectedElems - group of elements to which the replicated nodes
4903     #         should be associated to.
4904     #  @param theMakeGroup forces the generation of a group containing new elements.
4905     #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
4906     #  @return TRUE or created groups (one or two) if operation has been completed successfully,
4907     #          FALSE or None otherwise
4908     #  @ingroup l2_modif_duplicat
4909     def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
4910                              theMakeGroup=False, theMakeNodeGroup=False):
4911         if theMakeGroup or theMakeNodeGroup:
4912             twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
4913                                                              theAffectedElems,
4914                                                              theMakeGroup, theMakeNodeGroup)
4915             if theMakeGroup and theMakeNodeGroup:
4916                 return twoGroups
4917             else:
4918                 return twoGroups[ int(theMakeNodeGroup) ]
4919         return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
4920
4921     ## Create a hole in a mesh by doubling the nodes of some particular elements
4922     #  This method provided for convenience works as DoubleNodes() described above.
4923     #  @param theElems - list of groups of elements (edges or faces) to be replicated
4924     #  @param theNodesNot - list of groups of nodes not to replicated
4925     #  @param theShape - shape to detect affected elements (element which geometric center
4926     #         located on or inside shape).
4927     #         The replicated nodes should be associated to affected elements.
4928     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4929     #  @ingroup l2_modif_duplicat
4930     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
4931         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
4932
4933     ## Identify the elements that will be affected by node duplication (actual duplication is not performed.
4934     #  This method is the first step of DoubleNodeElemGroupsInRegion.
4935     #  @param theElems - list of groups of elements (edges or faces) to be replicated
4936     #  @param theNodesNot - list of groups of nodes not to replicated
4937     #  @param theShape - shape to detect affected elements (element which geometric center
4938     #         located on or inside shape).
4939     #         The replicated nodes should be associated to affected elements.
4940     #  @return groups of affected elements
4941     #  @ingroup l2_modif_duplicat
4942     def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape):
4943         return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape)
4944
4945     ## Double nodes on shared faces between groups of volumes and create flat elements on demand.
4946     #  The list of groups must describe a partition of the mesh volumes.
4947     #  The nodes of the internal faces at the boundaries of the groups are doubled.
4948     #  In option, the internal faces are replaced by flat elements.
4949     #  Triangles are transformed in prisms, and quadrangles in hexahedrons.
4950     #  @param theDomains - list of groups of volumes
4951     #  @param createJointElems - if TRUE, create the elements
4952     #  @param onAllBoundaries - if TRUE, the nodes and elements are also created on
4953     #         the boundary between \a theDomains and the rest mesh
4954     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4955     #  @ingroup l2_modif_duplicat
4956     def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
4957         return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
4958
4959     ## Double nodes on some external faces and create flat elements.
4960     #  Flat elements are mainly used by some types of mechanic calculations.
4961     #
4962     #  Each group of the list must be constituted of faces.
4963     #  Triangles are transformed in prisms, and quadrangles in hexahedrons.
4964     #  @param theGroupsOfFaces - list of groups of faces
4965     #  @return TRUE if operation has been completed successfully, FALSE otherwise
4966     #  @ingroup l2_modif_duplicat
4967     def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
4968         return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
4969
4970     ## identify all the elements around a geom shape, get the faces delimiting the hole
4971     #
4972     def CreateHoleSkin(self, radius, theShape, groupName, theNodesCoords):
4973         return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords )
4974
4975     def _getFunctor(self, funcType ):
4976         fn = self.functors[ EnumToLong(funcType) ]
4977         if not fn:
4978             fn = self.smeshpyD.GetFunctor(funcType)
4979             fn.SetMesh(self.mesh)
4980             self.functors[ EnumToLong(funcType) ] = fn
4981         return fn
4982
4983     ## Return value of a functor for a given element
4984     #  @param funcType an item of SMESH.FunctorType enum
4985     #         Type "SMESH.FunctorType._items" in the Python Console to see all items.
4986     #  @param elemId element or node ID
4987     #  @param isElem @a elemId is ID of element or node
4988     #  @return the functor value or zero in case of invalid arguments
4989     #  @ingroup l1_measurements
4990     def FunctorValue(self, funcType, elemId, isElem=True):
4991         fn = self._getFunctor( funcType )
4992         if fn.GetElementType() == self.GetElementType(elemId, isElem):
4993             val = fn.GetValue(elemId)
4994         else:
4995             val = 0
4996         return val
4997
4998     ## Get length of 1D element or sum of lengths of all 1D mesh elements
4999     #  @param elemId mesh element ID (if not defined - sum of length of all 1D elements will be calculated)
5000     #  @return element's length value if \a elemId is specified or sum of all 1D mesh elements' lengths otherwise
5001     #  @ingroup l1_measurements
5002     def GetLength(self, elemId=None):
5003         length = 0
5004         if elemId == None:
5005             length = self.smeshpyD.GetLength(self)
5006         else:
5007             length = self.FunctorValue(SMESH.FT_Length, elemId)
5008         return length
5009
5010     ## Get area of 2D element or sum of areas of all 2D mesh elements
5011     #  @param elemId mesh element ID (if not defined - sum of areas of all 2D elements will be calculated)
5012     #  @return element's area value if \a elemId is specified or sum of all 2D mesh elements' areas otherwise
5013     #  @ingroup l1_measurements
5014     def GetArea(self, elemId=None):
5015         area = 0
5016         if elemId == None:
5017             area = self.smeshpyD.GetArea(self)
5018         else:
5019             area = self.FunctorValue(SMESH.FT_Area, elemId)
5020         return area
5021
5022     ## Get volume of 3D element or sum of volumes of all 3D mesh elements
5023     #  @param elemId mesh element ID (if not defined - sum of volumes of all 3D elements will be calculated)
5024     #  @return element's volume value if \a elemId is specified or sum of all 3D mesh elements' volumes otherwise
5025     #  @ingroup l1_measurements
5026     def GetVolume(self, elemId=None):
5027         volume = 0
5028         if elemId == None:
5029             volume = self.smeshpyD.GetVolume(self)
5030         else:
5031             volume = self.FunctorValue(SMESH.FT_Volume3D, elemId)
5032         return volume
5033
5034     ## Get maximum element length.
5035     #  @param elemId mesh element ID
5036     #  @return element's maximum length value
5037     #  @ingroup l1_measurements
5038     def GetMaxElementLength(self, elemId):
5039         if self.GetElementType(elemId, True) == SMESH.VOLUME:
5040             ftype = SMESH.FT_MaxElementLength3D
5041         else:
5042             ftype = SMESH.FT_MaxElementLength2D
5043         return self.FunctorValue(ftype, elemId)
5044
5045     ## Get aspect ratio of 2D or 3D element.
5046     #  @param elemId mesh element ID
5047     #  @return element's aspect ratio value
5048     #  @ingroup l1_measurements
5049     def GetAspectRatio(self, elemId):
5050         if self.GetElementType(elemId, True) == SMESH.VOLUME:
5051             ftype = SMESH.FT_AspectRatio3D
5052         else:
5053             ftype = SMESH.FT_AspectRatio
5054         return self.FunctorValue(ftype, elemId)
5055
5056     ## Get warping angle of 2D element.
5057     #  @param elemId mesh element ID
5058     #  @return element's warping angle value
5059     #  @ingroup l1_measurements
5060     def GetWarping(self, elemId):
5061         return self.FunctorValue(SMESH.FT_Warping, elemId)
5062
5063     ## Get minimum angle of 2D element.
5064     #  @param elemId mesh element ID
5065     #  @return element's minimum angle value
5066     #  @ingroup l1_measurements
5067     def GetMinimumAngle(self, elemId):
5068         return self.FunctorValue(SMESH.FT_MinimumAngle, elemId)
5069
5070     ## Get taper of 2D element.
5071     #  @param elemId mesh element ID
5072     #  @return element's taper value
5073     #  @ingroup l1_measurements
5074     def GetTaper(self, elemId):
5075         return self.FunctorValue(SMESH.FT_Taper, elemId)
5076
5077     ## Get skew of 2D element.
5078     #  @param elemId mesh element ID
5079     #  @return element's skew value
5080     #  @ingroup l1_measurements
5081     def GetSkew(self, elemId):
5082         return self.FunctorValue(SMESH.FT_Skew, elemId)
5083
5084     ## Return minimal and maximal value of a given functor.
5085     #  @param funType a functor type, an item of SMESH.FunctorType enum
5086     #         (one of SMESH.FunctorType._items)
5087     #  @param meshPart a part of mesh (group, sub-mesh) to treat
5088     #  @return tuple (min,max)
5089     #  @ingroup l1_measurements
5090     def GetMinMax(self, funType, meshPart=None):
5091         unRegister = genObjUnRegister()
5092         if isinstance( meshPart, list ):
5093             meshPart = self.GetIDSource( meshPart, SMESH.ALL )
5094             unRegister.set( meshPart )
5095         if isinstance( meshPart, Mesh ):
5096             meshPart = meshPart.mesh
5097         fun = self._getFunctor( funType )
5098         if fun:
5099             if meshPart:
5100                 if hasattr( meshPart, "SetMesh" ):
5101                     meshPart.SetMesh( self.mesh ) # set mesh to filter
5102                 hist = fun.GetLocalHistogram( 1, False, meshPart )
5103             else:
5104                 hist = fun.GetHistogram( 1, False )
5105             if hist:
5106                 return hist[0].min, hist[0].max
5107         return None
5108
5109     pass # end of Mesh class
5110
5111
5112 ## Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility
5113 #  with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh
5114 #
5115 class meshProxy(SMESH._objref_SMESH_Mesh):
5116     def __init__(self, *args):
5117         SMESH._objref_SMESH_Mesh.__init__(self, *args)
5118     def __deepcopy__(self, memo=None):
5119         new = self.__class__(self)
5120         return new
5121     def CreateDimGroup(self,*args): # 2 args added: nbCommonNodes, underlyingOnly
5122         if len( args ) == 3:
5123             args += SMESH.ALL_NODES, True
5124         return SMESH._objref_SMESH_Mesh.CreateDimGroup( self, *args )
5125     pass
5126 omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy)
5127
5128
5129 ## Private class wrapping SMESH.SMESH_SubMesh in order to add Compute()
5130 #
5131 class submeshProxy(SMESH._objref_SMESH_subMesh):
5132     def __init__(self, *args):
5133         SMESH._objref_SMESH_subMesh.__init__(self, *args)
5134         self.mesh = None
5135     def __deepcopy__(self, memo=None):
5136         new = self.__class__(self)
5137         return new
5138
5139     ## Compute the sub-mesh and return the status of the computation
5140     #  @param refresh if @c True, Object browser is automatically updated (when running in GUI)
5141     #  @return True or False
5142     #
5143     #  This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or
5144     #  @ref smesh_algorithm.Mesh_Algorithm.GetSubMesh() "Mesh_Algorithm.GetSubMesh()".
5145     #  @ingroup l2_submeshes
5146     def Compute(self,refresh=False):
5147         if not self.mesh:
5148             self.mesh = Mesh( smeshBuilder(), None, self.GetMesh())
5149
5150         ok = self.mesh.Compute( self.GetSubShape(),refresh=[] )
5151
5152         if salome.sg.hasDesktop():
5153             smeshgui = salome.ImportComponentGUI("SMESH")
5154             smeshgui.Init()
5155             smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) )
5156             if refresh: salome.sg.updateObjBrowser()
5157             pass
5158
5159         return ok
5160     pass
5161 omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy)
5162
5163
5164 ## Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward
5165 #  compatibility with old dump scripts which call SMESH_MeshEditor directly and not via
5166 #  smeshBuilder.Mesh
5167 #
5168 class meshEditor(SMESH._objref_SMESH_MeshEditor):
5169     def __init__(self, *args):
5170         SMESH._objref_SMESH_MeshEditor.__init__(self, *args)
5171         self.mesh = None
5172     def __getattr__(self, name ): # method called if an attribute not found
5173         if not self.mesh:         # look for name() method in Mesh class
5174             self.mesh = Mesh( None, None, SMESH._objref_SMESH_MeshEditor.GetMesh(self))
5175         if hasattr( self.mesh, name ):
5176             return getattr( self.mesh, name )
5177         if name == "ExtrusionAlongPathObjX":
5178             return getattr( self.mesh, "ExtrusionAlongPathX" ) # other method name
5179         print("meshEditor: attribute '%s' NOT FOUND" % name)
5180         return None
5181     def __deepcopy__(self, memo=None):
5182         new = self.__class__(self)
5183         return new
5184     def FindCoincidentNodes(self,*args): # a 2nd arg added (SeparateCornerAndMediumNodes)
5185         if len( args ) == 1: args += False,
5186         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodes( self, *args )
5187     def FindCoincidentNodesOnPart(self,*args): # a 3d arg added (SeparateCornerAndMediumNodes)
5188         if len( args ) == 2: args += False,
5189         return SMESH._objref_SMESH_MeshEditor.FindCoincidentNodesOnPart( self, *args )
5190     def MergeNodes(self,*args): # 2 args added (NodesToKeep,AvoidMakingHoles)
5191         if len( args ) == 1:
5192             return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], [], False )
5193         NodesToKeep = args[1]
5194         AvoidMakingHoles = args[2] if len( args ) == 3 else False
5195         unRegister  = genObjUnRegister()
5196         if NodesToKeep:
5197             if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
5198                 NodesToKeep = self.MakeIDSource( NodesToKeep, SMESH.NODE )
5199             if not isinstance( NodesToKeep, list ):
5200                 NodesToKeep = [ NodesToKeep ]
5201         return SMESH._objref_SMESH_MeshEditor.MergeNodes( self, args[0], NodesToKeep, AvoidMakingHoles )
5202     pass
5203 omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor)
5204
5205 ## Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook
5206 #  variables in some methods
5207 #
5208 class Pattern(SMESH._objref_SMESH_Pattern):
5209
5210     def LoadFromFile(self, patternTextOrFile ):
5211         text = patternTextOrFile
5212         if os.path.exists( text ):
5213             text = open( patternTextOrFile ).read()
5214             pass
5215         return SMESH._objref_SMESH_Pattern.LoadFromFile( self, text )
5216
5217     def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
5218         decrFun = lambda i: i-1
5219         theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
5220         theMesh.SetParameters(Parameters)
5221         return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
5222
5223     def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
5224         decrFun = lambda i: i-1
5225         theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
5226         theMesh.SetParameters(Parameters)
5227         return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
5228
5229     def MakeMesh(self, mesh, CreatePolygons=False, CreatePolyhedra=False):
5230         if isinstance( mesh, Mesh ):
5231             mesh = mesh.GetMesh()
5232         return SMESH._objref_SMESH_Pattern.MakeMesh( self, mesh, CreatePolygons, CreatePolyhedra )
5233
5234 # Registering the new proxy for Pattern
5235 omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
5236
5237 ## Private class used to bind methods creating algorithms to the class Mesh
5238 #
5239 class algoCreator:
5240     def __init__(self, method):
5241         self.mesh = None
5242         self.defaultAlgoType = ""
5243         self.algoTypeToClass = {}
5244         self.method = method
5245
5246     # Store a python class of algorithm
5247     def add(self, algoClass):
5248         if inspect.isclass(algoClass) and \
5249            hasattr(algoClass, "algoType"):
5250             self.algoTypeToClass[ algoClass.algoType ] = algoClass
5251             if not self.defaultAlgoType and \
5252                hasattr( algoClass, "isDefault") and algoClass.isDefault:
5253                 self.defaultAlgoType = algoClass.algoType
5254             #print "Add",algoClass.algoType, "dflt",self.defaultAlgoType
5255
5256     # Create a copy of self and assign mesh to the copy
5257     def copy(self, mesh):
5258         other = algoCreator( self.method )
5259         other.defaultAlgoType = self.defaultAlgoType
5260         other.algoTypeToClass = self.algoTypeToClass
5261         other.mesh = mesh
5262         return other
5263
5264     # Create an instance of algorithm
5265     def __call__(self,algo="",geom=0,*args):
5266         algoType = ""
5267         shape = 0
5268         if isinstance( algo, str ):
5269             algoType = algo
5270         elif ( isinstance( algo, geomBuilder.GEOM._objref_GEOM_Object ) and \
5271                not isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object )):
5272             shape = algo
5273         elif algo:
5274             args += (algo,)
5275
5276         if isinstance( geom, geomBuilder.GEOM._objref_GEOM_Object ):
5277             shape = geom
5278         elif not algoType and isinstance( geom, str ):
5279             algoType = geom
5280         elif geom:
5281             args += (geom,)
5282         for arg in args:
5283             if isinstance( arg, geomBuilder.GEOM._objref_GEOM_Object ) and not shape:
5284                 shape = arg
5285             elif isinstance( arg, str ) and not algoType:
5286                 algoType = arg
5287             else:
5288                 import traceback, sys
5289                 msg = "Warning. Unexpected argument in mesh.%s() --->  %s" % ( self.method, arg )
5290                 sys.stderr.write( msg + '\n' )
5291                 tb = traceback.extract_stack(None,2)
5292                 traceback.print_list( [tb[0]] )
5293         if not algoType:
5294             algoType = self.defaultAlgoType
5295         if not algoType and self.algoTypeToClass:
5296             algoType = list(self.algoTypeToClass.keys())[0]
5297         if algoType in self.algoTypeToClass:
5298             #print "Create algo",algoType
5299
5300             return self.algoTypeToClass[ algoType ]( self.mesh, shape )
5301         raise RuntimeError( "No class found for algo type %s" % algoType)
5302         return None
5303
5304 ## Private class used to substitute and store variable parameters of hypotheses.
5305 #
5306 class hypMethodWrapper:
5307     def __init__(self, hyp, method):
5308         self.hyp    = hyp
5309         self.method = method
5310         #print "REBIND:", method.__name__
5311         return
5312
5313     # call a method of hypothesis with calling SetVarParameter() before
5314     def __call__(self,*args):
5315         if not args:
5316             return self.method( self.hyp, *args ) # hypothesis method with no args
5317
5318         #print "MethWrapper.__call__",self.method.__name__, args
5319         try:
5320             parsed = ParseParameters(*args)     # replace variables with their values
5321             self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
5322             result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
5323         except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
5324             # maybe there is a replaced string arg which is not variable
5325             result = self.method( self.hyp, *args )
5326         except ValueError as detail: # raised by ParseParameters()
5327             try:
5328                 result = self.method( self.hyp, *args )
5329             except omniORB.CORBA.BAD_PARAM:
5330                 raise ValueError(detail) # wrong variable name
5331
5332         return result
5333     pass
5334
5335 ## A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it
5336 #
5337 class genObjUnRegister:
5338
5339     def __init__(self, genObj=None):
5340         self.genObjList = []
5341         self.set( genObj )
5342         return
5343
5344     def set(self, genObj):
5345         "Store one or a list of of SALOME.GenericObj'es"
5346         if isinstance( genObj, list ):
5347             self.genObjList.extend( genObj )
5348         else:
5349             self.genObjList.append( genObj )
5350         return
5351
5352     def __del__(self):
5353         for genObj in self.genObjList:
5354             if genObj and hasattr( genObj, "UnRegister" ):
5355                 genObj.UnRegister()
5356
5357
5358 ## Bind methods creating mesher plug-ins to the Mesh class
5359 #
5360 for pluginName in os.environ[ "SMESH_MeshersList" ].split( ":" ):
5361     #
5362     #print "pluginName: ", pluginName
5363     pluginBuilderName = pluginName + "Builder"
5364     try:
5365         exec( "from salome.%s.%s import *" % (pluginName, pluginBuilderName))
5366     except Exception as e:
5367         from salome_utils import verbose
5368         if verbose(): print("Exception while loading %s: %s" % ( pluginBuilderName, e ))
5369         continue
5370     exec( "from salome.%s import %s" % (pluginName, pluginBuilderName))
5371     plugin = eval( pluginBuilderName )
5372     #print "  plugin:" , str(plugin)
5373
5374     # add methods creating algorithms to Mesh
5375     for k in dir( plugin ):
5376         if k[0] == '_': continue
5377         algo = getattr( plugin, k )
5378         #print "             algo:", str(algo)
5379         if inspect.isclass(algo) and hasattr(algo, "meshMethod"):
5380             #print "                     meshMethod:" , str(algo.meshMethod)
5381             if not hasattr( Mesh, algo.meshMethod ):
5382                 setattr( Mesh, algo.meshMethod, algoCreator( algo.meshMethod ))
5383                 pass
5384             getattr( Mesh, algo.meshMethod ).add( algo )
5385             pass
5386         pass
5387     pass
5388 del pluginName