star-enclosures-3d

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

senc3d_descriptor.c (7935B)


      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_enclosure_c.h"
     17 #include "senc3d_scene_c.h"
     18 #include "senc3d.h"
     19 
     20 #include <rsys/rsys.h>
     21 #include <rsys/double3.h>
     22 #include <rsys/mem_allocator.h>
     23 
     24 /******************************************************************************
     25  * Exported functions
     26  *****************************************************************************/
     27 res_T
     28 senc3d_scene_get_max_medium
     29   (const struct senc3d_scene* scn, medium_id_t* max_medium_id)
     30 {
     31   if(!scn || !max_medium_id) return RES_BAD_ARG;
     32   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
     33     == darray_side_range_size_get(&scn->media_use));
     34   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
     35   if(darray_side_range_size_get(&scn->media_use) == 1)
     36     *max_medium_id = SENC3D_UNSPECIFIED_MEDIUM;
     37   else {
     38     size_t sz = darray_side_range_size_get(&scn->media_use) - 2;
     39     ASSERT(sz <= MEDIUM_MAX__);
     40     *max_medium_id = (medium_id_t)sz;
     41   }
     42   return RES_OK;
     43 }
     44 
     45 res_T
     46 senc3d_scene_get_enclosure_count
     47   (const struct senc3d_scene* scn, enclosure_id_t* count)
     48 {
     49   if(!scn || !count) return RES_BAD_ARG;
     50   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
     51     return RES_BAD_OP;
     52   ASSERT(scn->analyze.enclosures_count ==
     53     darray_enclosure_size_get(&scn->analyze.enclosures));
     54   *count = scn->analyze.enclosures_count;
     55   return RES_OK;
     56 }
     57 
     58 res_T
     59 senc3d_scene_get_enclosure_count_by_medium
     60   (const struct senc3d_scene* scn,
     61    const medium_id_t imed,
     62    enclosure_id_t* count)
     63 {
     64   size_t tmp;
     65   size_t m_idx;
     66   const struct darray_enc_id* enc_ids;
     67   if(!scn || !count) return RES_BAD_ARG;
     68   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
     69     == darray_side_range_size_get(&scn->media_use));
     70   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
     71   if(imed != SENC3D_UNSPECIFIED_MEDIUM
     72     && imed >= darray_side_range_size_get(&scn->media_use))
     73     return RES_BAD_ARG;
     74   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
     75     return RES_BAD_OP;
     76   m_idx = medium_id_2_medium_idx(imed);
     77   enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
     78     + m_idx;
     79   tmp = darray_enc_id_size_get(enc_ids);
     80   ASSERT(tmp <= ENCLOSURE_MAX__); /* API type */
     81   *count = (enclosure_id_t)tmp;
     82   return RES_OK;
     83 }
     84 
     85 FINLINE res_T
     86 senc3d_scene_get_enclosure
     87   (struct senc3d_scene* scn,
     88    const enclosure_id_t idx,
     89    struct senc3d_enclosure** out_enc)
     90 {
     91   struct senc3d_enclosure* enc;
     92   if(!scn || !out_enc) return RES_BAD_ARG;
     93   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
     94     == darray_side_range_size_get(&scn->media_use));
     95   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
     96   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
     97     return RES_BAD_OP;
     98   if(idx >= darray_enclosure_size_get(&scn->analyze.enclosures))
     99     return RES_BAD_ARG;
    100   enc = enclosure_create(scn, idx);
    101   if(!enc) return RES_MEM_ERR;
    102   *out_enc = enc;
    103   return RES_OK;
    104 }
    105 
    106 res_T
    107 senc3d_scene_get_enclosure_by_medium
    108   (struct senc3d_scene* scn,
    109    const medium_id_t imed,
    110    const enclosure_id_t idx,
    111    struct senc3d_enclosure** out_enc)
    112 {
    113   size_t m_idx;
    114   const struct darray_enc_id* enc_ids;
    115   enclosure_id_t index;
    116   if(!scn || !out_enc) return RES_BAD_ARG;
    117   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    118     == darray_side_range_size_get(&scn->media_use));
    119   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    120   if(imed != SENC3D_UNSPECIFIED_MEDIUM
    121     && imed >= darray_side_range_size_get(&scn->media_use))
    122     return RES_BAD_ARG;
    123   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
    124     return RES_BAD_OP;
    125   m_idx = medium_id_2_medium_idx(imed);
    126   enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium)
    127     + m_idx;
    128   if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG;
    129   index = darray_enc_id_cdata_get(enc_ids)[idx];
    130   return senc3d_scene_get_enclosure(scn, index, out_enc);
    131 }
    132 
    133 res_T
    134 senc3d_scene_get_triangle_enclosures
    135   (const struct senc3d_scene* scn,
    136    const trg_id_t itri,
    137    enclosure_id_t enclosures[2])
    138 {
    139   const struct triangle_enc* trg;
    140   int i;
    141   if(!enclosures || !scn) return RES_BAD_ARG;
    142   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    143     == darray_side_range_size_get(&scn->media_use));
    144   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    145   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
    146     return RES_BAD_OP;
    147   if(itri >= darray_triangle_enc_size_get(&scn->analyze.triangles_enc))
    148     return RES_BAD_ARG;
    149   trg = darray_triangle_enc_cdata_get(&scn->analyze.triangles_enc) + itri;
    150   FOR_EACH(i, 0, 2) enclosures[i] = trg->enclosure[i];
    151   return RES_OK;
    152 }
    153 
    154 res_T
    155 senc3d_scene_get_frontier_segments_count
    156   (const struct senc3d_scene* scn,
    157    vrtx_id_t* count)
    158 {
    159   size_t tmp;
    160   if(!scn || !count)
    161     return RES_BAD_ARG;
    162   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    163     == darray_side_range_size_get(&scn->media_use));
    164   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    165   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
    166     return RES_BAD_OP;
    167   tmp = darray_frontier_edge_size_get(&scn->analyze.frontiers);
    168   ASSERT(tmp <= VRTX_MAX__);
    169   *count = (vrtx_id_t)tmp; /* Back to API type */
    170   return RES_OK;
    171 }
    172 
    173 res_T
    174 senc3d_scene_get_frontier_segment
    175   (const struct senc3d_scene* scn,
    176    const unsigned iseg, /* There is no defined type for segment IDs */
    177    vrtx_id_t vrtx_id[2],
    178    unsigned* trg_id)
    179 {
    180   const struct frontier_edge* edge;
    181   if(!vrtx_id || !scn || !trg_id
    182     || iseg >= darray_frontier_edge_size_get(&scn->analyze.frontiers))
    183     return RES_BAD_ARG;
    184   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    185     == darray_side_range_size_get(&scn->media_use));
    186   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    187   if(darray_trg_id_size_get(&scn->analyze.overlapping_ids))
    188     return RES_BAD_OP;
    189   edge = darray_frontier_edge_cdata_get(&scn->analyze.frontiers) + iseg;
    190   ASSERT(edge->vrtx0 <= VRTX_MAX__);
    191   ASSERT(edge->vrtx1 <= VRTX_MAX__);
    192   vrtx_id[0] = edge->vrtx0;
    193   vrtx_id[1] = edge->vrtx1;
    194   *trg_id = edge->trg;
    195   return RES_OK;
    196 }
    197 
    198 res_T
    199 senc3d_scene_get_overlapping_triangles_count
    200   (const struct senc3d_scene* scn,
    201    vrtx_id_t* count)
    202 {
    203   size_t tmp;
    204   if(!scn || !count)
    205     return RES_BAD_ARG;
    206   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    207     == darray_side_range_size_get(&scn->media_use));
    208   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    209   tmp = darray_trg_id_size_get(&scn->analyze.overlapping_ids);
    210   ASSERT(tmp <= VRTX_MAX__);
    211   *count = (trg_id_t)tmp; /* Back to API type */
    212   return RES_OK;
    213 }
    214 
    215 res_T
    216 senc3d_scene_get_overlapping_triangle
    217   (const struct senc3d_scene* scn,
    218    const unsigned idx,
    219    unsigned* trg_id)
    220 {
    221   if(!scn || !trg_id
    222     || idx >= darray_trg_id_size_get(&scn->analyze.overlapping_ids))
    223     return RES_BAD_ARG;
    224   ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium)
    225     == darray_side_range_size_get(&scn->media_use));
    226   ASSERT(darray_side_range_size_get(&scn->media_use) >= 1);
    227   *trg_id = darray_trg_id_cdata_get(&scn->analyze.overlapping_ids)[idx];
    228   return RES_OK;
    229 }