Salome HOME
92fefeda222c7358cbdbda9b314b3d295f345850
[modules/smesh.git] / src / SMESH_SWIG / smesh.py
1 #  Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 #  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 #
4 #  This library is free software; you can redistribute it and/or
5 #  modify it under the terms of the GNU Lesser General Public
6 #  License as published by the Free Software Foundation; either
7 #  version 2.1 of the License.
8 #
9 #  This library is distributed in the hope that it will be useful,
10 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 #  Lesser General Public License for more details.
13 #
14 #  You should have received a copy of the GNU Lesser General Public
15 #  License along with this library; if not, write to the Free Software
16 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 #  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19 #
20 #  File   : smesh.py
21 #  Author : Francis KLOSS, OCC
22 #  Module : SMESH
23
24 """
25  \namespace smesh
26  \brief Module smesh
27 """
28
29 import salome
30 import geompy
31 import StdMeshers
32 import SMESH
33
34 # Public variables
35 # ----------------
36
37 REGULAR = 1
38 PYTHON  = 2
39
40 NETGEN  = 3
41 GHS3D   = 4
42
43 smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
44 smesh.SetCurrentStudy(salome.myStudy)
45
46 # Private functions
47 # -----------------
48
49 NO_NAME = "NoName"
50
51 def GetName(obj):
52     ior  = salome.orb.object_to_string(obj)
53     sobj = salome.myStudy.FindObjectIOR(ior)
54     if sobj is None:
55         return NO_NAME
56     else:
57         attr = sobj.FindAttribute("AttributeName")[1]
58         return attr.Value()
59
60 def SetName(obj, name):
61     ior  = salome.orb.object_to_string(obj)
62     sobj = salome.myStudy.FindObjectIOR(ior)
63     attr = sobj.FindAttribute("AttributeName")[1]
64     attr.SetValue(name)
65
66 # Algorithms and hypothesis
67 # =========================
68
69 # Private class: Mesh_Algorithm
70 # -----------------------------
71
72 class Mesh_Algorithm:
73     """
74     Mother class to define algorithm, recommended to don't use directly
75     """
76
77     mesh = 0
78     geom = 0
79     subm = 0
80     algo = 0
81
82     def GetSubMesh(self):
83         """
84          If the algorithm is global, return 0
85          else return the submesh associated to this algorithm
86         """
87         return self.subm
88
89     def GetAlgorithm(self):
90         """
91          Return the wrapped mesher
92         """
93         return self.algo
94
95     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
96         """
97          Private method
98         """
99         self.mesh = mesh
100         piece = mesh.geom
101         if geom==0:
102             self.geom = piece
103             name = GetName(piece)
104         else:
105             self.geom = geom
106             name = GetName(geom)
107             if name==NO_NAME:
108                 name = geompy.SubShapeName(geom, piece)
109                 geompy.addToStudyInFather(piece, geom, name)
110             self.subm = mesh.mesh.GetSubMesh(geom, hypo)
111
112         self.algo = smesh.CreateHypothesis(hypo, so)
113         SetName(self.algo, name + "/" + hypo)
114         mesh.mesh.AddHypothesis(self.geom, self.algo)
115
116     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
117         """
118          Private method
119         """
120         hypo = smesh.CreateHypothesis(hyp, so)
121         a = ""
122         s = "="
123         i = 0
124         n = len(args)
125         while i<n:
126             a = a + s + str(args[i])
127             s = ","
128             i = i + 1
129         SetName(hypo, GetName(self.geom) + "/" + hyp + a)
130         self.mesh.mesh.AddHypothesis(self.geom, hypo)
131         return hypo
132
133 # Public class: Mesh_Segment
134 # --------------------------
135
136 class Mesh_Segment(Mesh_Algorithm):
137     """
138     Class to define a segment 1D algorithm for discretization
139     """
140
141     def __init__(self, mesh, geom=0):
142         """
143          Private constructor
144         """
145         self.Create(mesh, geom, "Regular_1D")
146
147     def LocalLength(self, l):
148         """
149          Define "LocalLength" hypothesis to cut an edge in several segments with the same length
150          \param l for the length of segments that cut an edge
151         """
152         hyp = self.Hypothesis("LocalLength", [l])
153         hyp.SetLength(l)
154         return hyp
155
156     def NumberOfSegments(self, n, s=[]):
157         """
158          Define "NumberOfSegments" hypothesis to cut an edge in several fixed number of segments
159          \param n for the number of segments that cut an edge
160          \param s for the scale factor (optional)
161         """
162         if s == []:
163             hyp = self.Hypothesis("NumberOfSegments", [n])
164         else:
165             hyp = self.Hypothesis("NumberOfSegments", [n,s])
166             hyp.SetDistrType( 1 )
167             hyp.SetScaleFactor(s)
168         hyp.SetNumberOfSegments(n)
169         return hyp
170
171     def Arithmetic1D(self, start, end):
172         """
173          Define "Arithmetic1D" hypothesis to cut an edge in several segments with arithmetic length increasing
174          \param start for the length of the first segment
175          \param end   for the length of the last  segment
176         """
177         hyp = self.Hypothesis("Arithmetic1D", [start, end])
178         hyp.SetLength(start, 1)
179         hyp.SetLength(end  , 0)
180         return hyp
181
182     def StartEndLength(self, start, end):
183         """
184          Define "StartEndLength" hypothesis to cut an edge in several segments with geometric length increasing
185          \param start for the length of the first segment
186          \param end   for the length of the last  segment
187         """
188         hyp = self.Hypothesis("StartEndLength", [start, end])
189         hyp.SetLength(start, 1)
190         hyp.SetLength(end  , 0)
191         return hyp
192
193     def Deflection1D(self, d):
194         """
195          Define "Deflection1D" hypothesis
196          \param d for the deflection
197         """
198         hyp = self.Hypothesis("Deflection1D", [d])
199         hyp.SetDeflection(d)
200         return hyp
201
202     def Propagation(self):
203         """
204          Define "Propagation" hypothesis that propagate all other hypothesis on all others edges that are in
205          the opposite side in the case of quadrangular faces
206         """
207         return self.Hypothesis("Propagation")
208
209     def AutomaticLength(self):
210         """
211          Define "AutomaticLength" hypothesis
212         """
213         return self.Hypothesis("AutomaticLength")
214
215 # Public class: Mesh_Segment_Python
216 # ---------------------------------
217
218 class Mesh_Segment_Python(Mesh_Segment):
219     """
220     Class to define a segment 1D algorithm for discretization with python function
221     """
222
223     def __init__(self, mesh, geom=0):
224         """
225          Private constructor
226         """
227         import Python1dPlugin
228         self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
229
230     def PythonSplit1D(self, n, func):
231         """
232          Define "PythonSplit1D" hypothesis based on the Erwan Adam patch, awaiting equivalent SALOME functionality
233          \param n for the number of segments that cut an edge
234          \param func for the python function that calculate the length of all segments
235         """
236         hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so")
237         hyp.SetNumberOfSegments(n)
238         hyp.SetPythonLog10RatioFunction(func)
239         return hyp
240
241 # Public class: Mesh_Triangle
242 # ---------------------------
243
244 class Mesh_Triangle(Mesh_Algorithm):
245     """
246     Class to define a triangle 2D algorithm
247     """
248
249     def __init__(self, mesh, geom=0):
250         """
251          Private constructor
252         """
253         self.Create(mesh, geom, "MEFISTO_2D")
254
255     def MaxElementArea(self, area):
256         """
257          Define "MaxElementArea" hypothesis to give the maximun area of each triangles
258          \param area for the maximum area of each triangles
259         """
260         hyp = self.Hypothesis("MaxElementArea", [area])
261         hyp.SetMaxElementArea(area)
262         return hyp
263
264     def LengthFromEdges(self):
265         """
266          Define "LengthFromEdges" hypothesis to build triangles based on the length of the edges taken from the wire
267         """
268         return self.Hypothesis("LengthFromEdges")
269
270 # Public class: Mesh_Quadrangle
271 # -----------------------------
272
273 class Mesh_Quadrangle(Mesh_Algorithm):
274     """
275     Class to define a quadrangle 2D algorithm
276     """
277
278     def __init__(self, mesh, geom=0):
279         """
280          Private constructor
281         """
282         self.Create(mesh, geom, "Quadrangle_2D")
283
284 # Public class: Mesh_Tetrahedron
285 # ------------------------------
286
287 class Mesh_Tetrahedron(Mesh_Algorithm):
288     """
289     Class to define a tetrahedron 3D algorithm
290     """
291
292     def __init__(self, mesh, algo, geom=0):
293         """
294          Private constructor
295         """
296         if algo == NETGEN:
297             self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
298         elif algo == GHS3D:
299             import GHS3DPlugin
300             self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
301
302     def MaxElementVolume(self, vol):
303         """
304          Define "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedral
305          \param vol for the maximum volume of each tetrahedral
306         """
307         hyp = self.Hypothesis("MaxElementVolume", [vol])
308         hyp.SetMaxElementVolume(vol)
309         return hyp
310
311 # Public class: Mesh_Hexahedron
312 # ------------------------------
313
314 class Mesh_Hexahedron(Mesh_Algorithm):
315     """
316     Class to define a hexahedron 3D algorithm
317     """
318
319     def __init__(self, mesh, geom=0):
320         """
321          Private constructor
322         """
323         self.Create(mesh, geom, "Hexa_3D")
324
325 # Public class: Mesh
326 # ==================
327
328 class Mesh:
329     """
330     Class to define a mesh
331     """
332
333     geom = 0
334     mesh = 0
335
336     def __init__(self, geom, name=0):
337         """
338          Constructor
339
340          Creates mesh on the shape \a geom,
341          sets GUI name of this mesh to \a name.
342          \param geom Shape to be meshed
343          \param name Study name of the mesh
344         """
345         self.geom = geom
346         self.mesh = smesh.CreateMesh(geom)
347         if name == 0:
348             SetName(self.mesh, GetName(geom))
349         else:
350             SetName(self.mesh, name)
351
352     def GetMesh(self):
353         """
354          Method that returns the mesh
355         """
356         return self.mesh
357
358     def GetShape(self):
359         """
360          Method that returns the shape associated to the mesh
361         """
362         return self.geom
363
364     def MeshDimension(self):
365         """
366         Returns mesh dimension depending on shape one
367         """
368         shells = geompy.SubShapeAllIDs( self.geom, geompy.ShapeType["SHELL"] )
369         if len( shells ) > 0 :
370             return 3
371         elif geompy.NumberOfFaces( self.geom ) > 0 :
372             return 2
373         elif geompy.NumberOfEdges( self.geom ) > 0 :
374             return 1
375         else:
376             return 0;
377         pass
378
379     def Segment(self, algo=REGULAR, geom=0):
380         """
381          Creates a segment discretization 1D algorithm.
382          If the optional \a algo parameter is not sets, this algorithm is REGULAR.
383          If the optional \a geom parameter is not sets, this algorithm is global.
384          Otherwise, this algorithm define a submesh based on \a geom subshape.
385          \param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
386          \param geom If defined, subshape to be meshed
387         """
388         ## if Segment(geom) is called by mistake
389         if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
390             algo, geom = geom, algo
391             pass
392         if algo == REGULAR:
393             return Mesh_Segment(self, geom)
394         elif algo == PYTHON:
395             return Mesh_Segment_Python(self, geom)
396         else:
397             return Mesh_Segment(self, geom)
398
399     def Triangle(self, geom=0):
400         """
401          Creates a triangle 2D algorithm for faces.
402          If the optional \a geom parameter is not sets, this algorithm is global.
403          Otherwise, this algorithm define a submesh based on \a geom subshape.
404          \param geom If defined, subshape to be meshed
405         """
406         return Mesh_Triangle(self, geom)
407
408     def Quadrangle(self, geom=0):
409         """
410          Creates a quadrangle 2D algorithm for faces.
411          If the optional \a geom parameter is not sets, this algorithm is global.
412          Otherwise, this algorithm define a submesh based on \a geom subshape.
413          \param geom If defined, subshape to be meshed
414         """
415         return Mesh_Quadrangle(self, geom)
416
417     def Tetrahedron(self, algo, geom=0):
418         """
419          Creates a tetrahedron 3D algorithm for solids.
420          The parameter \a algo permits to choice the algorithm: NETGEN or GHS3D
421          If the optional \a geom parameter is not sets, this algorithm is global.
422          Otherwise, this algorithm define a submesh based on \a geom subshape.
423          \param algo values are: smesh.NETGEN, smesh.GHS3D
424          \param geom If defined, subshape to be meshed
425         """
426         ## if Tetrahedron(geom) is called by mistake
427         if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
428             algo, geom = geom, algo
429             pass
430         return Mesh_Tetrahedron(self, algo, geom)
431
432     def Hexahedron(self, geom=0):
433         """
434          Creates a hexahedron 3D algorithm for solids.
435          If the optional \a geom parameter is not sets, this algorithm is global.
436          Otherwise, this algorithm define a submesh based on \a geom subshape.
437          \param geom If defined, subshape to be meshed
438         """
439         return Mesh_Hexahedron(self, geom)
440
441     def Compute(self):
442         """
443          Compute the mesh and return the status of the computation
444         """
445         b = smesh.Compute(self.mesh, self.geom)
446         if salome.sg.hasDesktop():
447             smeshgui = salome.ImportComponentGUI("SMESH")
448             smeshgui.Init(salome.myStudyId)
449             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b )
450             salome.sg.updateObjBrowser(1)
451         return b
452
453     def AutomaticTetrahedralization(self):
454         """
455         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
456         """
457         dim = self.MeshDimension()
458         # assign hypotheses
459         self.RemoveGlobalHypotheses()
460         self.Segment().AutomaticLength()
461         if dim > 1 :
462             self.Triangle().LengthFromEdges()
463             pass
464         if dim > 2 :
465             self.Tetrahedron(NETGEN)
466             pass
467         return self.Compute()
468
469     def AutomaticHexahedralization(self):
470         """
471         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
472         """
473         dim = self.MeshDimension()
474         # assign hypotheses
475         self.RemoveGlobalHypotheses()
476         self.Segment().AutomaticLength()
477         if dim > 1 :
478             self.Quadrangle()
479             pass
480         if dim > 2 :
481             self.Hexahedron()            
482             pass
483         return self.Compute()
484
485     def RemoveGlobalHypotheses(self):
486         """
487         Removes all global hypotheses
488         """
489         current_hyps = self.mesh.GetHypothesisList( self.geom )
490         for hyp in current_hyps:
491             self.mesh.RemoveHypothesis( self.geom, hyp )
492             pass
493         pass
494
495     def Group(self, grp, name=""):
496         """
497          Create a mesh group based on geometric object \a grp
498          and give a \a name, if this parameter is not defined
499          the name is the same as the geometric group name
500          \param grp  is a geometric group, a vertex, an edge, a face or a solid
501          \param name is the name of the mesh group
502         """
503         if name == "":
504             name = grp.GetName()
505
506         type = []
507         tgeo = str(grp.GetShapeType())
508         if tgeo == "VERTEX":
509             type = SMESH.NODE
510         elif tgeo == "EDGE":
511             type = SMESH.EDGE
512         elif tgeo == "FACE":
513             type = SMESH.FACE
514         elif tgeo == "SOLID":
515             type = SMESH.VOLUME
516         elif tgeo == "SHELL":
517             type = SMESH.VOLUME
518         elif tgeo == "COMPOUND":
519             tgeo = geompy.GetType(grp)
520             if tgeo == geompy.ShapeType["VERTEX"]:
521                 type = SMESH.NODE
522             elif tgeo == geompy.ShapeType["EDGE"]:
523                 type = SMESH.EDGE
524             elif tgeo == geompy.ShapeType["FACE"]:
525                 type = SMESH.FACE
526             elif tgeo == geompy.ShapeType["SOLID"]:
527                 type = SMESH.VOLUME
528
529         if type == []:
530             print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid"
531             return 0
532         else:
533             return self.mesh.CreateGroupFromGEOM(type, name, grp)
534
535     def ExportToMED(self, f, version, opt=0):
536         """
537          Export the mesh in a file with the MED format and choice the \a version of MED format
538          \param f is the file name
539          \param version values are smesh.MED_V2_1, smesh.MED_V2_2
540         """
541         self.mesh.ExportToMED(f, opt, version)
542
543     def ExportMED(self, f, opt=0):
544         """
545          Export the mesh in a file with the MED format
546          \param f is the file name
547         """
548         self.mesh.ExportMED(f, opt)
549
550     def ExportDAT(self, f):
551         """
552          Export the mesh in a file with the DAT format
553          \param f is the file name
554         """
555         self.mesh.ExportDAT(f)
556
557     def ExportUNV(self, f):
558         """
559          Export the mesh in a file with the UNV format
560          \param f is the file name
561         """
562         self.mesh.ExportUNV(f)
563
564     def ExportSTL(self, f, ascii=1):
565         """
566          Export the mesh in a file with the STL format
567          \param f is the file name
568          \param ascii defined the kind of file contents
569         """
570         self.mesh.ExportSTL(f, ascii)