test_senc3d_unspecified_medium.c (10647B)
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 /* This test has been created using the sg3_geometry_dump_as_C_code feature 17 * of star-geometry. It uses output from test_sg3_unspecified_properties. 18 * This test is similar to test_senc3d_many_enclosures that creates a huge 19 * geometry by program. */ 20 21 #include "senc3d.h" 22 #include "test_senc3d_utils.h" 23 24 #include <rsys/double3.h> 25 26 #define SG3D_UNSPECIFIED_PROPERTY UINT_MAX 27 28 /* Dump of star-geometry 'front_unspecified'. */ 29 static const unsigned front_unspecified_vertices_count = 8; 30 static const double front_unspecified_vertices[24] = 31 { 32 0.1, 0, 0, 33 1, 0, 0, 34 0, 1, 0, 35 1, 1, 0, 36 0, 0, 1.1, 37 1, 0, 1, 38 0, 1, 1, 39 1, 1.1, 1 40 }; 41 static const unsigned front_unspecified_triangles_count = 12; 42 static const unsigned front_unspecified_triangles[36] = 43 { 44 0, 2, 1, 45 1, 2, 3, 46 0, 4, 2, 47 2, 4, 6, 48 4, 5, 6, 49 6, 5, 7, 50 3, 7, 1, 51 1, 7, 5, 52 2, 6, 3, 53 3, 6, 7, 54 0, 1, 4, 55 4, 1, 5 56 }; 57 static const unsigned front_unspecified_properties[36] = 58 { 59 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 60 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 61 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 62 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 63 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 64 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 65 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 66 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 67 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 68 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 69 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 70 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY 71 }; 72 /* Dump of star-geometry 'front_half_unspecified'. */ 73 static const unsigned front_half_unspecified_vertices_count = 8; 74 static const double front_half_unspecified_vertices[24] = 75 { 76 0.1, 0, 0, 77 1, 0, 0, 78 0, 1, 0, 79 1, 1, 0, 80 0, 0, 1.1, 81 1, 0, 1, 82 0, 1, 1, 83 1, 1.1, 1 84 }; 85 static const unsigned front_half_unspecified_triangles_count = 12; 86 static const unsigned front_half_unspecified_triangles[36] = 87 { 88 0, 2, 1, 89 1, 2, 3, 90 0, 4, 2, 91 2, 4, 6, 92 4, 5, 6, 93 6, 5, 7, 94 3, 7, 1, 95 1, 7, 5, 96 2, 6, 3, 97 3, 6, 7, 98 0, 1, 4, 99 4, 1, 5 100 }; 101 static const unsigned front_half_unspecified_properties[36] = 102 { 103 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 104 0, 1, 0, 105 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 106 0, 1, 0, 107 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 108 0, 1, 0, 109 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 110 0, 1, 0, 111 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 112 0, 1, 0, 113 SG3D_UNSPECIFIED_PROPERTY, 1, SG3D_UNSPECIFIED_PROPERTY, 114 0, 1, 0 115 }; 116 /* Dump of star-geometry 'all_defined'. */ 117 static const unsigned all_defined_vertices_count = 8; 118 static const double all_defined_vertices[24] = 119 { 120 0.1, 0, 0, 121 1, 0, 0, 122 0, 1, 0, 123 1, 1, 0, 124 0, 0, 1.1, 125 1, 0, 1, 126 0, 1, 1, 127 1, 1.1, 1 128 }; 129 static const unsigned all_defined_triangles_count = 12; 130 static const unsigned all_defined_triangles[36] = 131 { 132 0, 2, 1, 133 1, 2, 3, 134 0, 4, 2, 135 2, 4, 6, 136 4, 5, 6, 137 6, 5, 7, 138 3, 7, 1, 139 1, 7, 5, 140 2, 6, 3, 141 3, 6, 7, 142 0, 1, 4, 143 4, 1, 5 144 }; 145 static const unsigned all_defined_properties[36] = 146 { 147 0, 1, 0, 148 0, 1, 0, 149 0, 1, 0, 150 0, 1, 0, 151 0, 1, 0, 152 0, 1, 0, 153 0, 1, 0, 154 0, 1, 0, 155 0, 1, 0, 156 0, 1, 0, 157 0, 1, 0, 158 0, 1, 0 159 }; 160 161 #undef SG3D_UNSPECIFIED_PROPERTY 162 163 static void 164 test(const int convention) 165 { 166 struct mem_allocator allocator; 167 struct senc3d_device* dev = NULL; 168 struct senc3d_scene* scn = NULL; 169 struct senc3d_enclosure* enclosure; 170 struct senc3d_enclosure_header header; 171 unsigned medium, expected_external_medium, expected_internal_medium; 172 unsigned gid; 173 enum senc3d_side side; 174 struct context ctx = CONTEXT_NULL__; 175 unsigned i, t, ecount; 176 const int conv_front = (convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0; 177 178 OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); 179 OK(senc3d_device_create(NULL, &allocator, SENC3D_NTHREADS_DEFAULT, 1, &dev)); 180 181 /* Geometry with no media information on both sides */ 182 ctx.positions = front_unspecified_vertices; 183 ctx.indices = front_unspecified_triangles; 184 ctx.properties = front_unspecified_properties; 185 OK(senc3d_scene_create(dev, convention, front_unspecified_triangles_count, 186 get_indices, get_media_from_properties, front_unspecified_vertices_count, 187 get_position, &ctx, &scn)); 188 189 OK(senc3d_scene_get_enclosure_count(scn, &ecount)); 190 CHK(ecount == 2); 191 192 FOR_EACH(i, 0, ecount) { 193 struct senc3d_enclosure* ee; 194 struct senc3d_enclosure_header hh; 195 unsigned cc; 196 OK(senc3d_scene_get_enclosure(scn, i, &enclosure)); 197 OK(senc3d_enclosure_get_header(enclosure, &header)); 198 199 CHK(header.enclosure_id == i); 200 CHK(header.enclosed_media_count == 1); 201 202 OK(senc3d_enclosure_get_medium(enclosure, 0, &medium)); 203 /* Geometrical normals point outside the cube in input triangles: 204 * if convention is front, front medium (unspecified) is outside, 205 * that is medium 0's enclosure is infinite */ 206 expected_external_medium = conv_front ? SENC3D_UNSPECIFIED_MEDIUM : 1; 207 expected_internal_medium = conv_front ? 1 : SENC3D_UNSPECIFIED_MEDIUM; 208 209 CHK(medium == (header.is_infinite 210 ? expected_external_medium : expected_internal_medium)); 211 CHK(header.primitives_count == ntriangles); 212 CHK(header.unique_primitives_count == ntriangles); 213 CHK(header.vertices_count == nvertices); 214 CHK(header.is_infinite == (i == 0)); 215 216 OK(senc3d_scene_get_enclosure_count_by_medium(scn, medium, &cc)); 217 CHK(cc == 1); 218 OK(senc3d_scene_get_enclosure_by_medium(scn, medium, 0, &ee)); 219 OK(senc3d_enclosure_get_header(ee, &hh)); 220 CHK(header.enclosure_id == hh.enclosure_id); 221 OK(senc3d_enclosure_ref_put(ee)); 222 223 FOR_EACH(t, 0, header.primitives_count) { 224 unsigned ind[3]; 225 OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side)); 226 CHK(gid == t); 227 CHK(side == (medium == 1) ? SENC3D_BACK : SENC3D_FRONT); 228 OK(senc3d_enclosure_get_triangle(enclosure, t, ind)); 229 } 230 OK(senc3d_enclosure_ref_put(enclosure)); 231 } 232 OK(senc3d_scene_ref_put(scn)); 233 234 /* Same geometry, front media are defined for odd triangles */ 235 ctx.positions = front_half_unspecified_vertices; 236 ctx.indices = front_half_unspecified_triangles; 237 ctx.properties = front_half_unspecified_properties; 238 OK(senc3d_scene_create(dev, convention, front_half_unspecified_triangles_count, 239 get_indices, get_media_from_properties, front_half_unspecified_vertices_count, 240 get_position, &ctx, &scn)); 241 242 OK(senc3d_scene_get_enclosure_count(scn, &ecount)); 243 CHK(ecount == 2); 244 245 FOR_EACH(i, 0, ecount) { 246 unsigned expected_external_media_count, expected_internal_media_count, 247 expected_media_count; 248 OK(senc3d_scene_get_enclosure(scn, i, &enclosure)); 249 OK(senc3d_enclosure_get_header(enclosure, &header)); 250 251 CHK(header.enclosure_id == i); 252 253 OK(senc3d_enclosure_get_medium(enclosure, 0, &medium)); 254 /* Geometrical normals point outside the cube in input triangles: 255 * if convention is front, front medium is outside and the enclosure 256 * contains 2 media */ 257 expected_external_media_count = conv_front ? 2 : 1; 258 expected_internal_media_count = conv_front ? 1 : 2; 259 expected_media_count = header.is_infinite 260 ? expected_external_media_count : expected_internal_media_count; 261 CHK(header.enclosed_media_count == expected_media_count); 262 OK(senc3d_enclosure_ref_put(enclosure)); 263 } 264 OK(senc3d_scene_ref_put(scn)); 265 266 /* Same geometry, all media are defined */ 267 ctx.positions = all_defined_vertices; 268 ctx.indices = all_defined_triangles; 269 ctx.properties = all_defined_properties; 270 OK(senc3d_scene_create(dev, convention, all_defined_triangles_count, 271 get_indices, get_media_from_properties, all_defined_vertices_count, 272 get_position, &ctx, &scn)); 273 274 OK(senc3d_scene_get_enclosure_count(scn, &ecount)); 275 CHK(ecount == 2); 276 277 FOR_EACH(i, 0, ecount) { 278 struct senc3d_enclosure* ee; 279 struct senc3d_enclosure_header hh; 280 unsigned cc; 281 OK(senc3d_scene_get_enclosure(scn, i, &enclosure)); 282 OK(senc3d_enclosure_get_header(enclosure, &header)); 283 284 CHK(header.enclosure_id == i); 285 CHK(header.enclosed_media_count == 1); 286 OK(senc3d_enclosure_get_medium(enclosure, 0, &medium)); 287 /* Geometrical normals point outside the cube in input triangles: 288 * if convention is front, front medium (0) is outside, 289 * that is medium 0's enclosure is infinite */ 290 CHK(conv_front == ((medium == 0) == header.is_infinite)); 291 CHK(header.primitives_count == ntriangles); 292 CHK(header.unique_primitives_count == ntriangles); 293 CHK(header.vertices_count == nvertices); 294 CHK(header.is_infinite == (i == 0)); 295 296 OK(senc3d_scene_get_enclosure_count_by_medium(scn, medium, &cc)); 297 CHK(cc == 1); 298 OK(senc3d_scene_get_enclosure_by_medium(scn, medium, 0, &ee)); 299 OK(senc3d_enclosure_get_header(ee, &hh)); 300 CHK(header.enclosure_id == hh.enclosure_id); 301 OK(senc3d_enclosure_ref_put(ee)); 302 303 FOR_EACH(t, 0, header.primitives_count) { 304 OK(senc3d_enclosure_get_triangle_id(enclosure, t, &gid, &side)); 305 CHK(gid == t); 306 CHK(side == (medium == 1) ? SENC3D_BACK : SENC3D_FRONT); 307 } 308 OK(senc3d_enclosure_ref_put(enclosure)); 309 } 310 311 SENC3D(scene_ref_put(scn)); 312 SENC3D(device_ref_put(dev)); 313 314 check_memory_allocator(&allocator); 315 mem_shutdown_proxy_allocator(&allocator); 316 CHK(mem_allocated_size() == 0); 317 } 318 319 int 320 main(int argc, char** argv) 321 { 322 (void) argc, (void) argv; 323 test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_INSIDE); 324 test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_INSIDE); 325 test(SENC3D_CONVENTION_NORMAL_FRONT | SENC3D_CONVENTION_NORMAL_OUTSIDE); 326 test(SENC3D_CONVENTION_NORMAL_BACK | SENC3D_CONVENTION_NORMAL_OUTSIDE); 327 return 0; 328 }