commit d4e76776f903fab8ab6769c777d4c6b9955c3451
parent a14788671ec6786440abdd2902d275e5569ab234
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 13 Sep 2016 09:25:15 +0200
Fix test solver #2
Diffstat:
4 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -290,11 +290,10 @@ hit_filter_function
ASSERT(seg->self_instance);
NCHECK(seg->self_front, 99);
- /* Discard self intersection; using raytracing normal */
+ /* Discard self intersection */
+ seg->hit_front = f3_dot(hit->normal, dir) < 0;
inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id);
-
- int hit_front = f3_dot(hit->normal, dir) < 0;
- if (seg->self_instance == inst && seg->self_front != hit_front) {
+ if (seg->self_instance == inst && seg->self_front != seg->hit_front) {
return 1;
}
@@ -330,7 +329,6 @@ hit_filter_function
/* transform normal to world */
d33_invtrans(tr, transform);
d33_muld3(seg->hit_normal, tr, seg->hit_normal);
- ASSERT(d3_dot(seg->hit_normal, d3_set_f3(tr, hit->normal)) > 0);
break;
}
case SHAPE_MESH: {
@@ -342,13 +340,11 @@ hit_filter_function
default: FATAL("Unreachable code.\n"); break;
}
- seg->hit_front = d3_dot(seg->hit_normal, seg->dir) < 0;
- ASSERT(hit_front == seg->hit_front);
-
if(seg->hit_front) {
seg->hit_material = inst->object->mtl_front;
receiver_name = &inst->receiver_front;
} else {
+ d3_muld(seg->hit_normal, seg->hit_normal, -1);
seg->hit_material = inst->object->mtl_back;
receiver_name = &inst->receiver_back;
}
diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h
@@ -58,16 +58,16 @@ enum realisation_mode {
struct segment {
const struct ssol_instance* hit_instance;
- const struct ssol_instance* self_instance;
+ const struct ssol_instance* self_instance; /* instance of the starting point */
const struct ssol_material* hit_material;
double weight;
struct s3d_hit hit;
double org[3], dir[4];
double hit_pos[3];
double hit_pos_local[3]; /* in local coordinate, only set on punched shapes */
- double hit_normal[3];
- char hit_front;
- char self_front;
+ double hit_normal[3]; /* possibly reversed to face the incoming dir */
+ char hit_front; /* is the ending point of the segment on the front face? */
+ char self_front; /* was the starting point of the segment on the front face? */
char on_punched; /* is the hit on a punched shape? */
};
@@ -77,11 +77,11 @@ struct starting_point {
struct s3d_primitive sampl_primitive;
double sundir[3];
double pos[3];
- double pos_local[3]; /* in local coordinate, only set on quadrics */
- double normal[3]; /* oriented to face the sun*/
- double cos_sun;
+ double pos_local[3]; /* in local coordinate, only set on punched shapes */
+ double normal[3]; /* oriented towards the sun*/
+ double cos_sun; /* > 0 */
float uv[2];
- char front_exposed;
+ char front_exposed; /* if false, normal has been reversed */
char on_punched; /* is the point on a punched shape? */
};
@@ -104,7 +104,7 @@ struct solver_data {
/* Tmp data used for propagation */
struct brdf_composite* brdfs;
struct surface_fragment fragment;
-
+ /* total area of the surface sampled as starting point candidate */
float sampled_area;
};
diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c
@@ -130,7 +130,6 @@ main(int argc, char** argv)
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);
tmp = tmpfile();
CHECK(!tmp, 0);
#define N 10000
@@ -140,6 +139,7 @@ main(int argc, char** argv)
CHECK(eq_eps(m, 4 * DNI_cos, 4 * DNI_cos * 1e-2), 1);
#define SQR(x) ((x)*(x))
CHECK(eq_eps(std, sqrt((SQR(12 * DNI_cos) / 3 - SQR(4 * DNI_cos)) / N), 1e-1), 1);
+ logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
CHECK(fclose(tmp), 0);
CHECK(ssol_instance_dont_sample(target, 1), RES_OK);
@@ -147,11 +147,15 @@ main(int argc, char** argv)
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);
+
+ CHECK(ssol_solve(scene, rng, 20, stdout), 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);
+ logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
/* free data */
diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c
@@ -62,6 +62,8 @@ main(int argc, char** argv)
double transform2[12]; /* 3x4 column major matrix */
double polygon[] = { -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0 };
const size_t npolygon_verts = sizeof(polygon) / sizeof(double[2]);
+ FILE* tmp;
+ double m, std;
(void) argc, (void) argv;
@@ -95,12 +97,6 @@ main(int argc, char** argv)
CHECK(ssol_scene_create(dev, &scene), RES_OK);
CHECK(ssol_scene_attach_sun(scene, sun), RES_OK);
- CHECK(ssol_solve(NULL, rng, 10, stdout), RES_BAD_ARG);
- CHECK(ssol_solve(scene, NULL, 10, stdout), RES_BAD_ARG);
- CHECK(ssol_solve(scene, rng, 0, stdout), RES_BAD_ARG);
- CHECK(ssol_solve(scene, rng, 10, NULL), RES_BAD_ARG);
- CHECK(ssol_solve(scene, rng, 10, stdout), RES_BAD_ARG); /* no geometry */
-
/* create scene content */
CHECK(ssol_shape_create_mesh(dev, &square), RES_OK);
@@ -130,25 +126,34 @@ 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, 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, 0), RES_OK);
+ CHECK(ssol_instance_dont_sample(secondary, 1), 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, 0), RES_OK);
+ CHECK(ssol_instance_set_target_mask(target, 0x1, 0), RES_OK);
+ CHECK(ssol_instance_dont_sample(target, 1), RES_OK);
CHECK(ssol_scene_attach_instance(scene, target), RES_OK);
CHECK(ssol_solve(scene, rng, 20, stdout), RES_OK);
+ tmp = tmpfile();
+#define N 10000
+ 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 * 1e-4), 1);
+#define SQR(x) ((x)*(x))
+ CHECK(eq_eps(std, sqrt((SQR(4 * DNI_cos) - SQR(4 * DNI_cos)) / N), 1e-4), 1);
+ logger_print(&logger, LOG_OUTPUT, "\nP = %g +/- %g\n", m, std);
/* free data */
CHECK(ssol_instance_ref_put(heliostat), RES_OK);