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:
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 */