test_senc3d_inconsistant_cube.c (5662B)
1 /* Copyright (C) 2018-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 "senc3d.h" 17 #include "test_senc3d_utils.h" 18 19 #include <rsys/double3.h> 20 21 /* The following array lists the indices toward the 3D vertices of each 22 * triangle. 23 * ,6---,7 ,6----7 24 * ,' | ,'/| ,' | \ | Y Z 25 * 2----3' / | 2', | \ | | ,' 26 * |', | / ,5 | ',4---,5 0----X 27 * | ',|/,' | ,' | ,' 28 * 0----1' 0----1' 29 * Front, right Back, left and 30 * and Top faces bottom faces */ 31 /* Triangle #0 rotation order is not consistant with other triangles */ 32 static unsigned 33 inconsistant_box_indices[12/*#triangles*/ * 3/*#indices per triangle*/] = { 34 0, 1, 2, 1, 2, 3, /* Front face */ 35 0, 4, 2, 2, 4, 6, /* Left face*/ 36 4, 5, 6, 6, 5, 7, /* Back face */ 37 3, 7, 1, 1, 7, 5, /* Right face */ 38 2, 6, 3, 3, 6, 7, /* Top face */ 39 0, 1, 4, 4, 1, 5 /* Bottom face */ 40 }; 41 static const unsigned inconsistant_box_ntriangles 42 = sizeof(inconsistant_box_indices) / (3 * sizeof(*inconsistant_box_indices)); 43 44 /* Media definitions reflect triangle #0 inconsistancy */ 45 static const unsigned 46 inconsistant_medium_front[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 47 static const unsigned 48 inconsistant_medium_back[12] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 49 static const double inconsistant_cube_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = { 50 10.0, 10.0, 10.0, 51 11.0, 10.0, 10.0, 52 10.0, 11.0, 10.0, 53 11.0, 11.0, 10.0, 54 10.0, 10.0, 11.0, 55 11.0, 10.0, 11.0, 56 10.0, 11.0, 11.0, 57 11.0, 11.0, 11.0 58 }; 59 60 static void 61 test(const int convention) 62 { 63 struct mem_allocator allocator; 64 struct senc3d_device* dev = NULL; 65 struct senc3d_scene* scn = NULL; 66 struct senc3d_enclosure* enclosure; 67 struct senc3d_enclosure_header header; 68 int conv; 69 int conv_front, conv_in; 70 struct context ctx = CONTEXT_NULL__; 71 unsigned i, e, ecount; 72 73 OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); 74 OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev)); 75 76 /* A 3D cube. 77 * 2 enclosures (inside, outside) sharing the same triangles, 78 * but opposite sides. 79 * What differs in this test is that triangle #0 vertices are given 80 * in the opposite rotation order. */ 81 ctx.positions = inconsistant_cube_vertices; 82 ctx.indices = inconsistant_box_indices; 83 ctx.front_media = inconsistant_medium_front; 84 ctx.back_media = inconsistant_medium_back; 85 86 OK(senc3d_scene_create(dev, convention, inconsistant_box_ntriangles, 87 get_indices, get_media, nvertices, get_position, &ctx, &scn)); 88 89 OK(senc3d_scene_get_enclosure_count(scn, &ecount)); 90 CHK(ecount == 2); 91 92 OK(senc3d_scene_get_convention(scn, &conv)); 93 CHK(conv == convention); 94 conv_front = (conv & SENC3D_CONVENTION_NORMAL_FRONT) != 0; 95 conv_in = (conv & SENC3D_CONVENTION_NORMAL_INSIDE) != 0; 96 97 FOR_EACH(e, 0, ecount) { 98 unsigned medium, expected_external_medium, expected_medium; 99 char name[128]; 100 enum senc3d_side side, expected_side; 101 unsigned gid; 102 (void)name; 103 OK(senc3d_scene_get_enclosure(scn, e, &enclosure)); 104 OK(senc3d_enclosure_get_header(enclosure, &header)); 105 CHK(header.enclosed_media_count == 1); 106 CHK(header.area == 6); 107 CHK(header.volume == (header.is_infinite ? -1 : 1)); 108 OK(senc3d_enclosure_get_medium(enclosure, 0, &medium)); 109 /* If NORMAL_FRONT the external enclosure's medium should be 0, 110 * 1 if NORMAL_BACK */ 111 expected_external_medium = conv_front ? 0 : 1; 112 expected_medium = (header.is_infinite ? 113 expected_external_medium : !expected_external_medium); 114 CHK(medium == expected_medium); 115 116 #ifdef DUMP_ENCLOSURES 117 sprintf(name, "test_inconsistant_cube_%s_%s_%u.obj", 118 conv_front ? "front" : "back", conv_in ? "in" : "out", e); 119 dump_enclosure(scn, e, name); 120 #endif 121 122 FOR_EACH(i, 0, header.primitives_count) { 123 int same, reversed, fst_reversed; 124 fst_reversed = ((e == 0) == conv_in); 125 expected_side = (inconsistant_medium_front[i] == expected_medium) 126 ? SENC3D_FRONT : SENC3D_BACK; 127 cmp_trg(i, enclosure, 128 inconsistant_box_indices + (3 * i), inconsistant_cube_vertices, 129 &same, &reversed); 130 /* Should be made of the same triangles */ 131 CHK(same); 132 CHK(i ? reversed != fst_reversed : reversed == fst_reversed); 133 OK(senc3d_enclosure_get_triangle_id(enclosure, i, &gid, &side)); 134 CHK(side == expected_side); 135 } 136 SENC3D(enclosure_ref_put(enclosure)); 137 } 138 139 SENC3D(scene_ref_put(scn)); 140 SENC3D(device_ref_put(dev)); 141 142 check_memory_allocator(&allocator); 143 mem_shutdown_proxy_allocator(&allocator); 144 CHK(mem_allocated_size() == 0); 145 } 146 147 int main(int argc, char** argv) 148 { 149 (void) argc, (void) argv; 150 151 test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE); 152 test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE); 153 test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_OUTSIDE); 154 test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE); 155 156 return 0; 157 }