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_scene_c.h (7962B)


      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 #ifndef SENC3D_SCENE_C_H
     17 #define SENC3D_SCENE_C_H
     18 
     19 #include "senc3d_internal_types.h"
     20 #include "senc3d_enclosure_data.h"
     21 #include "senc3d_side_range.h"
     22 #include "senc3d.h"
     23 
     24 #include <rsys/ref_count.h>
     25 #include <rsys/dynamic_array.h>
     26 #include <rsys/hash_table.h>
     27 
     28 struct mem_allocator;
     29 struct senc3d_scene;
     30 
     31 struct triangle_comp {
     32   /* The connex component in which each side is. */
     33   component_id_t component[2];
     34 };
     35 
     36 static void
     37 triangle_comp_init(struct mem_allocator* alloc, struct triangle_comp* trg) {
     38   int i;
     39   (void)alloc;
     40   ASSERT(trg);
     41   FOR_EACH(i, 0, 2) trg->component[i] = COMPONENT_NULL__;
     42 }
     43 
     44 #define DARRAY_NAME triangle_comp
     45 #define DARRAY_DATA struct triangle_comp
     46 #define DARRAY_FUNCTOR_INIT triangle_comp_init
     47 #include <rsys/dynamic_array.h>
     48 
     49 struct triangle_enc {
     50   /* The enclosure in which each side is. */
     51   enclosure_id_t enclosure[2];
     52 };
     53 
     54 #ifndef NDEBUG
     55 static void
     56 triangle_enc_init(struct mem_allocator* alloc, struct triangle_enc* trg) {
     57   int i;
     58   (void)alloc;
     59   ASSERT(trg);
     60   FOR_EACH(i, 0, 2) trg->enclosure[i] = ENCLOSURE_NULL__;
     61 }
     62 #define DARRAY_FUNCTOR_INIT triangle_enc_init
     63 #endif
     64 
     65 #define DARRAY_NAME triangle_enc
     66 #define DARRAY_DATA struct triangle_enc
     67 #include <rsys/dynamic_array.h>
     68 
     69 /* Triangle edge struct and basic functions */
     70 struct trg_edge {
     71   vrtx_id_t vrtx0, vrtx1;
     72 };
     73 
     74 static FINLINE int
     75 edge_ok(const struct trg_edge* edge) {
     76   return(edge
     77     && edge->vrtx0 <= VRTX_MAX__
     78     && edge->vrtx1 <= VRTX_MAX__
     79     && edge->vrtx0 < edge->vrtx1);
     80 }
     81 
     82 static FINLINE void
     83 set_edge
     84   (const vrtx_id_t vrtx0,
     85    const vrtx_id_t vrtx1,
     86    struct trg_edge* edge,
     87    uchar* reversed)
     88 {
     89   ASSERT(edge && reversed && vrtx0 != vrtx1);
     90   ASSERT(*reversed == UCHAR_MAX); /* Should not be already set. */
     91   if(vrtx0 < vrtx1) {
     92     edge->vrtx0 = vrtx0;
     93     edge->vrtx1 = vrtx1;
     94     *reversed = 0; /* Non reversed edge */
     95   } else {
     96     edge->vrtx0 = vrtx1;
     97     edge->vrtx1 = vrtx0;
     98     *reversed = 1; /* Reversed edge */
     99   }
    100   ASSERT(edge_ok(edge));
    101 }
    102 
    103 static FINLINE int
    104 edge_eq(const struct trg_edge* e1, const struct trg_edge* e2)
    105 {
    106   ASSERT(edge_ok(e1) && edge_ok(e2));
    107   return e1->vrtx0 == e2->vrtx0 && e1->vrtx1 == e2->vrtx1;
    108 }
    109 
    110 /* Information kept during the building of side groups. */
    111 struct trgside {
    112   /* Rank of the trgside facing this trgside through its edges */
    113   side_id_t facing_side_id[3];
    114   /* Id of this trgside's medium */
    115   medium_id_t medium;
    116 
    117   /* Implicit information that we don't need to store:
    118    * - triangle_id
    119    * - side
    120    * This is due to the memory layout of the elt darray:
    121    * front(trg_0), back(trg_0), front(trg_1), back(trg_1), ... */
    122 };
    123 
    124 /* Frontier edge type */
    125 struct frontier_edge {
    126   trg_id_t trg;
    127   vrtx_id_t vrtx0, vrtx1;
    128 };
    129 
    130 #define DARRAY_NAME frontier_edge
    131 #define DARRAY_DATA struct frontier_edge
    132 #include <rsys/dynamic_array.h>
    133 
    134 union double3 {
    135   struct {
    136     double x, y, z;
    137   } pos;
    138   double vec[3];
    139 };
    140 #define DARRAY_NAME position
    141 #define DARRAY_DATA union double3
    142 #include <rsys/dynamic_array.h>
    143 /* Triangle information.
    144  * Depending on lifespan, information is kept in different places:
    145  * - triangle_in for user provided information (kept in scene)
    146  * - triangle_comp for information describing components (kept in struct descriptor)
    147  * - triangle_tmp for tmp information (kept until triangle_comp is ready) */
    148 struct triangle_in {
    149   /* Ids of the triangle's vertices */
    150   vrtx_id_t vertice_id[3];
    151   /* Ids of this triangle's media */
    152   medium_id_t medium[2];
    153 };
    154 
    155 static FINLINE void
    156 triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) {
    157   int i;
    158   (void)alloc;
    159   ASSERT(trg);
    160   FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__;
    161   FOR_EACH(i, 0, 2) trg->medium[i] = SENC3D_UNSPECIFIED_MEDIUM;
    162 }
    163 
    164 #define DARRAY_NAME triangle_in
    165 #define DARRAY_DATA struct triangle_in
    166 #define DARRAY_FUNCTOR_INIT triangle_in_init
    167 #include <rsys/dynamic_array.h>
    168 
    169 static FINLINE void
    170 triangle_in_flip(struct triangle_in* trg) {
    171   vrtx_id_t v;
    172   medium_id_t m;
    173   ASSERT(trg);
    174   v = trg->vertice_id[1];
    175   trg->vertice_id[1] = trg->vertice_id[2];
    176   trg->vertice_id[2] = v;
    177   m = trg->medium[0];
    178   trg->medium[0] = trg->medium[1];
    179   trg->medium[1] = m;
    180 }
    181 
    182 static FINLINE int
    183 vrtx_eq(const union double3* v1, const union double3* v2)
    184 {
    185   ASSERT(v1 && v2);
    186   return (v1->pos.x == v2->pos.x
    187     && v1->pos.y == v2->pos.y
    188     && v1->pos.z == v2->pos.z);
    189 }
    190 
    191 #define HTABLE_NAME vrtx
    192 #define HTABLE_KEY union double3
    193 #define HTABLE_DATA vrtx_id_t
    194 #define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
    195 #include <rsys/hash_table.h>
    196 
    197 union vrtx_id3 {
    198   struct {
    199     vrtx_id_t v0, v1, v2;
    200   } pos;
    201   vrtx_id_t vec[3];
    202 };
    203 
    204 static FINLINE char /* Return 1 if reversed */
    205 trg_make_key(union vrtx_id3* k, const vrtx_id_t t[3])
    206 {
    207   ASSERT(t);
    208   ASSERT(t[0] != t[1] && t[0] != t[2] && t[1] != t[2]);
    209   if(t[0] < t[2]) {
    210     if(t[0] < t[1]) {
    211       k->vec[0] = t[0];
    212       if(t[1] < t[2]) {
    213         k->vec[1] = t[1];
    214         k->vec[2] = t[2];
    215         return 0;
    216       } else {
    217         k->vec[1] = t[2];
    218         k->vec[2] = t[1];
    219         return 1;
    220       }
    221     } else {
    222       k->vec[0] = t[1];
    223       if(t[0] < t[2]) {
    224         k->vec[1] = t[0];
    225         k->vec[2] = t[2];
    226         return 1;
    227       } else {
    228         k->vec[1] = t[2];
    229         k->vec[2] = t[0];
    230         return 0;
    231       }
    232     }
    233   } else if(t[2] < t[1]) {
    234     k->vec[0] = t[2];
    235     if(t[0] < t[1]) {
    236       k->vec[1] = t[0];
    237       k->vec[2] = t[1];
    238       return 0;
    239     } else {
    240       k->vec[1] = t[1];
    241       k->vec[2] = t[0];
    242       return 1;
    243     }
    244   } else {
    245     k->vec[0] = t[1];
    246     if(t[0] < t[2]) {
    247       k->vec[1] = t[0];
    248       k->vec[2] = t[2];
    249       return 1;
    250     } else {
    251       k->vec[1] = t[2];
    252       k->vec[2] = t[0];
    253       return 0;
    254     }
    255   }
    256 }
    257 
    258 static FINLINE int
    259 trg_key_eq(const union vrtx_id3* k1, const union vrtx_id3* k2)
    260 {
    261   ASSERT(k1 && k2);
    262   ASSERT(k1->vec[0] < k1->vec[1] && k1->vec[1] < k1->vec[2]);
    263   ASSERT(k2->vec[0] < k2->vec[1] && k2->vec[1] < k2->vec[2]);
    264   return (k1->vec[0] == k2->vec[0])
    265     && (k1->vec[1] == k2->vec[1])
    266     && (k1->vec[2] == k2->vec[2]);
    267 }
    268 
    269 #define HTABLE_NAME trg
    270 #define HTABLE_KEY union vrtx_id3
    271 #define HTABLE_DATA trg_id_t
    272 #define HTABLE_KEY_FUNCTOR_EQ trg_key_eq
    273 #include <rsys/hash_table.h>
    274 
    275 #define DARRAY_NAME trg_id
    276 #define DARRAY_DATA trg_id_t
    277 #include <rsys/dynamic_array.h>
    278 
    279 struct descriptor {
    280   enclosure_id_t enclosures_count;
    281   /* Store by-triangle enclosures */
    282   struct darray_triangle_enc triangles_enc;
    283   /* Store enclosures */
    284   struct darray_enclosure enclosures;
    285   struct darray_enc_ids_array enc_ids_array_by_medium;
    286   /* Store frontiers */
    287   struct darray_frontier_edge frontiers;
    288   /* Store overlapping triangles */
    289   struct darray_trg_id overlapping_ids;
    290 };
    291 
    292 struct senc3d_scene {
    293   /* Front / Back sides convention */
    294   int convention;
    295   /* Triangle information as given by user */
    296   struct darray_triangle_in triangles_in;
    297   /* Vertex information as given by user */
    298   struct darray_position vertices;
    299 
    300   /* Keep sizes */
    301   trg_id_t ntris; /* Trg count */
    302   vrtx_id_t nverts; /* Vrtx count */
    303   /* media_use 0 is for SENC3D_UNSPECIFIED_MEDIUM, n+1 is for n */
    304   struct darray_side_range media_use;
    305 
    306   /* The descriptor of the analyze */
    307   struct descriptor analyze;
    308 
    309   ref_T ref;
    310   struct senc3d_device* dev;
    311 };
    312 
    313 #endif /* SENC3D_SCENE_C_H */