sg2d_geometry.h (8057B)
1 /* Copyright (C) 2019, 2020, 2023 |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 SG2D_GEOMETRY_H__ 17 #define SG2D_GEOMETRY_H__ 18 19 #include "sg2d.h" 20 #include "sg2d_misc.h" 21 22 #include <rsys/ref_count.h> 23 #include <rsys/dynamic_array.h> 24 #include <rsys/dynamic_array_uint.h> 25 #include <rsys/hash_table.h> 26 27 /* Forward declaration of external opaque data types */ 28 29 /****************************************************************************** 30 * A type to store segments 31 *****************************************************************************/ 32 struct segment { 33 vrtx_id_t vertex_ids[2]; 34 /* FRONT/BACK/INTERFACE property */ 35 prop_id_t properties[SG2D_PROP_TYPES_COUNT__]; 36 /* ID of the segment in user world, i.e. without deduplication */ 37 seg_id_t user_id; 38 }; 39 #define SEG_UNDEF__ {\ 40 { SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY },\ 41 { SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY, SG2D_UNSPECIFIED_PROPERTY },\ 42 SG2D_UNSPECIFIED_PROPERTY\ 43 } 44 #define DARRAY_NAME segment 45 #define DARRAY_DATA struct segment 46 #include <rsys/dynamic_array.h> 47 48 /****************************************************************************** 49 * A type to store vertices 50 *****************************************************************************/ 51 struct vertex { 52 double coord[2]; 53 }; 54 #define DARRAY_NAME vertex 55 #define DARRAY_DATA struct vertex 56 #include <rsys/dynamic_array.h> 57 58 /****************************************************************************** 59 * A type to map segment vertices to IDs in unique_segments 60 *****************************************************************************/ 61 struct vrtx_id2 { vrtx_id_t x[2]; }; 62 63 static FINLINE int 64 seg_key_eq(const struct vrtx_id2* k1, const struct vrtx_id2* k2) 65 { 66 ASSERT(k1 && k2 && k1->x[0] < k1->x[1] && k2->x[0] < k2->x[1]); 67 return (k1->x[0] == k2->x[0]) && (k1->x[1] == k2->x[1]); 68 } 69 70 #define HTABLE_NAME seg 71 #define HTABLE_KEY struct vrtx_id2 72 #define HTABLE_DATA seg_id_t 73 #define HTABLE_KEY_FUNCTOR_EQ seg_key_eq 74 #include <rsys/hash_table.h> 75 76 /****************************************************************************** 77 * A type to map vertex coordinates to IDs in unique_vertices 78 *****************************************************************************/ 79 static FINLINE int 80 vrtx_eq(const struct vertex* v1, const struct vertex* v2) 81 { 82 int i; 83 ASSERT(v1 && v2); 84 FOR_EACH(i, 0, 2) if(v1->coord[i] != v2->coord[i]) return 0; 85 return 1; 86 } 87 88 #define HTABLE_NAME vrtx 89 #define HTABLE_KEY struct vertex 90 #define HTABLE_DATA vrtx_id_t 91 #define HTABLE_KEY_FUNCTOR_EQ vrtx_eq 92 #include <rsys/hash_table.h> 93 94 /****************************************************************************** 95 * Types to record sources and values of segment descriptions. 96 *****************************************************************************/ 97 98 /* A type to store a value and the files defining this value 99 * (usualy a single file) */ 100 struct definition { 101 /* The value */ 102 prop_id_t property_value; 103 /* The IDs of the geometry sets that defined the value */ 104 struct darray_uint set_ids; 105 }; 106 107 static FINLINE void 108 init_definition 109 (struct mem_allocator* alloc, 110 struct definition* data) 111 { 112 ASSERT(alloc && data); 113 data->property_value = SG2D_UNSPECIFIED_PROPERTY; 114 darray_uint_init(alloc, &data->set_ids); 115 } 116 117 static INLINE res_T 118 copy_definition 119 (struct definition* dst, 120 const struct definition* src) 121 { 122 res_T res = RES_OK; 123 ASSERT(dst && src); 124 dst->property_value = src->property_value; 125 ERR(darray_uint_copy(&dst->set_ids, &src->set_ids)); 126 exit: 127 return res; 128 error: 129 goto exit; 130 } 131 132 static FINLINE void 133 release_definition 134 (struct definition* data) 135 { 136 ASSERT(data); 137 darray_uint_release(&data->set_ids); 138 } 139 140 #define DARRAY_NAME definition 141 #define DARRAY_DATA struct definition 142 #define DARRAY_FUNCTOR_INIT init_definition 143 #define DARRAY_FUNCTOR_COPY copy_definition 144 #define DARRAY_FUNCTOR_RELEASE release_definition 145 #include <rsys/dynamic_array.h> 146 147 /* A type to accumulate information for a segment. 148 * If there is more than 1 definition / field, it is a conflict */ 149 struct seg_descriptions { 150 struct darray_definition defs[SG2D_PROP_TYPES_COUNT__]; 151 int merge_conflict; 152 int properties_conflict; 153 char defs_include_unspecified; 154 char property_defined[SG2D_PROP_TYPES_COUNT__]; 155 }; 156 157 static FINLINE void 158 init_seg_descriptions 159 (struct mem_allocator* alloc, 160 struct seg_descriptions* data) 161 { 162 int i; 163 ASSERT(alloc && data); 164 FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__) 165 darray_definition_init(alloc, data->defs + i); 166 data->merge_conflict = 0; 167 data->properties_conflict = 0; 168 data->defs_include_unspecified = 0; 169 FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__) 170 data->property_defined[i] = 0; 171 } 172 173 static INLINE res_T 174 copy_seg_descriptions 175 (struct seg_descriptions* dst, 176 const struct seg_descriptions* src) 177 { 178 res_T res = RES_OK; 179 int i; 180 ASSERT(dst && src); 181 FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__) 182 ERR(darray_definition_copy(&dst->defs[i], &src->defs[i])); 183 dst->merge_conflict = src->merge_conflict; 184 dst->properties_conflict = src->properties_conflict; 185 dst->defs_include_unspecified = src->defs_include_unspecified; 186 FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__) 187 dst->property_defined[i] = src->property_defined[i]; 188 exit: 189 return res; 190 error: 191 goto exit; 192 } 193 194 static FINLINE void 195 release_seg_descriptions 196 (struct seg_descriptions* data) 197 { 198 int i; 199 ASSERT(data); 200 FOR_EACH(i, 0, SG2D_PROP_TYPES_COUNT__) 201 darray_definition_release(data->defs + i); 202 } 203 204 #define DARRAY_NAME seg_descriptions 205 #define DARRAY_DATA struct seg_descriptions 206 #define DARRAY_FUNCTOR_INIT init_seg_descriptions 207 #define DARRAY_FUNCTOR_COPY copy_seg_descriptions 208 #define DARRAY_FUNCTOR_RELEASE release_seg_descriptions 209 #include <rsys/dynamic_array.h> 210 211 /****************************************************************************** 212 * Types to store geometry amid sg2d_geometry_add calls. 213 *****************************************************************************/ 214 struct sg2d_geometry { 215 /* Record unique (i.e. deduplicated) segments */ 216 struct darray_segment unique_segments; 217 /* Record coordinates for unique (i.e. deduplicated) vertices */ 218 struct darray_vertex unique_vertices; 219 220 /* A table to map segment vertices to IDs in unique_segments */ 221 struct htable_seg unique_segments_ids; 222 /* A table to map vertex coordinates to IDs in unique_vertices */ 223 struct htable_vrtx unique_vertices_ids; 224 225 /* Record which set defined what */ 226 struct darray_seg_descriptions seg_descriptions; 227 228 /* Counts */ 229 unsigned set_id; 230 seg_id_t segment_count_including_duplicates; 231 side_id_t sides_with_defined_medium_count; 232 seg_id_t seg_with_unspecified_sides_count; 233 seg_id_t seg_with_unspecified_intface_count; 234 seg_id_t merge_conflict_count; 235 seg_id_t properties_conflict_count; 236 237 struct sg2d_device* dev; 238 ref_T ref; 239 }; 240 241 /****************************************************************************** 242 * Local functions 243 *****************************************************************************/ 244 245 extern LOCAL_SYM res_T 246 geometry_register_segment 247 (struct sg2d_geometry* geometry, 248 const struct segment* segment, 249 const seg_id_t segment_unique_id, 250 const unsigned set_id, 251 const int merge_conflict); 252 253 /* Add new undefined segment descriptions to a geometry */ 254 extern LOCAL_SYM res_T 255 geometry_enlarge_seg_descriptions 256 (struct sg2d_geometry* geom, 257 const seg_id_t sz); 258 259 #endif /* SG2D_GEOMETRY_H__ */