star-gf

Compute Gebhart factors
git clone git://git.meso-star.fr/star-gf.git
Log | Files | Refs | README | LICENSE

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:
Mcmake/CMakeLists.txt | 1+
Msrc/sgf.h | 19+++++++++++--------
Msrc/sgf_shape.c | 23++++++++++++++++++-----
Asrc/test_sgf_shape3d.c | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sgf_utils.h | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
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) {