test_sg3d_geometry.c (13125B)
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 static res_T 22 validate 23 (const unsigned itri, 24 const unsigned properties[SG3D_PROP_TYPES_COUNT__], 25 void* context, 26 int* properties_conflict) 27 { 28 (void)itri; (void)properties; (void)context; 29 *properties_conflict = 0; 30 return RES_OK; 31 } 32 33 static res_T 34 merge_trg 35 (const unsigned user_id, 36 const unsigned itri, 37 const int reversed_triangle, 38 unsigned triangle_properties[SG3D_PROP_TYPES_COUNT__], 39 const unsigned merged_properties[SG3D_PROP_TYPES_COUNT__], 40 void* context, 41 int* merge_conflict) 42 { 43 ASSERT(triangle_properties && merged_properties && merge_conflict); 44 (void)user_id; (void)reversed_triangle; (void)context; 45 (void)triangle_properties; (void)merged_properties; (void)merge_conflict; 46 *merge_conflict = (int)itri; 47 return RES_OK; 48 } 49 50 static res_T 51 degenerated_triangle 52 (const unsigned itri, 53 void* context, 54 int* abort) 55 { 56 struct context* ctx = context; 57 ASSERT(abort && ctx); 58 (void)itri; 59 *abort = *(int*)ctx->custom; 60 return RES_OK; 61 } 62 63 int 64 main(int argc, char** argv) 65 { 66 struct mem_allocator allocator; 67 struct sg3d_device* dev; 68 struct sg3d_geometry* geom; 69 double coord[3]; 70 unsigned indices[3]; 71 const unsigned degenerated1[3] = { 0, 0, 0 }; 72 const unsigned degenerated2[3] = { 0, 1, 2 }; 73 const double degenerated_vertices[3/*#vertices*/ * 3/*#coords per vertex*/] 74 = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0, 0.0 }; 75 unsigned properties[SG3D_PROP_TYPES_COUNT__]; 76 struct sg3d_geometry_add_callbacks callbacks = SG3D_ADD_CALLBACKS_NULL__; 77 unsigned user_id; 78 unsigned count, i; 79 struct context ctx = CONTEXT_NULL__; 80 (void)argc, (void)argv; 81 82 OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); 83 OK(sg3d_device_create(NULL, &allocator, 1, &dev)); 84 85 BA(sg3d_geometry_create(NULL, &geom)); 86 BA(sg3d_geometry_create(dev, NULL)); 87 OK(sg3d_geometry_create(dev, &geom)); 88 89 BA(sg3d_geometry_ref_get(NULL)); 90 OK(sg3d_geometry_ref_get(geom)); 91 92 BA(sg3d_geometry_ref_put(NULL)); 93 OK(sg3d_geometry_ref_put(geom)); 94 OK(sg3d_geometry_ref_put(geom)); 95 96 OK(sg3d_geometry_create(dev, &geom)); 97 98 BA(sg3d_geometry_validate_properties(NULL, NULL, NULL)); 99 BA(sg3d_geometry_validate_properties(geom, NULL, NULL)); 100 BA(sg3d_geometry_validate_properties(NULL, validate, NULL)); 101 OK(sg3d_geometry_validate_properties(geom, validate, NULL)); 102 103 BA(sg3d_geometry_get_unique_vertices_count(NULL, NULL)); 104 BA(sg3d_geometry_get_unique_vertices_count(geom, NULL)); 105 BA(sg3d_geometry_get_unique_vertices_count(NULL, &count)); 106 OK(sg3d_geometry_get_unique_vertices_count(geom, &count)); 107 108 BA(sg3d_geometry_get_added_triangles_count(NULL, NULL)); 109 BA(sg3d_geometry_get_added_triangles_count(geom, NULL)); 110 BA(sg3d_geometry_get_added_triangles_count(NULL, &count)); 111 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 112 113 BA(sg3d_geometry_get_unique_triangles_count(NULL, NULL)); 114 BA(sg3d_geometry_get_unique_triangles_count(geom, NULL)); 115 BA(sg3d_geometry_get_unique_triangles_count(NULL, &count)); 116 OK(sg3d_geometry_get_unique_triangles_count(geom, &count)); 117 118 BA(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(NULL, NULL)); 119 BA(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, NULL)); 120 BA(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(NULL, &count)); 121 OK(sg3d_geometry_get_unique_triangles_with_unspecified_side_count(geom, &count)); 122 123 BA(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(NULL, NULL)); 124 BA(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, NULL)); 125 BA(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(NULL, &count)); 126 OK(sg3d_geometry_get_unique_triangles_with_unspecified_interface_count(geom, &count)); 127 128 BA(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(NULL, NULL)); 129 BA(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, NULL)); 130 BA(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(NULL, &count)); 131 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 132 133 BA(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(NULL, NULL)); 134 BA(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, NULL)); 135 BA(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(NULL, &count)); 136 OK(sg3d_geometry_get_unique_triangles_with_properties_conflict_count(geom, &count)); 137 138 BA(sg3d_geometry_dump_as_obj(NULL, NULL, 0)); 139 BA(sg3d_geometry_dump_as_obj(geom, NULL, 0)); 140 BA(sg3d_geometry_dump_as_obj(NULL, stdout, 0)); 141 BA(sg3d_geometry_dump_as_obj(NULL, NULL, SG3D_OBJ_DUMP_ALL)); 142 BA(sg3d_geometry_dump_as_obj(geom, stdout, 0)); 143 BA(sg3d_geometry_dump_as_obj(geom, NULL, SG3D_OBJ_DUMP_ALL)); 144 BA(sg3d_geometry_dump_as_obj(NULL, stdout, SG3D_OBJ_DUMP_ALL)); 145 /* BA because geometry is empty */ 146 BA(sg3d_geometry_dump_as_obj(geom, stdout, SG3D_OBJ_DUMP_ALL)); 147 148 BA(sg3d_geometry_dump_as_vtk(NULL, NULL)); 149 BA(sg3d_geometry_dump_as_vtk(geom, NULL)); 150 BA(sg3d_geometry_dump_as_vtk(NULL, stdout)); 151 /* BA because geometry is empty */ 152 BA(sg3d_geometry_dump_as_vtk(geom, stdout)); 153 154 BA(sg3d_geometry_dump_as_c_code(NULL, NULL, NULL, 0)); 155 BA(sg3d_geometry_dump_as_c_code(geom, NULL, NULL, 0)); 156 BA(sg3d_geometry_dump_as_c_code(NULL, stdout, NULL, 0)); 157 BA(sg3d_geometry_dump_as_c_code(NULL, NULL, "test", 0)); 158 BA(sg3d_geometry_dump_as_c_code(geom, NULL, "test", 0)); 159 BA(sg3d_geometry_dump_as_c_code(NULL, stdout, "test", 0)); 160 /* BA because geometry is empty */ 161 BA(sg3d_geometry_dump_as_c_code(geom, stdout, NULL, 0)); 162 BA(sg3d_geometry_dump_as_c_code(geom, stdout, "test", 0)); 163 164 BA(sg3d_geometry_add(NULL, 0, 0, &callbacks, NULL)); 165 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 166 CHK(count == 0); 167 BA(sg3d_geometry_add(geom, nvertices, ntriangles, NULL, NULL)); 168 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 169 CHK(count == ntriangles); 170 /* Mandatory callbacks are NULL */ 171 callbacks.get_indices = NULL; 172 callbacks.get_position = get_position; 173 BA(sg3d_geometry_add(geom, 0, 0, &callbacks, NULL)); 174 callbacks.get_indices = get_indices; 175 callbacks.get_position = NULL; 176 BA(sg3d_geometry_add(geom, 0, 0, &callbacks, NULL)); 177 callbacks.get_indices = NULL; 178 callbacks.get_position = NULL; 179 BA(sg3d_geometry_add(geom, 0, 0, &callbacks, NULL)); 180 /* Add 0 items */ 181 callbacks.get_indices = get_indices; 182 callbacks.get_position = get_position; 183 OK(sg3d_geometry_add(geom, 0, 0, &callbacks, NULL)); 184 OK(sg3d_geometry_get_added_triangles_count(geom, &count)); 185 CHK(count == ntriangles); 186 187 /* A 3D cube. 188 * 2 enclosures (inside, outside) sharing the same triangles, 189 * but opposite sides */ 190 ctx.positions = cube_vertices; 191 ctx.indices = cube_indices; 192 ctx.front_media = medium0; 193 ctx.back_media = medium1; 194 ctx.intface = intface0; 195 196 callbacks.get_indices = get_indices; 197 callbacks.get_properties = get_properties; 198 callbacks.get_position = get_position; 199 200 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 201 OK(sg3d_geometry_dump_as_obj(geom, stdout, SG3D_OBJ_DUMP_ALL)); 202 OK(sg3d_geometry_dump_as_vtk(geom, stdout)); 203 OK(sg3d_geometry_dump_as_c_code(geom, stdout, NULL, 0)); 204 OK(sg3d_geometry_dump_as_c_code(geom, stdout, "test", 205 SG3D_C_DUMP_STATIC | SG3D_C_DUMP_CONST)); 206 207 BA(sg3d_geometry_get_unique_vertex(NULL, ntriangles, NULL)); 208 BA(sg3d_geometry_get_unique_vertex(geom, ntriangles, NULL)); 209 BA(sg3d_geometry_get_unique_vertex(NULL, 0, NULL)); 210 BA(sg3d_geometry_get_unique_vertex(NULL, ntriangles, coord)); 211 BA(sg3d_geometry_get_unique_vertex(geom, 0, NULL)); 212 BA(sg3d_geometry_get_unique_vertex(geom, ntriangles, coord)); 213 BA(sg3d_geometry_get_unique_vertex(NULL, 0, coord)); 214 OK(sg3d_geometry_get_unique_vertex(geom, 0, coord)); 215 216 BA(sg3d_geometry_get_unique_triangle_vertices(NULL, ntriangles, NULL)); 217 BA(sg3d_geometry_get_unique_triangle_vertices(geom, ntriangles, NULL)); 218 BA(sg3d_geometry_get_unique_triangle_vertices(NULL, 0, NULL)); 219 BA(sg3d_geometry_get_unique_triangle_vertices(NULL, ntriangles, indices)); 220 BA(sg3d_geometry_get_unique_triangle_vertices(geom, 0, NULL)); 221 BA(sg3d_geometry_get_unique_triangle_vertices(geom, ntriangles, indices)); 222 BA(sg3d_geometry_get_unique_triangle_vertices(NULL, 0, indices)); 223 OK(sg3d_geometry_get_unique_triangle_vertices(geom, 0, indices)); 224 FOR_EACH(i, 0 , 3) CHK(indices[i] == cube_indices[i]); 225 226 BA(sg3d_geometry_get_unique_triangle_properties(NULL, ntriangles, NULL)); 227 BA(sg3d_geometry_get_unique_triangle_properties(geom, ntriangles, NULL)); 228 BA(sg3d_geometry_get_unique_triangle_properties(NULL, 0, NULL)); 229 BA(sg3d_geometry_get_unique_triangle_properties(NULL, ntriangles, properties)); 230 BA(sg3d_geometry_get_unique_triangle_properties(geom, 0, NULL)); 231 BA(sg3d_geometry_get_unique_triangle_properties(geom, ntriangles, properties)); 232 BA(sg3d_geometry_get_unique_triangle_properties(NULL, 0, properties)); 233 OK(sg3d_geometry_get_unique_triangle_properties(geom, 0, properties)); 234 CHK(medium0[0] == properties[SG3D_FRONT]); 235 CHK(medium1[0] == properties[SG3D_BACK]); 236 CHK(intface0[0] == properties[SG3D_INTFACE]); 237 238 BA(sg3d_geometry_get_unique_triangle_user_id(NULL, ntriangles, NULL)); 239 BA(sg3d_geometry_get_unique_triangle_user_id(geom, ntriangles, NULL)); 240 BA(sg3d_geometry_get_unique_triangle_user_id(NULL, 0, NULL)); 241 BA(sg3d_geometry_get_unique_triangle_user_id(NULL, ntriangles, &user_id)); 242 BA(sg3d_geometry_get_unique_triangle_user_id(geom, 0, NULL)); 243 BA(sg3d_geometry_get_unique_triangle_user_id(geom, ntriangles, &user_id)); 244 BA(sg3d_geometry_get_unique_triangle_user_id(NULL, 0, &user_id)); 245 OK(sg3d_geometry_get_unique_triangle_user_id(geom, 0, &user_id)); 246 /* Due to a failed attempt to add ntriangles triangles, user_id for the 247 * first successfully added triangle is shifted */ 248 CHK(user_id == ntriangles); 249 250 /* Conflicts with merge_trg callback */ 251 callbacks.merge_triangle = merge_trg; 252 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 253 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 254 /* Due to merge_trg internals, all but the first triangle have conflict */ 255 CHK(count == ntriangles - 1); 256 OK(sg3d_geometry_dump_as_obj(geom, stdout, SG3D_OBJ_DUMP_ALL)); 257 OK(sg3d_geometry_dump_as_vtk(geom, stdout)); 258 /* BA because of conflicts */ 259 BA(sg3d_geometry_dump_as_c_code(geom, stdout, "test", SG3D_C_DUMP_STATIC)); 260 OK(sg3d_geometry_ref_put(geom)); 261 262 /* Conflicts without merge_trg callback */ 263 OK(sg3d_geometry_create(dev, &geom)); 264 callbacks.merge_triangle = NULL; 265 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 266 ctx.front_media = medium1_front0; 267 OK(sg3d_geometry_add(geom, nvertices, ntriangles, &callbacks, &ctx)); 268 OK(sg3d_geometry_get_unique_triangles_with_merge_conflict_count(geom, &count)); 269 FOR_EACH(i, 0, ntriangles) if(medium0[i] != medium1_front0[i]) count--; 270 CHK(count == 0); 271 OK(sg3d_geometry_dump_as_obj(geom, stdout, SG3D_OBJ_DUMP_ALL)); 272 OK(sg3d_geometry_dump_as_vtk(geom, stdout)); 273 /* BA because of conflicts */ 274 BA(sg3d_geometry_dump_as_c_code(geom, stdout, "test", SG3D_C_DUMP_CONST)); 275 276 /* Degenerated triangles: duplicated vertex */ 277 ctx.indices = degenerated1; 278 /* Without callback : OK */ 279 OK(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 280 /* With callback : OK */ 281 callbacks.degenerated_triangle = degenerated_triangle; 282 ctx.custom = &i; 283 i = 0; 284 OK(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 285 /* With callback : KO */ 286 i = 1; 287 BA(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 288 289 /* Degenerated triangles: flat triangle */ 290 ctx.indices = degenerated2; 291 ctx.positions = degenerated_vertices; 292 callbacks.degenerated_triangle = NULL; 293 /* Without callback : OK */ 294 OK(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 295 /* With callback : OK */ 296 callbacks.degenerated_triangle = degenerated_triangle; 297 ctx.custom = &i; 298 i = 0; 299 OK(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 300 /* With callback : KO */ 301 i = 1; 302 BA(sg3d_geometry_add(geom, nvertices, 1, &callbacks, &ctx)); 303 304 OK(sg3d_geometry_ref_put(geom)); 305 OK(sg3d_device_ref_put(dev)); 306 307 check_memory_allocator(&allocator); 308 mem_shutdown_proxy_allocator(&allocator); 309 CHK(mem_allocated_size() == 0); 310 return 0; 311 }