star-cpr

Clip 2D meshes with 2D polygons
git clone git://git.meso-star.fr/star-cpr.git
Log | Files | Refs | README | LICENSE

commit 8fcfd5fddd719b84f952f749a535a76f7c0f670e
parent 991e826eccce4ba68e92de2d0dc8649a28627f13
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 22 Aug 2016 11:28:52 +0200

Test the mesh API

Diffstat:
Mcmake/CMakeLists.txt | 13++++++-------
Msrc/cpr.h | 4++--
Msrc/cpr_mesh.c | 14++++++++------
Asrc/test_cpr_mesh.c | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_cpr_utils.h | 33+++++++++++++++++++++++++++++++++
5 files changed, 245 insertions(+), 15 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -55,7 +55,6 @@ if(BUILD_STATIC) add_library(cpr STATIC ${CPR_FILES_SRC} ${CPR_FILES_INC}) set_target_properties(cpr PROPERTIES DEFINE_SYMBOL CPR_STATIC_BUILD) else() - add_library(cpr SHARED ${CPR_FILES_SRC} ${CPR_FILES_INC}) set_target_properties(cpr PROPERTIES DEFINE_SYMBOL CPR_SHARED_BUILD @@ -69,12 +68,12 @@ rcmake_setup_devel(cpr CPR ${VERSION} cpr_version.h) ################################################################################ # Define tests ################################################################################ -#if(NOT NO_TEST) -# add_executable(test_cpr_mesh ${CPR_SOURCE_DIR}/test_cpr_mesh.c) -# target_link_libraries(test_cpr_mesh cpr) -# add_test(test_cpr_mesh test_cpr_mesh) -# rcmake_set_test_runtime_dirs(test_cpr_mesh _runtime_dirs) -#endif(NOT NO_TEST) +if(NOT NO_TEST) + add_executable(test_cpr_mesh ${CPR_SOURCE_DIR}/test_cpr_mesh.c) + target_link_libraries(test_cpr_mesh cpr) + add_test(test_cpr_mesh test_cpr_mesh) + rcmake_set_test_runtime_dirs(test_cpr_mesh _runtime_dirs) +endif() ################################################################################ # Install directories diff --git a/src/cpr.h b/src/cpr.h @@ -65,9 +65,9 @@ cpr_mesh_ref_put CPR_API res_T cpr_mesh_setup_indexed_vertices (struct cpr_mesh* mesh, - const unsigned ntris, + const size_t ntris, void (*get_indices)(const size_t itri, size_t ids[3], void* ctx), - const unsigned nverts, + const size_t nverts, void (*get_position)(const size_t ivert, double pos[2], void* ctx), void* data); /* Client data set as the last param of the callbacks */ diff --git a/src/cpr_mesh.c b/src/cpr_mesh.c @@ -99,9 +99,9 @@ cpr_mesh_ref_put(struct cpr_mesh* mesh) res_T cpr_mesh_setup_indexed_vertices (struct cpr_mesh* mesh, - const unsigned ntris, + const size_t ntris, void (*get_indices)(const size_t itri, size_t ids[3], void* ctx), - const unsigned nverts, + const size_t nverts, void (*get_position)(const size_t ivert, double pos[2], void* ctx), void* data) { @@ -141,8 +141,10 @@ cpr_mesh_setup_indexed_vertices exit: return res; error: - darray_double_clear(&mesh->coords); - darray_size_t_clear(&mesh->indices); + if(mesh) { + darray_double_clear(&mesh->coords); + darray_size_t_clear(&mesh->indices); + } goto exit; } @@ -186,8 +188,8 @@ cpr_mesh_get_position if(!mesh || !pos) return RES_BAD_ARG; CPR(mesh_get_vertices_count(mesh, &nverts)); if(ivert >= nverts) return RES_BAD_ARG; - pos[0] = darray_double_cdata_get(&mesh->coords)[ivert*2 + 0]; - pos[1] = darray_double_cdata_get(&mesh->coords)[ivert*2 + 2]; + pos[0] = darray_double_cdata_get(&mesh->coords)[ivert*2+0]; + pos[1] = darray_double_cdata_get(&mesh->coords)[ivert*2+1]; return RES_OK; } diff --git a/src/test_cpr_mesh.c b/src/test_cpr_mesh.c @@ -0,0 +1,196 @@ +/* Copyright (C) 2016 Vincent Forest (vaplv@free.fr) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "cpr.h" +#include "test_cpr_utils.h" + +struct context { + const double* coords; + size_t nverts; + const size_t* indices; + size_t ntris; +}; + +static void +get_pos(const size_t ivert, double pos[2], void* context) +{ + const struct context* ctx = context; + NCHECK(pos, NULL); + NCHECK(context, NULL); + NCHECK(ctx->coords, NULL); + CHECK(ivert < ctx->nverts, 1); + pos[0] = ctx->coords[ivert*2 + 0]; + pos[1] = ctx->coords[ivert*2 + 1]; +} + +static void +get_ids(const size_t itri, size_t ids[3], void* context) +{ + const struct context* ctx = context; + NCHECK(ids, NULL); + NCHECK(context, NULL); + NCHECK(ctx->indices, NULL); + CHECK(itri < ctx->ntris, 1); + ids[0] = ctx->indices[itri*3 + 0]; + ids[1] = ctx->indices[itri*3 + 1]; + ids[2] = ctx->indices[itri*3 + 2]; +} + +int +main(int argc, char** argv) +{ + const double coords[] = { + 0.0, 0.0, + 0.0, 0.5, + 0.0, 1.0, + 0.5, 0.0, + 0.5, 0.5, + 0.5, 1.0, + 1.0, 0.0, + 1.0, 0.5, + 1.0, 1.0 + }; + const size_t nverts = sizeof(coords)/sizeof(double[2]); + const size_t indices[] = { + 0, 1, 3, + 3, 1, 4, + 1, 2, 4, + 4, 2, 5, + 3, 4, 6, + 6, 4, 7, + 4, 5, 7, + 7, 5, 8 + }; + const size_t ntris = sizeof(indices)/sizeof(size_t[3]); + const size_t indices_bad[] = { 7, 5, 9 }; + size_t ids[3]; + double pos[2]; + size_t i, n; + struct mem_allocator allocator; + struct context ctx; + struct cpr_mesh* mesh; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + + CHECK(cpr_mesh_create(NULL, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_create(&allocator, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_create(NULL, &mesh), RES_OK); + + CHECK(cpr_mesh_ref_get(NULL), RES_BAD_ARG); + CHECK(cpr_mesh_ref_get(mesh), RES_OK); + CHECK(cpr_mesh_ref_put(NULL), RES_BAD_ARG); + CHECK(cpr_mesh_ref_put(mesh), RES_OK); + CHECK(cpr_mesh_ref_put(mesh), RES_OK); + + CHECK(cpr_mesh_create(&allocator, &mesh), RES_OK); + + ctx.coords = coords; + ctx.nverts = nverts; + ctx.indices = indices; + ctx.ntris = ntris; + + #define SETUP cpr_mesh_setup_indexed_vertices + CHECK(SETUP(NULL, 0, NULL, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, NULL, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, NULL, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, NULL, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, get_ids, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, get_ids, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, get_ids, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, get_ids, 0, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, NULL, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, NULL, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, NULL, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, NULL, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, get_ids, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, get_ids, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, get_ids, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, get_ids, nverts, NULL, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, NULL, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, NULL, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, NULL, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, NULL, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, get_ids, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, get_ids, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, get_ids, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, get_ids, 0, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, NULL, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, NULL, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, NULL, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, NULL, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, 0, get_ids, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, 0, get_ids, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(NULL, ntris, get_ids, nverts, get_pos, &ctx), RES_BAD_ARG); + CHECK(SETUP(mesh, ntris, get_ids, nverts, get_pos, &ctx), RES_OK); + ctx.indices = indices_bad; + CHECK(SETUP(mesh, 1, get_ids, nverts, get_pos, &ctx), RES_BAD_ARG); + #undef SETUP + + CHECK(cpr_mesh_get_triangles_count(NULL, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_triangles_count(mesh, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_triangles_count(NULL, &n), RES_BAD_ARG); + CHECK(cpr_mesh_get_triangles_count(mesh, &n), RES_OK); + CHECK(n, 0); + + CHECK(cpr_mesh_get_vertices_count(NULL, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_vertices_count(mesh, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_vertices_count(NULL, &n), RES_BAD_ARG); + CHECK(cpr_mesh_get_vertices_count(mesh, &n), RES_OK); + CHECK(n, 0); + + ctx.indices = indices; + CHECK(cpr_mesh_setup_indexed_vertices + (mesh, ntris, get_ids, nverts, get_pos, &ctx), RES_OK); + CHECK(cpr_mesh_get_triangles_count(mesh, &n), RES_OK); + CHECK(n, ntris); + CHECK(cpr_mesh_get_vertices_count(mesh, &n), RES_OK); + CHECK(n, nverts); + + CHECK(cpr_mesh_get_indices(NULL, ntris, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(mesh, ntris, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(NULL, 0, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(mesh, 0, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(NULL, ntris, ids), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(mesh, ntris, ids), RES_BAD_ARG); + CHECK(cpr_mesh_get_indices(NULL, 0, ids), RES_BAD_ARG); + FOR_EACH(i, 0, ntris) { + CHECK(cpr_mesh_get_indices(mesh, i, ids), RES_OK); + CHECK(ids[0], indices[i*3+0]); + CHECK(ids[1], indices[i*3+1]); + CHECK(ids[2], indices[i*3+2]); + } + + CHECK(cpr_mesh_get_position(NULL, nverts, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(mesh, nverts, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(NULL, 0, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(mesh, 0, NULL), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(NULL, nverts, pos), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(mesh, nverts, pos), RES_BAD_ARG); + CHECK(cpr_mesh_get_position(NULL, 0, pos), RES_BAD_ARG); + FOR_EACH(i, 0, nverts) { + CHECK(cpr_mesh_get_position(mesh, i, pos), RES_OK); + CHECK(pos[0], coords[i*2+0]); + CHECK(pos[1], coords[i*2+1]); + } + + CHECK(cpr_mesh_ref_put(mesh), RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + return 0; +} + diff --git a/src/test_cpr_utils.h b/src/test_cpr_utils.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2016 Vincent Forest (vaplv@free.fr) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef TEST_CPR_UTILS_H +#define TEST_CPR_UTILS_H + +#include <rsys/mem_allocator.h> +#include <stdio.h> + +static void +check_memory_allocator(struct mem_allocator* allocator) +{ + if(MEM_ALLOCATED_SIZE(allocator)) { + char dump[512]; + MEM_DUMP(allocator, dump, sizeof(dump)/sizeof(char)); + fprintf(stderr, "%s\n", dump); + FATAL("Memory leaks\n"); + } +} + +#endif /* TEST_CPR_UTILS_H */