senc2d.h (14055B)
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_H 17 #define SENC2D_H 18 19 #include <rsys/rsys.h> 20 21 #include <limits.h> 22 23 /* Library symbol management */ 24 #if defined(SENC2D_SHARED_BUILD) 25 #define SENC2D_API extern EXPORT_SYM 26 #elif defined(SENC2D_STATIC_BUILD) 27 #define SENC2D_API extern LOCAL_SYM 28 #else /* Use shared library */ 29 #define SENC2D_API extern IMPORT_SYM 30 #endif 31 32 /* Helper macro that asserts if the invocation of the StarEnc function `Func' 33 * returns an error. One should use this macro on StarEnc function calls for 34 * which no explicit error checking is performed. */ 35 #ifndef NDEBUG 36 #define SENC2D(Func) ASSERT(senc2d_ ## Func == RES_OK) 37 #else 38 #define SENC2D(Func) senc2d_ ## Func 39 #endif 40 41 /* Syntactic sugar used to inform the library that it can use as many threads 42 * as CPU cores */ 43 #define SENC2D_NTHREADS_DEFAULT (~0u) 44 45 /* A constant to denote an unspecified medium */ 46 #define SENC2D_UNSPECIFIED_MEDIUM UINT_MAX 47 48 /* Forward declaration of external opaque data types */ 49 struct logger; 50 struct mem_allocator; 51 52 /* Forward declaration of star-enclosures-2d opaque data types. These data 53 * types are ref counted. Once created with the appropriated 54 * `senc2d_<TYPE>_create' function, the caller implicitly owns the created 55 * data, i.e. its reference counter is set to 1. 56 * The senc2d_<TYPE>_ref_<get|put> functions get or release a reference on the 57 * data, i.e. they increment or decrement the reference counter, respectively. 58 * When this counter reaches 0, the object is silently destroyed and cannot be 59 * used anymore. */ 60 struct senc2d_device; 61 struct senc2d_scene; 62 struct senc2d_enclosure; 63 64 /****************************************************************************** 65 * The dimension of the geometry used in the library. 66 *****************************************************************************/ 67 #define SENC2D_GEOMETRY_DIMENSION 2 68 69 /* A type to discriminate segment sides */ 70 enum senc2d_side { 71 SENC2D_FRONT, 72 SENC2D_BACK 73 }; 74 75 /* Enclosure header type */ 76 struct senc2d_enclosure_header { 77 /* The ID of the enclosure; 0, 1, ... */ 78 unsigned enclosure_id; 79 /* Number of segments; a segment can be counted twice, once by side */ 80 unsigned primitives_count; 81 /* Number of segments; a segment cannot be counted twice */ 82 unsigned unique_primitives_count; 83 /* Number of vertices */ 84 unsigned vertices_count; 85 /* The number of media inside the enclosure, 86 * SENC2D_UNSPECIFIED_MEDIUM included */ 87 unsigned enclosed_media_count; 88 /* Is the enclosure open/infinite? 89 * Only the outermost enclosure is infinite. */ 90 int is_infinite; 91 /* The volume of the enclosure, in m^2 (2D volume is in m^2!). 92 * For the outermost enclosure, that goes to infinity, the volume is negative 93 * and is the volume substracted from an hypothetical surrounding object. 94 * If the two sides of a segment are part of the enclosure, the segment is 95 * counted as 0. */ 96 double volume; 97 /* The area of the enclosure, in m (2D area is in m!). 98 * If the two sides of a segment are part of the enclosure, the segment is 99 * counted twice. */ 100 double area; 101 }; 102 103 /* We consider the geometrical normal Ng to a segment V0 V1 that verifies 104 * "(V0, V0V1, Ng) is a direct system" (right-handed system). 105 * 106 * The user can set the convention used to determine which side of 107 * a segment is to be considered front/back by using the flags : 108 * SENC2D_CONVENTION_NORMAL_FRONT => Ng points toward the front side, 109 * SENC2D_CONVENTION_NORMAL_BACK => Ng points toward the back side. 110 * 111 * Additionally the user can set the convention used to output enclosures 112 * so that Ng points toward the enclosure or on the opposite direction 113 * (for a closed enclosure Ng points toward the inside or toward the outside) 114 * by using the flags : 115 * SENC2D_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure, 116 * SENC2D_CONVENTION_NORMAL_OUTSIDE => Ng points toward the opposite of the 117 * enclosure. 118 * 119 * Note that normals in output data can be opposite to normals in input data 120 * (vertices are then given in reverse order). 121 * 122 * Also note that both sides of a segment can be part of the same enclosure; 123 * in this case the 2 sides will be given with opposite Ng (meaning they 124 * will be given with opposite vertices order). 125 */ 126 enum senc2d_convention { 127 /* 128 * Convention regarding FRONT/BACK sides in input data 129 */ 130 131 /* Geometrical normals point toward the front side */ 132 SENC2D_CONVENTION_NORMAL_FRONT = BIT(0), 133 /* Geometrical normals point toward the back side */ 134 SENC2D_CONVENTION_NORMAL_BACK = BIT(1), 135 136 /* 137 * Convention regarding geometrical normals in output data 138 */ 139 140 /* Geometrical normals point toward the enclosure */ 141 SENC2D_CONVENTION_NORMAL_INSIDE = BIT(2), 142 /* Geometrical normals point to the opposite of the enclosure */ 143 SENC2D_CONVENTION_NORMAL_OUTSIDE = BIT(3) 144 }; 145 146 BEGIN_DECLS 147 148 /****************************************************************************** 149 * star-enclosures-2d device. It is an handle toward the StarEnc library. 150 * It manages the lib resources. 151 * If provided, the allocator has to be suitable for parallel high frequency 152 * allocations. As a consequence, a rsys proxy allocator should be avoided. 153 *****************************************************************************/ 154 SENC2D_API res_T 155 senc2d_device_create 156 (struct logger* logger, /* May be NULL <=> use default logger */ 157 struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ 158 const unsigned nthreads_hint, 159 const int verbose, 160 struct senc2d_device** device); 161 162 SENC2D_API res_T 163 senc2d_device_ref_get 164 (struct senc2d_device* device); 165 166 SENC2D_API res_T 167 senc2d_device_ref_put 168 (struct senc2d_device* device); 169 170 /****************************************************************************** 171 * star-enclosures-2d scene. A scene is a collection of segments. Each segment 172 * is defined with a medium on each side. 173 * Scenes with overlapping segments are considered ill-formed and any 174 * enclosure-related API call on such a scene will return RES_BAD_OP. 175 *****************************************************************************/ 176 /* Creates a scene from some vertices and segments. 177 * Neither vertices nor segments can include duplicates. 178 * Segments cannot be degenerated. */ 179 SENC2D_API res_T 180 senc2d_scene_create 181 (struct senc2d_device* device, 182 const int convention, 183 /* Number of segments */ 184 const unsigned segments_count, 185 /* User function that provides vertices ids for segments */ 186 void(*get_indices)( 187 const unsigned iseg, 188 unsigned ids[SENC2D_GEOMETRY_DIMENSION], 189 void* context), 190 /* User function that provides media ids for segments */ 191 void(*get_media) /* Can be NULL <=> SENC2D_UNSPECIFIED_MEDIUM medium used */ 192 (const unsigned iseg, unsigned med[2], void* context), 193 /* Number of vertices */ 194 const unsigned vertices_count, 195 /* User function that provides coordinates for vertices */ 196 void(*get_position)( 197 const unsigned ivert, 198 double pos[SENC2D_GEOMETRY_DIMENSION], 199 void* context), 200 /* Context provided to user callbacks; can be NULL */ 201 void* context, 202 /* The created scene */ 203 struct senc2d_scene** scene); 204 205 /* Returns the convention flags in use with the scene. */ 206 SENC2D_API res_T 207 senc2d_scene_get_convention 208 (const struct senc2d_scene* scene, 209 int* convention); 210 211 /* Returns the number of segments in the scene. */ 212 SENC2D_API res_T 213 senc2d_scene_get_segments_count 214 (const struct senc2d_scene* scene, 215 unsigned* count); 216 217 /* Returns the iseg_th segment vertices' indices. */ 218 SENC2D_API res_T 219 senc2d_scene_get_segment 220 (const struct senc2d_scene* scene, 221 const unsigned iseg, 222 unsigned indices[SENC2D_GEOMETRY_DIMENSION]); 223 224 /* Returns the media for the iseg_th segment. */ 225 SENC2D_API res_T 226 senc2d_scene_get_segment_media 227 (const struct senc2d_scene* scene, 228 const unsigned iseg, 229 unsigned media[2]); 230 231 /* Returns the number of vertices in the scene. */ 232 SENC2D_API res_T 233 senc2d_scene_get_vertices_count 234 (const struct senc2d_scene* scene, 235 unsigned* count); 236 237 /* Returns the coordinates of the ivert_th vertex. */ 238 SENC2D_API res_T 239 senc2d_scene_get_vertex 240 (const struct senc2d_scene* scene, 241 const unsigned ivert, 242 double coord[SENC2D_GEOMETRY_DIMENSION]); 243 244 /* Returns the greater medium id found in added geometry. In API calls using a 245 * medium, any value in the [0 max_medium_id[ range is valid. However there can 246 * be unused ids (no geometry refered to this medium id). */ 247 SENC2D_API res_T 248 senc2d_scene_get_max_medium 249 (const struct senc2d_scene* scene, 250 unsigned* max_medium_id); 251 252 /* Returns the number of enclosures. */ 253 SENC2D_API res_T 254 senc2d_scene_get_enclosure_count 255 (const struct senc2d_scene* scene, 256 unsigned* count); 257 258 /* Returns the number of enclosures that have some geometry refering to the 259 * imed_th medium or SENC2D_UNSPECIFIED_MEDIUM. */ 260 SENC2D_API res_T 261 senc2d_scene_get_enclosure_count_by_medium 262 (const struct senc2d_scene* scene, 263 const unsigned imed, 264 unsigned* count); 265 266 /* Returns the idx_th enclosure. */ 267 SENC2D_API res_T 268 senc2d_scene_get_enclosure 269 (struct senc2d_scene* scene, 270 const unsigned idx, 271 struct senc2d_enclosure** enclosure); 272 273 /* Returns the idx_th enclosure using the imed_th medium or 274 * SENC2D_UNSPECIFIED_MEDIUM. */ 275 SENC2D_API res_T 276 senc2d_scene_get_enclosure_by_medium 277 (struct senc2d_scene* scene, 278 const unsigned imed, 279 const unsigned idx, 280 struct senc2d_enclosure** enclosure); 281 282 /* Returns the enclosures the iseg_th segment front and back sides are member 283 * of. */ 284 SENC2D_API res_T 285 senc2d_scene_get_segment_enclosures 286 (const struct senc2d_scene* scene, 287 const unsigned iseg, 288 unsigned enclosures[2]); 289 290 /* Returns the number of vertices that are frontier vertices: 291 * - that have arity 1 (single segment using the vertex) 292 * - that connect 2 different media */ 293 SENC2D_API res_T 294 senc2d_scene_get_frontier_vertice_count 295 (const struct senc2d_scene* scene, 296 unsigned* count); 297 298 /* Returns the iver_th frontier vertex (segment and vertex global IDs). */ 299 SENC2D_API res_T 300 senc2d_scene_get_frontier_vertex 301 (const struct senc2d_scene* scene, 302 const unsigned iver, 303 unsigned vrtx_id[SENC2D_GEOMETRY_DIMENSION-1], 304 unsigned* seg_id); 305 306 /* Returns the number of overlapping segments. 307 * A model including overlapping segments cannot be split into enclosures 308 * unequivocally and will probably be ruled invalid by most softwares. 309 * As a consequence, one cannot query enclosure-related information on a model 310 * with overlapping segments. 311 * The library currently only detects overlapping segments that share a 312 * vertex. */ 313 SENC2D_API res_T 314 senc2d_scene_get_overlapping_segments_count 315 (const struct senc2d_scene* scene, 316 unsigned* count); 317 318 /* Returns the idx_th overlapping triangle id. */ 319 SENC2D_API res_T 320 senc2d_scene_get_overlapping_segment 321 (const struct senc2d_scene* scene, 322 const unsigned idx, 323 unsigned* id); 324 325 SENC2D_API res_T 326 senc2d_scene_ref_get 327 (struct senc2d_scene* scene); 328 329 SENC2D_API res_T 330 senc2d_scene_ref_put 331 (struct senc2d_scene* scene); 332 333 /****************************************************************************** 334 * star-enclosures-2d enclosure. It is an handle toward an enclosure. 335 * Counts and other information on enclosures are not individually accessible, 336 * but as a whole through header access. 337 * An enclosure can list the "same" segment twice if both sides are in. In this 338 * case the 2 occurences of the segment have reversed vertices order and 339 * unique_primitives_count and primitives_count differ. 340 * Vertices and segments numbering schemes are specific to each enclosure: 341 * the "same" item appearing in 2 different enclosures has no reason to get the 342 * same index twice or to have the same index in the global numbering scheme. 343 * By-index API accesses of segments (or properties) visit unique segments 344 * for indices in the [0 unique_primitives_count[ range and back-faces of the 345 * doubly-included segments in the [unique_primitives_count primitives_count[ 346 * range. 347 *****************************************************************************/ 348 /* Returns the header of an enclosure. */ 349 SENC2D_API res_T 350 senc2d_enclosure_get_header 351 (const struct senc2d_enclosure* enclosure, 352 struct senc2d_enclosure_header* header); 353 354 /* Returns the iseg_th segment of an enclosure. 355 * Indices are local to the enclosure. */ 356 SENC2D_API res_T 357 senc2d_enclosure_get_segment 358 (const struct senc2d_enclosure* enclosure, 359 const unsigned iseg, 360 unsigned indices[SENC2D_GEOMETRY_DIMENSION]); 361 362 /* Returns the coordinates of the ivert_th vertex of an enclosure. */ 363 SENC2D_API res_T 364 senc2d_enclosure_get_vertex 365 (const struct senc2d_enclosure* enclosure, 366 const unsigned ivert, 367 double coord[SENC2D_GEOMETRY_DIMENSION]); 368 369 /* Returns the global id of the iseg_th segment of an enclosure 370 * and the involved side. */ 371 SENC2D_API res_T 372 senc2d_enclosure_get_segment_id 373 (const struct senc2d_enclosure* enclosure, 374 const unsigned iseg, 375 unsigned* gid, 376 enum senc2d_side* side); 377 378 /* Returns the id of the imed_th medium of an enclosure. */ 379 SENC2D_API res_T 380 senc2d_enclosure_get_medium 381 (const struct senc2d_enclosure* enclosure, 382 const unsigned imed, 383 unsigned* medium); 384 385 SENC2D_API res_T 386 senc2d_enclosure_ref_get 387 (struct senc2d_enclosure* enclosure); 388 389 SENC2D_API res_T 390 senc2d_enclosure_ref_put 391 (struct senc2d_enclosure* enclosure); 392 393 END_DECLS 394 395 #endif /* SENC2D_H */