solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

commit 12493f4f35124890f24e2f2eef98dcd66b010320
parent 2c26a2f248c578f4abc10ad23b2b2e2a0a5f3a3c
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 15 Mar 2017 13:53:30 +0100

Merge remote-tracking branch 'origin/develop' into feature_outputs

Diffstat:
Msrc/ssol.h | 51+++++++++++++++++++++++++++++++++++++++++++--------
Msrc/ssol_estimator_c.h | 148++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/ssol_mc_receiver.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/ssol_object.c | 15+++++++++++++--
Msrc/ssol_object_c.h | 6++++++
Msrc/ssol_solver.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/test_ssol_solver1.c | 46++++++++++++++++++++++++++++++----------------
7 files changed, 290 insertions(+), 129 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -298,12 +298,20 @@ struct ssol_mc_result { double V; /* Variance */ double SE; /* Standard error, i.e. sqrt(Expectation / N) */ }; +#define SSOL_MC_RESULT_NULL__ {0, 0, 0} +static const struct ssol_mc_result SSOL_MC_RESULT_NULL = SSOL_MC_RESULT_NULL__; struct ssol_mc_global { struct ssol_mc_result cos_factor; /* [0 1] */ struct ssol_mc_result shadowed; /* In W */ struct ssol_mc_result missing; /* In W */ }; +#define SSOL_MC_GLOBAL_NULL__ { \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__ \ +} +static const struct ssol_mc_global SSOL_MC_GLOBAL_NULL = SSOL_MC_GLOBAL_NULL__; struct ssol_mc_receiver { struct ssol_mc_result integrated_irradiance; /* In W */ @@ -313,8 +321,27 @@ struct ssol_mc_receiver { /* Internal data */ size_t N__; - const void* mc__; + void* mc__; + const struct ssol_instance* instance__; +}; +#define SSOL_MC_RECEIVER_NULL__ { \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + 0, NULL, NULL \ +} +static const struct ssol_mc_receiver SSOL_MC_RECEIVER_NULL = + SSOL_MC_RECEIVER_NULL__; + +struct ssol_mc_shape { + /* Internal data */ + size_t N__; + void* mc__; + const struct ssol_shape* shape__; }; +#define SSOL_MC_SHAPE_NULL__ { 0, NULL, NULL } +static const struct ssol_mc_shape SSOL_MC_SHAPE_NULL = SSOL_MC_SHAPE_NULL__; struct ssol_mc_sampled { struct ssol_mc_result shadowed; @@ -327,8 +354,15 @@ struct ssol_mc_primitive { struct ssol_mc_result integrated_absorbed_irradiance; /* In W */ struct ssol_mc_result absorptivity_loss; /* In W */ struct ssol_mc_result reflectivity_loss; /* In W */ - size_t index; /* Index of the primitive */ }; +#define SSOL_MC_PRIMITIVE_NULL__ { \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__, \ + SSOL_MC_RESULT_NULL__ \ +} +static const struct ssol_mc_primitive SSOL_MC_PRIMITIVE_NULL = + SSOL_MC_PRIMITIVE_NULL__; typedef res_T (*ssol_write_pixels_T) @@ -969,14 +1003,15 @@ ssol_estimator_get_mc_receiver struct ssol_mc_receiver* rcv); SSOL_API res_T -ssol_mc_receiver_get_mc_primitives_count - (const struct ssol_mc_receiver* rcv, - size_t* count); +ssol_mc_receiver_get_mc_shape + (struct ssol_mc_receiver* rcv, + const struct ssol_shape* shape, + struct ssol_mc_shape* mc); SSOL_API res_T -ssol_mc_receiver_get_mc_primitive - (const struct ssol_mc_receiver* rcv, - const size_t i, +ssol_mc_shape_get_mc_primitive + (struct ssol_mc_shape* shape, + const unsigned i, /* In [0, ssol_shape_get_triangles_count[ */ struct ssol_mc_primitive* prim); /******************************************************************************* diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h @@ -18,8 +18,7 @@ #include "ssol_device_c.h" #include "ssol_instance_c.h" - -#include <limits.h> +#include "ssol_shape_c.h" #include <rsys/ref_count.h> #include <rsys/hash_table.h> @@ -36,9 +35,6 @@ struct mc_data { #define MC_DATA_NULL__ { 0, 0 } static const struct mc_data MC_DATA_NULL = MC_DATA_NULL__; -/******************************************************************************* - * One sided Per receiver MC data - ******************************************************************************/ #define MC_RECEIVER_DATA \ struct mc_data integrated_irradiance; /* In W */ \ struct mc_data integrated_absorbed_irradiance; /* In W */ \ @@ -51,31 +47,99 @@ static const struct mc_data MC_DATA_NULL = MC_DATA_NULL__; MC_DATA_NULL__, \ MC_DATA_NULL__ +/******************************************************************************* + * One sided per shape MC data + ******************************************************************************/ struct mc_primitive_1side { MC_RECEIVER_DATA - unsigned index; }; -#define MC_PRIMITIVE_1SIDE_NULL__ { MC_RECEIVER_DATA_NULL__, UINT_MAX } +#define MC_PRIMITIVE_1SIDE_NULL__ { MC_RECEIVER_DATA_NULL__ } static const struct mc_primitive_1side MC_PRIMITIVE_1SIDE_NULL = MC_PRIMITIVE_1SIDE_NULL__; -/* Declare the hash table that maps a primitive index to its corresponding - * entry into an array of Monte-Carlo estimations */ +/* Map an unsigned to a struct mc_primitive_1side */ #define HTABLE_NAME prim2mc #define HTABLE_KEY unsigned -#define HTABLE_DATA unsigned +#define HTABLE_DATA struct mc_primitive_1side #include <rsys/hash_table.h> -/* Declare the list of per primitive MC estimations */ -#define DARRAY_NAME mc_prim -#define DARRAY_DATA struct mc_primitive_1side -#include <rsys/dynamic_array.h> +struct mc_shape_1side { + struct htable_prim2mc prim2mc; +}; + +static INLINE void +mc_shape_1side_init + (struct mem_allocator* allocator, struct mc_shape_1side* mc) +{ + ASSERT(mc); + htable_prim2mc_init(allocator, &mc->prim2mc); +} + +static INLINE void +mc_shape_1side_release(struct mc_shape_1side* mc) +{ + ASSERT(mc); + htable_prim2mc_release(&mc->prim2mc); +} + +static INLINE res_T +mc_shape_1side_copy + (struct mc_shape_1side* dst, const struct mc_shape_1side* src) +{ + ASSERT(dst && src); + return htable_prim2mc_copy(&dst->prim2mc, &src->prim2mc); +} + +static INLINE res_T +mc_shape_1side_copy_and_release + (struct mc_shape_1side* dst, struct mc_shape_1side* src) +{ + ASSERT(dst && src); + return htable_prim2mc_copy_and_release(&dst->prim2mc, &src->prim2mc); +} + +static INLINE res_T +mc_shape_1side_get_mc_primitive + (struct mc_shape_1side* mc_shape1, + const unsigned iprim, + struct mc_primitive_1side** out_mc_prim1) +{ + struct mc_primitive_1side* mc_prim1 = NULL; + res_T res = RES_OK; + ASSERT(mc_shape1 && out_mc_prim1); + + mc_prim1 = htable_prim2mc_find(&mc_shape1->prim2mc, &iprim); + if(!mc_prim1) { + res = htable_prim2mc_set(&mc_shape1->prim2mc, &iprim, &MC_PRIMITIVE_1SIDE_NULL); + if(res != RES_OK) goto error; + + mc_prim1 = htable_prim2mc_find(&mc_shape1->prim2mc, &iprim); + } + +exit: + *out_mc_prim1 = mc_prim1; + return res; +error: + goto exit; +} + +/******************************************************************************* + * One sided per receiver MC data + ******************************************************************************/ +/* Map a ssol shape to a struct mc_shape_1side */ +#define HTABLE_NAME shape2mc +#define HTABLE_KEY const struct ssol_shape* +#define HTABLE_DATA struct mc_shape_1side +#define HTABLE_DATA_FUNCTOR_INIT mc_shape_1side_init +#define HTABLE_DATA_FUNCTOR_RELEASE mc_shape_1side_release +#define HTABLE_DATA_FUNCTOR_COPY mc_shape_1side_copy +#define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE mc_shape_1side_copy_and_release +#include <rsys/hash_table.h> struct mc_receiver_1side { MC_RECEIVER_DATA - struct htable_prim2mc prim2mc; - struct darray_mc_prim mc_prims; + struct htable_shape2mc shape2mc; }; static INLINE void @@ -87,82 +151,64 @@ mc_receiver_1side_init mc->integrated_absorbed_irradiance = MC_DATA_NULL; mc->absorptivity_loss = MC_DATA_NULL; mc->reflectivity_loss = MC_DATA_NULL; - htable_prim2mc_init(allocator, &mc->prim2mc); - darray_mc_prim_init(allocator, &mc->mc_prims); + htable_shape2mc_init(allocator, &mc->shape2mc); } static INLINE void mc_receiver_1side_release(struct mc_receiver_1side* mc) { ASSERT(mc); - htable_prim2mc_release(&mc->prim2mc); - darray_mc_prim_release(&mc->mc_prims); + htable_shape2mc_release(&mc->shape2mc); } static INLINE res_T mc_receiver_1side_copy (struct mc_receiver_1side* dst, const struct mc_receiver_1side* src) { - res_T res = RES_OK; ASSERT(dst && src); dst->integrated_irradiance = src->integrated_irradiance; dst->integrated_absorbed_irradiance = src->integrated_absorbed_irradiance; dst->absorptivity_loss = src->absorptivity_loss; dst->reflectivity_loss = src->reflectivity_loss; - res = htable_prim2mc_copy(&dst->prim2mc, &src->prim2mc); - if(res != RES_OK) return res; - res = darray_mc_prim_copy(&dst->mc_prims, &src->mc_prims); - if(res != RES_OK) return res; - return RES_OK; + return htable_shape2mc_copy(&dst->shape2mc, &src->shape2mc); } static INLINE res_T mc_receiver_1side_copy_and_release (struct mc_receiver_1side* dst, struct mc_receiver_1side* src) { - res_T res = RES_OK; ASSERT(dst && src); dst->integrated_irradiance = src->integrated_irradiance; dst->integrated_absorbed_irradiance = src->integrated_absorbed_irradiance; dst->absorptivity_loss = src->absorptivity_loss; dst->reflectivity_loss = src->reflectivity_loss; - res = htable_prim2mc_copy(&dst->prim2mc, &src->prim2mc); - if(res != RES_OK) return res; - res = darray_mc_prim_copy(&dst->mc_prims, &src->mc_prims); - if(res != RES_OK) return res; - return RES_OK; + return htable_shape2mc_copy_and_release(&dst->shape2mc, &src->shape2mc); } static INLINE res_T -mc_receiver_1side_get_mc_primitive +mc_receiver_1side_get_mc_shape (struct mc_receiver_1side* mc_rcv, - const unsigned iprim, - struct mc_primitive_1side** out_mc_prim1) + const struct ssol_shape* shape, + struct mc_shape_1side** out_mc_shape1) { - unsigned* pui = NULL; - struct mc_primitive_1side* mc_prim1 = NULL; + struct mc_shape_1side* mc_shape1 = NULL; + struct mc_shape_1side mc_shape1_null; res_T res = RES_OK; - ASSERT(mc_rcv); + ASSERT(mc_rcv && shape && out_mc_shape1); - pui = htable_prim2mc_find(&mc_rcv->prim2mc, &iprim); - if(pui) { - mc_prim1 = darray_mc_prim_data_get(&mc_rcv->mc_prims) + *pui; - ASSERT(*pui < darray_mc_prim_size_get(&mc_rcv->mc_prims)); - ASSERT(mc_prim1->index == *pui); - } else { - unsigned ui = (unsigned)darray_mc_prim_size_get(&mc_rcv->mc_prims); + mc_shape_1side_init(shape->dev->allocator, &mc_shape1_null); - res = darray_mc_prim_push_back(&mc_rcv->mc_prims, &MC_PRIMITIVE_1SIDE_NULL); + mc_shape1 = htable_shape2mc_find(&mc_rcv->shape2mc, &shape); + if(!mc_shape1) { + res = htable_shape2mc_set(&mc_rcv->shape2mc, &shape, &mc_shape1_null); if(res != RES_OK) goto error; - mc_prim1 = darray_mc_prim_data_get(&mc_rcv->mc_prims) + ui; - mc_prim1->index = ui; - res = htable_prim2mc_set(&mc_rcv->prim2mc, &iprim, &ui); - if(res != RES_OK) goto error; + mc_shape1 = htable_shape2mc_find(&mc_rcv->shape2mc, &shape); } exit: - *out_mc_prim1 = mc_prim1; + mc_shape_1side_release(&mc_shape1_null); + *out_mc_shape1 = mc_shape1; return res; error: goto exit; diff --git a/src/ssol_mc_receiver.c b/src/ssol_mc_receiver.c @@ -15,6 +15,7 @@ #include "ssol.h" #include "ssol_estimator_c.h" +#include "ssol_object_c.h" /******************************************************************************* * Exported functions @@ -26,8 +27,8 @@ ssol_estimator_get_mc_receiver const enum ssol_side_flag side, struct ssol_mc_receiver* rcv) { - const struct mc_receiver* mc_rcv = NULL; - const struct mc_receiver_1side* mc_rcv1 = NULL; + struct mc_receiver* mc_rcv = NULL; + struct mc_receiver_1side* mc_rcv1 = NULL; if(!estimator || !instance || !rcv || !(instance->receiver_mask & (int)side)) @@ -56,49 +57,68 @@ ssol_estimator_get_mc_receiver #undef SETUP_MC_RESULT rcv->mc__ = mc_rcv1; rcv->N__ = estimator->realisation_count; + rcv->instance__ = instance; return RES_OK; } res_T -ssol_mc_receiver_get_mc_primitives_count - (const struct ssol_mc_receiver* rcv, size_t* count) +ssol_mc_receiver_get_mc_shape + (struct ssol_mc_receiver* rcv, + const struct ssol_shape* shape, + struct ssol_mc_shape* mc) { - const struct mc_receiver_1side* mc_rcv1; - if(!rcv || !count) return RES_BAD_ARG; + struct mc_receiver_1side* mc_rcv1; + + if(!rcv || !shape || !mc) return RES_BAD_ARG; + if(!object_has_shape(rcv->instance__->object, shape)) return RES_BAD_ARG; mc_rcv1 = rcv->mc__; - *count = darray_mc_prim_size_get(&mc_rcv1->mc_prims); + mc->N__ = rcv->N__; + mc->mc__ = htable_shape2mc_find(&mc_rcv1->shape2mc, &shape); + mc->shape__ = shape; return RES_OK; } res_T -ssol_mc_receiver_get_mc_primitive - (const struct ssol_mc_receiver* rcv, - const size_t i, +ssol_mc_shape_get_mc_primitive + (struct ssol_mc_shape* shape, + const unsigned i, struct ssol_mc_primitive* prim) { - const struct mc_primitive_1side* mc_prim1; - const struct mc_receiver_1side* mc_rcv1; + struct mc_shape_1side* mc_shape1; + struct mc_primitive_1side* mc_prim1; + unsigned ntris; - if(!rcv || !prim) return RES_BAD_ARG; + if(!shape || !prim) return RES_BAD_ARG; - mc_rcv1 = rcv->mc__; - if(i >= darray_mc_prim_size_get(&mc_rcv1->mc_prims)) - return RES_BAD_ARG; + SSOL(shape_get_triangles_count(shape->shape__, &ntris)); + if(i >= ntris) return RES_BAD_ARG; - mc_prim1 = darray_mc_prim_cdata_get(&mc_rcv1->mc_prims) + i; - #define SETUP_MC_RESULT(Name) { \ - const double N = (double)rcv->N__; \ - const struct mc_data* data = &mc_prim1->Name; \ - prim->Name.E = data->weight / N; \ - prim->Name.V = data->sqr_weight/N - prim->Name.E*prim->Name.E; \ - prim->Name.SE = prim->Name.V > 0 ? sqrt(prim->Name.V / N) : 0; \ - } (void)0 - SETUP_MC_RESULT(integrated_irradiance); - SETUP_MC_RESULT(integrated_absorbed_irradiance); - SETUP_MC_RESULT(absorptivity_loss); - SETUP_MC_RESULT(reflectivity_loss); - #undef SETUP_MC_RESULT - prim->index = i; + mc_shape1 = shape->mc__; + if(!mc_shape1 || !(mc_prim1 = htable_prim2mc_find(&mc_shape1->prim2mc, &i))) { + #define SETUP_MC_RESULT(Name) { \ + prim->Name.E = 0; \ + prim->Name.V = 0; \ + prim->Name.SE = 0; \ + } (void)0 + SETUP_MC_RESULT(integrated_irradiance); + SETUP_MC_RESULT(integrated_absorbed_irradiance); + SETUP_MC_RESULT(absorptivity_loss); + SETUP_MC_RESULT(reflectivity_loss); + #undef SETUP_MC_RESULT + } else { + #define SETUP_MC_RESULT(Name) { \ + const double N = (double)shape->N__; \ + const struct mc_data* data = &mc_prim1->Name; \ + prim->Name.E = data->weight / N; \ + prim->Name.V = data->sqr_weight/N - prim->Name.E*prim->Name.E; \ + prim->Name.SE = prim->Name.V > 0 ? sqrt(prim->Name.V / N) : 0; \ + } (void)0 + SETUP_MC_RESULT(integrated_irradiance); + SETUP_MC_RESULT(integrated_absorbed_irradiance); + SETUP_MC_RESULT(absorptivity_loss); + SETUP_MC_RESULT(reflectivity_loss); + #undef SETUP_MC_RESULT + } return RES_OK; } diff --git a/src/ssol_object.c b/src/ssol_object.c @@ -242,4 +242,16 @@ ssol_object_get_normal /* the area of the 3D surface */ d3_set(normal, object->n); return RES_OK; -} -\ No newline at end of file +} + +/******************************************************************************* + * Local function + ******************************************************************************/ +int +object_has_shape(struct ssol_object* obj, const struct ssol_shape* shape) +{ + unsigned id; + ASSERT(obj && shape); + S3D(shape_get_id(shape->shape_rt, &id)); + return htable_shaded_shape_find(&obj->shaded_shapes_rt, &id) != NULL; +} diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h @@ -54,4 +54,10 @@ struct ssol_object { ref_T ref; }; +extern LOCAL_SYM int +object_has_shape + (struct ssol_object* obj, + const struct ssol_shape* shape); + #endif /* SSOL_OBJECT_C_H */ + diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -465,9 +465,7 @@ accum_mc_receivers_1side (struct mc_receiver_1side* dst, struct mc_receiver_1side* src) { - const struct mc_primitive_1side* src_mc_prim; - struct mc_primitive_1side* dst_mc_prim; - size_t i; + struct htable_shape2mc_iterator it_shape, end_shape; res_T res = RES_OK; ASSERT(dst && src); @@ -481,22 +479,48 @@ accum_mc_receivers_1side ACCUM_WEIGHT(reflectivity_loss); #undef ACCUM_WEIGHT - /* Merge the per primitive MC of the integrated irradiance */ - FOR_EACH(i, 0, darray_mc_prim_size_get(&src->mc_prims)) { - src_mc_prim = darray_mc_prim_cdata_get(&src->mc_prims) + i; - res = mc_receiver_1side_get_mc_primitive - (dst, src_mc_prim->index, &dst_mc_prim); + /* Merge the per shape MC */ + htable_shape2mc_begin(&src->shape2mc, &it_shape); + htable_shape2mc_end(&src->shape2mc, &end_shape); + while(!htable_shape2mc_iterator_eq(&it_shape, &end_shape)) { + struct htable_prim2mc_iterator it_prim, end_prim; + const struct ssol_shape* shape = *htable_shape2mc_iterator_key_get(&it_shape); + struct mc_shape_1side* mc_shape1_src; + struct mc_shape_1side* mc_shape1_dst; + + mc_shape1_src = htable_shape2mc_iterator_data_get(&it_shape); + + res = mc_receiver_1side_get_mc_shape(dst, shape, &mc_shape1_dst); if(res != RES_OK) goto error; - #define ACCUM_WEIGHT(Name) { \ - dst_mc_prim->Name.weight += src_mc_prim->Name.weight; \ - dst_mc_prim->Name.sqr_weight += src_mc_prim->Name.sqr_weight; \ - } (void)0 - ACCUM_WEIGHT(integrated_irradiance); - ACCUM_WEIGHT(integrated_absorbed_irradiance); - ACCUM_WEIGHT(absorptivity_loss); - ACCUM_WEIGHT(reflectivity_loss); - #undef ACCUM_WEIGHT + + /* Merge the per primitive MC */ + htable_prim2mc_begin(&mc_shape1_src->prim2mc, &it_prim); + htable_prim2mc_end(&mc_shape1_src->prim2mc, &end_prim); + while(!htable_prim2mc_iterator_eq(&it_prim, &end_prim)) { + const unsigned iprim = *htable_prim2mc_iterator_key_get(&it_prim); + struct mc_primitive_1side* mc_prim1_src; + struct mc_primitive_1side* mc_prim1_dst; + + mc_prim1_src = htable_prim2mc_iterator_data_get(&it_prim); + + res = mc_shape_1side_get_mc_primitive(mc_shape1_dst, iprim, &mc_prim1_dst); + if(res != RES_OK) goto error; + + #define ACCUM_WEIGHT(Name) { \ + mc_prim1_dst->Name.weight += mc_prim1_src->Name.weight; \ + mc_prim1_dst->Name.sqr_weight += mc_prim1_src->Name.sqr_weight; \ + } (void)0 + ACCUM_WEIGHT(integrated_irradiance); + ACCUM_WEIGHT(integrated_absorbed_irradiance); + ACCUM_WEIGHT(absorptivity_loss); + ACCUM_WEIGHT(reflectivity_loss); + #undef ACCUM_WEIGHT + + htable_prim2mc_iterator_next(&it_prim); + } + htable_shape2mc_iterator_next(&it_shape); } + exit: return res; error: @@ -599,13 +623,18 @@ update_mc /* Per primitive receiver MC accumulation */ if(pt->inst->receiver_per_primitive) { - struct mc_primitive_1side* mc_prim; - res = mc_receiver_1side_get_mc_primitive - (mc_rcv1, pt->prim.prim_id, &mc_prim); + struct mc_shape_1side* mc_shape1; + struct mc_primitive_1side* mc_prim1; + + res = mc_receiver_1side_get_mc_shape(mc_rcv1, pt->sshape->shape, &mc_shape1); + if(res != RES_OK) goto error; + + res = mc_shape_1side_get_mc_primitive(mc_shape1, pt->prim.prim_id, &mc_prim1); if(res != RES_OK) goto error; + #define ACCUM_WEIGHT(Name, W) { \ - mc_prim->Name.weight += (W); \ - mc_prim->Name.sqr_weight += (W)*(W); \ + mc_prim1->Name.weight += (W); \ + mc_prim1->Name.sqr_weight += (W)*(W); \ } (void)0 ACCUM_WEIGHT(integrated_irradiance, pt->incoming_weight); ACCUM_WEIGHT(integrated_absorbed_irradiance, pt->absorbed_irradiance); diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -52,6 +52,7 @@ main(int argc, char** argv) struct ssol_device* dev; struct ssp_rng* rng; struct ssol_scene* scene; + struct ssol_shape* dummy; struct ssol_shape* square; struct ssol_vertex_data attribs[1] = { SSOL_VERTEX_DATA_NULL__ }; struct ssol_material *m_mtl, *m_mtl2; @@ -71,6 +72,7 @@ main(int argc, char** argv) struct ssol_mc_sampled sampled; struct ssol_mc_global mc_global; struct ssol_mc_receiver mc_rcv; + struct ssol_mc_shape mc_shape; struct ssol_mc_primitive mc_prim; double dir[3]; double wavelengths[3] = { 1, 2, 3 }; @@ -86,6 +88,7 @@ main(int argc, char** argv) double m, std; double a_m, a_std; uint32_t r_id; + unsigned ntris; (void) argc, (void) argv; @@ -128,6 +131,7 @@ main(int argc, char** argv) CHECK(ssol_solve(scene, rng, 10, NULL, &estimator), RES_BAD_ARG); /* Create scene content */ + CHECK(ssol_shape_create_mesh(dev, &dummy), RES_OK); CHECK(ssol_shape_create_mesh(dev, &square), RES_OK); attribs[0].usage = SSOL_POSITION; attribs[0].get = get_position; @@ -444,24 +448,33 @@ main(int argc, char** argv) + mc_rcv.absorptivity_loss.E + mc_rcv.reflectivity_loss.E + (1 - mc_global.cos_factor.E) * 4 * DNI, 4 * DNI, 1e-8), 1); - CHECK(ssol_mc_receiver_get_mc_primitives_count(NULL, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitives_count(&mc_rcv, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitives_count(NULL, &count), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitives_count(&mc_rcv, &count), RES_OK); - NCHECK(count, 0); - - CHECK(ssol_mc_receiver_get_mc_primitive(NULL, count, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(&mc_rcv, count, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(NULL, 0, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(&mc_rcv, 0, NULL), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(NULL, count, &mc_prim), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(&mc_rcv, count, &mc_prim), RES_BAD_ARG); - CHECK(ssol_mc_receiver_get_mc_primitive(NULL, 0, &mc_prim), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(NULL, NULL, NULL), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(&mc_rcv, NULL, NULL), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(NULL, square, NULL), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(&mc_rcv, square, NULL), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(NULL, NULL, &mc_shape), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(&mc_rcv, NULL, &mc_shape), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(NULL, square, &mc_shape), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(&mc_rcv, dummy, &mc_shape), RES_BAD_ARG); + CHECK(ssol_mc_receiver_get_mc_shape(&mc_rcv, square, &mc_shape), RES_OK); + + CHECK(ssol_shape_get_triangles_count(square, &ntris), RES_OK); + NCHECK(ntris, 0); + + CHECK(ssol_mc_shape_get_mc_primitive(NULL, ntris, NULL), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(&mc_shape, ntris, NULL), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(NULL, 0, NULL), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(&mc_shape, 0, NULL), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(NULL, ntris, &mc_prim), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(&mc_shape, ntris, &mc_prim), RES_BAD_ARG); + CHECK(ssol_mc_shape_get_mc_primitive(NULL, 0, &mc_prim), RES_BAD_ARG); + dbl = 0; - FOR_EACH(i, 0, count) { - CHECK(ssol_mc_receiver_get_mc_primitive(&mc_rcv, i, &mc_prim), RES_OK); + FOR_EACH(i, 0, ntris) { + CHECK(ssol_mc_shape_get_mc_primitive(&mc_shape, (unsigned)i, &mc_prim), RES_OK); dbl += mc_prim.integrated_irradiance.E; } + CHECK(eq_eps(dbl, a_m, 1.e-6), 1); CHECK(ssol_estimator_ref_put(estimator), RES_OK); @@ -517,18 +530,19 @@ main(int argc, char** argv) CHECK(ssol_instance_ref_put(target), RES_OK); CHECK(ssol_object_ref_put(m_object), RES_OK); CHECK(ssol_object_ref_put(t_object), RES_OK); + CHECK(ssol_shape_ref_put(dummy), RES_OK); CHECK(ssol_shape_ref_put(square), RES_OK); CHECK(ssol_material_ref_put(m_mtl), RES_OK); CHECK(ssol_material_ref_put(v_mtl), RES_OK); CHECK(ssol_device_ref_put(dev), RES_OK); CHECK(ssol_scene_ref_put(scene), RES_OK); - CHECK(ssp_rng_ref_put(rng), RES_OK); CHECK(ssol_spectrum_ref_put(abs), RES_OK); CHECK(ssol_atmosphere_ref_put(atm), RES_OK); CHECK(ssol_estimator_ref_put(estimator), RES_OK); CHECK(ssol_spectrum_ref_put(spectrum), RES_OK); CHECK(ssol_sun_ref_put(sun), RES_OK); CHECK(ssol_sun_ref_put(sun_mono), RES_OK); + CHECK(ssp_rng_ref_put(rng), RES_OK); check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator);