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

Implement and test the s2d_scene_compute_area function

Diffstat:
Msrc/s2d_scene.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/test_s2d_scene.c | 16++++++++++++++++
2 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/src/s2d_scene.c b/src/s2d_scene.c @@ -959,8 +959,9 @@ s2d_scene_primitives_count(struct s2d_scene* scn, size_t* prims_count) ASSERT(pgeom != NULL); geom = *pgeom; - if(!geom->is_enabled) continue; - nprims += line_segments_get_nsegments(geom->lines); + if(geom->is_enabled) { + nprims += line_segments_get_nsegments(geom->lines); + } } } exit: @@ -1011,8 +1012,9 @@ s2d_scene_compute_contour_length(struct s2d_scene* scn, float* out_length) ASSERT(pgeom != NULL); geom = *pgeom; - if(!geom->is_enabled) continue; - length += line_segments_compute_length(geom->lines); + if(geom->is_enabled) { + length += line_segments_compute_length(geom->lines); + } } } @@ -1023,3 +1025,48 @@ error: goto exit; } +res_T +s2d_scene_compute_area(struct s2d_scene* scn, float* out_area) +{ + struct list_node* node; + struct s2d_shape* shape; + struct geometry** pgeom; + struct geometry* geom; + float area = 0.f; + res_T res = RES_OK; + + if(!scn || !out_area) { + 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; + } + + 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) { + area += line_segments_compute_area(geom->lines, geom->flip_contour); + } + } + if(area < 0.f) { + log_error(scn->dev, + "%s: The area of the scene polygons is negative. The scene shapes might\n" + " not represent closed manifold polygons, or their contour might not point\n" + " inward the polygon.\n", __FUNCTION__); + } + +exit: + if(out_area) *out_area = area; + return res; +error: + goto exit; +} + diff --git a/src/test_s2d_scene.c b/src/test_s2d_scene.c @@ -43,6 +43,7 @@ main(int argc, char** argv) size_t nprims; size_t i; float length; + float area; int mask; (void)argc, (void)argv; @@ -162,12 +163,27 @@ main(int argc, char** argv) CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK); CHECK(eq_epsf(length, 8.f, 1.e-6f), 1); + CHECK(s2d_scene_compute_area(NULL, NULL), RES_BAD_ARG); + CHECK(s2d_scene_compute_area(scn, NULL), RES_BAD_ARG); + CHECK(s2d_scene_compute_area(NULL, &area), RES_BAD_ARG); + CHECK(s2d_scene_compute_area(scn, &area), RES_OK); + CHECK(eq_epsf(area, 4.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_compute_area(scn, &area), RES_BAD_OP); + + CHECK(s2d_shape_flip_contour(shape), RES_OK); + 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_compute_area(scn, &area), RES_OK); + CHECK(eq_epsf(area, -4.f, 1.e-6f), 1); + CHECK(s2d_scene_end_session(scn), RES_OK); CHECK(s2d_shape_ref_put(shape), RES_OK);