polygon

Polygon triangulation
git clone git://git.meso-star.fr/polygon.git
Log | Files | Refs | README | LICENSE

commit 73c5dae8f495a22dba46b74997561fe63e092ce5
parent 93512b81678a25a4ffc75fbb93237a13c8b9efde
Author: vaplv <vaplv@free.fr>
Date:   Tue, 23 Sep 2014 17:22:59 +0200

Replace the useless enum polygon_result type by res_T

Diffstat:
Msrc/polygon.c | 68+++++++++++++++++++++++++++++++++++---------------------------------
Msrc/polygon.h | 24+++++++++---------------
Msrc/test_polygon.c | 141+++++++++++++++++++++++++++++++++++++++----------------------------------------
3 files changed, 113 insertions(+), 120 deletions(-)

diff --git a/src/polygon.c b/src/polygon.c @@ -157,6 +157,7 @@ node_is_an_ear } return 1; } + static void release_polygon(ref_T* ref) { @@ -171,21 +172,21 @@ release_polygon(ref_T* ref) /******************************************************************************* * Exported functions ******************************************************************************/ -enum polygon_result +res_T polygon_create(struct mem_allocator* allocator, struct polygon** out_polygon) { struct polygon* poly = NULL; struct mem_allocator* mem_allocator; - enum polygon_result res = POLYGON_OK; + res_T res = R_OK; if(!out_polygon) { - res = POLYGON_BAD_ARGUMENT; + res = R_BAD_ARG; goto error; } mem_allocator = allocator ? allocator : &mem_default_allocator; poly = MEM_CALLOC(mem_allocator, 1, sizeof(struct polygon)); if(!poly) { - res = POLYGON_MEMORY_ERROR; + res = R_MEM_ERR; goto error; } poly->allocator = mem_allocator; @@ -209,43 +210,43 @@ error: goto exit; } -enum polygon_result +res_T polygon_ref_get(struct polygon* polygon) { - if(!polygon) return POLYGON_BAD_ARGUMENT; + if(!polygon) return R_BAD_ARG; ref_get(&polygon->ref); - return POLYGON_OK; + return R_OK; } -enum polygon_result +res_T polygon_ref_put(struct polygon* polygon) { - if(!polygon) return POLYGON_BAD_ARGUMENT; + if(!polygon) return R_BAD_ARG; ref_put(&polygon->ref, release_polygon); - return POLYGON_OK; + return R_OK; } -enum polygon_result +res_T polygon_clear(struct polygon* poly) { - if(!poly) return POLYGON_BAD_ARGUMENT; + if(!poly) return R_BAD_ARG; darray_vertex_node_clear(&poly->pool); htable_u32_clear(&poly->vertices_concave); poly->vertices = UINT32_MAX; poly->nvertices = 0; - return POLYGON_OK; + return R_OK; } -enum polygon_result +res_T polygon_vertex_add(struct polygon* poly, const float pos[3]) { struct vertex_node* nodes; struct vertex_node* node_free; uint32_t inode_free; - enum polygon_result res = POLYGON_OK; + res_T res = R_OK; if(!poly || !pos) { - res = POLYGON_BAD_ARGUMENT; + res = R_BAD_ARG; goto error; } @@ -273,10 +274,9 @@ polygon_vertex_add(struct polygon* poly, const float pos[3]) /* Alloc a new vertex node */ inode_free = (uint32_t)darray_vertex_node_size_get(&poly->pool); - if(darray_vertex_node_resize(&poly->pool, inode_free + 1)) { - res = POLYGON_MEMORY_ERROR; + res = darray_vertex_node_resize(&poly->pool, inode_free + 1); + if(res != R_OK) goto error; - } node_free = darray_vertex_node_data_get(&poly->pool) + inode_free; /* Init the new node */ @@ -300,27 +300,27 @@ error: goto exit; } -enum polygon_result +res_T polygon_vertices_count_get(const struct polygon* poly, uint32_t* nvertices) { - if(!poly || !nvertices) return POLYGON_BAD_ARGUMENT; + if(!poly || !nvertices) return R_BAD_ARG; *nvertices = poly->nvertices; - return POLYGON_OK; + return R_OK; } -enum polygon_result +res_T polygon_vertex_get (const struct polygon* poly, const uint32_t ivertex, float pos[3]) { const struct vertex_node* node; if(!poly || !pos || ivertex >= poly->nvertices) - return POLYGON_BAD_ARGUMENT; + return R_BAD_ARG; node = darray_vertex_node_cdata_get(&poly->pool) + ivertex; f3_set(pos, node->pos); - return POLYGON_OK; + return R_OK; } -enum polygon_result +res_T polygon_triangulate (struct polygon* poly, const uint32_t** indices, @@ -329,10 +329,10 @@ polygon_triangulate struct vertex_node* nodes; uint32_t ivert, inode; float normal_convex[3], normal[3]; - enum polygon_result res = POLYGON_OK; + res_T res = R_OK; if(!poly || !indices || !nindices) { - res = POLYGON_BAD_ARGUMENT; + res = R_BAD_ARG; goto error; } @@ -344,7 +344,8 @@ polygon_triangulate if(poly->nvertices == 3) { /* Already a triangle */ FOR_EACH(ivert, 0, 3) { - if(darray_u32_push_back(&poly->triangle_ids, &ivert)) + res = darray_u32_push_back(&poly->triangle_ids, &ivert); + if(res != R_OK) goto error; } goto exit; @@ -359,7 +360,8 @@ polygon_triangulate node_normal_compute(poly, inode, normal); if(f3_dot(normal_convex, normal) <= 0.f) { const char dummy = 1; - if(htable_u32_set(&poly->vertices_concave, &inode, &dummy)) + res = htable_u32_set(&poly->vertices_concave, &inode, &dummy); + if(res != R_OK) goto error; } } @@ -377,9 +379,9 @@ polygon_triangulate uint32_t inode_prev; /* Register the {prev.prev, prev, cur} triangle */ - if(darray_u32_push_back(&poly->triangle_ids, &iv0) - || darray_u32_push_back(&poly->triangle_ids, &iv1) - || darray_u32_push_back(&poly->triangle_ids, &iv2)) + if(R_OK != (res = darray_u32_push_back(&poly->triangle_ids, &iv0)) + || R_OK != (res = darray_u32_push_back(&poly->triangle_ids, &iv1)) + || R_OK != (res = darray_u32_push_back(&poly->triangle_ids, &iv2))) goto error; /* Cut the ear by removing `prev' from the node list */ diff --git a/src/polygon.h b/src/polygon.h @@ -27,52 +27,46 @@ #endif #ifndef NDEBUG - #define POLYGON(Func) ASSERT(polygon_##Func == POLYGON_OK) + #define POLYGON(Func) ASSERT(polygon_##Func == R_OK) #else #define POLYGON(Func) polygon_##Func #endif -enum polygon_result { - POLYGON_BAD_ARGUMENT, - POLYGON_MEMORY_ERROR, - POLYGON_OK -}; - struct mem_allocator; struct polygon; BEGIN_DECLS -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_create (struct mem_allocator* allocator, /* May be NULL <=> default allocator */ struct polygon** polygon); -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_ref_get (struct polygon* polygon); -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_ref_put (struct polygon* polygon); -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_clear (struct polygon* polygon); /* Append a vertex to the polygon contour. Note that this vertex may replace * the previous one if it is aligned with the two last ones */ -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_vertex_add (struct polygon* polygon, const float pos[3]); -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_vertices_count_get (const struct polygon* polygon, uint32_t* nvertices); -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_vertex_get (const struct polygon* polygon, const uint32_t ivertex, @@ -80,7 +74,7 @@ polygon_vertex_get /* This function assumes that the polygon vertices lie on the same plane and * that they define a unique contour that is not intersected itself */ -POLYGON_API enum polygon_result +POLYGON_API res_T polygon_triangulate (struct polygon* polygon, const uint32_t** indices, diff --git a/src/test_polygon.c b/src/test_polygon.c @@ -20,9 +20,6 @@ #include <string.h> -#define BARG POLYGON_BAD_ARGUMENT -#define OK POLYGON_OK - static float /* Return the area of the triangulated polygon */ check_triangulation (struct polygon* poly, @@ -47,9 +44,9 @@ check_triangulation float e0[3], e1[3], N[3]; float v0[3], v1[3], v2[3]; float len; - CHECK(polygon_vertex_get(poly, tri[0], v0), OK); - CHECK(polygon_vertex_get(poly, tri[1], v1), OK); - CHECK(polygon_vertex_get(poly, tri[2], v2), OK); + CHECK(polygon_vertex_get(poly, tri[0], v0), R_OK); + CHECK(polygon_vertex_get(poly, tri[1], v1), R_OK); + CHECK(polygon_vertex_get(poly, tri[2], v2), R_OK); /* Compute the triangle area and add it to the overall polygon area */ f3_sub(e0, v1, v0); f3_sub(e1, v2, v0); @@ -111,134 +108,134 @@ main(int argc, char** argv) mem_init_proxy_allocator(&allocator_proxy, &mem_default_allocator); - CHECK(polygon_create(NULL, NULL), BARG); - CHECK(polygon_create(&allocator_proxy, NULL), BARG); - CHECK(polygon_create(NULL, &poly), OK); + CHECK(polygon_create(NULL, NULL), R_BAD_ARG); + CHECK(polygon_create(&allocator_proxy, NULL), R_BAD_ARG); + CHECK(polygon_create(NULL, &poly), R_OK); - CHECK(polygon_ref_get(NULL), BARG); - CHECK(polygon_ref_get(poly), OK); - CHECK(polygon_ref_put(NULL), BARG); - CHECK(polygon_ref_put(poly), OK); - CHECK(polygon_ref_put(poly), OK); + CHECK(polygon_ref_get(NULL), R_BAD_ARG); + CHECK(polygon_ref_get(poly), R_OK); + CHECK(polygon_ref_put(NULL), R_BAD_ARG); + CHECK(polygon_ref_put(poly), R_OK); + CHECK(polygon_ref_put(poly), R_OK); - CHECK(polygon_create(&allocator_proxy, &poly), OK); + CHECK(polygon_create(&allocator_proxy, &poly), R_OK); - CHECK(polygon_vertices_count_get(NULL, NULL), BARG); - CHECK(polygon_vertices_count_get(poly, NULL), BARG); - CHECK(polygon_vertices_count_get(NULL, &nvertices), BARG); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertices_count_get(NULL, NULL), R_BAD_ARG); + CHECK(polygon_vertices_count_get(poly, NULL), R_BAD_ARG); + CHECK(polygon_vertices_count_get(NULL, &nvertices), R_BAD_ARG); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 0); - CHECK(polygon_vertex_add(NULL, NULL), BARG); - CHECK(polygon_vertex_add(poly, NULL), BARG); - CHECK(polygon_vertex_add(NULL, vertices + 3), BARG); - CHECK(polygon_vertex_add(poly, vertices + 3), OK); + CHECK(polygon_vertex_add(NULL, NULL), R_BAD_ARG); + CHECK(polygon_vertex_add(poly, NULL), R_BAD_ARG); + CHECK(polygon_vertex_add(NULL, vertices + 3), R_BAD_ARG); + CHECK(polygon_vertex_add(poly, vertices + 3), R_OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 1); /* The last vertex is equal to the new one => skip it */ - CHECK(polygon_vertex_add(poly, vertices + 3), OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertex_add(poly, vertices + 3), R_OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 1); - CHECK(polygon_vertex_add(poly, vertices + 6), OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertex_add(poly, vertices + 6), R_OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 2); /* The new vertex is aligned with the 2 previous one => replace the last * vertex by the new one */ - CHECK(polygon_vertex_add(poly, vertices + 15), OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertex_add(poly, vertices + 15), R_OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 2); - CHECK(polygon_vertex_get(NULL, UINT32_MAX, NULL), BARG); - CHECK(polygon_vertex_get(poly, UINT32_MAX, NULL), BARG); - CHECK(polygon_vertex_get(NULL, 0, NULL), BARG); - CHECK(polygon_vertex_get(poly, 0, NULL), BARG); - CHECK(polygon_vertex_get(NULL, UINT32_MAX, pos), BARG); - CHECK(polygon_vertex_get(poly, UINT32_MAX, pos), BARG); - CHECK(polygon_vertex_get(NULL, 0, pos), BARG); - CHECK(polygon_vertex_get(poly, 0, pos), OK); + CHECK(polygon_vertex_get(NULL, UINT32_MAX, NULL), R_BAD_ARG); + CHECK(polygon_vertex_get(poly, UINT32_MAX, NULL), R_BAD_ARG); + CHECK(polygon_vertex_get(NULL, 0, NULL), R_BAD_ARG); + CHECK(polygon_vertex_get(poly, 0, NULL), R_BAD_ARG); + CHECK(polygon_vertex_get(NULL, UINT32_MAX, pos), R_BAD_ARG); + CHECK(polygon_vertex_get(poly, UINT32_MAX, pos), R_BAD_ARG); + CHECK(polygon_vertex_get(NULL, 0, pos), R_BAD_ARG); + CHECK(polygon_vertex_get(poly, 0, pos), R_OK); CHECK(f3_eq_eps(pos, vertices + 3, 1.e-6f), 1); - CHECK(polygon_vertex_get(poly, 1, pos), OK); + CHECK(polygon_vertex_get(poly, 1, pos), R_OK); CHECK(f3_eq_eps(pos, vertices + 15, 1.e-6f), 1); - CHECK(polygon_vertex_get(poly, 2, pos), BARG); + CHECK(polygon_vertex_get(poly, 2, pos), R_BAD_ARG); - CHECK(polygon_clear(NULL), BARG); - CHECK(polygon_clear(poly), OK); + CHECK(polygon_clear(NULL), R_BAD_ARG); + CHECK(polygon_clear(poly), R_OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, 0); FOR_EACH(ivertex, 0, sizeof(vertices)/sizeof(float[3])) - CHECK(polygon_vertex_add(poly, vertices + ivertex * 3), OK); + CHECK(polygon_vertex_add(poly, vertices + ivertex * 3), R_OK); - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, sizeof(vertices)/sizeof(float[3])); FOR_EACH(ivertex, 0, sizeof(vertices)/sizeof(float[3])) { - CHECK(polygon_vertex_get(poly, ivertex, pos), OK); + CHECK(polygon_vertex_get(poly, ivertex, pos), R_OK); CHECK(f3_eq_eps(pos, vertices + ivertex*3, 1.e-6f), 1); } - CHECK(polygon_triangulate(NULL, NULL, NULL), BARG); - CHECK(polygon_triangulate(poly, NULL, NULL), BARG); - CHECK(polygon_triangulate(NULL, &indices, NULL), BARG); - CHECK(polygon_triangulate(poly, &indices, NULL), BARG); - CHECK(polygon_triangulate(NULL, NULL, &nindices), BARG); - CHECK(polygon_triangulate(poly, NULL, &nindices), BARG); - CHECK(polygon_triangulate(NULL, &indices, &nindices), BARG); + CHECK(polygon_triangulate(NULL, NULL, NULL), R_BAD_ARG); + CHECK(polygon_triangulate(poly, NULL, NULL), R_BAD_ARG); + CHECK(polygon_triangulate(NULL, &indices, NULL), R_BAD_ARG); + CHECK(polygon_triangulate(poly, &indices, NULL), R_BAD_ARG); + CHECK(polygon_triangulate(NULL, NULL, &nindices), R_BAD_ARG); + CHECK(polygon_triangulate(poly, NULL, &nindices), R_BAD_ARG); + CHECK(polygon_triangulate(NULL, &indices, &nindices), R_BAD_ARG); /* Check full triangulation */ - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 30); CHECK(eq_eps(check_triangulation (poly, indices, nindices, 12), 1.f, 1.e-6f), 1); /* After the triangulation the input polygon may be unchanged */ - CHECK(polygon_vertices_count_get(poly, &nvertices), OK); + CHECK(polygon_vertices_count_get(poly, &nvertices), R_OK); CHECK(nvertices, sizeof(vertices)/sizeof(float[3])); FOR_EACH(ivertex, 0, sizeof(vertices)/sizeof(float[3])) { - CHECK(polygon_vertex_get(poly, ivertex, pos), OK); + CHECK(polygon_vertex_get(poly, ivertex, pos), R_OK); CHECK(f3_eq_eps(pos, vertices + ivertex*3, 1.e-6f), 1); } /* Check that the input polygon can be retriangulated */ - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 30); CHECK(eq_eps(check_triangulation (poly, indices, nindices, 12), 1.f, 1.e-6f), 1); /* One can triangulate empty polygon */ - CHECK(polygon_clear(poly), OK); - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_clear(poly), R_OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 0); /* Check the triangulation of an updated polygon */ - CHECK(polygon_vertex_add(poly, vertices + 0), OK); - CHECK(polygon_vertex_add(poly, vertices + 3), OK); - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_vertex_add(poly, vertices + 0), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 3), R_OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 0); - CHECK(polygon_vertex_add(poly, vertices + 6), OK); - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_vertex_add(poly, vertices + 6), R_OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 3); CHECK(eq_eps(check_triangulation (poly, indices, nindices, 3), 0.5f, 1.e-6f), 1); - CHECK(polygon_vertex_add(poly, vertices + 9), OK); - CHECK(polygon_vertex_add(poly, vertices + 12), OK); - CHECK(polygon_vertex_add(poly, vertices + 15), OK); - CHECK(polygon_vertex_add(poly, vertices + 18), OK); - CHECK(polygon_vertex_add(poly, vertices + 21), OK); - CHECK(polygon_vertex_add(poly, vertices + 21), OK); - CHECK(polygon_triangulate(poly, &indices, &nindices), OK); + CHECK(polygon_vertex_add(poly, vertices + 9), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 12), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 15), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 18), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 21), R_OK); + CHECK(polygon_vertex_add(poly, vertices + 21), R_OK); + CHECK(polygon_triangulate(poly, &indices, &nindices), R_OK); CHECK(nindices, 18); CHECK(eq_eps(check_triangulation (poly, indices, nindices, 8), 1.375f, 1.e-6f), 1); - CHECK(polygon_ref_put(poly), OK); + CHECK(polygon_ref_put(poly), R_OK); if(MEM_ALLOCATED_SIZE(&allocator_proxy)) { char dump[512]; MEM_DUMP(&allocator_proxy, dump, sizeof(dump)/sizeof(char));