Salome HOME
fe237e511c83a47bde0b8043dce92de8526f0f28
[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, fineness):
210         """
211          Define "AutomaticLength" hypothesis
212          \param fineness for the fineness [0-1]
213         """
214         hyp = self.Hypothesis("AutomaticLength")
215         hyp.SetFineness( fineness )
216         return hyp
217
218 # Public class: Mesh_Segment_Python
219 # ---------------------------------
220
221 class Mesh_Segment_Python(Mesh_Segment):
222     """
223     Class to define a segment 1D algorithm for discretization with python function
224     """
225
226     def __init__(self, mesh, geom=0):
227         """
228          Private constructor
229         """
230         import Python1dPlugin
231         self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
232
233     def PythonSplit1D(self, n, func):
234         """
235          Define "PythonSplit1D" hypothesis based on the Erwan Adam patch, awaiting equivalent SALOME functionality
236          \param n for the number of segments that cut an edge
237          \param func for the python function that calculate the length of all segments
238         """
239         hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so")
240         hyp.SetNumberOfSegments(n)
241         hyp.SetPythonLog10RatioFunction(func)
242         return hyp
243
244 # Public class: Mesh_Triangle
245 # ---------------------------
246
247 class Mesh_Triangle(Mesh_Algorithm):
248     """
249     Class to define a triangle 2D algorithm
250     """
251
252     def __init__(self, mesh, geom=0):
253         """
254          Private constructor
255         """
256         self.Create(mesh, geom, "MEFISTO_2D")
257
258     def MaxElementArea(self, area):
259         """
260          Define "MaxElementArea" hypothesis to give the maximun area of each triangles
261          \param area for the maximum area of each triangles
262         """
263         hyp = self.Hypothesis("MaxElementArea", [area])
264         hyp.SetMaxElementArea(area)
265         return hyp
266
267     def LengthFromEdges(self):
268         """
269          Define "LengthFromEdges" hypothesis to build triangles based on the length of the edges taken from the wire
270         """
271         return self.Hypothesis("LengthFromEdges")
272
273 # Public class: Mesh_Quadrangle
274 # -----------------------------
275
276 class Mesh_Quadrangle(Mesh_Algorithm):
277     """
278     Class to define a quadrangle 2D algorithm
279     """
280
281     def __init__(self, mesh, geom=0):
282         """
283          Private constructor
284         """
285         self.Create(mesh, geom, "Quadrangle_2D")
286
287     def QuadranglePreference(self):
288         """
289          Define "QuadranglePreference" hypothesis, forcing construction
290          of quadrangles if the number of nodes on opposite edges is not the same
291          in the case where the global number of nodes on edges is even
292         """
293         hyp = self.Hypothesis("QuadranglePreference")
294         return hyp
295
296 # Public class: Mesh_Tetrahedron
297 # ------------------------------
298
299 class Mesh_Tetrahedron(Mesh_Algorithm):
300     """
301     Class to define a tetrahedron 3D algorithm
302     """
303
304     def __init__(self, mesh, algo, geom=0):
305         """
306          Private constructor
307         """
308         if algo == NETGEN:
309             self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
310         elif algo == GHS3D:
311             import GHS3DPlugin
312             self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
313
314     def MaxElementVolume(self, vol):
315         """
316          Define "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedral
317          \param vol for the maximum volume of each tetrahedral
318         """
319         hyp = self.Hypothesis("MaxElementVolume", [vol])
320         hyp.SetMaxElementVolume(vol)
321         return hyp
322
323 # Public class: Mesh_Hexahedron
324 # ------------------------------
325
326 class Mesh_Hexahedron(Mesh_Algorithm):
327     """
328     Class to define a hexahedron 3D algorithm
329     """
330
331     def __init__(self, mesh, geom=0):
332         """
333          Private constructor
334         """
335         self.Create(mesh, geom, "Hexa_3D")
336
337 # Public class: Mesh
338 # ==================
339
340 class Mesh:
341     """
342     Class to define a mesh
343     """
344
345     geom = 0
346     mesh = 0
347
348     def __init__(self, geom, name=0):
349         """
350          Constructor
351
352          Creates mesh on the shape \a geom,
353          sets GUI name of this mesh to \a name.
354          \param geom Shape to be meshed
355          \param name Study name of the mesh
356         """
357         self.geom = geom
358         self.mesh = smesh.CreateMesh(geom)
359         if name == 0:
360             SetName(self.mesh, GetName(geom))
361         else:
362             SetName(self.mesh, name)
363
364     def GetMesh(self):
365         """
366          Method that returns the mesh
367         """
368         return self.mesh
369
370     def GetShape(self):
371         """
372          Method that returns the shape associated to the mesh
373         """
374         return self.geom
375
376     def MeshDimension(self):
377         """
378         Returns mesh dimension depending on shape one
379         """
380         shells = geompy.SubShapeAllIDs( self.geom, geompy.ShapeType["SHELL"] )
381         if len( shells ) > 0 :
382             return 3
383         elif geompy.NumberOfFaces( self.geom ) > 0 :
384             return 2
385         elif geompy.NumberOfEdges( self.geom ) > 0 :
386             return 1
387         else:
388             return 0;
389         pass
390
391     def Segment(self, algo=REGULAR, geom=0):
392         """
393          Creates a segment discretization 1D algorithm.
394          If the optional \a algo parameter is not sets, this algorithm is REGULAR.
395          If the optional \a geom parameter is not sets, this algorithm is global.
396          Otherwise, this algorithm define a submesh based on \a geom subshape.
397          \param algo values are smesh.REGULAR or smesh.PYTHON for discretization via python function
398          \param geom If defined, subshape to be meshed
399         """
400         ## if Segment(geom) is called by mistake
401         if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
402             algo, geom = geom, algo
403             pass
404         if algo == REGULAR:
405             return Mesh_Segment(self, geom)
406         elif algo == PYTHON:
407             return Mesh_Segment_Python(self, geom)
408         else:
409             return Mesh_Segment(self, geom)
410
411     def Triangle(self, geom=0):
412         """
413          Creates a triangle 2D algorithm for faces.
414          If the optional \a geom parameter is not sets, this algorithm is global.
415          Otherwise, this algorithm define a submesh based on \a geom subshape.
416          \param geom If defined, subshape to be meshed
417         """
418         return Mesh_Triangle(self, geom)
419
420     def Quadrangle(self, geom=0):
421         """
422          Creates a quadrangle 2D algorithm for faces.
423          If the optional \a geom parameter is not sets, this algorithm is global.
424          Otherwise, this algorithm define a submesh based on \a geom subshape.
425          \param geom If defined, subshape to be meshed
426         """
427         return Mesh_Quadrangle(self, geom)
428
429     def Tetrahedron(self, algo, geom=0):
430         """
431          Creates a tetrahedron 3D algorithm for solids.
432          The parameter \a algo permits to choice the algorithm: NETGEN or GHS3D
433          If the optional \a geom parameter is not sets, this algorithm is global.
434          Otherwise, this algorithm define a submesh based on \a geom subshape.
435          \param algo values are: smesh.NETGEN, smesh.GHS3D
436          \param geom If defined, subshape to be meshed
437         """
438         ## if Tetrahedron(geom) is called by mistake
439         if ( isinstance( algo, geompy.GEOM._objref_GEOM_Object)):
440             algo, geom = geom, algo
441             pass
442         return Mesh_Tetrahedron(self, algo, geom)
443
444     def Hexahedron(self, geom=0):
445         """
446          Creates a hexahedron 3D algorithm for solids.
447          If the optional \a geom parameter is not sets, this algorithm is global.
448          Otherwise, this algorithm define a submesh based on \a geom subshape.
449          \param geom If defined, subshape to be meshed
450         """
451         return Mesh_Hexahedron(self, geom)
452
453     def Compute(self):
454         """
455          Compute the mesh and return the status of the computation
456         """
457         b = smesh.Compute(self.mesh, self.geom)
458         if salome.sg.hasDesktop():
459             smeshgui = salome.ImportComponentGUI("SMESH")
460             smeshgui.Init(salome.myStudyId)
461             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), b )
462             salome.sg.updateObjBrowser(1)
463         return b
464
465     def AutomaticTetrahedralization(self):
466         """
467         Compute tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
468         """
469         dim = self.MeshDimension()
470         # assign hypotheses
471         self.RemoveGlobalHypotheses()
472         self.Segment().AutomaticLength()
473         if dim > 1 :
474             self.Triangle().LengthFromEdges()
475             pass
476         if dim > 2 :
477             self.Tetrahedron(NETGEN)
478             pass
479         return self.Compute()
480
481     def AutomaticHexahedralization(self):
482         """
483         Compute hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
484         """
485         dim = self.MeshDimension()
486         # assign hypotheses
487         self.RemoveGlobalHypotheses()
488         self.Segment().AutomaticLength()
489         if dim > 1 :
490             self.Quadrangle()
491             pass
492         if dim > 2 :
493             self.Hexahedron()            
494             pass
495         return self.Compute()
496
497     def RemoveGlobalHypotheses(self):
498         """
499         Removes all global hypotheses
500         """
501         current_hyps = self.mesh.GetHypothesisList( self.geom )
502         for hyp in current_hyps:
503             self.mesh.RemoveHypothesis( self.geom, hyp )
504             pass
505         pass
506
507     def Group(self, grp, name=""):
508         """
509          Create a mesh group based on geometric object \a grp
510          and give a \a name, if this parameter is not defined
511          the name is the same as the geometric group name
512          \param grp  is a geometric group, a vertex, an edge, a face or a solid
513          \param name is the name of the mesh group
514         """
515         if name == "":
516             name = grp.GetName()
517
518         type = []
519         tgeo = str(grp.GetShapeType())
520         if tgeo == "VERTEX":
521             type = SMESH.NODE
522         elif tgeo == "EDGE":
523             type = SMESH.EDGE
524         elif tgeo == "FACE":
525             type = SMESH.FACE
526         elif tgeo == "SOLID":
527             type = SMESH.VOLUME
528         elif tgeo == "SHELL":
529             type = SMESH.VOLUME
530         elif tgeo == "COMPOUND":
531             tgeo = geompy.GetType(grp)
532             if tgeo == geompy.ShapeType["VERTEX"]:
533                 type = SMESH.NODE
534             elif tgeo == geompy.ShapeType["EDGE"]:
535                 type = SMESH.EDGE
536             elif tgeo == geompy.ShapeType["FACE"]:
537                 type = SMESH.FACE
538             elif tgeo == geompy.ShapeType["SOLID"]:
539                 type = SMESH.VOLUME
540
541         if type == []:
542             print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid"
543             return 0
544         else:
545             return self.mesh.CreateGroupFromGEOM(type, name, grp)
546
547     def ExportToMED(self, f, version, opt=0):
548         """
549          Export the mesh in a file with the MED format and choice the \a version of MED format
550          \param f is the file name
551          \param version values are smesh.MED_V2_1, smesh.MED_V2_2
552         """
553         self.mesh.ExportToMED(f, opt, version)
554
555     def ExportMED(self, f, opt=0):
556         """
557          Export the mesh in a file with the MED format
558          \param f is the file name
559         """
560         self.mesh.ExportMED(f, opt)
561
562     def ExportDAT(self, f):
563         """
564          Export the mesh in a file with the DAT format
565          \param f is the file name
566         """
567         self.mesh.ExportDAT(f)
568
569     def ExportUNV(self, f):
570         """
571          Export the mesh in a file with the UNV format
572          \param f is the file name
573         """
574         self.mesh.ExportUNV(f)
575
576     def ExportSTL(self, f, ascii=1):
577         """
578          Export the mesh in a file with the STL format
579          \param f is the file name
580          \param ascii defined the kind of file contents
581         """
582         self.mesh.ExportSTL(f, ascii)