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_analyze_c.h (6246B)


      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_SCNENE_ANALYZE_C_H
     17 #define SENC3D_SCNENE_ANALYZE_C_H
     18 
     19 #include "senc3d_internal_types.h"
     20 #include "senc3d_side_range.h"
     21 #include "senc3d_scene_c.h"
     22 #include "senc3d.h"
     23 
     24 #include <rsys/mem_allocator.h>
     25 #include <rsys/hash_table.h>
     26 #include <rsys/double3.h>
     27 
     28 struct senc3d_scene;
     29 
     30 static FINLINE void
     31 init_trgside(struct mem_allocator* alloc, struct trgside* data)
     32 {
     33   int i;
     34   ASSERT(data); (void)alloc;
     35   FOR_EACH(i, 0, 3) data->facing_side_id[i] = SIDE_NULL__;
     36   data->medium = MEDIUM_NULL__;
     37 }
     38 
     39 #define DARRAY_NAME side_id
     40 #define DARRAY_DATA side_id_t
     41 #include <rsys/dynamic_array.h>
     42 
     43 /* Descriptors for connex component.
     44  * Define lists of trg sides starting from a given head.
     45  * Also keeps the maximum z info of the component
     46  * and the list of media found  */
     47 struct cc_descriptor {
     48   /* Twice the area of the component */
     49   double _2area;
     50   /* Six times the signed volume of the component */
     51   double _6volume;
     52   /* The component's bounding Box */
     53   double bbox[3][2];
     54   /* Media used by this component */
     55   uchar* media;
     56   unsigned media_count;
     57   /* Does this component is an outer border of an enclosure or an inner one? */
     58   int is_outer_border;
     59   vrtx_id_t max_z_vrtx_id; /* id of the vrtx with max z value */
     60   side_id_t side_count;
     61   /* Used when grouping components to form enclosures */
     62   component_id_t cc_id;
     63   component_id_t cc_group_root;
     64   enclosure_id_t enclosure_id;
     65   /* Range of sides member of this component */
     66   struct side_range side_range;
     67 };
     68 extern const struct cc_descriptor CC_DESCRIPTOR_NULL;
     69 
     70 static FINLINE void
     71 cc_descriptor_init
     72   (struct mem_allocator* alloc,
     73    struct cc_descriptor* data)
     74 {
     75   ASSERT(data);
     76   (void)alloc;
     77   *data = CC_DESCRIPTOR_NULL;
     78 }
     79 
     80 static FINLINE void
     81 ptr_component_descriptor_init
     82   (struct mem_allocator* alloc,
     83    struct cc_descriptor** data)
     84 {
     85   (void)alloc;
     86   ASSERT(data);
     87   *data = NULL;
     88 }
     89 
     90 #define DARRAY_NAME ptr_component_descriptor
     91 #define DARRAY_DATA struct cc_descriptor*
     92 #define DARRAY_FUNCTOR_INIT ptr_component_descriptor_init
     93 #include <rsys/dynamic_array.h>
     94 
     95 /* Need allocator to free array elts: cannot rely on standard
     96  * darray release stuff */
     97 static FINLINE void
     98 custom_darray_ptr_component_descriptor_release
     99   (struct darray_ptr_component_descriptor* array)
    100 {
    101   size_t c, cc_count;
    102   struct cc_descriptor** components;
    103   if(!array) return;
    104   cc_count = darray_ptr_component_descriptor_size_get(array);
    105   components = darray_ptr_component_descriptor_data_get(array);
    106   FOR_EACH(c, 0, cc_count) {
    107     if(!components[c]) continue;
    108     MEM_RM(array->allocator, components[c]->media);
    109     MEM_RM(array->allocator, components[c]);
    110   }
    111   darray_ptr_component_descriptor_release(array);
    112 }
    113 
    114 /* Triangle information.
    115  * Depending on lifespan, information is kept in different places:
    116  * - triangle_in for user provided information (kept in scene)
    117  * - triangle_tmp for tmp information (kept until triangle_comp is ready)
    118  * - triangle_comp for information describing components (kept until
    119  *   triangle_enc is ready)
    120  * - triangle_enc for information describing enclosures (kept in
    121  *   struct descriptor). */
    122 struct triangle_tmp {
    123   /* Are the edges of the triangle defined in the same order than
    124    * the edges they are linked to? */
    125   uchar reversed_edge[3];
    126   double max_z;
    127 };
    128 
    129 #ifndef NDEBUG
    130 static FINLINE void
    131 triangle_tmp_init(struct mem_allocator* alloc, struct triangle_tmp* trg) {
    132   int i;
    133   (void)alloc;
    134   ASSERT(trg);
    135   FOR_EACH(i, 0, 3) trg->reversed_edge[i] = UCHAR_MAX;
    136   trg->max_z = -DBL_MAX;
    137 }
    138 #define DARRAY_FUNCTOR_INIT triangle_tmp_init
    139 #endif
    140 
    141 #define DARRAY_NAME triangle_tmp
    142 #define DARRAY_DATA struct triangle_tmp
    143 #include <rsys/dynamic_array.h>
    144 
    145 #define HTABLE_NAME edge_id
    146 #define HTABLE_KEY struct trg_edge
    147 #define HTABLE_DATA edge_id_t
    148 #define HTABLE_KEY_FUNCTOR_EQ edge_eq
    149 #include <rsys/hash_table.h>
    150 
    151 struct neighbour_info {
    152   double angle;
    153   trg_id_t trg_id;
    154   /* Rank of the edge in the triangle (in [0 2]) */
    155   uchar common_edge_rank;
    156   /* Does the geometrical normal point towards the next neighbour
    157    * (if not, it points towards the previous one)? */
    158   uchar normal_toward_next_neighbour;
    159 };
    160 #define DARRAY_NAME neighbour
    161 #define DARRAY_DATA struct neighbour_info
    162 #include <rsys/dynamic_array.h>
    163 
    164 struct edge_neighbourhood {
    165   struct trg_edge edge;
    166   struct darray_neighbour neighbours;
    167 };
    168 static void
    169 neighbourhood_init
    170   (struct mem_allocator* alloc,
    171    struct edge_neighbourhood* n)
    172 {
    173   ASSERT(n);
    174   darray_neighbour_init(alloc, &n->neighbours);
    175 }
    176 static res_T
    177 neighbourhood_copy
    178   (struct edge_neighbourhood* dst,
    179    const struct edge_neighbourhood* src)
    180 {
    181   ASSERT(src && dst);
    182   dst->edge = src->edge;
    183   return darray_neighbour_copy(&dst->neighbours, &src->neighbours);
    184 }
    185 static void
    186 neighbourhood_release(struct edge_neighbourhood* n) {
    187   ASSERT(n);
    188   darray_neighbour_release(&n->neighbours);
    189 }
    190 static res_T
    191 neighbourhood_copy_and_release
    192   (struct edge_neighbourhood* dst,
    193    struct edge_neighbourhood* src)
    194 {
    195   ASSERT(src && dst);
    196   dst->edge = src->edge;
    197   return darray_neighbour_copy_and_release(&dst->neighbours, &src->neighbours);
    198 }
    199 #define DARRAY_NAME neighbourhood
    200 #define DARRAY_DATA struct edge_neighbourhood
    201 #define DARRAY_FUNCTOR_INIT neighbourhood_init
    202 #define DARRAY_FUNCTOR_COPY neighbourhood_copy
    203 #define DARRAY_FUNCTOR_RELEASE neighbourhood_release
    204 #define DARRAY_FUNCTOR_COPY_AND_RELEASE neighbourhood_copy_and_release
    205 #include <rsys/dynamic_array.h>
    206 
    207 extern LOCAL_SYM res_T
    208 scene_analyze(struct senc3d_scene* scene);
    209 
    210 #endif /* SENC3D_SCNENE_ANALYZE_C_H */