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


      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 #ifndef SENC2D_SCENE_C_H
     17 #define SENC2D_SCENE_C_H
     18 
     19 #include "senc2d_internal_types.h"
     20 #include "senc2d_enclosure_data.h"
     21 #include "senc2d_side_range.h"
     22 #include "senc2d.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 senc2d_scene;
     30 
     31 struct segment_comp {
     32   /* The connex component in which each side is. */
     33   component_id_t component[2];
     34 };
     35 
     36 static void
     37 segment_comp_init(struct mem_allocator* alloc, struct segment_comp* seg) {
     38   int i;
     39   (void)alloc;
     40   ASSERT(seg);
     41   FOR_EACH(i, 0, 2) seg->component[i] = COMPONENT_NULL__;
     42 }
     43 
     44 #define DARRAY_NAME segment_comp
     45 #define DARRAY_DATA struct segment_comp
     46 #define DARRAY_FUNCTOR_INIT segment_comp_init
     47 #include <rsys/dynamic_array.h>
     48 
     49 struct segment_enc {
     50   /* The enclosure in which each side is. */
     51   enclosure_id_t enclosure[2];
     52 };
     53 
     54 #ifndef NDEBUG
     55 static void
     56 segment_enc_init(struct mem_allocator* alloc, struct segment_enc* seg) {
     57   int i;
     58   (void)alloc;
     59   ASSERT(seg);
     60   FOR_EACH(i, 0, 2) seg->enclosure[i] = ENCLOSURE_NULL__;
     61 }
     62 #define DARRAY_FUNCTOR_INIT segment_enc_init
     63 #endif
     64 
     65 #define DARRAY_NAME segment_enc
     66 #define DARRAY_DATA struct segment_enc
     67 #include <rsys/dynamic_array.h>
     68 
     69 /* Segment edge struct and basic functions */
     70 struct seg_edge {
     71   vrtx_id_t vrtx0, vrtx1;
     72 };
     73 
     74 static FINLINE int
     75 edge_ok(const struct seg_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 seg_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 seg_edge* e1, const struct seg_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 segside {
    112   /* Rank of the segside facing this segside through its edges */
    113   side_id_t facing_side_id[2];
    114   /* Id of this segside's medium */
    115   medium_id_t medium;
    116 
    117   /* Implicit information that we don't need to store:
    118    * - segment_id
    119    * - side
    120    * This is due to the memory layout of the elt darray:
    121    * front(seg_0), back(seg_0), front(seg_1), back(seg_1), ... */
    122 };
    123 
    124 /* Frontier vertex type */
    125 struct frontier_vertex {
    126   seg_id_t seg;
    127   vrtx_id_t vrtx;
    128 };
    129 
    130 #define DARRAY_NAME frontier_vertex
    131 #define DARRAY_DATA struct frontier_vertex
    132 #include <rsys/dynamic_array.h>
    133 
    134 union double2 {
    135   struct {
    136     double x, y;
    137   } pos;
    138   double vec[2];
    139 };
    140 #define DARRAY_NAME position
    141 #define DARRAY_DATA union double2
    142 #include <rsys/dynamic_array.h>
    143 /* Segment information.
    144  * Depending on lifespan, information is kept in different places:
    145  * - segment_in for user provided information (kept in scene)
    146  * - segment_comp for information describing components (kept in struct descriptor)
    147  * - segment_tmp for tmp information (kept until segment_comp is ready) */
    148 struct segment_in {
    149   /* Ids of the segment's vertices */
    150   vrtx_id_t vertice_id[2];
    151   /* Ids of this segment's media */
    152   medium_id_t medium[2];
    153 };
    154 
    155 static FINLINE void
    156 segment_in_init(struct mem_allocator* alloc, struct segment_in* seg) {
    157   int i;
    158   (void)alloc;
    159   ASSERT(seg);
    160   FOR_EACH(i, 0, 2) seg->vertice_id[i] = VRTX_NULL__;
    161   FOR_EACH(i, 0, 2) seg->medium[i] = SENC2D_UNSPECIFIED_MEDIUM;
    162 }
    163 
    164 #define DARRAY_NAME segment_in
    165 #define DARRAY_DATA struct segment_in
    166 #define DARRAY_FUNCTOR_INIT segment_in_init
    167 #include <rsys/dynamic_array.h>
    168 
    169 static FINLINE int
    170 vrtx_eq(const union double2* v1, const union double2* v2)
    171 {
    172   ASSERT(v1 && v2);
    173   return (v1->pos.x == v2->pos.x && v1->pos.y == v2->pos.y);
    174 }
    175 
    176 #define HTABLE_NAME vrtx
    177 #define HTABLE_KEY union double2
    178 #define HTABLE_DATA vrtx_id_t
    179 #define HTABLE_KEY_FUNCTOR_EQ vrtx_eq
    180 #include <rsys/hash_table.h>
    181 
    182 union vrtx_id2 {
    183   struct {
    184     vrtx_id_t v0, v1;
    185   } pos;
    186   vrtx_id_t vec[2];
    187 };
    188 
    189 static FINLINE char /* Return 1 if reversed */
    190 seg_make_key(union vrtx_id2* k, const vrtx_id_t v[2])
    191 {
    192   ASSERT(v);
    193   ASSERT(v[0] != v[1]);
    194   if(v[0] < v[1]) {
    195     k->vec[0] = v[0];
    196     k->vec[1] = v[1];
    197     return 0;
    198   } else {
    199     k->vec[0] = v[1];
    200     k->vec[1] = v[0];
    201     return 1;
    202   }
    203 }
    204 
    205 static FINLINE int
    206 seg_key_eq(const union vrtx_id2* k1, const union vrtx_id2* k2)
    207 {
    208   ASSERT(k1 && k2);
    209   ASSERT(k1->vec[0] < k1->vec[1]);
    210   ASSERT(k2->vec[0] < k2->vec[1]);
    211   return (k1->vec[0] == k2->vec[0]) && (k1->vec[1] == k2->vec[1]);
    212 }
    213 
    214 #define HTABLE_NAME seg
    215 #define HTABLE_KEY union vrtx_id2
    216 #define HTABLE_DATA seg_id_t
    217 #define HTABLE_KEY_FUNCTOR_EQ seg_key_eq
    218 #include <rsys/hash_table.h>
    219 
    220 #define DARRAY_NAME seg_id
    221 #define DARRAY_DATA seg_id_t
    222 #include <rsys/dynamic_array.h>
    223 
    224 struct descriptor {
    225   enclosure_id_t enclosures_count;
    226   /* Store by-segment enclosures */
    227   struct darray_segment_enc segments_enc;
    228   /* Store enclosures */
    229   struct darray_enclosure enclosures;
    230   struct darray_enc_ids_array enc_ids_array_by_medium;
    231   /* Store frontiers */
    232   struct darray_frontier_vertex frontiers;
    233   /* Store overlapping segments */
    234   struct darray_seg_id overlapping_ids;
    235 };
    236 
    237 struct senc2d_scene {
    238   /* Front / Back sides convention */
    239   int convention;
    240   /* Segment information as given by user */
    241   struct darray_segment_in segments_in;
    242   /* Vertex information as given by user */
    243   struct darray_position vertices;
    244 
    245   /* Keep sizes */
    246   seg_id_t nsegs; /* Seg count */
    247   vrtx_id_t nverts; /* Vrtx count */
    248   medium_id_t next_medium_idx;
    249   /* media_use 0 is for SENC2D_UNSPECIFIED_MEDIUM, n+1 is for n */
    250   struct darray_side_range media_use;
    251 
    252   /* The descriptor of the analyze */
    253   struct descriptor analyze;
    254 
    255   ref_T ref;
    256   struct senc2d_device* dev;
    257 };
    258 
    259 #endif /* SENC2D_SCENE_C_H */