star-geometry-2d

Cleaning and decorating 2D geometries
git clone git://git.meso-star.fr/star-geometry-2d.git
Log | Files | Refs | README | LICENSE

test_sg2_geometry_2.c (17626B)


      1 /* Copyright (C) 2019, 2020, 2023 |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 "sg2.h"
     17 #include "test_sg2d_utils.h"
     18 
     19 #include <stdio.h>
     20 
     21  /* Manage add_geometry behaviour */
     22 struct add_geom_ctx {
     23   unsigned add_cpt, merge_cpt;
     24   res_T add_res, merge_res;
     25 };
     26 
     27 static res_T
     28 add_seg
     29   (const unsigned unique_id,
     30    const unsigned iseg,
     31    void* context)
     32 {
     33   struct context* ctx = context;
     34   struct add_geom_ctx* add_geom_ctx;
     35   ASSERT(ctx); (void)unique_id; (void)iseg;
     36   add_geom_ctx = ctx->custom;
     37   if(add_geom_ctx->add_res == RES_OK) ++add_geom_ctx->add_cpt;
     38   return add_geom_ctx->add_res;
     39 }
     40 
     41 static res_T
     42 merge_seg
     43   (const unsigned unique_id,
     44    const unsigned iseg,
     45    const int reversed_segment,
     46    unsigned segment_properties[SG2D_PROP_TYPES_COUNT__],
     47    const unsigned merged_properties[SG2D_PROP_TYPES_COUNT__],
     48    void* context,
     49    int* merge_conflict)
     50 {
     51   struct context* ctx = context;
     52   struct add_geom_ctx* add_geom_ctx;
     53   int i;
     54   ASSERT(ctx && segment_properties && merged_properties && merge_conflict);
     55   (void)unique_id; (void)iseg; (void)reversed_segment;
     56   (void)segment_properties; (void)merged_properties;
     57   add_geom_ctx = ctx->custom;
     58   if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt;
     59   FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__)
     60     if(!sg2d_compatible_property(segment_properties[i], merged_properties[i]))
     61       *merge_conflict = 1;
     62   return add_geom_ctx->merge_res;
     63 }
     64 
     65 static res_T
     66 validate
     67   (const unsigned iseg,
     68    const unsigned properties[SG2D_PROP_TYPES_COUNT__],
     69    void* context,
     70    int* properties_conflict)
     71 {
     72   (void)iseg; (void)properties; (void)context;
     73   *properties_conflict = 0;
     74   return RES_OK;
     75 }
     76 
     77 static res_T
     78 validate2
     79   (const unsigned iseg,
     80    const unsigned properties[SG2D_PROP_TYPES_COUNT__],
     81    void* context,
     82    int* properties_conflict)
     83 {
     84   (void)iseg; (void)properties; (void)context;
     85   *properties_conflict = (iseg % 2 == 0) ? 0 : (int)iseg;
     86   return RES_OK;
     87 }
     88 
     89 int
     90 main(int argc, char** argv)
     91 {
     92   struct mem_allocator allocator;
     93   struct sg2d_device* dev;
     94   struct sg2d_geometry* geom;
     95   struct context ctx = CONTEXT_NULL__;
     96   struct sg2d_geometry_add_callbacks callbacks = SG2D_ADD_CALLBACKS_NULL__;
     97   struct add_geom_ctx add_geom_ctx;
     98   unsigned property[12];
     99   unsigned i;
    100   const unsigned property_count = sizeof(property) / sizeof(*property);
    101   unsigned count;
    102   (void)argc, (void)argv;
    103   
    104   OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
    105   OK(sg2d_device_create(NULL, &allocator, 1, &dev));
    106   OK(sg2d_geometry_create(dev, &geom));
    107 
    108   /* A 2D square.
    109    * 2 enclosures (inside, outside) sharing the same segments,
    110    * but opposite sides */
    111   ctx.positions = square_vertices;
    112   ctx.indices = box_indices;
    113   ctx.custom = &add_geom_ctx;
    114 
    115   add_geom_ctx.add_cpt = add_geom_ctx.merge_cpt = 0;
    116   add_geom_ctx.add_res = add_geom_ctx.merge_res = RES_OK;
    117 
    118   /* Geometry with no media information on both sides */
    119   for(i = 0; i < property_count; i++) property[i] = SG2D_UNSPECIFIED_PROPERTY;
    120   ctx.front_media = property;
    121   ctx.back_media = property;
    122   ctx.intface = property;
    123 
    124   callbacks.get_indices = get_indices;
    125   callbacks.get_properties = get_properties;
    126   callbacks.get_position = get_position;
    127   callbacks.add_segment = add_seg;
    128   callbacks.merge_segment = merge_seg;
    129 
    130   /* If add fails, add geometry fails the same way */
    131   add_geom_ctx.add_res = RES_BAD_ARG;
    132 
    133   BA(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    134   CHK(add_geom_ctx.add_cpt == 0);
    135   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    136   CHK(count == nvertices);
    137   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    138   CHK(count == nsegments);
    139   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    140   CHK(count == 0);
    141   add_geom_ctx.add_res = RES_MEM_ERR;
    142   ME(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    143   CHK(add_geom_ctx.add_cpt == 0);
    144   CHK(count == 0);
    145   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    146   CHK(count == 2 * nsegments);
    147   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    148   CHK(count == 0);
    149   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    150   CHK(count == 0);
    151   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    152   CHK(count == 0);
    153   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    154   CHK(count == 0);
    155   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    156   CHK(count == 0);
    157 
    158   /* Successful add geometry with add callback */
    159   add_geom_ctx.add_res = RES_OK;
    160   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    161   CHK(add_geom_ctx.add_cpt == nsegments);
    162   CHK(add_geom_ctx.merge_cpt == 0);
    163   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    164   CHK(count == nvertices);
    165   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    166   CHK(count == 3 * nsegments);
    167   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    168   CHK(count == nsegments);
    169   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    170   CHK(count == nsegments);
    171   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    172   CHK(count == nsegments);
    173   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    174   CHK(count == 0);
    175   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    176   CHK(count == 0);
    177 
    178   OK(sg2d_geometry_dump_as_c_code(geom, stdout, "test_unspecified",
    179     SG2D_C_DUMP_STATIC | SG2D_C_DUMP_CONST));
    180 
    181   /* Clear geometry */
    182   SG2(geometry_ref_put(geom));
    183   OK(sg2d_geometry_create(dev, &geom));
    184 
    185   /* Successful add geometry without add callback */
    186   add_geom_ctx.add_cpt = 0;
    187   callbacks.add_segment = NULL;
    188   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    189   CHK(add_geom_ctx.add_cpt == 0);
    190   CHK(add_geom_ctx.merge_cpt == 0);
    191   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    192   CHK(count == nvertices);
    193   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    194   CHK(count == nsegments);
    195   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    196   CHK(count == nsegments);
    197   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    198   CHK(count == nsegments);
    199   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    200   CHK(count == nsegments);
    201   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    202   CHK(count == 0);
    203   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    204   CHK(count == 0);
    205 
    206   /* If merge fails, add geometry fails the same way */
    207   add_geom_ctx.merge_res = RES_BAD_ARG;
    208   callbacks.add_segment = add_seg;
    209   BA(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    210   CHK(add_geom_ctx.merge_cpt == 0);
    211   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    212   CHK(count == 2 * nsegments);
    213   add_geom_ctx.merge_res = RES_MEM_ERR;
    214   ME(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    215   CHK(add_geom_ctx.merge_cpt == 0);
    216   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    217   CHK(count == 3 * nsegments);
    218   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    219   CHK(count == nvertices);
    220   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    221   CHK(count == nsegments);
    222   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    223   CHK(count == nsegments);
    224   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    225   CHK(count == nsegments);
    226   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    227   CHK(count == 0); /* merge failed but with a no-conflict status */
    228   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    229   CHK(count == 0);
    230 
    231   /* Successful add geometry without merge callback */
    232   callbacks.merge_segment = NULL;
    233   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    234   CHK(add_geom_ctx.merge_cpt == 0);
    235   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    236   CHK(count == nvertices);
    237   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    238   CHK(count == 4 * nsegments);
    239   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    240   CHK(count == nsegments);
    241   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    242   CHK(count == nsegments);
    243   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    244   CHK(count == nsegments);
    245   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    246   CHK(count == 0);
    247   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    248   CHK(count == 0);
    249 
    250   /* Successful add geometry with merge callback */
    251   add_geom_ctx.merge_res = RES_OK;
    252   callbacks.merge_segment = merge_seg;
    253   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    254   CHK(add_geom_ctx.merge_cpt == nsegments);
    255   add_geom_ctx.merge_cpt = 0;
    256   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    257   CHK(count == nvertices);
    258   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    259   CHK(count == 5 * nsegments);
    260   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    261   CHK(count == nsegments);
    262   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    263   CHK(count == nsegments);
    264   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    265   CHK(count == nsegments);
    266   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    267   CHK(count == 0); /* merge failed but with a no-conflict status */
    268   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    269   CHK(count == 0);
    270 
    271   /* Geometry with media information on both sides */
    272   ctx.front_media = medium0;
    273   ctx.back_media = medium1;
    274 
    275   /* Clear geometry */
    276   SG2(geometry_ref_put(geom));
    277   OK(sg2d_geometry_create(dev, &geom));
    278 
    279   /* Successful add geometry with add callback
    280    * First half of the segments, then all of them */
    281   add_geom_ctx.add_res = RES_OK;
    282   OK(sg2d_geometry_add(geom, nvertices, nsegments / 2, &callbacks, &ctx));
    283   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    284   CHK(count == nsegments / 2);
    285   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    286   CHK(add_geom_ctx.add_cpt == nsegments);
    287   CHK(add_geom_ctx.merge_cpt == nsegments / 2);
    288   add_geom_ctx.add_cpt = 0;
    289   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    290   CHK(count == nsegments + nsegments / 2);
    291   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    292   CHK(count == nvertices);
    293   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    294   CHK(count == nsegments);
    295   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    296   CHK(count == 0); /* media where defined */
    297   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    298   CHK(count == nsegments); /* interfaces where unspecified */
    299   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    300   CHK(count == 0);
    301   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    302   CHK(count == 0);
    303   OK(sg2d_geometry_dump_as_vtk(geom, stdout));
    304   /* Second add was half duplicated, so numbering is shifted */
    305   FOR_EACH(i, 0, nsegments) {
    306     unsigned id;
    307     OK(sg2d_geometry_get_unique_segment_user_id(geom, i, &id));
    308     CHK(i < nsegments / 2 ? id == i : id == i + nsegments / 2);
    309   }
    310 
    311   /* Clear geometry */
    312   SG2(geometry_ref_put(geom));
    313   OK(sg2d_geometry_create(dev, &geom));
    314   add_geom_ctx.merge_cpt = 0;
    315 
    316   /* Successful add geometry with add callback and no defined properties */
    317   add_geom_ctx.add_res = RES_OK;
    318   callbacks.get_properties = NULL;
    319   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    320   CHK(add_geom_ctx.add_cpt == nsegments);
    321   CHK(add_geom_ctx.merge_cpt == 0);
    322   add_geom_ctx.add_cpt = 0;
    323   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    324   CHK(count == nvertices);
    325   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    326   CHK(count == nsegments);
    327   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    328   CHK(count == nsegments);
    329   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    330   CHK(count == nsegments); /* media where unspecified */
    331   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    332   CHK(count == nsegments); /* interfaces where unspecified */
    333   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    334   CHK(count == 0);
    335   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    336   CHK(count == 0);
    337 
    338   /* Define interface */
    339   ctx.intface = intface0;
    340 
    341   /* Successful add geometry with merge callback and properties */
    342   add_geom_ctx.merge_res = RES_OK;
    343   callbacks.get_properties = get_properties;
    344   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    345   CHK(add_geom_ctx.merge_cpt == nsegments);
    346   add_geom_ctx.merge_cpt = 0;
    347   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    348   CHK(count == nvertices);
    349   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    350   CHK(count == 2 * nsegments);
    351   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    352   CHK(count == nsegments);
    353   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    354   CHK(count == 0); /* media where defined */
    355   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    356   CHK(count == 0); /* interfaces where defined */
    357   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    358   CHK(count == 0);
    359   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    360   CHK(count == 0);
    361 
    362   /* Geometry with incompatible media information on both sides */
    363   ctx.front_media = medium1;
    364   ctx.back_media = medium0;
    365 
    366   /* Add geometry without merge callback and conflicts */
    367   callbacks.merge_segment = NULL;
    368   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    369   CHK(add_geom_ctx.merge_cpt == 0);
    370   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    371   CHK(count == nvertices);
    372   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    373   CHK(count == 3 * nsegments);
    374   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    375   CHK(count == nsegments);
    376   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    377   CHK(count == 0); /* media where defined */
    378   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    379   CHK(count == 0); /* interfaces where defined */
    380   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    381   CHK(count == nsegments);
    382   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    383   CHK(count == 0);
    384 
    385   /* Incompatible interface */
    386   ctx.intface = intface1;
    387 
    388   /* Successful add geometry with merge callback */
    389   add_geom_ctx.merge_res = RES_OK;
    390   callbacks.merge_segment = merge_seg;
    391   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    392   CHK(add_geom_ctx.merge_cpt == nsegments);
    393   add_geom_ctx.merge_cpt = 0;
    394   OK(sg2d_geometry_get_unique_vertices_count(geom, &count));
    395   CHK(count == nvertices);
    396   OK(sg2d_geometry_get_added_segments_count(geom, &count));
    397   CHK(count == 4 * nsegments);
    398   OK(sg2d_geometry_get_unique_segments_count(geom, &count));
    399   CHK(count == nsegments);
    400   OK(sg2d_geometry_get_unique_segments_with_unspecified_side_count(geom, &count));
    401   CHK(count == 0); /* media where defined */
    402   OK(sg2d_geometry_get_unique_segments_with_unspecified_interface_count(geom, &count));
    403   CHK(count == 0); /* interfaces where defined */
    404   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    405   CHK(count == nsegments);
    406   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    407   CHK(count == 0);
    408 
    409   /* Clear geometry */
    410   SG2(geometry_ref_put(geom));
    411   OK(sg2d_geometry_create(dev, &geom));
    412 
    413   /* Successful add geometry with merge callback */
    414   OK(sg2d_geometry_add(geom, nvertices, nsegments, &callbacks, &ctx));
    415   OK(sg2d_geometry_get_unique_segments_with_merge_conflict_count(geom, &count));
    416   CHK(count == 0);
    417 
    418   OK(sg2d_geometry_validate_properties(geom, validate, NULL));
    419   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    420   CHK(count == 0);
    421   OK(sg2d_geometry_dump_as_obj(geom, stdout, SG2D_OBJ_DUMP_ALL));
    422 
    423   OK(sg2d_geometry_validate_properties(geom, validate, NULL));
    424   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    425   CHK(count == 0);
    426 
    427   OK(sg2d_geometry_validate_properties(geom, validate2, NULL));
    428   OK(sg2d_geometry_get_unique_segments_with_properties_conflict_count(geom, &count));
    429   CHK(count == nsegments / 2);
    430 
    431   OK(sg2d_geometry_ref_put(geom));
    432   OK(sg2d_device_ref_put(dev));
    433 
    434   check_memory_allocator(&allocator);
    435   mem_shutdown_proxy_allocator(&allocator);
    436   CHK(mem_allocated_size() == 0);
    437   return 0;
    438 }