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