solstice-solver

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

commit a14788671ec6786440abdd2902d275e5569ab234
parent 344467206bf5ecb09fbaa1ceebff244a99de3ab5
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 12 Sep 2016 10:24:58 +0200

Add dont_sample flag on instances, introduce front/back target_masks.

Sampling is not on instances with mirror material anymore, but on any
instance with dont_sample flag unset. Will allow to sample lenses, ...

Diffstat:
Msrc/ssol.h | 9++++++---
Msrc/ssol_instance.c | 20+++++++++++++++++---
Msrc/ssol_instance_c.h | 3++-
Msrc/ssol_scene.c | 10+++++-----
Msrc/ssol_solver.c | 7++++++-
Msrc/test_ssol_instance.c | 11+++++++----
Msrc/test_ssol_solver1.c | 22+++++++++++++++++-----
Msrc/test_ssol_solver2.c | 6+++---
8 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -424,13 +424,16 @@ ssol_instance_set_receiver const char* name_front, /* May be NULL <=> Front faces are no more receivers */ const char* name_back); /* May be NULL <=> back faces are no more receivers */ -/* TODO: per face mask */ SSOL_API res_T ssol_instance_set_target_mask (struct ssol_instance* instance, - const uint32_t mask); + const uint32_t front_mask, + const uint32_t back_mask); -/* TODO: add a dont_sample flag */ +SSOL_API res_T +ssol_instance_dont_sample +(struct ssol_instance* instance, + const int dont_sample); SSOL_API res_T ssol_instance_is_attached diff --git a/src/ssol_instance.c b/src/ssol_instance.c @@ -79,7 +79,7 @@ ssol_object_instantiate instance->object = object; d33_set_identity(instance->transform); d3_splat(instance->transform + 9, 0); - instance->target_mask = 0; + instance->target_front_mask = instance->target_back_mask = 0; str_init(dev->allocator, &instance->receiver_front); str_init(dev->allocator, &instance->receiver_back); SSOL(object_ref_get(object)); @@ -196,12 +196,26 @@ error: res_T ssol_instance_set_target_mask (struct ssol_instance* instance, - const uint32_t mask) + const uint32_t front_mask, + const uint32_t back_mask) { if (!instance) return RES_BAD_ARG; - instance->target_mask = mask; + instance->target_front_mask = front_mask; + instance->target_back_mask = back_mask; + return RES_OK; +} + +res_T +ssol_instance_dont_sample + (struct ssol_instance* instance, + const int dont_sample) +{ + if (!instance) + return RES_BAD_ARG; + + instance->dont_sample = dont_sample; return RES_OK; } diff --git a/src/ssol_instance_c.h b/src/ssol_instance_c.h @@ -27,7 +27,8 @@ struct ssol_instance { struct str receiver_front; /* Empty if front faces are not receivers */ struct str receiver_back; /* Empty if back faces are not receivers */ double transform[12]; /* Column major 4x3 affine transformation */ - uint32_t target_mask; + uint32_t target_front_mask, target_back_mask; + int dont_sample; struct ssol_device* dev; ref_T ref; diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -235,10 +235,7 @@ scene_setup_s3d_sampling_scene(struct ssol_scene* scn) unsigned id; htable_instance_iterator_next(&it); - /* TODO: keep only primary mirrors */ - if(inst->object->mtl_front->type != MATERIAL_MIRROR - && inst->object->mtl_back->type != MATERIAL_MIRROR) - continue; + if(inst->dont_sample) continue; /* Attach the instantiated s3d sampling shape to the s3d sampling scene */ res = s3d_scene_attach_shape(scn->scn_samp, inst->shape_samp); @@ -372,7 +369,10 @@ hit_filter_function /* register success mask */ if(seg->hit_front) { - rs->success_mask |= inst->target_mask; + rs->success_mask |= inst->target_front_mask; + } + else { + rs->success_mask |= inst->target_back_mask; } if(seg->hit_material->type == MATERIAL_VIRTUAL) { return 1; /* Discard virtual material */ diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -553,7 +553,12 @@ receive_sunlight(struct realisation* rs) } /* register success mask (normal orientation has already been checked) */ - rs->success_mask |= start->instance->target_mask; + if (start->front_exposed) { + rs->success_mask |= start->instance->target_front_mask; + } + else { + rs->success_mask |= start->instance->target_back_mask; + } return 1; } diff --git a/src/test_ssol_instance.c b/src/test_ssol_instance.c @@ -68,10 +68,13 @@ main(int argc, char** argv) CHECK(SET_RECEIVER(instance, NULL, "receiver back"), RES_OK); #undef SET_RECEIVER - CHECK(ssol_instance_set_target_mask(NULL, 1), RES_BAD_ARG); - CHECK(ssol_instance_set_target_mask(instance, 1), RES_OK); - CHECK(ssol_instance_set_target_mask(instance, 0), RES_OK); - CHECK(ssol_instance_set_target_mask(instance, 0x10), RES_OK); + CHECK(ssol_instance_set_target_mask(NULL, 1, 1), RES_BAD_ARG); + CHECK(ssol_instance_set_target_mask(instance, 0, 1), RES_OK); + CHECK(ssol_instance_set_target_mask(instance, 0x10, 0xF0), RES_OK); + + CHECK(ssol_instance_dont_sample(NULL, 1), RES_BAD_ARG); + CHECK(ssol_instance_dont_sample(instance, 1), RES_OK); + CHECK(ssol_instance_dont_sample(instance, 0), RES_OK); CHECK(ssol_instance_ref_put(instance), RES_OK); diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -114,20 +114,20 @@ main(int argc, char** argv) CHECK(ssol_object_create(dev, square, m_mtl, m_mtl, &m_object), RES_OK); CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK); CHECK(ssol_instance_set_receiver(heliostat, "miroir", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(heliostat, 0x1), RES_OK); + CHECK(ssol_instance_set_target_mask(heliostat, 0x1, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK); CHECK(ssol_object_instantiate(m_object, &secondary), RES_OK); CHECK(ssol_instance_set_receiver(secondary, "secondaire", NULL), RES_OK); CHECK(ssol_instance_set_transform(secondary, transform1), RES_OK); - CHECK(ssol_instance_set_target_mask(secondary, 0x2), RES_OK); + CHECK(ssol_instance_set_target_mask(secondary, 0x2, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK); CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK); CHECK(ssol_object_instantiate(t_object, &target), RES_OK); CHECK(ssol_instance_set_transform(target, transform2), RES_OK); CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(target, 0x4), RES_OK); + CHECK(ssol_instance_set_target_mask(target, 0x4, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, target), RES_OK); CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK); @@ -137,9 +137,21 @@ main(int argc, char** argv) CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); #define DNI_cos (1000 * cos(PI / 4)) - CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 2e-2), 1); + CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-2), 1); #define SQR(x) ((x)*(x)) - CHECK(eq_eps(std, sqrt((SQR(8 * DNI_cos) / 2 - SQR(4 * DNI_cos)) / N), 0.01), 1); + CHECK(eq_eps(std, sqrt((SQR(12 * DNI_cos) / 3 - SQR(4 * DNI_cos)) / N), 1e-1), 1); + CHECK(fclose(tmp), 0); + + CHECK(ssol_instance_dont_sample(target, 1), RES_OK); + CHECK(ssol_instance_dont_sample(secondary, 1), RES_OK); + CHECK(ssol_instance_set_target_mask(heliostat, 0, 0), RES_OK); + CHECK(ssol_instance_set_target_mask(secondary, 0, 0), RES_OK); + CHECK(ssol_instance_set_target_mask(target, 0x1, 0), RES_OK); + tmp = tmpfile(); + CHECK(ssol_solve(scene, rng, N, tmp), RES_OK); + CHECK(pp_sum(tmp, "cible", &m, &std), RES_OK); + CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-4), 1); + CHECK(eq_eps(std, sqrt((SQR(4 * DNI_cos) - SQR(4 * DNI_cos)) / N), 1e-4), 1); /* free data */ diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c @@ -130,21 +130,21 @@ main(int argc, char** argv) CHECK(ssol_object_create(dev, square, m_mtl, m_mtl, &m_object), RES_OK); CHECK(ssol_object_instantiate(m_object, &heliostat), RES_OK); CHECK(ssol_instance_set_receiver(heliostat, "miroir", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(heliostat, 0x1), RES_OK); + CHECK(ssol_instance_set_target_mask(heliostat, 0x1, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, heliostat), RES_OK); CHECK(ssol_object_create(dev, quad_square, m_mtl, m_mtl, &s_object), RES_OK); CHECK(ssol_object_instantiate(s_object, &secondary), RES_OK); CHECK(ssol_instance_set_receiver(secondary, "secondaire", NULL), RES_OK); CHECK(ssol_instance_set_transform(secondary, transform1), RES_OK); - CHECK(ssol_instance_set_target_mask(secondary, 0x2), RES_OK); + CHECK(ssol_instance_set_target_mask(secondary, 0x2, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, secondary), RES_OK); CHECK(ssol_object_create(dev, square, v_mtl, v_mtl, &t_object), RES_OK); CHECK(ssol_object_instantiate(t_object, &target), RES_OK); CHECK(ssol_instance_set_transform(target, transform2), RES_OK); CHECK(ssol_instance_set_receiver(target, "cible", NULL), RES_OK); - CHECK(ssol_instance_set_target_mask(target, 0x4), RES_OK); + CHECK(ssol_instance_set_target_mask(target, 0x4, 0), RES_OK); CHECK(ssol_scene_attach_instance(scene, target), RES_OK); CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK);