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:
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);