star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

commit 7f24a2187d65049727abe7e82d45c6c9f8c46119
parent e6f99b36207299e7799e9c5972a7ecd8b7ffed05
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  8 Jun 2016 15:09:56 +0200

First version of the API

Only the API function profiles and the API types are listed. Nothing is
currently implemented.

Diffstat:
Asrc/s2d.h | 447+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 447 insertions(+), 0 deletions(-)

diff --git a/src/s2d.h b/src/s2d.h @@ -0,0 +1,447 @@ +/* Copyright (C) |Meso|Star> 2016 (contact@meso-star.com) + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. */ + +#ifndef S2D_H +#define S2D_H + +#include <rsys/rsys.h> +#include <float.h> + +/* Library symbol management */ +#if defined(S2D_SHARED_BUILD) /* Build shared library */ + #define S2D_API extern EXPORT_SYM +#elif defined(S2D_STATIC) /* Use/build static library */ + #define S2D_API extern LOCAL_SYM +#else /* Use shared library */ + #define S2D_API extern IMPORT_SYM +#endif + +/* Helper macro that asserts if the invocation of the s2d function `Func' + * returns an error. One should use this macro on s2d function calls for which + * no explicit error checking is performed */ +#ifndef NDEBUG + #define S2D(Func) ASSERT(s2d_ ## Func == RES_OK) +#else + #define S2D(Func) s2d_ ## Func +#endif + +/* Syntactic sugar use during the setup of the shape. Setting a vertex data + * functor to S2D_KEEP means that this vertex data will not be updated */ +#define S2D_KEEP NULL + +#define S2D_INVALID_ID ((unsigned)-1) /* Value of an invalid identifer */ + +enum s2d_attrib_usage { + S2D_POSITION, /* World space position */ + S2D_ATTRIBS_COUNT__, + /* Unormalized world space face normal. For line segments, the outward + * orientation is defined with respect to the Clock Wise vertex ordering */ + S2D_GEOMETRY_NORMAL +}; + +enum s2d_type { + S2D_FLOAT, + S2D_FLOAT2, + S2D_FLOAT3 +}; + +/* Primitive descriptor. The geom indentifier covers a compact ranges of value. + * They can be used in conjunction with a dynamic array to map from s2d + * geometry to application geometry */ +struct s2d_primitive { + unsigned prim_id; /* Primitive identifier */ + unsigned geom_id; /* Geometry identifier */ + unsigned scene_prim_id; /* Identifier of the primitive in the scene */ + /* Internal data. Should not be accessed */ + void* mesh__; +}; + +#define S2D_PRIMITIVE_NULL__ { \ + S2D_INVALID_ID, S2D_INVALID_ID, S2D_INVALID_ID, NULL \ +} +static const struct s2d_primitive S2D_PRIMITIVE_NULL = S2D_PRIMITIVE_NULL__; + +/* Helper macro that defines whether or not 2 primitives are equal */ +#define S2D_PRIMITIVE_EQ(Prim0, Prim1) \ + ( (Prim0)->prim_id == (Prim1)->prim_id \ + && (Prim0)->geom_id == (Prim1)->geom_id) + +/* Untyped vertex attribute */ +struct s2d_attrib { + float value[3]; + enum s2d_type type; + enum s2d_attrib_usage usage; +}; + +/* Describe a per vertex data */ +struct s2d_vertex_data { + /* Semantic of the data. Note that the S2D_GEOMETRY_NORMAL is not a valid + * vertex usage */ + enum s2d_attrib_usage usage; + enum s2d_type type; + /* Retreive the vertex data value of `ivert'. Set it to S2D_KEEP, to keep the + * previously set data */ + void (*get) + (const unsigned ivert, /* Index of the vertex */ + float* value, /* Retrieved attrib value */ + void* ctx); /* Pointer to user data */ +}; + +/* Invalid vertex data */ +#define S2D_VERTEX_DATA_NULL__ { S2D_ATTRIBS_COUNT__, S2D_FLOAT, NULL } +static const struct s2d_vertex_data S2D_VERTEX_DATA_NULL = S2D_VERTEX_DATA_NULL__; + +/* Intersection point */ +struct s2d_hit { + struct s2d_primitive prim; /* Intersected primitive */ + float normal[2]; /* Unormalized geometry normal */ + float u; /* Barycentric coordinates of the hit onto `prim' */ + float distance; /* Hit distance from the ray origin */ +}; + +/* Constant defining a NULL intersection. Should be used to initialize a hit */ +#define S2D_HIT_NULL__ { \ + S2D_PRIMITIVE_NULL__, \ + { 0.f, 0.f }, \ + 0.f, \ + FLT_MAX \ +} +static const struct s2d_hit S2D_HIT_NULL = S2D_HIT_NULL__; + +/* Helper macro that defines whether or not the hit is valid, i.e. the ray + * intersects a shape or not */ +#define S2D_HIT_NONE(Hit) ((Hit)->distance >= FLT_MAX) + +/* Filter function data type. One can define such function to discard + * intersections along a ray with respect to user defined criteria, e.g.: + * masked/transparent primitive, etc. Return 0 or the intersection is not + * discarded and a value not equal to zero otherwise. */ +typedef int +(*s2d_hit_filter_function_T) + (const struct s2d_hit* hit, + const float ray_org[2], + const float ray_dir[2], + void* ray_data, /* User data submitted on trace ray(s) invocation */ + void* filter_data); /* Data defined on the setup of the filter function */ + +enum s2d_session_flag { + S2D_TRACE = BIT(0), + S2D_SAMPLE = BIT(1), + S2D_GET_PRIMITIVE = BIT(2) +}; + +/* Forward declaration of s2d opaque data types */ +struct s2d_device; +struct s2d_scene; +struct s2d_shape; + +/* Forward declaration of external data types */ +struct logger; +struct mem_allocator; + +BEGIN_DECLS + +/******************************************************************************* + * Device API - entry point of the s2d library + ******************************************************************************/ +S2D_API res_T +s2d_device_create + (struct logger* logger, /* May be NULL <=> use default logger */ + struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ + const int verbose, /* Define the level of verbosity */ + struct s2d_device** dev); + +S2D_API res_T +s2d_device_ref_get + (struct s2d_device* dev); + +S2D_API res_T +s2d_device_ref_put + (struct s2d_device* dev); + +/******************************************************************************* + * Scene API - collection of shapes + ******************************************************************************/ +S2D_API res_T +s2d_scene_create + (struct s2d_device* dev, + struct s2d_scene** scn); + +S2D_API res_T +s2d_scene_ref_get + (struct s2d_scene* scn); + +S2D_API res_T +s2d_scene_ref_put + (struct s2d_scene* scn); + +/* Attach the shape to the scene. If the shape is already attached to the same + * or another scene, nothing is performed and a RES_BAD_ARG error is returned. + * On success, the scene gets a reference onto the attached shape */ +S2D_API res_T +s2d_scene_attach_shape + (struct s2d_scene* scn, + struct s2d_shape* shape); + +/* Remove the shape from the scene. After its detachment, the scene + * release its reference on the shape */ +S2D_API res_T +s2d_scene_detach_shape + (struct s2d_scene* scn, + struct s2d_shape* shape); + +/* Detach all the shapes from the scene and release the reference that the + * scene takes onto them */ +S2D_API res_T +s2d_scene_clear + (struct s2d_scene* scn); + +/* Synchronize the scene geometry with the geometry of its attached shapes. If + * a s2d_scene_begin_session is already active on `scn' or one of its attached + * instance a RES_BAD_OP error is returned. On success neither another begin + * session nor a clear or shape_detach can be invoked on `scn' and its attached + * instances until s2d_scene_end_session is called. */ +S2D_API res_T +s2d_scene_begin_session + (struct s2d_scene* scn, + const int session_mask); /* Combination of s2d_session_flag */ + +/* End the session on the `scn' */ +S2D_API res_T +s2d_scene_end_session + (struct s2d_scene* scn); + +S2D_API res_T +s2d_scene_get_session_mask + (struct s2d_scene* scn, + int* mask); + +/* Trace a ray into the `scn' and return the closest intersection. The ray is + * defined by `origin' + t*`direction' = 0 with t in [`range[0]', `range[1]'). + * Note that if range is degenerated (i.e. `range[0]' >= `range[1]') then the + * ray is not traced and `hit' is set to S2D_HIT_NULL. Can be called only if an + * S2D_TRACE session is active on `scn' */ +S2D_API res_T +s2d_scene_trace_ray + (struct s2d_scene* scn, + const float origin[2], /* Ray origin */ + const float direction[2], /* Ray direction. Must be normalized */ + const float range[2], /* In [0, INF)^2 */ + void* ray_data, /* User ray data sent to the hit filter func. May be NULL */ + struct s2d_hit* hit); + +/* Uniformly sample the scene and returned the sampled primitive and its sample + * s position. Can be called only if a S2D_SAMPLE session is active on `scn'*/ +S2D_API res_T +s2d_scene_sample + (struct s2d_scene* scn, + const float u, const float v, /* Random numbers in [0, 1) */ + struct s2d_primitive* primitive, /* Sampled primitive */ + float* s); /* Sampled parametric coordinates on the primitive */ + +/* Retrieve a primitive from the scene. Can be called only if a + * S2D_GET_PRIMITIVE session is active on `scn' */ +S2D_API res_T +s2d_scene_get_primitive + (struct s2d_scene* scn, + const unsigned iprim, /* in [0, #prims) */ + struct s2d_primitive* prim); + +/* Retrieve the number of scene primitives. Can be called only if a sessio is + * active on `scn' */ +S2D_API res_T +s2d_scene_primitives_count + (struct s2d_scene* scn, + size_t* primitives_count); + +/* Compute the overall length of the shape contours. Return RES_BAD_ARG if no + * session is active on scn. */ +S2D_API res_T +s2d_scene_compute_contour_length + (struct s2d_scene* scn, + float* volume); + +/* This function assumes that the scene defines a closed polygon and that the + * normals point into the polygon. Return RES_BAD_ARG if no session is active + * on scn */ +S2D_API res_T +s2d_scene_compute_area + (struct s2d_scene* scn, + float* area); + +/* Retrieve the Axis Aligned Bounding Box of the scene. Return RES_BAD_ARG if + * no session is active on scn */ +S2D_API res_T +s2d_scene_get_aabb + (struct s2d_scene* scn, + float lower[3], /* AABB lower bound */ + float upper[3]); /* AABB upper bound */ + +/* Retrieve the device from which the scene was created */ +S2D_API res_T +s2d_scene_get_device + (struct s2d_scene* scn, + struct s2d_device** dev); + +/******************************************************************************* + * Shape API - define a 2D contour that can be attached to *one* scene. + ******************************************************************************/ +S2D_API res_T +s2d_shape_create_line_segments + (struct s2d_device* dev, + struct s2d_shape** shape); + +S2D_API res_T +s2d_shape_ref_get + (struct s2d_shape* shape); + +S2D_API res_T +s2d_shape_ref_put + (struct s2d_shape* shape); + +/* Retrieve the id of the shape. This id covers a compact range of value. + * Consequently, it can be used to map from the s2d shapes to the geometry + * representation of the caller with a simple dynamic array */ +S2D_API res_T +s2d_shape_get_id + (struct s2d_shape* shape, + unsigned* id); + +/* Enable/disable the shape, i.e. it cannot be hit when its associated scene is + * ray-traced or sampled */ +S2D_API res_T +s2d_shape_enable + (struct s2d_shape* shape, + const char enable); + +/* Return whether or not the shape is enabled, i.e. ray-traced or sampled. + * Default is 1 */ +S2D_API res_T +s2d_shape_is_enabled + (struct s2d_shape* shape, + char* is_enabled); + +/* Define whether the shape is attached or not */ +S2D_API res_T +s2d_shape_is_attached + (struct s2d_shape* shape, + char* is_attached); + +/* Flip the contour orientation, i.e. flip the normal of the contour */ +S2D_API res_T +s2d_shape_flip_contour + (struct s2d_shape* shape); + +/******************************************************************************* + * Primitive API - Define a geometric primitive of a shape + ******************************************************************************/ +/* Retrieve the attribute of the shape primitive `iprim' at the barycentric + * coordinates `uv' */ +S2D_API res_T +s2d_primitive_get_attrib + (const struct s2d_primitive* prim, + const enum s2d_attrib_usage attr, /* Attribute to retrieve */ + const float s, /* Parametric coordinates of `attr' on `prim' */ + struct s2d_attrib* attrib); /* Resulting attrib */ + +/* Uniform sampling of the primitive */ +S2D_API res_T +s2d_primitive_sample + (const struct s2d_primitive* prim, + const float u, /* Random numbers in [0, 1) */ + float* s); /* Sampled parametric coordinates on prim */ + +S2D_API res_T +s2d_primitive_compute_length + (const struct s2d_primitive* prim, + float* area); + +/******************************************************************************* + * Line Segments API - manage a list of segments + ******************************************************************************/ +S2D_API res_T +s2d_line_segments_setup_indexed_vertices + (struct s2d_shape* shape, + const unsigned nsegments, + void (*get_indices) /* May be S2D_KEEP, i.e. do not update the indices */ + (const unsigned isegment, unsigned ids[3], void* ctx), + const unsigned nverts, + /* List of the shape vertex data. Must have at least an attrib with the + * S2D_POSITION usage. */ + struct s2d_vertex_data attribs[], + const unsigned nattribs, /* # attributes in the attribs list */ + void* data); /* Client data set as the last param of the callbacks */ + +/* Copy the line segments data from `src' to `dst' */ +S2D_API res_T +s2d_line_segments_copy + (const struct s2d_shape* src, + struct s2d_shape* dst); + +S2D_API res_T +s2d_line_segments_get_vertices_count + (const struct s2d_shape* shape, + unsigned* nverts); + +S2D_API res_T +s2d_line_segments_get_vertex_attrib + (const struct s2d_shape* shape, + const unsigned ivert, + const enum s2d_attrib_usage usage, + struct s2d_attrib* attrib); + +S2D_API res_T +s2d_line_segments_get_segments_count + (const struct s2d_shape* shape, + unsigned* nsegments); + +S2D_API res_T +s2d_line_segments_get_segment_indices + (const struct s2d_shape* shape, + const unsigned itri, + unsigned ids[3]); + +/* Define a intersection filter function. The filter function is invoked at + * each intersection found during the s2d_scene_trace_ray calls. If func does + * not return 0, then the intersection is ignored and the ray pursues its + * traversal. */ +S2D_API res_T +s2d_line_segments_set_hit_filter_function + (struct s2d_shape* shape, + s2d_hit_filter_function_T func, + void* filter_data); + +S2D_API res_T +s2d_line_segments_get_hit_filter_data + (struct s2d_shape* shape, + void** data); + +END_DECLS + +#endif /* S2D_H */ +