Salome HOME
[bos #40653][CEA] New mesh import export formats with meshio.
[modules/smesh.git] / test / SMESH_MeshioFiles.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # =======================================
22 # Testing export/import of sample meshes from meshio repository
23 #  File   : SMESH_MeshioFiles.py
24 #  Module : SMESH
25
26 import tempfile
27 import subprocess
28 import os
29 from pathlib import Path
30
31 from SMESH_MeshioShapes import export_mesh, import_file
32
33
34 def supported_extensions():
35     """
36     Returns a list of format extensions that salome already supports
37     for import/export operations.
38     """
39
40     return [
41         '.med',
42         '.unv',
43         '.stl',
44         '.cgns',
45         '.mesh',
46         '.meshb'
47     ]
48
49
50 def convert(source_file, target_file, errors):
51     """
52     Converts files with meshio shell command.
53     """
54     try:
55         cmd = 'meshio convert {} {}'.format(source_file, target_file)
56         print('{} start...'.format(cmd))
57
58         subprocess.run(['meshio', 'convert', source_file, target_file], check=True)
59
60         return True
61
62     except Exception:
63         source_ext = Path(source_file).suffix.upper()
64         target_ext = Path(target_file).suffix.upper()
65
66         errors.append('[{} -> {}]: {} failed!'.format(source_ext, target_ext, cmd))
67
68         return False
69
70
71 def print_errors(errors):
72     """
73     Checks if we have got any saved error messages and print them.
74     """
75
76     if not len(errors):
77         return
78
79     print('\nErrors:')
80     for idx, err in enumerate(errors):
81         print('{:02}: {}'.format(idx, err))
82
83     print('\n===============================================')
84
85
86 def perform_ext(directory, ext, errors):
87     """
88     Exports a given mesh and imports it back for each mesh file
89     through a file with a given extension.
90     It uses shell meshio convert command for conversion.
91     """
92
93     for subdir, _, files in os.walk(directory):
94         for file in files:
95
96             # Skip helper files
97             if file.endswith('.md') or file.endswith('Makefile'):
98                 continue
99
100             filepath = os.path.join(subdir, file)
101
102             with tempfile.NamedTemporaryFile(suffix=ext) as temp_file:
103                 temp_file.close() # prevents PermissionError on Windows
104                 if not convert(filepath, temp_file.name, errors):
105                     continue
106
107                 file_extension = Path(file).suffix
108                 with tempfile.NamedTemporaryFile(suffix=file_extension) as temp_file_back:
109                     temp_file.close() # prevents PermissionError on Windows
110                     temp_file_back.close() # prevents PermissionError on Windows
111                     convert(temp_file.name, temp_file_back.name, errors)
112
113
114 def test_shell(directory, errors):
115     """
116     Iterates salome extensions and convert meshes through
117     a corresponding format.
118     .
119     """
120
121     for ext in supported_extensions():
122         perform_ext(directory, ext, errors)
123
124
125 def test_salome(directory, errors):
126     """
127     Iterates over mesh files in a given directory and tries to import
128     them into salome and export back to a temp file with the same format.
129     """
130
131     for subdir, _, files in os.walk(directory):
132         for file in files:
133
134             # Skip helper files
135             if file.endswith('.md') or file.endswith('Makefile'):
136                 continue
137
138             # Skip files those have issues with current meshio version
139             if (file.endswith('.f3grid') or
140                 file.endswith('.ugrid') or
141                 file.endswith('.su2') or
142                 file.endswith('element_elset.inp') or
143                 file.endswith('insulated-4.1.msh') or
144                 file.endswith('insulated-2.2.msh') or
145                 file.endswith('simple1')):
146                 continue
147
148             filepath = os.path.join(subdir, file)
149
150             # Import a file
151             mesh = import_file(filepath, errors)
152             if not mesh:
153                 continue
154
155             file_extension = Path(file).suffix
156             with tempfile.NamedTemporaryFile(suffix=file_extension) as temp_file:
157                 temp_file.close() # prevents PermissionError on Windows
158                 export_mesh(mesh, temp_file.name, errors)
159
160
161 def test():
162     """
163     Tests import/export of meshes from a given directory
164     and prints errors if we have any.
165     """
166
167     errors = []
168     directory = 'data/meshio_meshes'
169
170     # Only for debug purpose.
171     # Uncomment if you need to test meshio library shell command itself.
172     # test_shell(directory, errors)
173
174     test_salome(directory, errors)
175
176     print_errors(errors)
177     assert not len(errors)
178
179
180 if __name__ == "__main__":
181     test()