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_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 }