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:
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);