star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

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