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