star-uvm

Spatial structuring of unstructured volumetric meshes
git clone git://git.meso-star.fr/star-uvm.git
Log | Files | Refs | README | LICENSE

suvm.h (9295B)


      1 /* Copyright (C) 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 SUVM_H
     17 #define SUVM_H
     18 
     19 #include <rsys/hash.h>
     20 #include <rsys/rsys.h>
     21 #include <float.h>
     22 
     23 /* Library symbol management */
     24 #if defined(SUVM_SHARED_BUILD) /* Build shared library */
     25   #define SUVM_API extern EXPORT_SYM
     26 #elif defined(SUVM_STATIC) /* Use/build static library */
     27   #define SUVM_API extern LOCAL_SYM
     28 #else /* Use shared library */
     29   #define SUVM_API extern IMPORT_SYM
     30 #endif
     31 
     32 /* Helper macro that asserts if the invocation of the suvm function `Func'
     33  * returns an error. One should use this macro on suvm function calls for
     34  * which no explicit error checking is performed */
     35 #ifndef NDEBUG
     36   #define SUVM(Func) ASSERT(suvm_ ## Func == RES_OK)
     37 #else
     38   #define SUVM(Func) suvm_ ## Func
     39 #endif
     40 
     41 /* Maximum number of vertices per volumetric primitive */
     42 #define SUVM_PRIMITIVE_MAX_VERTICES_COUNT 4
     43 
     44 enum suvm_volume_cpnt_flag {
     45   SUVM_POSITIONS = BIT(0),
     46   SUVM_INDICES = BIT(1),
     47   SUVM_PRIMITIVE_DATA = BIT(2),
     48   SUVM_VERTEX_DATA = BIT(3)
     49 };
     50 
     51 struct suvm_data {
     52   void (*get)(const size_t id, void* data, void* ctx); /* Data getter */
     53   size_t size; /* Size of the data in bytes */
     54   size_t alignment; /* Alignment of the data */
     55 };
     56 #define SUVM_DATA_NULL__ {NULL, 0, 0}
     57 static const struct suvm_data SUVM_DATA_NULL = SUVM_DATA_NULL__;
     58 
     59 struct suvm_primitive {
     60   const void* data; /* Data of the primitive */
     61   const void* vertex_data[SUVM_PRIMITIVE_MAX_VERTICES_COUNT]; /* Vertex data */
     62   size_t indices[SUVM_PRIMITIVE_MAX_VERTICES_COUNT]; /* Vertex indices */
     63   size_t iprim; /* Identifier of the primitive */
     64   size_t nvertices; /* #vertices of the primitive */
     65 
     66   /* Internal data */
     67   const struct suvm_volume* volume__;
     68 };
     69 #define SUVM_PRIMITIVE_NULL__ {                                                \
     70   NULL, /* Primitive data */                                                   \
     71   {NULL}, /* Vertex data */                                                    \
     72   {0}, /* Vertex indices */                                                    \
     73   SIZE_MAX, /* Primitive id */                                                 \
     74   SIZE_MAX, /* #vertices */                                                    \
     75   NULL /* Pointer toward its associated volume */                              \
     76 }
     77 static const struct suvm_primitive SUVM_PRIMITIVE_NULL = SUVM_PRIMITIVE_NULL__;
     78 
     79 #define SUVM_PRIMITIVE_NONE(Prim) ((Prim)->iprim == SIZE_MAX)
     80 
     81 /* Precomputed data from a suvm_primitive used to speed up AABB/primitive
     82  * intersection tests */
     83 struct suvm_polyhedron {
     84   float v[4/*#vertices*/][3/*#coords*/]; /* Vertices */
     85   float N[4/*#vertices*/][3/*#coords*/]; /* Normals */
     86   float D[4/*#facets*/]; /* Slope parameter of the plane (D = -(Ax+By+Cz)) */
     87 
     88   /* 2D equation of the silhouette edges projected along the X, Y and Z axis of
     89    * the form Ax + By + C = 0, with (A, B) the normals of the edge  */
     90   float Ep[3/*#axes*/][4/*#edges max*/][3/*#equation parameters*/];
     91 
     92   /* Number of silhouette edges in the ZY, XZ and XY planes (3 or 4) */
     93   int nEp[3/*#coords*/];
     94 
     95   /* Tetrahedron axis aligned bounding box */
     96   float lower[3/*#coords*/];
     97   float upper[3/*#coords*/];
     98 };
     99 
    100 /* Internal copy of the unstructured mesh */
    101 struct suvm_mesh_desc {
    102   const float* positions;
    103   const uint32_t* indices;
    104   size_t nvertices;
    105   size_t nprimitives;
    106   unsigned dvertex; /* Dimension of a vertex */
    107   unsigned dprimitive; /* Dimension of a primitive */
    108 };
    109 #define SUVM_MESH_DESC_NULL__ {NULL, NULL, 0, 0, 0, 0}
    110 static const struct suvm_mesh_desc SUVM_MESH_DESC_NULL = SUVM_MESH_DESC_NULL__;
    111 
    112 struct suvm_tetrahedral_mesh_args {
    113   size_t ntetrahedra; /* #tetrahedra */
    114   size_t nvertices; /* #vertices */
    115 
    116   /* Each tetrahedron has to list the bottom triangle in counterclockwise order,
    117    * and then the top vertex. */
    118   void (*get_indices)(const size_t itetra, size_t ids[4], void* ctx);
    119   void (*get_position)(const size_t ivert, double pos[3], void* ctx);
    120 
    121   /* Per tetrahedron/vertex data. SUVM_DATA_NULL <=> no data */
    122   struct suvm_data tetrahedron_data;
    123   struct suvm_data vertex_data;
    124 
    125   /* Define whether tetrahedron normals are precomputed or not. When
    126    * precomputed, the normals of each tetrahedron facet are explicitly stored
    127    * and thus increase the memory footprint but speed up accessors that use
    128    * them (e.g. suvm_volume_at). */
    129   int precompute_normals;
    130 
    131   void* context; /* Client data set as the last param of the callbacks */
    132 };
    133 #define SUVM_TETRAHEDRAL_MESH_ARGS_NULL__ {                                    \
    134   0, 0, NULL, NULL, SUVM_DATA_NULL__, SUVM_DATA_NULL__, 0, NULL                \
    135 }
    136 static const struct suvm_tetrahedral_mesh_args SUVM_TETRAHEDRAL_MESH_ARGS_NULL =
    137   SUVM_TETRAHEDRAL_MESH_ARGS_NULL__;
    138 
    139 enum suvm_intersection_type {
    140   SUVM_INTERSECT_NONE,
    141   SUVM_INTERSECT_INCLUDE,
    142   SUVM_INTERSECT_IS_INCLUDED,
    143   SUVM_INTERSECT_PARTIAL
    144 };
    145 
    146 /* Callback invoked on suvm_volume_intersect_aabb invocation on each primitives
    147  * intersected by the submitted Axis Aligned Bounding Box */
    148 typedef void
    149 (*suvm_primitive_intersect_aabb_T)
    150   (const struct suvm_primitive* primitive, /* Intersected primitive */
    151    const double low[3], /* AABB lower bound */
    152    const double upp[3], /* AABB upper bound */
    153    void* context); /* User data */
    154 
    155 /* Forward declaration of external data types */
    156 struct logger;
    157 struct mem_allocator;
    158 
    159 /* Forward declaration of opaque data types */
    160 struct suvm_device;
    161 struct suvm_volume;
    162 
    163 BEGIN_DECLS
    164 
    165 /*******************************************************************************
    166  * Device API
    167  ******************************************************************************/
    168 SUVM_API res_T
    169 suvm_device_create
    170   (struct logger* logger, /* NULL <=> use default logger */
    171    struct mem_allocator* allocator, /* NULL <=> use default allocator */
    172    const int verbose, /* Verbosity */
    173    struct suvm_device** suvm);
    174 
    175 SUVM_API res_T
    176 suvm_device_ref_get
    177   (struct suvm_device* dev);
    178 
    179 SUVM_API res_T
    180 suvm_device_ref_put
    181   (struct suvm_device* dev);
    182 
    183 /*******************************************************************************
    184  * Volume mesh API
    185  ******************************************************************************/
    186 SUVM_API res_T
    187 suvm_tetrahedral_mesh_create
    188   (struct suvm_device* dev,
    189    const struct suvm_tetrahedral_mesh_args* args,
    190    struct suvm_volume** volume);
    191 
    192 SUVM_API res_T
    193 suvm_volume_ref_get
    194   (struct suvm_volume* volume);
    195 
    196 SUVM_API res_T
    197 suvm_volume_ref_put
    198   (struct suvm_volume* volume);
    199 
    200 SUVM_API res_T
    201 suvm_volume_get_aabb
    202   (const struct suvm_volume* volume,
    203    double lower[3],
    204    double upper[3]);
    205 
    206 /* Return the primitive into which `pos' lies and the barycentric coordinates
    207  * of `pos' into this primitive. The returned primitive is SUVM_PRIMITIVE_NULL
    208  * if `pos' is not included into any volumic primitive. One can use the
    209  * SUVM_PRIMIIVE_NONE macro to check this case. */
    210 SUVM_API res_T
    211 suvm_volume_at
    212   (struct suvm_volume* volume,
    213    const double pos[3],
    214    struct suvm_primitive* prim, /* Geometric primitive where `pos' lies */
    215    double barycentric_coords[4]); /* `pos' into the primitive */
    216 
    217 /* Iterate over the volumetric primitives intersecting the submitted Axis
    218  * Aligned Bounding Box and invoke the `clbk' function onto them. */
    219 SUVM_API res_T
    220 suvm_volume_intersect_aabb
    221   (struct suvm_volume* volume,
    222    const double low[3], /* AABB lower bound */
    223    const double upp[3], /* AABB upper bound */
    224    suvm_primitive_intersect_aabb_T clbk,
    225    void* context); /* User data sent as the last argument of clbk */
    226 
    227 SUVM_API res_T
    228 suvm_volume_get_primitives_count
    229   (const struct suvm_volume* volume,
    230    size_t* nprims);
    231 
    232 SUVM_API res_T
    233 suvm_volume_get_primitive
    234   (const struct suvm_volume* volume,
    235    const size_t iprim, /* In [0, suvm_volume_get_primitives_count[ */
    236    struct suvm_primitive* prim);
    237 
    238 SUVM_API res_T
    239 suvm_volume_compute_hash
    240   (const struct suvm_volume* volume,
    241    const int cpnt_mask, /* Combination of suvm_volume_cpnt_flag */
    242    hash256_T hash);
    243 
    244 SUVM_API res_T
    245 suvm_volume_get_mesh_desc
    246   (const struct suvm_volume* volume,
    247    struct suvm_mesh_desc* desc);
    248 
    249 SUVM_API res_T
    250 suvm_mesh_desc_compute_hash
    251   (const struct suvm_mesh_desc* desc,
    252    hash256_T hash);
    253 
    254 /*******************************************************************************
    255  * Primitive API
    256  ******************************************************************************/
    257 SUVM_API res_T
    258 suvm_primitive_setup_polyhedron
    259   (const struct suvm_primitive* prim,
    260    struct suvm_polyhedron* poly);
    261 
    262 SUVM_API enum suvm_intersection_type
    263 suvm_polyhedron_intersect_aabb
    264   (const struct suvm_polyhedron* poly,
    265    const float low[3],
    266    const float upp[3]);
    267 
    268 END_DECLS
    269 
    270 #endif /* SUVM_H */
    271