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 a7a99a9e6eea8c1a9ca219ca4e1d6a0999316fb2
parent 6665dab14dfa1598f8f748125814092c6c6333cc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 28 Jun 2016 10:28:24 +0200

Implement and test the s2d_scene_compute_contour_length function

Diffstat:
Msrc/s2d.h | 2+-
Msrc/s2d_scene.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_s2d_scene.c | 14++++++++++++++
3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/src/s2d.h b/src/s2d.h @@ -284,7 +284,7 @@ s2d_scene_primitives_count S2D_API res_T s2d_scene_compute_contour_length (struct s2d_scene* scn, - float* volume); + float* length); /* 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 diff --git a/src/s2d_scene.c b/src/s2d_scene.c @@ -969,3 +969,57 @@ exit: error: goto exit; } + +res_T +s2d_scene_compute_contour_length(struct s2d_scene* scn, float* out_length) +{ + float length = 0; + res_T res = RES_OK; + + if(!scn || !out_length) { + res = RES_BAD_ARG; + goto error; + } + + if(!scn->session_mask) { + log_error(scn->dev, + "%s: A session must be active on the submitted scene.\n", __FUNCTION__); + res = RES_BAD_OP; + goto error; + } + + if((scn->session_mask & S2D_SAMPLE) != 0) { + /* Retrieve the overall scene contour length from the scene cumulative + * distribution function. Note that the CDF stores the cumulative contour + * length. The real contour length is thus the CDF upper bound */ + size_t len = darray_fltui_size_get(&scn->cdf); + if(!len) { + length = 0.f; + } else { + length = darray_fltui_cdata_get(&scn->cdf)[len-1].flt; + } + } else { + struct list_node* node; + struct s2d_shape* shape; + struct geometry** pgeom; + struct geometry* geom; + + length = 0; + LIST_FOR_EACH(node, &scn->shapes) { + shape = CONTAINER_OF(node, struct s2d_shape, scene_attachment); + pgeom = htable_geom_find(&scn->cached_geoms, &shape); + ASSERT(pgeom != NULL); + geom = *pgeom; + + if(!geom->is_enabled) continue; + length += line_segments_compute_length(geom->lines); + } + } + +exit: + if(out_length) *out_length = length; + return res; +error: + goto exit; +} + diff --git a/src/test_s2d_scene.c b/src/test_s2d_scene.c @@ -42,6 +42,7 @@ main(int argc, char** argv) struct s2d_primitive prim; size_t nprims; size_t i; + float length; int mask; (void)argc, (void)argv; @@ -154,6 +155,19 @@ main(int argc, char** argv) default: FATAL("Unreachable code.\n"); } } + + CHECK(s2d_scene_compute_contour_length(NULL, NULL), RES_BAD_ARG); + CHECK(s2d_scene_compute_contour_length(scn, NULL), RES_BAD_ARG); + CHECK(s2d_scene_compute_contour_length(NULL, &length), RES_BAD_ARG); + CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK); + CHECK(eq_epsf(length, 8.f, 1.e-6f), 1); + + CHECK(s2d_scene_end_session(scn), RES_OK); + + CHECK(s2d_scene_compute_contour_length(scn, &length), RES_BAD_OP); + CHECK(s2d_scene_begin_session(scn, S2D_SAMPLE), RES_OK); + CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK); + CHECK(eq_epsf(length, 8.f, 1.e-6f), 1); CHECK(s2d_scene_end_session(scn), RES_OK); CHECK(s2d_shape_ref_put(shape), RES_OK);