senc3d.h (14594B)
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_H 17 #define SENC3D_H 18 19 #include <rsys/rsys.h> 20 21 #include <limits.h> 22 23 /* Library symbol management */ 24 #if defined(SENC3D_SHARED_BUILD) 25 #define SENC3D_API extern EXPORT_SYM 26 #elif defined(SENC3D_STATIC_BUILD) 27 #define SENC3D_API extern LOCAL_SYM 28 #else /* Use shared library */ 29 #define SENC3D_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 SENC3D(Func) ASSERT(senc3d_ ## Func == RES_OK) 37 #else 38 #define SENC3D(Func) senc3d_ ## 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 SENC3D_NTHREADS_DEFAULT (~0u) 44 45 /* A constant to denote an unspecified medium */ 46 #define SENC3D_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-3d opaque data types. These data 53 * types are ref counted. Once created with the appropriated 54 * `senc3d__<TYPE>_create' function, the caller implicitly owns the created 55 * data, i.e. its reference counter is set to 1. 56 * The senc3d__<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 senc3d_device; 61 struct senc3d_scene; 62 struct senc3d_enclosure; 63 64 /****************************************************************************** 65 * The dimension of the geometry used in the library. 66 *****************************************************************************/ 67 #define SENC3D_GEOMETRY_DIMENSION 3 68 69 /* A type to discriminate triangle sides */ 70 enum senc3d_side { 71 SENC3D_FRONT, 72 SENC3D_BACK 73 }; 74 75 /* Enclosure header type */ 76 struct senc3d_enclosure_header { 77 /* The ID of the enclosure; 0, 1, ... */ 78 unsigned enclosure_id; 79 /* Number of triangles; a triangle can be counted twice, once by side*/ 80 unsigned primitives_count; 81 /* Number of unique triangles; a triangle 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 * SENC3D_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^3. 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 triangle are part of the enclosure, the triangle is 95 * counted as 0. */ 96 double volume; 97 /* The area of the enclosure, in m^2. 98 * If the two sides of a triangle are part of the enclosure, the triangle is 99 * counted twice. */ 100 double area; 101 }; 102 103 /* We consider the geometrical normal Ng to a triangle V0 V1 V2 104 * that verifies "(V0, V0V1, V0V2, Ng) is a direct system" 105 * (right-handed system). 106 * 107 * The user can set the convention used to determine which side of 108 * a triangle is to be considered front/back by using the flags : 109 * SENC3D_CONVENTION_NORMAL_FRONT => Ng points toward the front side, 110 * SENC3D_CONVENTION_NORMAL_BACK => Ng points toward the back side. 111 * 112 * Additionally the user can set the convention used to output enclosures 113 * so that Ng points toward the enclosure or on the opposite direction 114 * (for a closed enclosure Ng points toward the inside or toward the outside) 115 * by using the flags : 116 * SENC3D_CONVENTION_NORMAL_INSIDE => Ng points toward the enclosure, 117 * SENC3D_CONVENTION_NORMAL_OUTSIDE => Ng points toward the opposite of the 118 * enclosure. 119 * 120 * Note that normals in output data can be opposite to normals in input data 121 * (vertices are then given in reverse order). 122 * 123 * Also note that both sides of a triangle can be part of the same enclosure; 124 * in this case the 2 sides will be given with opposite Ng (meaning they 125 * will be given with opposite vertices order). 126 */ 127 enum senc3d_convention { 128 /* 129 * Convention regarding FRONT/BACK sides in input data 130 */ 131 132 /* Geometrical normals point toward the front side */ 133 SENC3D_CONVENTION_NORMAL_FRONT = BIT(0), 134 /* Geometrical normals point toward the back side */ 135 SENC3D_CONVENTION_NORMAL_BACK = BIT(1), 136 137 /* 138 * Convention regarding geometrical normals in output data 139 */ 140 141 /* Geometrical normals point toward the enclosure */ 142 SENC3D_CONVENTION_NORMAL_INSIDE = BIT(2), 143 /* Geometrical normals point to the opposite of the enclosure */ 144 SENC3D_CONVENTION_NORMAL_OUTSIDE = BIT(3), 145 146 /* 147 * Additional bits used for debugging purposes 148 */ 149 150 /* Dump identified connex components before grouping in STL files */ 151 SENC3D_DUMP_COMPONENTS_STL = BIT(4), 152 /* Extensive logs on grouping algorithm */ 153 SENC3D_LOG_COMPONENTS_INFORMATION = BIT(5) 154 }; 155 156 BEGIN_DECLS 157 158 /****************************************************************************** 159 * star_enclosures-3d device. It is an handle toward the StarEnc library. 160 * It manages the lib resources. 161 * If provided, the allocator has to be suitable for parallel high frequency 162 * allocations. As a consequence, a rsys proxy allocator should be avoided. 163 *****************************************************************************/ 164 SENC3D_API res_T 165 senc3d_device_create 166 (struct logger* logger, /* May be NULL <=> use default logger */ 167 struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ 168 const unsigned nthreads_hint, 169 const int verbose, 170 struct senc3d_device** device); 171 172 SENC3D_API res_T 173 senc3d_device_ref_get 174 (struct senc3d_device* device); 175 176 SENC3D_API res_T 177 senc3d_device_ref_put 178 (struct senc3d_device* device); 179 180 /****************************************************************************** 181 * star_enclosures-3d scene. A scene is a collection of triangles. Each 182 * triangle is defined with a medium on each side. 183 * Scenes with overlapping triangles are considered ill-formed and any 184 * enclosure-related API call on such a scene will return RES_BAD_OP. 185 *****************************************************************************/ 186 /* Creates a scene from some vertices and triangles. 187 * Neither vertices nor triangles can include duplicates. 188 * Triangles cannot be degenerated. */ 189 SENC3D_API res_T 190 senc3d_scene_create 191 (struct senc3d_device* device, 192 const int convention, 193 /* Number of triangles */ 194 const unsigned triangles_count, 195 /* User function that provides vertices ids for triangles */ 196 void(*get_indices)( 197 const unsigned itri, 198 unsigned ids[SENC3D_GEOMETRY_DIMENSION], 199 void* context), 200 /* User function that provides medium ids for triangles */ 201 void(*get_media) /* Can be NULL <=> SENC3D_UNSPECIFIED_MEDIUM medium used */ 202 (const unsigned itri, unsigned med[2], void* context), 203 /* Number of vertices */ 204 const unsigned vertices_count, 205 /* User function that provides coordinates for vertices */ 206 void(*get_position)( 207 const unsigned ivert, 208 double pos[SENC3D_GEOMETRY_DIMENSION], 209 void* context), 210 /* Context provided to user callbacks; can be NULL */ 211 void* context, 212 /* The created scene */ 213 struct senc3d_scene** scene); 214 215 /* Returns the convention flags in use with the scene. */ 216 SENC3D_API res_T 217 senc3d_scene_get_convention 218 (const struct senc3d_scene* scene, 219 int* convention); 220 221 /* Returns the number of triangles in the scene. */ 222 SENC3D_API res_T 223 senc3d_scene_get_triangles_count 224 (const struct senc3d_scene* scene, 225 unsigned* count); 226 227 /* Returns the itri_th triangle vertices' indices. */ 228 SENC3D_API res_T 229 senc3d_scene_get_triangle 230 (const struct senc3d_scene* scene, 231 const unsigned itri, 232 unsigned indices[SENC3D_GEOMETRY_DIMENSION]); 233 234 /* Returns the media for the itri_th triangle. */ 235 SENC3D_API res_T 236 senc3d_scene_get_triangle_media 237 (const struct senc3d_scene* scene, 238 const unsigned itri, 239 unsigned media[2]); 240 241 /* Returns the number of vertices in the scene. */ 242 SENC3D_API res_T 243 senc3d_scene_get_vertices_count 244 (const struct senc3d_scene* scene, 245 unsigned* count); 246 247 /* Returns the coordinates of the ivert_th vertex. */ 248 SENC3D_API res_T 249 senc3d_scene_get_vertex 250 (const struct senc3d_scene* scene, 251 const unsigned ivert, 252 double coord[SENC3D_GEOMETRY_DIMENSION]); 253 254 /* Returns the greater medium id found in geometry or SENC3D_UNSPECIFIED_MEDIUM 255 * if the geometry only used SENC3D_UNSPECIFIED_MEDIUM. Any value in range 256 * [0 max_medium_id[ as well as SENC3D_UNSPECIFIED_MEDIUM is valid in API calls 257 * requiring a medium (even if this medium id is unused). */ 258 SENC3D_API res_T 259 senc3d_scene_get_max_medium 260 (const struct senc3d_scene* scene, 261 unsigned* max_medium_id); 262 263 /* Returns the number of enclosures. */ 264 SENC3D_API res_T 265 senc3d_scene_get_enclosure_count 266 (const struct senc3d_scene* scene, 267 unsigned* count); 268 269 /* Returns the number of enclosures that have some geometry refering to the 270 * medium med (including SENC3D_UNSPECIFIED_MEDIUM). */ 271 SENC3D_API res_T 272 senc3d_scene_get_enclosure_count_by_medium 273 (const struct senc3d_scene* scene, 274 const unsigned med, 275 unsigned* count); 276 277 /* Returns the idx_th enclosure. */ 278 SENC3D_API res_T 279 senc3d_scene_get_enclosure 280 (struct senc3d_scene* scene, 281 const unsigned idx, 282 struct senc3d_enclosure** enclosure); 283 284 /* Returns the idx_th enclosure using the medium med (including 285 * SENC3D_UNSPECIFIED_MEDIUM). */ 286 SENC3D_API res_T 287 senc3d_scene_get_enclosure_by_medium 288 (struct senc3d_scene* scene, 289 const unsigned med, 290 const unsigned idx, 291 struct senc3d_enclosure** enclosure); 292 293 /* Returns the enclosures the itri_th triangle front and back sides are member 294 * of. */ 295 SENC3D_API res_T 296 senc3d_scene_get_triangle_enclosures 297 (const struct senc3d_scene* scene, 298 const unsigned itri, 299 unsigned enclosures[2]); 300 301 /* Returns the number of segments that are frontier segments: 302 * - that have arity 1 (single triangle using the segment) 303 * - that connect 2 different media */ 304 SENC3D_API res_T 305 senc3d_scene_get_frontier_segments_count 306 (const struct senc3d_scene* scene, 307 unsigned* count); 308 309 /* Returns the iseg_th frontier segment (triangle and vertices global IDs). */ 310 SENC3D_API res_T 311 senc3d_scene_get_frontier_segment 312 (const struct senc3d_scene* scene, 313 const unsigned iseg, 314 unsigned vrtx_id[SENC3D_GEOMETRY_DIMENSION-1], 315 unsigned* trg_id); 316 317 /* Returns the number of overlapping triangles. 318 * A model including overlapping triangles cannot be split into enclosures 319 * unequivocally and will probably be ruled invalid by most softwares. 320 * As a consequence, one cannot query enclosure-related information on a model 321 * with overlapping triangles. 322 * The library currently only detects overlapping triangles that share an 323 * edge. */ 324 SENC3D_API res_T 325 senc3d_scene_get_overlapping_triangles_count 326 (const struct senc3d_scene* scene, 327 unsigned* count); 328 329 /* Returns the idx_th overlapping triangle id. */ 330 SENC3D_API res_T 331 senc3d_scene_get_overlapping_triangle 332 (const struct senc3d_scene* scene, 333 const unsigned idx, 334 unsigned* id); 335 336 /* Dump a given enclosure in an OBJ file */ 337 SENC3D_API res_T 338 senc3d_scene_dump_enclosure_obj 339 (struct senc3d_scene* scn, 340 const unsigned enc, 341 const char* filename); 342 343 SENC3D_API res_T 344 senc3d_scene_ref_get 345 (struct senc3d_scene* scene); 346 347 SENC3D_API res_T 348 senc3d_scene_ref_put 349 (struct senc3d_scene* scene); 350 351 /****************************************************************************** 352 * star_enclosures-3d enclosure. It is an handle toward an enclosure. 353 * Counts and other information on enclosures are not individually accessible, 354 * but as a whole through header access. 355 * An enclosure can list the "same" triangle twice if both sides are in. In 356 * this case the 2 occurences of the triangle have reversed vertices order and 357 * unique_triangle_count and triangle_count differ. 358 * Vertices and triangles numbering schemes are specific to each enclosure: 359 * the "same" item appearing in 2 different enclosures has no reason to get the 360 * same index twice or to have the same index in the global numbering scheme. 361 * By-index API accesses of triangles (or properties) visit unique triangles 362 * for indices in the [0 unique_triangle_count[ range and back-faces of the 363 * doubly-included triangles in the [unique_triangle_count triangle_count[ 364 * range. 365 *****************************************************************************/ 366 /* Returns the header of an enclosure. */ 367 SENC3D_API res_T 368 senc3d_enclosure_get_header 369 (const struct senc3d_enclosure* enclosure, 370 struct senc3d_enclosure_header* header); 371 372 /* Returns the itri_th triangle of an enclosure. 373 * Indices are local to the enclosure. */ 374 SENC3D_API res_T 375 senc3d_enclosure_get_triangle 376 (const struct senc3d_enclosure* enclosure, 377 const unsigned itri, 378 unsigned indices[SENC3D_GEOMETRY_DIMENSION]); 379 380 /* Returns the coordinates of the ivert_th vertex of an enclosure. */ 381 SENC3D_API res_T 382 senc3d_enclosure_get_vertex 383 (const struct senc3d_enclosure* enclosure, 384 const unsigned ivert, 385 double coord[SENC3D_GEOMETRY_DIMENSION]); 386 387 /* Returns the global id of the itri_th triangle of an enclosure 388 * and the involved side. */ 389 SENC3D_API res_T 390 senc3d_enclosure_get_triangle_id 391 (const struct senc3d_enclosure* enclosure, 392 const unsigned itri, 393 unsigned* gid, 394 enum senc3d_side* side); 395 396 /* Returns the the imed_th medium id of an enclosure. */ 397 SENC3D_API res_T 398 senc3d_enclosure_get_medium 399 (const struct senc3d_enclosure* enclosure, 400 const unsigned imed, 401 unsigned* medium); 402 403 SENC3D_API res_T 404 senc3d_enclosure_ref_get 405 (struct senc3d_enclosure* enclosure); 406 407 SENC3D_API res_T 408 senc3d_enclosure_ref_put 409 (struct senc3d_enclosure* enclosure); 410 411 END_DECLS 412 413 #endif /* SENC3D_H */