test_sphin_load_geometry.c (9419B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 25 #include "sphin.h" 26 27 #include <rsys/math.h> 28 #include <rsys/mem_allocator.h> 29 30 #include <stdio.h> 31 #include <string.h> 32 33 struct sphin; 34 35 static void 36 write_stl_test_files 37 (void) 38 { 39 FILE* file; 40 static const char* test0 = 41 "solid\n" 42 " facet normal 0.0 -1.0 0.0\n" 43 " outer loop\n" 44 " vertex 0.0 0.0 0.0\n" 45 " vertex 1.0 0.0 0.0\n" 46 " vertex 0.0 0.0 1.0\n" 47 " endloop\n" 48 " endfacet\n" 49 "endsolid"; 50 static const char* test1 = 51 "solid\n" 52 " facet normal 0.0 0.0 -1.0\n" 53 " outer loop\n" 54 " vertex 0.0 0.0 0.0\n" 55 " vertex 1.935 0.0 0.0\n" 56 " vertex 0.0 0.0 3.142\n" 57 " endloop\n" 58 " endfacet\n" 59 "endsolid"; 60 file = fopen("test_0.stl", "w"); 61 CHK(file != NULL); 62 fwrite(test0, sizeof(char), strlen(test0), file); 63 fclose(file); 64 file = fopen("test_1.stl", "w"); 65 CHK(file != NULL); 66 fwrite(test1, sizeof(char), strlen(test1), file); 67 fclose(file); 68 file = fopen("test_2.stl", "w"); 69 CHK(file != NULL); 70 fprintf(file, "solid cube\n"); 71 fprintf(file, "facet normal 0.0 0.0 1.0\n"); 72 fprintf(file, " outer loop\n"); 73 fprintf(file, " vertex -1 -1 -1\n"); 74 fprintf(file, " vertex 1 -1 -1\n"); 75 fprintf(file, " vertex 1 1 -1\n"); 76 fprintf(file, " endloop\n"); 77 fprintf(file, "endfacet\n"); 78 fprintf(file, "facet normal 0.0 0.0 1.0\n"); 79 fprintf(file, " outer loop\n"); 80 fprintf(file, " vertex -1 -1 -1\n"); 81 fprintf(file, " vertex 1 1 -1\n"); 82 fprintf(file, " vertex -1 1 -1\n"); 83 fprintf(file, " endloop\n"); 84 fprintf(file, "endfacet\n"); 85 fprintf(file, "facet normal 0.0 0.0 1.0\n"); 86 fprintf(file, " outer loop\n"); 87 fprintf(file, " vertex -1 -1 1\n"); 88 fprintf(file, " vertex 1 -1 1\n"); 89 fprintf(file, " vertex 1 1 1\n"); 90 fprintf(file, " endloop\n"); 91 fprintf(file, "endfacet\n"); 92 fprintf(file, "facet normal 0.0 0.0 1.0\n"); 93 fprintf(file, " outer loop\n"); 94 fprintf(file, " vertex -1 -1 1\n"); 95 fprintf(file, " vertex 1 1 1\n"); 96 fprintf(file, " vertex -1 1 1\n"); 97 fprintf(file, " endloop\n"); 98 fprintf(file, "endfacet\n"); 99 fprintf(file, "facet normal 0.0 -1.0 0.0\n"); 100 fprintf(file, " outer loop\n"); 101 fprintf(file, " vertex -1 -1 -1\n"); 102 fprintf(file, " vertex 1 -1 -1\n"); 103 fprintf(file, " vertex 1 -1 1\n"); 104 fprintf(file, " endloop\n"); 105 fprintf(file, "endfacet\n"); 106 fprintf(file, "facet normal 0.0 -1.0 0.0\n"); 107 fprintf(file, " outer loop\n"); 108 fprintf(file, " vertex -1 -1 -1\n"); 109 fprintf(file, " vertex 1 -1 1\n"); 110 fprintf(file, " vertex -1 -1 1\n"); 111 fprintf(file, " endloop\n"); 112 fprintf(file, "endfacet\n"); 113 fprintf(file, "facet normal 0.0 1.0 0.0\n"); 114 fprintf(file, " outer loop\n"); 115 fprintf(file, " vertex 1 1 -1\n"); 116 fprintf(file, " vertex -1 1 -1\n"); 117 fprintf(file, " vertex -1 1 1\n"); 118 fprintf(file, " endloop\n"); 119 fprintf(file, "endfacet\n"); 120 fprintf(file, "facet normal 0.0 1.0 0.0\n"); 121 fprintf(file, " outer loop\n"); 122 fprintf(file, " vertex 1 1 -1\n"); 123 fprintf(file, " vertex -1 1 1\n"); 124 fprintf(file, " vertex 1 1 1\n"); 125 fprintf(file, " endloop\n"); 126 fprintf(file, "endfacet\n"); 127 fprintf(file, "facet normal 1.0 0.0 0.0\n"); 128 fprintf(file, " outer loop\n"); 129 fprintf(file, " vertex -1 -1 -1\n"); 130 fprintf(file, " vertex -1 1 -1\n"); 131 fprintf(file, " vertex -1 1 1\n"); 132 fprintf(file, " endloop\n"); 133 fprintf(file, "endfacet\n"); 134 fprintf(file, "facet normal 1.0 0.0 0.0\n"); 135 fprintf(file, " outer loop\n"); 136 fprintf(file, " vertex -1 -1 -1\n"); 137 fprintf(file, " vertex -1 1 1\n"); 138 fprintf(file, " vertex -1 -1 1\n"); 139 fprintf(file, " endloop\n"); 140 fprintf(file, "endfacet\n"); 141 fprintf(file, "facet normal 1.0 0.0 0.0\n"); 142 fprintf(file, " outer loop\n"); 143 fprintf(file, " vertex 1 -1 -1\n"); 144 fprintf(file, " vertex 1 1 -1\n"); 145 fprintf(file, " vertex 1 1 1\n"); 146 fprintf(file, " endloop\n"); 147 fprintf(file, "endfacet\n"); 148 fprintf(file, "facet normal 1.0 0.0 0.0\n"); 149 fprintf(file, " outer loop\n"); 150 fprintf(file, " vertex 1 -1 -1\n"); 151 fprintf(file, " vertex 1 1 1\n"); 152 fprintf(file, " vertex 1 -1 1\n"); 153 fprintf(file, " endloop\n"); 154 fprintf(file, "endfacet\n"); 155 fprintf(file, "endsolid cube\n"); 156 fclose(file); 157 } 158 159 static void 160 test_geometry_api 161 (struct sphin* sphin) 162 { 163 const char* path = "file.txt"; 164 size_t nsurfaces, ngeometries, igeometry; 165 struct sphin_config* config = NULL; 166 struct sphin_surface* surface = NULL; 167 struct sphin_geometry* geom = NULL; 168 struct sphin_geometry_descriptor desc = SPHIN_GEOMETRY_DESCRIPTOR_NULL; 169 170 FILE* fp = NULL; 171 172 CHK(fp = fopen(path, "w+")); 173 fprintf(fp, "\t\t surface : \"surface name\"\n"); 174 fprintf(fp, "\tgeometry: FRONT test_0.stl\t\n"); 175 fprintf(fp, "\tgeometry: BACK test_1.stl\t\n"); 176 fprintf(fp, "\tgeometry: BACK test_2.stl\n"); 177 fprintf(fp, "\tgeometry: BACK test_1.stl cm\t\n"); 178 fprintf(fp, "\tgeometry: BACK test_1.stl mm\t\n"); 179 fprintf(fp, "\tgeometry: BACK test_1.stl km\t\n"); 180 fclose(fp); 181 182 CHK(sphin_load(sphin, path, &config) == RES_OK); 183 CHK(sphin_config_get_surface_count(config, &nsurfaces) == RES_OK); 184 CHK(nsurfaces == 1); 185 CHK(sphin_config_get_surface(config, 0, &surface) == RES_OK); 186 CHK(sphin_surface_get_geometry_count(NULL, &ngeometries) == RES_BAD_ARG); 187 CHK(sphin_surface_get_geometry_count(surface, &ngeometries) == RES_OK); 188 CHK(ngeometries == 6); 189 190 igeometry = 0; 191 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 192 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 193 CHK(strcmp(desc.filename, "test_0.stl") == 0); 194 CHK(desc.side == SPHIN_SIDE_FRONT); 195 CHK(desc.mesh.triangle_count == 1); 196 CHK(desc.mesh.vertex_count == 3); 197 198 igeometry++; 199 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 200 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 201 CHK(desc.side == SPHIN_SIDE_BACK); 202 CHK(desc.mesh.triangle_count == 1); 203 CHK(desc.mesh.vertex_count == 3); 204 CHK(strcmp(desc.filename, "test_1.stl") == 0); 205 206 igeometry++; 207 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 208 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 209 CHK(desc.side == SPHIN_SIDE_BACK); 210 CHK(desc.mesh.triangle_count == 12); 211 CHK(desc.mesh.vertex_count == 8); 212 CHK(strcmp(desc.filename, "test_2.stl") == 0); 213 214 /* Test geometry units */ 215 216 /* In the following assertions, we use an epsilon (tolerable error) of 1e-6 217 * instead of the 1e-15 used elsewhere in sphin. This is because, although 218 * sphin performs all computations using doubles, the third-party library 219 * star-stl, which is used to parse STL files, handles mesh coordinates 220 * using floats (even though those are exposed as doubles by sphin). 221 * As a result, the precision of geometrical coordinates is 222 * limited to approximately six digits. */ 223 224 igeometry++; 225 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 226 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 227 CHK(eq_eps(desc.mesh.coords[3], 0.01935, 1e-9)); 228 CHK(eq_eps(desc.mesh.coords[8], 0.03142, 1e-9)); 229 230 igeometry++; 231 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 232 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 233 CHK(eq_eps(desc.mesh.coords[3], 0.001935, 1e-8)); 234 CHK(eq_eps(desc.mesh.coords[8], 0.003142, 1e-8)); 235 236 igeometry++; 237 CHK(sphin_surface_get_geometry(surface, igeometry, &geom) == RES_OK); 238 CHK(sphin_geometry_get_desc(geom, &desc) == RES_OK); 239 CHK(eq_eps(desc.mesh.coords[3], 1935, 1e-3)); 240 CHK(eq_eps(desc.mesh.coords[8], 3142, 1e-3)); 241 242 CHK(sphin_geometry_ref_get(NULL) == RES_BAD_ARG); 243 CHK(sphin_geometry_ref_put(NULL) == RES_BAD_ARG); 244 CHK(sphin_geometry_ref_get(geom) == RES_OK); 245 CHK(sphin_geometry_ref_put(geom) == RES_OK); 246 CHK(sphin_config_ref_put(config) == RES_OK); 247 } 248 249 int 250 main(int argc, char** argv) 251 { 252 struct sphin* sphin = NULL; 253 struct sphin_create_args args = SPHIN_CREATE_ARGS_DEFAULT; 254 255 (void)argc; 256 (void)argv; 257 258 args.verbose = 1; 259 sphin_create(&args, &sphin); 260 261 write_stl_test_files(); 262 test_geometry_api(sphin); 263 264 CHK(sphin_ref_put(sphin) == RES_OK); 265 266 CHK(mem_allocated_size() == 0); 267 return 0; 268 }