star-geometry-3d

Clean and decorate 3D geometries
git clone git://git.meso-star.fr/star-geometry-3d.git
Log | Files | Refs | README | LICENSE

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 }