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