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 fff4552e9a86d43f0bb0da8515173ff1a4eb8c2d
parent 4a6590b500b657c3fcd1dad2473cc68988df8d03
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  9 Oct 2018 11:11:09 +0200

Add and test the s2d_segment_get_vertex_attrib function

Diffstat:
Msrc/s2d.h | 7+++++++
Msrc/s2d_primitive.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/test_s2d_primitive.c | 18++++++++++++++++--
3 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/src/s2d.h b/src/s2d.h @@ -402,6 +402,13 @@ s2d_primitive_compute_length (const struct s2d_primitive* prim, float* area); +S2D_API res_T +s2d_segment_get_vertex_attrib + (const struct s2d_primitive* prim, + const size_t ivertex, /* in [0..2[ */ + const enum s2d_attrib_usage usage, + struct s2d_attrib* attrib); /* Resulting attrib */ + /******************************************************************************* * Line Segments API - manage a list of segments ******************************************************************************/ diff --git a/src/s2d_primitive.c b/src/s2d_primitive.c @@ -27,12 +27,25 @@ * knowledge of the CeCILL license and that you accept its terms. */ #include "s2d.h" +#include "s2d_c.h" #include "s2d_geometry.h" #include "s2d_line_segments.h" #include <rsys/float2.h> /******************************************************************************* + * Helper functions + ******************************************************************************/ +static int +check_primitive(const struct s2d_primitive* prim) +{ + return prim + && prim->geom_id != S2D_INVALID_ID + && prim->prim_id != S2D_INVALID_ID + && prim->mesh__ != NULL; +} + +/******************************************************************************* * Exported functions ******************************************************************************/ res_T @@ -46,20 +59,13 @@ s2d_primitive_get_attrib struct geometry* geom = NULL; res_T res = RES_OK; - if(!prim + if(!check_primitive(prim) || !attrib || (usage != S2D_GEOMETRY_NORMAL && (unsigned)usage >= S2D_ATTRIBS_COUNT__)) { res = RES_BAD_ARG; goto error; } - if(prim->geom_id == S2D_INVALID_ID - || prim->prim_id == S2D_INVALID_ID - || prim->mesh__ == NULL) { - res = RES_BAD_ARG; - goto error; - } - /* Unnormalized barycentric coordinates */ if(s < 0.f || s > 1.f) { res = RES_BAD_ARG; @@ -126,7 +132,7 @@ s2d_primitive_sample const float u, float* s) { - if(!prim || S2D_PRIMITIVE_EQ(prim, &S2D_PRIMITIVE_NULL) || !s) + if(!check_primitive(prim) || !s) return RES_BAD_ARG; if(u < 0.f || u >= 1.f) @@ -148,7 +154,7 @@ s2d_primitive_compute_length(const s2d_primitive* prim, float* length) float tmp[2]; struct geometry* geom; - if(!prim || !length || S2D_PRIMITIVE_EQ(prim, &S2D_PRIMITIVE_NULL)) + if(!check_primitive(prim) || !length) return RES_BAD_ARG; geom = (struct geometry*)prim->mesh__; @@ -160,3 +166,52 @@ s2d_primitive_compute_length(const s2d_primitive* prim, float* length) return RES_OK; } +res_T +s2d_segment_get_vertex_attrib + (const struct s2d_primitive* prim, + const size_t ivertex, /* in [0..2[ */ + const enum s2d_attrib_usage usage, + struct s2d_attrib* attrib) /* Resulting attrib */ +{ + struct geometry* geom; + const uint32_t* ids; + + if(!check_primitive(prim) || ivertex > 1 + || (unsigned)usage >= S2D_ATTRIBS_COUNT__ || !attrib) { + return RES_BAD_ARG; + } + + geom = (struct geometry*)prim->mesh__; + ASSERT(prim->geom_id == geom->name); + + /* The segment have not the required attrib */ + if(!geom->lines->attribs[usage]) { + return RES_BAD_ARG; + } + + /* Out of bound primitive index */ + if(prim->prim_id >= line_segments_get_nverts(geom->lines)) { + return RES_BAD_ARG; + } + + ids = line_segments_get_ids(geom->lines) + prim->prim_id*2/*#segment ids*/; + attrib->usage = usage; + + if(usage != S2D_POSITION) { + const float* attr; + unsigned i, dim; + attrib->type = geom->lines->attribs_type[usage]; + /* Fetch attrib data */ + dim = s2d_type_get_dimension(attrib->type); + attr = line_segments_get_attr(geom->lines, usage) + ids[ivertex]*dim; + FOR_EACH(i, 0, dim) attrib->value[i] = attr[i]; + } else { + const float* pos; + attrib->type = S2D_FLOAT2; + /* Fetch data */ + pos = line_segments_get_pos(geom->lines) + ids[ivertex]*2; + f2_set(attrib->value, pos); + } + return RES_OK; +} + diff --git a/src/test_s2d_primitive.c b/src/test_s2d_primitive.c @@ -108,7 +108,6 @@ main(int argc, char** argv) CHK(s2d_scene_view_create(scn, S2D_GET_PRIMITIVE, &scnview) == RES_OK); CHK(s2d_scene_view_primitives_count(scnview, &nprims) == RES_OK); CHK(nprims == 4); - CHK(s2d_scene_view_ref_put(scnview) == RES_OK); CHK(s2d_primitive_compute_length(NULL, NULL) == RES_BAD_ARG); CHK(s2d_primitive_compute_length(&prim, NULL) == RES_BAD_ARG); @@ -124,7 +123,7 @@ main(int argc, char** argv) CHK(s2d_primitive_sample(&prim, 2.f, &s) == RES_BAD_ARG); CHK(s2d_primitive_sample(NULL, 0.5f, &s) == RES_BAD_ARG); CHK(s2d_primitive_sample(&prim, 0.5f, &s) == RES_OK); - CHK(eq_epsf(s, 0.5f, 1.e-6f) == 1); + CHK(eq_epsf(s, 0.5f, 1.e-6f)); FOR_EACH(i, 0, NSAMPS) { CHK(s2d_primitive_sample(&prim, rand_canonic(), &s) == RES_OK); @@ -132,8 +131,23 @@ main(int argc, char** argv) CHK(s <= 1.f); } + CHK(s2d_scene_view_get_primitive(scnview, 0, &prim) == RES_OK); + + #define GET_VERTEX_ATTR s2d_segment_get_vertex_attrib + CHK(GET_VERTEX_ATTR(NULL, 0, S2D_POSITION, &attr) == RES_BAD_ARG); + CHK(GET_VERTEX_ATTR(&prim, 2, S2D_POSITION, &attr) == RES_BAD_ARG); + CHK(GET_VERTEX_ATTR(&prim, 0, S2D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG); + CHK(GET_VERTEX_ATTR(&prim, 0, S2D_POSITION, NULL) == RES_BAD_ARG); + CHK(GET_VERTEX_ATTR(&prim, 0, S2D_POSITION, &attr) == RES_OK); + CHK(attr.type == S2D_FLOAT2); + CHK(f2_eq_eps(attr.value, square_verts + square_ids[0]*2, 1.e-6f)); + CHK(GET_VERTEX_ATTR(&prim, 1, S2D_POSITION, &attr) == RES_OK); + CHK(attr.type == S2D_FLOAT2); + CHK(f2_eq_eps(attr.value, square_verts + square_ids[1]*2, 1.e-6f)); + CHK(s2d_device_ref_put(dev) == RES_OK); CHK(s2d_scene_ref_put(scn) == RES_OK); + CHK(s2d_scene_view_ref_put(scnview) == RES_OK); CHK(s2d_shape_ref_put(shape) == RES_OK); check_memory_allocator(&allocator);