star-enclosures-2d

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

senc2d_descriptor.c (6098B)


      1 /* Copyright (C) 2018-2021, 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 "senc2d_enclosure_c.h"
     17 #include "senc2d_scene_c.h"
     18 #include "senc2d.h"
     19 
     20 #include <rsys/rsys.h>
     21 #include <rsys/double2.h>
     22 #include <rsys/mem_allocator.h>
     23 
     24 /******************************************************************************
     25  * Exported functions
     26  *****************************************************************************/
     27 res_T
     28 senc2d_scene_get_max_medium
     29   (const struct senc2d_scene* scn, medium_id_t* max_medium_id)
     30 {
     31   if(!scn || !max_medium_id) return RES_BAD_ARG;
     32   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
     33     return RES_BAD_OP;
     34   *max_medium_id = scn->next_medium_idx - 1;
     35   return RES_OK;
     36 }
     37 
     38 res_T
     39 senc2d_scene_get_enclosure_count
     40   (const struct senc2d_scene* scn, enclosure_id_t* count)
     41 {
     42   if(!scn || !count) return RES_BAD_ARG;
     43   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
     44     return RES_BAD_OP;
     45   ASSERT(scn->analyze.enclosures_count ==
     46     darray_enclosure_size_get(&scn->analyze.enclosures));
     47   *count = scn->analyze.enclosures_count;
     48   return RES_OK;
     49 }
     50 
     51 res_T
     52 senc2d_scene_get_enclosure_count_by_medium
     53   (const struct senc2d_scene* scn,
     54    const medium_id_t imed,
     55    enclosure_id_t* count)
     56 {
     57   size_t tmp;
     58   size_t m_idx;
     59   const struct darray_enc_id* enc_ids;
     60   if(!scn || !count
     61     || (imed != SENC2D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
     62     return RES_BAD_ARG;
     63   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
     64     return RES_BAD_OP;
     65   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
     66     == 1 + scn->next_medium_idx);
     67   m_idx = medium_id_2_medium_idx(imed);
     68   enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
     69     + m_idx;
     70   tmp = darray_enc_id_size_get(enc_ids);
     71   ASSERT(tmp <= ENCLOSURE_MAX__); /* API type */
     72   *count = (enclosure_id_t)tmp;
     73   return RES_OK;
     74 }
     75 
     76 FINLINE res_T
     77 senc2d_scene_get_enclosure
     78   (struct senc2d_scene* scn,
     79    const enclosure_id_t idx,
     80    struct senc2d_enclosure** out_enc)
     81 {
     82   struct senc2d_enclosure* enc;
     83   if(!scn || !out_enc) return RES_BAD_ARG;
     84   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
     85     return RES_BAD_OP;
     86   if(idx >= darray_enclosure_size_get(&scn->analyze.enclosures))
     87     return RES_BAD_ARG;
     88   enc = enclosure_create(scn, idx);
     89   if(!enc) return RES_MEM_ERR;
     90   *out_enc = enc;
     91   return RES_OK;
     92 }
     93 
     94 res_T
     95 senc2d_scene_get_enclosure_by_medium
     96   (struct senc2d_scene* scn,
     97    const medium_id_t imed,
     98    const enclosure_id_t idx,
     99    struct senc2d_enclosure** out_enc)
    100 {
    101   size_t m_idx;
    102   const struct darray_enc_id* enc_ids;
    103   enclosure_id_t index;
    104   if(!scn || !out_enc
    105     || (imed != SENC2D_UNSPECIFIED_MEDIUM && imed >= scn->next_medium_idx))
    106     return RES_BAD_ARG;
    107   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
    108     return RES_BAD_OP;
    109   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    110     == 1 + scn->next_medium_idx);
    111   m_idx = medium_id_2_medium_idx(imed);
    112   enc_ids =
    113     darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx;
    114   if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG;
    115   index = darray_enc_id_cdata_get(enc_ids)[idx];
    116   return senc2d_scene_get_enclosure(scn, index, out_enc);
    117 }
    118 
    119 res_T
    120 senc2d_scene_get_segment_enclosures
    121   (const struct senc2d_scene* scn,
    122    const seg_id_t iseg,
    123    enclosure_id_t enclosures[2])
    124 {
    125   const struct segment_enc* seg;
    126   int i;
    127   if(!enclosures || !scn) return RES_BAD_ARG;
    128   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
    129     return RES_BAD_OP;
    130   if(iseg >= darray_segment_enc_size_get(&scn->analyze.segments_enc))
    131     return RES_BAD_ARG;
    132   seg = darray_segment_enc_cdata_get(&scn->analyze.segments_enc) + iseg;
    133   FOR_EACH(i, 0, 2) enclosures[i] = seg->enclosure[i];
    134   return RES_OK;
    135 }
    136 
    137 res_T
    138 senc2d_scene_get_frontier_vertice_count
    139   (const struct senc2d_scene* scn,
    140    unsigned* count)
    141 {
    142   size_t tmp;
    143   if(!scn || !count)
    144     return RES_BAD_ARG;
    145   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
    146     return RES_BAD_OP;
    147   tmp = darray_frontier_vertex_size_get(&scn->analyze.frontiers);
    148   ASSERT(tmp <= VRTX_MAX__);
    149   *count = (unsigned)tmp; /* Back to API type */
    150   return RES_OK;
    151 }
    152 
    153 res_T
    154 senc2d_scene_get_frontier_vertex
    155   (const struct senc2d_scene* scn,
    156    const unsigned iver,
    157    unsigned vrtx_id[SENC2D_GEOMETRY_DIMENSION-1],
    158    unsigned* seg_id)
    159 {
    160   const struct frontier_vertex* vrtx;
    161   if(!vrtx_id || !scn || !seg_id
    162     || iver >= darray_frontier_vertex_size_get(&scn->analyze.frontiers))
    163     return RES_BAD_ARG;
    164   if(darray_seg_id_size_get(&scn->analyze.overlapping_ids))
    165     return RES_BAD_OP;
    166   vrtx = darray_frontier_vertex_cdata_get(&scn->analyze.frontiers) + iver;
    167   *vrtx_id = vrtx->vrtx;
    168   *seg_id = vrtx->seg;
    169   return RES_OK;
    170 }
    171 
    172 res_T
    173 senc2d_scene_get_overlapping_segments_count
    174   (const struct senc2d_scene* scn,
    175    unsigned* count)
    176 {
    177   size_t tmp;
    178   if(!scn || !count)
    179     return RES_BAD_ARG;
    180   tmp = darray_seg_id_size_get(&scn->analyze.overlapping_ids);
    181   ASSERT(tmp <= VRTX_MAX__);
    182   *count = (seg_id_t)tmp; /* Back to API type */
    183   return RES_OK;
    184 }
    185 
    186 res_T
    187 senc2d_scene_get_overlapping_segment
    188   (const struct senc2d_scene* scn,
    189    const unsigned idx,
    190    unsigned* trg_id)
    191 {
    192   if(!scn || !trg_id
    193     || idx >= darray_seg_id_size_get(&scn->analyze.overlapping_ids))
    194     return RES_BAD_ARG;
    195   *trg_id = darray_seg_id_cdata_get(&scn->analyze.overlapping_ids)[idx];
    196   return RES_OK;
    197 }