test_sg3d_geometry_2.c (17789B)
1 /* Copyright (C) 2019, 2020, 2023, 2024 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "sg3d.h" 17 #include "test_sg3d_utils.h" 18 19 #include <stdio.h> 20 21 /* Manage add_geometry behaviour */ 22 struct add_geom_ctx { 23 unsigned add_cpt, merge_cpt; 24 res_T add_res, merge_res; 25 }; 26 27 static res_T 28 add_trg 29 (const unsigned unique_id, 30 const unsigned iseg, 31 void* context) 32 { 33 struct context* ctx = context; 34 struct add_geom_ctx* add_geom_ctx; 35 ASSERT(ctx); (void)unique_id; (void)iseg; 36 add_geom_ctx = ctx->custom; 37 if(add_geom_ctx->add_res == RES_OK) ++add_geom_ctx->add_cpt; 38 return add_geom_ctx->add_res; 39 } 40 41 static res_T 42 merge_trg 43 (const unsigned unique_id, 44 const unsigned itri, 45 const int reversed_triangle, 46 unsigned triangle_properties[SG3D_PROP_TYPES_COUNT__], 47 const unsigned merged_properties[SG3D_PROP_TYPES_COUNT__], 48 void* context, 49 int* merge_conflict) 50 { 51 struct context* ctx = context; 52 struct add_geom_ctx* add_geom_ctx; 53 int i; 54 ASSERT(ctx && triangle_properties && merged_properties && merge_conflict); 55 (void)unique_id; (void)itri; (void)reversed_triangle; 56 (void)triangle_properties; (void)merged_properties; 57 add_geom_ctx = ctx->custom; 58 if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt; 59 FOR_EACH(i, 0, SG3D_PROP_TYPES_COUNT__) 60 if(!sg3d_compatible_property(triangle_properties[i], merged_properties[i])) 61 *merge_conflict = 1; 62 return add_geom_ctx->merge_res; 63 } 64 65 static res_T 66 validate 67 (const unsigned itri, 68 const unsigned properties[SG3D_PROP_TYPES_COUNT__], 69 void* context, 70 int* properties_conflict) 71 { 72 (void)itri; (void)properties; (void)context; 73 *properties_conflict = 0; 74 return RES_OK; 75 } 76 77 static res_T 78 validate2 79 (const unsigned itri, 80 const unsigned properties[SG3D_PROP_TYPES_COUNT__], 81 void* context, 82 int* properties_conflict) 83 { 84 (void)itri; (void)properties; (void)context; 85 *properties_conflict = (itri % 2 == 0) ? 0 : (int)itri; 86 return RES_OK; 87 } 88 89 int 90 main(int argc, char** argv) 91 { 92 struct mem_allocator allocator; 93 struct sg3d_device* dev; 94 struct sg3d_geometry* geom; 95 struct context ctx = CONTEXT_NULL__; 96 struct sg3d_geometry_add_callbacks callbacks = SG3D_ADD_CALLBACKS_NULL__; 97 struct add_geom_ctx add_geom_ctx; 98 unsigned property[12]; 99 unsigned i; 100 const unsigned property_count = sizeof(property) / sizeof(*property); 101 unsigned count; 102 (void)argc, (void)argv; 103 104 OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); 105 OK(sg3d_device_create(NULL, &allocator, 1, &dev)); 106 OK(sg3d_geometry_create(dev, &geom)); 107 108 /* A 3D cube. 109 * 2 enclosures (inside, outside) sharing the same triangles, 110 * but opposite sides */ 111 ctx.positions = cube_vertices; 112 ctx.indices = cube_indices; 113 ctx.custom = &add_geom_ctx; 114 115 add_geom_ctx.add_cpt = add_geom_ctx.merge_cpt = 0; 116 add_geom_ctx.add_res = add_geom_ctx.merge_res = RES_OK; 117 118 /* Geometry with no media information on both sides */ 119 for(i = 0; i < property_count; i++) property[i] = SG3D_UNSPECIFIED_PROPERTY; 120 ctx.front_media = property; 121 ctx.back_media = property; 122 ctx.intface = property; 123 124 callbacks.get_indices = get_indices; 125 callbacks.get_properties = get_properties; 126 callbacks.get_position = get_position; 127 callbacks.add_triangle = add_trg; 128 callbacks.merge_triangle = merge_trg; 129 130 /* If add fails, add geometry fails the same way */ 131 add_geom_ctx.add_res = RES_BAD_ARG; 132 133 BA(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 134 CHK(add_geom_ctx.add_cpt == 0); 135 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 136 CHK(count == nvertices); 137 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 138 CHK(count == ntriangles); 139 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 140 CHK(count == 0); 141 add_geom_ctx.add_res = RES_MEM_ERR; 142 ME(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 143 CHK(add_geom_ctx.add_cpt == 0); 144 CHK(count == 0); 145 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 146 CHK(count == 2 * ntriangles); 147 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 148 CHK(count == 0); 149 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 150 CHK(count == 0); 151 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 152 CHK(count == 0); 153 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 154 CHK(count == 0); 155 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 156 CHK(count == 0); 157 158 /* Successful add geometry with add callback */ 159 add_geom_ctx.add_res = RES_OK; 160 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 161 CHK(add_geom_ctx.add_cpt == ntriangles); 162 CHK(add_geom_ctx.merge_cpt == 0); 163 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 164 CHK(count == nvertices); 165 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 166 CHK(count == 3 * ntriangles); 167 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 168 CHK(count == ntriangles); 169 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 170 CHK(count == ntriangles); 171 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 172 CHK(count == ntriangles); 173 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 174 CHK(count == 0); 175 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 176 CHK(count == 0); 177 178 OK(sg3d_geometry_dump_as_c_code(geom, stdout, "test_unspecified", 179 SG3D_C_DUMP_STATIC | SG3D_C_DUMP_CONST)); 180 181 /* Clear geometry */ 182 SG3D(geometry_ref_put(geom)); 183 OK(sg3d_geometry_create(dev, &geom)); 184 185 /* Successful add geometry without add callback */ 186 add_geom_ctx.add_cpt = 0; 187 callbacks.add_triangle = NULL; 188 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 189 CHK(add_geom_ctx.add_cpt == 0); 190 CHK(add_geom_ctx.merge_cpt == 0); 191 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 192 CHK(count == nvertices); 193 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 194 CHK(count == ntriangles); 195 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 196 CHK(count == ntriangles); 197 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 198 CHK(count == ntriangles); 199 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 200 CHK(count == ntriangles); 201 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 202 CHK(count == 0); 203 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 204 CHK(count == 0); 205 206 /* If merge fails, add geometry fails the same way */ 207 add_geom_ctx.merge_res = RES_BAD_ARG; 208 callbacks.add_triangle = add_trg; 209 BA(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 210 CHK(add_geom_ctx.merge_cpt == 0); 211 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 212 CHK(count == 2 * ntriangles); 213 add_geom_ctx.merge_res = RES_MEM_ERR; 214 ME(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 215 CHK(add_geom_ctx.merge_cpt == 0); 216 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 217 CHK(count == 3 * ntriangles); 218 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 219 CHK(count == nvertices); 220 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 221 CHK(count == ntriangles); 222 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 223 CHK(count == ntriangles); 224 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 225 CHK(count == ntriangles); 226 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 227 CHK(count == 0); /* merge failed but with a no-conflict status */ 228 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 229 CHK(count == 0); 230 231 /* Successful add geometry without merge callback */ 232 callbacks.merge_triangle = NULL; 233 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 234 CHK(add_geom_ctx.merge_cpt == 0); 235 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 236 CHK(count == nvertices); 237 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 238 CHK(count == 4 * ntriangles); 239 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 240 CHK(count == ntriangles); 241 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 242 CHK(count == ntriangles); 243 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 244 CHK(count == ntriangles); 245 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 246 CHK(count == 0); 247 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 248 CHK(count == 0); 249 250 /* Successful add geometry with merge callback */ 251 add_geom_ctx.merge_res = RES_OK; 252 callbacks.merge_triangle = merge_trg; 253 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 254 CHK(add_geom_ctx.merge_cpt == ntriangles); 255 add_geom_ctx.merge_cpt = 0; 256 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 257 CHK(count == nvertices); 258 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 259 CHK(count == 5 * ntriangles); 260 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 261 CHK(count == ntriangles); 262 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 263 CHK(count == ntriangles); 264 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 265 CHK(count == ntriangles); 266 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 267 CHK(count == 0); /* merge failed but with a no-conflict status */ 268 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 269 CHK(count == 0); 270 271 /* Geometry with media information on both sides */ 272 ctx.front_media = medium0; 273 ctx.back_media = medium1; 274 275 /* Clear geometry */ 276 SG3D(geometry_ref_put(geom)); 277 OK(sg3d_geometry_create(dev, &geom)); 278 279 /* Successful add geometry with add callback 280 * First half of the triangles, then all of them */ 281 add_geom_ctx.add_res = RES_OK; 282 OK(sg3d_geometry_add(geom, nvertices, ntriangles / 2, &callbacks, &ctx)); 283 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 284 CHK(count == ntriangles / 2); 285 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 286 CHK(add_geom_ctx.add_cpt == ntriangles); 287 CHK(add_geom_ctx.merge_cpt == ntriangles / 2); 288 add_geom_ctx.add_cpt = 0; 289 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 290 CHK(count == ntriangles + ntriangles / 2); 291 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 292 CHK(count == nvertices); 293 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 294 CHK(count == ntriangles); 295 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 296 CHK(count == 0); /* media where defined */ 297 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 298 CHK(count == ntriangles); /* interfaces where unspecified */ 299 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 300 CHK(count == 0); 301 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 302 CHK(count == 0); 303 OK(sg3d_geometry_dump_as_vtk(geom, stdout)); 304 /* Second add was half duplicated, so numbering is shifted */ 305 FOR_EACH(i, 0, ntriangles) { 306 unsigned id; 307 OK(sg3d_geometry_get_unique_triangle_user_id(geom, i, &id)); 308 CHK(i < ntriangles / 2 ? id == i : id == i + ntriangles / 2); 309 } 310 311 /* Clear geometry */ 312 SG3D(geometry_ref_put(geom)); 313 OK(sg3d_geometry_create(dev, &geom)); 314 add_geom_ctx.merge_cpt = 0; 315 316 /* Successful add geometry with add callback and no defined properties */ 317 add_geom_ctx.add_res = RES_OK; 318 callbacks.get_properties = NULL; 319 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 320 CHK(add_geom_ctx.add_cpt == ntriangles); 321 CHK(add_geom_ctx.merge_cpt == 0); 322 add_geom_ctx.add_cpt = 0; 323 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 324 CHK(count == nvertices); 325 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 326 CHK(count == ntriangles); 327 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 328 CHK(count == ntriangles); 329 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 330 CHK(count == ntriangles); /* media where unspecified */ 331 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 332 CHK(count == ntriangles); /* interfaces where unspecified */ 333 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 334 CHK(count == 0); 335 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 336 CHK(count == 0); 337 338 /* Define interface */ 339 ctx.intface = intface0; 340 341 /* Successful add geometry with merge callback and properties */ 342 add_geom_ctx.merge_res = RES_OK; 343 callbacks.get_properties = get_properties; 344 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 345 CHK(add_geom_ctx.merge_cpt == ntriangles); 346 add_geom_ctx.merge_cpt = 0; 347 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 348 CHK(count == nvertices); 349 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 350 CHK(count == 2 * ntriangles); 351 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 352 CHK(count == ntriangles); 353 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 354 CHK(count == 0); /* media where defined */ 355 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 356 CHK(count == 0); /* interfaces where defined */ 357 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 358 CHK(count == 0); 359 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 360 CHK(count == 0); 361 362 /* Geometry with incompatible media information on both sides */ 363 ctx.front_media = medium1; 364 ctx.back_media = medium0; 365 366 /* Add geometry without merge callback and conflicts */ 367 callbacks.merge_triangle = NULL; 368 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 369 CHK(add_geom_ctx.merge_cpt == 0); 370 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 371 CHK(count == nvertices); 372 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 373 CHK(count == 3 * ntriangles); 374 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 375 CHK(count == ntriangles); 376 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 377 CHK(count == 0); /* media where defined */ 378 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 379 CHK(count == 0); /* interfaces where defined */ 380 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 381 CHK(count == ntriangles); 382 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 383 CHK(count == 0); 384 385 /* Incompatible interface */ 386 ctx.intface = intface1; 387 388 /* Successful add geometry with merge callback */ 389 add_geom_ctx.merge_res = RES_OK; 390 callbacks.merge_triangle = merge_trg; 391 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 392 CHK(add_geom_ctx.merge_cpt == ntriangles); 393 add_geom_ctx.merge_cpt = 0; 394 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 395 CHK(count == nvertices); 396 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 397 CHK(count == 4 * ntriangles); 398 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 399 CHK(count == ntriangles); 400 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 401 CHK(count == 0); /* media where defined */ 402 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 403 CHK(count == 0); /* interfaces where defined */ 404 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 405 CHK(count == ntriangles); 406 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 407 CHK(count == 0); 408 409 /* Clear geometry */ 410 SG3D(geometry_ref_put(geom)); 411 OK(sg3d_geometry_create(dev, &geom)); 412 413 /* Successful add geometry with merge callback */ 414 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 415 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 416 CHK(count == 0); 417 418 OK(sg3d_geometry_validate_properties(geom, validate, NULL)); 419 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 420 CHK(count == 0); 421 OK(sg3d_geometry_dump_as_obj(geom, stdout, SG3D_OBJ_DUMP_ALL)); 422 423 OK(sg3d_geometry_validate_properties(geom, validate, NULL)); 424 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 425 CHK(count == 0); 426 427 OK(sg3d_geometry_validate_properties(geom, validate2, NULL)); 428 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 429 CHK(count == ntriangles / 2); 430 431 OK(sg3d_geometry_ref_put(geom)); 432 OK(sg3d_device_ref_put(dev)); 433 434 check_memory_allocator(&allocator); 435 mem_shutdown_proxy_allocator(&allocator); 436 CHK(mem_allocated_size() == 0); 437 return 0; 438 }