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 */