Salome HOME
PAL10237. Add Mesh.AutomaticTetrahedralization() and Mesh.AutomaticHexahedralization()
[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
81     def GetSubMesh(self):
82         """
83          If the algorithm is global, return 0
84          else return the submesh associated to this algorithm
85         """
86         return self.subm
87
88     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
89         """
90          Private method
91         """
92         self.mesh = mesh
93         piece = mesh.geom
94         if geom==0:
95             self.geom = piece
96             name = GetName(piece)
97         else:
98             self.geom = geom
99             name = GetName(geom)
100             if name==NO_NAME:
101                 name = geompy.SubShapeName(geom, piece)
102                 geompy.addToStudyInFather(piece, geom, name)
103             self.subm = mesh.mesh.GetSubMesh(geom, hypo)
104
105         algo = smesh.CreateHypothesis(hypo, so)
106         SetName(algo, name + "/" + hypo)
107         mesh.mesh.AddHypothesis(self.geom, algo)
108
109     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
110         """
111          Private method
112         """
113         hypo = smesh.CreateHypothesis(hyp, so)
114         a = ""
115         s = "="
116         i = 0
117         n = len(args)
118         while i<n:
119             a = a + s + str(args[i])
120             s = ","
121             i = i + 1
122         SetName(hypo, GetName(self.geom) + "/" + hyp + a)
123         self.mesh.mesh.AddHypothesis(self.geom, hypo)
124         return hypo
125
126 # Public class: Mesh_Segment
127 # --------------------------
128
129 class Mesh_Segment(Mesh_Algorithm):
130     """
131     Class to define a segment 1D algorithm for discretization
132     """
133
134     def __init__(self, mesh, geom=0):
135         """
136          Private constructor
137         """
138         self.Create(mesh, geom, "Regular_1D")
139
140     def LocalLength(self, l):
141         """
142          Define "LocalLength" hypothesis to cut an edge in several segments with the same length
143          \param l for the length of segments that cut an edge
144         """
145         hyp = self.Hypothesis("LocalLength", [l])
146         hyp.SetLength(l)
147         return hyp
148
149     def NumberOfSegments(self, n, s=[]):
150         """
151          Define "NumberOfSegments" hypothesis to cut an edge in several fixed number of segments
152          \param n for the number of segments that cut an edge
153          \param s for the scale factor (optional)
154         """
155         if s == []:
156             hyp = self.Hypothesis("NumberOfSegments", [n])
157         else:
158             hyp = self.Hypothesis("NumberOfSegments", [n,s])
159             hyp.SetDistrType( 1 )
160             hyp.SetScaleFactor(s)
161         hyp.SetNumberOfSegments(n)
162         return hyp
163
164     def Arithmetic1D(self, start, end):
165         """
166          Define "Arithmetic1D" hypothesis to cut an edge in several segments with arithmetic length increasing
167          \param start for the length of the first segment
168          \param end   for the length of the last  segment
169         """
170         hyp = self.Hypothesis("Arithmetic1D", [start, end])
171         hyp.SetLength(start, 1)
172         hyp.SetLength(end  , 0)
173         return hyp
174
175     def StartEndLength(self, start, end):
176         """
177          Define "StartEndLength" hypothesis to cut an edge in several segments with geometric length increasing
178          \param start for the length of the first segment
179          \param end   for the length of the last  segment
180         """
181         hyp = self.Hypothesis("StartEndLength", [start, end])
182         hyp.SetLength(start, 1)
183         hyp.SetLength(end  , 0)
184         return hyp
185
186     def Deflection1D(self, d):
187         """
188          Define "Deflection1D" hypothesis
189          \param d for the deflection
190         """
191         hyp = self.Hypothesis("Deflection1D", [d])
192         hyp.SetDeflection(d)
193         return hyp
194
195     def Propagation(self):
196         """
197          Define "Propagation" hypothesis that propagate all other hypothesis on all others edges that are in
198          the opposite side in the case of quadrangular faces
199         """
200         return self.Hypothesis("Propagation")
201
202     def AutomaticLength(self):
203         """
204          Define "AutomaticLength" hypothesis
205         """
206         return self.Hypothesis("AutomaticLength")
207
208 # Public class: Mesh_Segment_Python
209 # ---------------------------------
210
211 class Mesh_Segment_Python(Mesh_Segment):
212     """
213     Class to define a segment 1D algorithm for discretization with python function
214     """
215
216     def __init__(self, mesh, geom=0):
217         """
218          Private constructor
219         """
220         import Python1dPlugin
221         self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
222
223     def PythonSplit1D(self, n, func):
224         """
225          Define "PythonSplit1D" hypothesis based on the Erwan Adam patch, awaiting equivalent SALOME functionality
226          \param n for the number of segments that cut an edge
227          \param func for the python function that calculate the length of all segments
228         """
229         hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so")
230         hyp.SetNumberOfSegments(n)
231         hyp.SetPythonLog10RatioFunction(func)
232         return hyp
233
234 # Public class: Mesh_Triangle
235 # ---------------------------
236
237 class Mesh_Triangle(Mesh_Algorithm):
238     """
239     Class to define a triangle 2D algorithm
240     """
241
242     def __init__(self, mesh, geom=0):
243         """
244          Private constructor
245         """
246         self.Create(mesh, geom, "MEFISTO_2D")
247
248     def MaxElementArea(self, area):
249         """
250          Define "MaxElementArea" hypothesis to give the maximun area of each triangles
251          \param area for the maximum area of each triangles
252         """
253         hyp = self.Hypothesis("MaxElementArea", [area])
254         hyp.SetMaxElementArea(area)
255         return hyp
256
257     def LengthFromEdges(self):
258         """
259          Define "LengthFromEdges" hypothesis to build triangles based on the length of the edges taken from the wire
260         """
261         return self.Hypothesis("LengthFromEdges")
262
263 # Public class: Mesh_Quadrangle
264 # -----------------------------
265
266 class Mesh_Quadrangle(Mesh_Algorithm):
267     """
268     Class to define a quadrangle 2D algorithm
269     """
270
271     def __init__(self, mesh, geom=0):
272         """
273          Private constructor
274         """
275         self.Create(mesh, geom, "Quadrangle_2D")
276
277 # Public class: Mesh_Tetrahedron
278 # ------------------------------
279
280 class Mesh_Tetrahedron(Mesh_Algorithm):
281     """
282     Class to define a tetrahedron 3D algorithm
283     """
284
285     def __init__(self, mesh, algo, geom=0):
286         """
287          Private constructor
288         """
289         if algo == NETGEN:
290             self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
291         elif algo == GHS3D:
292             import GHS3DPlugin
293             self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
294
295     def MaxElementVolume(self, vol):
296         """
297          Define "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedral
298          \param vol for the maximum volume of each tetrahedral
299         """
300         hyp = self.Hypothesis("MaxElementVolume", [vol])
301         hyp.SetMaxElementVolume(vol)
302         return hyp
303
304 # Public class: Mesh_Hexahedron
305 # ------------------------------
306
307 class Mesh_Hexahedron(Mesh_Algorithm):
308     """
309     Class to define a hexahedron 3D algorithm
310     """
311
312     def __init__(self, mesh, geom=0):
313         """
314          Private constructor
315         """
316         self.Create(mesh, geom, "Hexa_3D")
317
318 # Public class: Mesh
319 # ==================
320
321 class Mesh:
322     """
323     Class to define a mesh
324     """
325
326     geom = 0
327     mesh = 0
328
329     def __init__(self, geom, name=0):
330         """
331          Constructor
332
333          Creates mesh on the shape \a geom,
334          sets GUI name of this mesh to \a name.
335          \param geom Shape to be meshed
336          \param name Study name of the mesh
337         """
338         self.geom = geom
339         self.mesh = smesh.CreateMesh(geom)
340         if name == 0:
341             SetName(self.mesh, GetName(geom))
342         else:
343             SetName(self.mesh, name)
344
345     def GetMesh(self):
346         """
347          Method that returns the mesh
348         """
349         return self.mesh
350
351     def GetShape(self):
352         """
353          Method that returns the shape associated to the mesh
354         """
355         return self.geom
356
357     def MeshDimension(self):
358         """
359         Returns mesh dimension depending on shape one
360         """
361         shells = geompy.SubShapeAllIDs( self.geom, geompy.ShapeType["SHELL"] )
362         if len( shells ) > 0 :
363             return 3
364         elif geompy.NumberOfFaces( self.geom ) > 0 :
365             return 2
366         elif geompy.NumberOfEdges( self.geom ) > 0 :
367             return 1
368         else:
369             return 0;
370         pass
371
372     def Segment(self, algo=REGULAR, geom=0):
373         """
374          Creates a segment discretization 1D algorithm.
375          If the optional \a algo parameter is not sets, this algorithm is REGULAR.
376          If the optional \a geom parameter is not sets, this algorithm is global.
377          Otherwise, this algorithm define a submesh based on \a geom subshape.
378          \param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
379          \param geom If defined, subshape to be meshed
380         """
381         if algo == REGULAR:
382             return Mesh_Segment(self, geom)
383         elif algo == PYTHON:
384             return Mesh_Segment_Python(self, geom)
385         else:
386             return Mesh_Segment(self, algo)
387
388     def Triangle(self, geom=0):
389         """
390          Creates a triangle 2D algorithm for faces.
391          If the optional \a geom parameter is not sets, this algorithm is global.
392          Otherwise, this algorithm define a submesh based on \a geom subshape.
393          \param geom If defined, subshape to be meshed
394         """
395         return Mesh_Triangle(self, geom)
396
397     def Quadrangle(self, geom=0):
398         """
399          Creates a quadrangle 2D algorithm for faces.
400          If the optional \a geom parameter is not sets, this algorithm is global.
401          Otherwise, this algorithm define a submesh based on \a geom subshape.
402          \param geom If defined, subshape to be meshed
403         """
404         return Mesh_Quadrangle(self, geom)
405
406     def Tetrahedron(self, algo, geom=0):
407         """
408          Creates a tetrahedron 3D algorithm for solids.
409          The parameter \a algo permits to choice the algorithm: NETGEN or GHS3D
410          If the optional \a geom parameter is not sets, this algorithm is global.
411          Otherwise, this algorithm define a submesh based on \a geom subshape.
412          \param algo values are: smesh.NETGEN, smesh.GHS3D
413          \param geom If defined, subshape to be meshed
414         """
415         return Mesh_Tetrahedron(self, algo, geom)
416
417     def Hexahedron(self, geom=0):
418         """
419          Creates a hexahedron 3D algorithm for solids.
420          If the optional \a geom parameter is not sets, this algorithm is global.
421          Otherwise, this algorithm define a submesh based on \a geom subshape.
422          \param geom If defined, subshape to be meshed
423         """
424         return Mesh_Hexahedron(self, geom)
425
426     def Compute(self):
427         """
428          Compute the mesh and return the status of the computation
429         """
430         b = smesh.Compute(self.mesh, self.geom)
431         if salome.sg.hasDesktop():
432             smeshgui = salome.ImportComponentGUI("SMESH")
433             smeshgui.Init(salome.myStudyId)
434             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b )
435             salome.sg.updateObjBrowser(1)
436         return b
437
438     def AutomaticTetrahedralization(self):
439         """
440         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
441         """
442         dim = self.MeshDimension()
443         # assign hypotheses
444         self.RemoveGlobalHypotheses()
445         self.Segment().AutomaticLength()
446         if dim > 1 :
447             self.Triangle().LengthFromEdges()
448             pass
449         if dim > 2 :
450             self.Tetrahedron(NETGEN)
451             pass
452         self.Compute()
453         pass
454
455     def AutomaticHexahedralization(self):
456         """
457         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
458         """
459         dim = self.MeshDimension()
460         # assign hypotheses
461         self.RemoveGlobalHypotheses()
462         self.Segment().AutomaticLength()
463         if dim > 1 :
464             self.Quadrangle()
465             pass
466         if dim > 2 :
467             self.Hexahedron()            
468             pass
469         self.Compute()
470         pass
471
472     def RemoveGlobalHypotheses(self):
473         """
474         Removes all global hypotheses
475         """
476         current_hyps = self.mesh.GetHypothesisList( self.geom )
477         for hyp in current_hyps:
478             self.mesh.RemoveHypothesis( self.geom, hyp )
479             pass
480         pass
481
482     def Group(self, grp, name=""):
483         """
484          Create a mesh group based on geometric object \a grp
485          and give a \a name, if this parameter is not defined
486          the name is the same as the geometric group name
487          \param grp  is a geometric group, a vertex, an edge, a face or a solid
488          \param name is the name of the mesh group
489         """
490         if name == "":
491             name = grp.GetName()
492
493         type = []
494         tgeo = str(grp.GetShapeType())
495         if tgeo == "VERTEX":
496             type = SMESH.NODE
497         elif tgeo == "EDGE":
498             type = SMESH.EDGE
499         elif tgeo == "FACE":
500             type = SMESH.FACE
501         elif tgeo == "SOLID":
502             type = SMESH.VOLUME
503         elif tgeo == "SHELL":
504             type = SMESH.VOLUME
505         elif tgeo == "COMPOUND":
506             tgeo = geompy.GetType(grp)
507             if tgeo == geompy.ShapeType["VERTEX"]:
508                 type = SMESH.NODE
509             elif tgeo == geompy.ShapeType["EDGE"]:
510                 type = SMESH.EDGE
511             elif tgeo == geompy.ShapeType["FACE"]:
512                 type = SMESH.FACE
513             elif tgeo == geompy.ShapeType["SOLID"]:
514                 type = SMESH.VOLUME
515
516         if type == []:
517             print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid"
518             return 0
519         else:
520             return self.mesh.CreateGroupFromGEOM(type, name, grp)
521
522     def ExportToMED(self, f, version, opt=0):
523         """
524          Export the mesh in a file with the MED format and choice the \a version of MED format
525          \param f is the file name
526          \param version values are smesh.MED_V2_1, smesh.MED_V2_2
527         """
528         self.mesh.ExportToMED(f, opt, version)
529
530     def ExportMED(self, f, opt=0):
531         """
532          Export the mesh in a file with the MED format
533          \param f is the file name
534         """
535         self.mesh.ExportMED(f, opt)
536
537     def ExportDAT(self, f):
538         """
539          Export the mesh in a file with the DAT format
540          \param f is the file name
541         """
542         self.mesh.ExportDAT(f)
543
544     def ExportUNV(self, f):
545         """
546          Export the mesh in a file with the UNV format
547          \param f is the file name
548         """
549         self.mesh.ExportUNV(f)
550
551     def ExportSTL(self, f, ascii=1):
552         """
553          Export the mesh in a file with the STL format
554          \param f is the file name
555          \param ascii defined the kind of file contents
556         """
557         self.mesh.ExportSTL(f, ascii)