star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

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 }