commit f44e25c4ba4056602880bc100d136290b8aee921
parent 3c33496b28657f576404c487b0bbdf4a3f834344
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 19 Oct 2016 10:35:02 +0200
Test the sgf_shape3d API
Diffstat:
5 files changed, 228 insertions(+), 16 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -89,6 +89,7 @@ if(NOT NO_TEST)
new_test(test_sgf_cube)
new_test(test_sgf_device)
new_test(test_sgf_estimator)
+ new_test(test_sgf_shape3d)
new_test(test_sgf_square)
new_test(test_sgf_tetrahedron)
rcmake_copy_runtime_libraries(test_sgf_tetrahedron)
diff --git a/src/sgf.h b/src/sgf.h
@@ -84,20 +84,23 @@ struct sgf_shape3d_desc {
void (*get_indices)(const unsigned itri, unsigned ids[3], void* ctx);
void (*get_position)(const unsigned ivert, float pos[3], void* ctx);
- void (*get_emissivity)
- (const unsigned itri, const unsigned iband, double* val, void* ctx);
- void (*get_reflectivity)
- (const unsigned itri, const unsigned iband, double* val, void* ctx);
- void (*get_specularity)
- (const unsigned itri, const unsigned iband, double* val, void* ctx);
- void (*get_absorption) /* May be NULL <=> no medium */
- (const unsigned itri, const unsigned iband, double* val, void* ctx);
+ double (*get_emissivity)
+ (const unsigned itri, const unsigned iband, void* ctx);
+ double (*get_reflectivity)
+ (const unsigned itri, const unsigned iband, void* ctx);
+ double (*get_specularity)
+ (const unsigned itri, const unsigned iband, void* ctx);
+ double (*get_absorption) /* May be NULL <=> no medium */
+ (const unsigned itri, const unsigned iband, void* ctx);
void* context; /* User defined data */
unsigned ntris; /* #triangles */
unsigned nverts; /* #vertices */
unsigned nbands; /* #spectral bands */
};
+#define SGF_SHAPE3D_DESC_NULL__ { 0 }
+static const struct sgf_shape3d_desc SGF_SHAPE3D_DESC_NULL =
+ SGF_SHAPE3D_DESC_NULL__;
/* Estimated Gebart Factor between 2 faces */
struct sgf_status {
diff --git a/src/sgf_shape.c b/src/sgf_shape.c
@@ -32,7 +32,8 @@ check_shape3d_desc(const struct sgf_shape3d_desc* desc)
&& desc->get_specularity
&& desc->get_position
&& desc->ntris
- && desc->nverts;
+ && desc->nverts
+ && desc->nbands;
}
static void
@@ -144,12 +145,24 @@ sgf_shape3d_setup
emi = darray_double_data_get(&shape->emi);
refl = darray_double_data_get(&shape->refl);
spec = darray_double_data_get(&shape->spec);
+ i = 0;
FOR_EACH(iband, 0, desc->nbands) {
FOR_EACH(iprim, 0, desc->ntris) {
- if(abs) desc->get_absorption(iprim, iband, abs + i, desc->context);
- desc->get_emissivity(iprim, iband, emi + i, desc->context);
- desc->get_reflectivity(iprim, iband, refl + i, desc->context);
- desc->get_specularity(iprim, iband, spec + i, desc->context);
+ #define FETCH(Dst, Name, Low, Upp) { \
+ (Dst) = desc->get_##Name(iprim, iband, desc->context); \
+ if((Dst) < (Low) || (Dst) > (Upp)) { \
+ log_error(shape->dev, "%s: invalid "STR(Name)" `%g'.\n", \
+ FUNC_NAME, (Dst)); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ } (void) 0
+
+ if(abs) FETCH(abs[i], absorption, 0, DBL_MAX);
+ FETCH(emi[i], emissivity, 0, 1);
+ FETCH(refl[i], reflectivity, 0, 1);
+ FETCH(spec[i], specularity, 0, 1);
+ #undef FETCH
++i;
}}
diff --git a/src/test_sgf_shape3d.c b/src/test_sgf_shape3d.c
@@ -0,0 +1,126 @@
+/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.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 "sgf.h"
+#include "test_sgf_utils.h"
+
+static const float vertices[] = {
+ 0.f, 0.f, 0.f,
+ 1.f, 0.f, 0.f,
+ 0.f, 1.f, 0.f,
+ 1.f, 1.f, 0.f,
+};
+static const size_t nvertices = sizeof(vertices) / sizeof(float[3]);
+
+static const unsigned indices[] = { 0, 2, 1, 1, 2, 3 };
+static const size_t nprims = (int)(sizeof(indices) / sizeof(unsigned[3]));
+static const double emissivity[] = { 0.6, 0.6 };
+static const double emissivity_bad[] = { 0.6, 1.1 };
+static const double specularity[] = { 0.0, 0.0 };
+static const double specularity_bad[] = { 1.1, 0.0 };
+static const double absorption[] = { 0.0, 0.0 };
+static const double absorption_bad[] = { -0.1, 0.0 };
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct shape_context ctx;
+ struct sgf_device* sgf;
+ struct sgf_shape* shape;
+ struct sgf_shape3d_desc desc = SGF_SHAPE3D_DESC_NULL;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
+
+ CHECK(sgf_shape3d_create(NULL, NULL), RES_BAD_ARG);
+ CHECK(sgf_shape3d_create(sgf, NULL), RES_BAD_ARG);
+ CHECK(sgf_shape3d_create(NULL, &shape), RES_BAD_ARG);
+ CHECK(sgf_shape3d_create(sgf, &shape), RES_OK);
+
+ ctx.emissivity = emissivity;
+ ctx.specularity = specularity;
+ ctx.vertices = vertices;
+ ctx.nvertices = nvertices;
+ ctx.indices = indices;
+ ctx.nprimitives = nprims;
+
+ desc.get_position = get_position;
+ desc.get_indices = get_indices;
+ desc.get_emissivity = get_emissivity;
+ desc.get_reflectivity = get_reflectivity;
+ desc.get_specularity = get_specularity;
+ desc.context = &ctx;
+ desc.ntris = (unsigned)nprims;
+ desc.nverts = (unsigned)nvertices;
+ desc.nbands = 1;
+
+ CHECK(sgf_shape3d_setup(NULL, NULL), RES_BAD_ARG);
+ CHECK(sgf_shape3d_setup(shape, NULL), RES_BAD_ARG);
+ CHECK(sgf_shape3d_setup(NULL, &desc), RES_BAD_ARG);
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_OK);
+
+ desc.get_position = NULL;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.get_position = get_pos;
+ desc.get_indices = NULL;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.get_indices = get_ids;
+ desc.get_emissivity = NULL;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.get_emissivity = get_emissivity;
+ desc.get_reflectivity = NULL;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.get_reflectivity = get_reflectivity;
+ desc.get_specularity = NULL;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.get_specularity = get_specularity;
+ desc.ntris = 0;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.ntris = (unsigned)nprims;
+ desc.nverts = 0;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.nverts = (unsigned)nvertices;
+ desc.nbands = 0;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ desc.nbands = 1;
+ ctx.emissivity = emissivity_bad;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ ctx.emissivity = emissivity;
+ ctx.specularity = specularity_bad;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+ ctx.specularity = specularity;
+ desc.get_absorption = get_absorption;
+ ctx.absorption = absorption;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_OK);
+ ctx.absorption = absorption_bad;
+ CHECK(sgf_shape3d_setup(shape, &desc), RES_BAD_ARG);
+
+ CHECK(sgf_shape_ref_get(NULL), RES_BAD_ARG);
+ CHECK(sgf_shape_ref_get(shape), RES_OK);
+ CHECK(sgf_shape_ref_put(NULL), RES_BAD_ARG);
+ CHECK(sgf_shape_ref_put(shape), RES_OK);
+ CHECK(sgf_shape_ref_put(shape), RES_OK);
+
+ CHECK(sgf_device_ref_put(sgf), RES_OK);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return RES_OK;
+}
+
diff --git a/src/test_sgf_utils.h b/src/test_sgf_utils.h
@@ -19,20 +19,30 @@
#include <rsys/mem_allocator.h>
#include <stdio.h>
-struct triangle_mesh {
+struct triangle_mesh { /* TODO remove this */
const float* vertices;
size_t nvertices;
const unsigned* indices;
size_t ntriangles;
};
-struct material {
+struct material { /* TODO remove this */
const double* emissivity;
const double* specularity;
const double* absorption;
};
-static INLINE void
+struct shape_context {
+ const float* vertices;
+ size_t nvertices;
+ const unsigned* indices;
+ size_t nprimitives;
+ const double* emissivity;
+ const double* specularity;
+ const double* absorption;
+};
+
+static INLINE void /* TODO remove this */
get_ids(const unsigned itri, unsigned ids[3], void* data)
{
const struct triangle_mesh* mesh = data;
@@ -46,6 +56,19 @@ get_ids(const unsigned itri, unsigned ids[3], void* data)
}
static INLINE void
+get_indices(const unsigned itri, unsigned ids[3], void* data)
+{
+ const struct shape_context* shape = data;
+ const unsigned id = itri * 3;
+ NCHECK(shape, NULL);
+ NCHECK(ids, NULL);
+ CHECK(itri < shape->nprimitives, 1);
+ ids[0] = shape->indices[id + 0];
+ ids[1] = shape->indices[id + 1];
+ ids[2] = shape->indices[id + 2];
+}
+
+static INLINE void
get_pos(const unsigned ivert, float pos[3], void* data)
{
const struct triangle_mesh* mesh = data;
@@ -58,6 +81,19 @@ get_pos(const unsigned ivert, float pos[3], void* data)
pos[2] = mesh->vertices[i + 2];
}
+static INLINE void
+get_position(const unsigned ivert, float pos[3], void* data)
+{
+ const struct shape_context* shape = data;
+ const unsigned i = ivert*3;
+ NCHECK(shape, NULL);
+ NCHECK(pos, NULL);
+ CHECK(ivert < shape->nvertices, 1);
+ pos[0] = shape->vertices[i + 0];
+ pos[1] = shape->vertices[i + 1];
+ pos[2] = shape->vertices[i + 2];
+}
+
static INLINE double
get_material_property
(void* material,
@@ -77,6 +113,39 @@ get_material_property
}
}
+static INLINE double
+get_absorption(const unsigned iprim, const unsigned iband, void* ctx)
+{
+ struct shape_context* shape = ctx;
+ NCHECK(shape, NULL);
+ (void)iband;
+ return shape->absorption[iprim];
+}
+
+static INLINE double
+get_emissivity(const unsigned iprim, const unsigned iband, void* ctx)
+{
+ struct shape_context* shape = ctx;
+ NCHECK(shape, NULL);
+ (void)iband;
+ return shape->emissivity[iprim];
+}
+
+static INLINE double
+get_specularity(const unsigned iprim, const unsigned iband, void* ctx)
+{
+ struct shape_context* shape = ctx;
+ NCHECK(shape, NULL);
+ (void)iband;
+ return shape->specularity[iprim];
+}
+
+static INLINE double
+get_reflectivity(const unsigned iprim, const unsigned iband, void* ctx)
+{
+ return 1 - get_specularity(iprim, iband, ctx);
+}
+
static INLINE void
dump_triangle_mesh(struct triangle_mesh* mesh)
{