solstice-solver

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

commit d0f2f125467cfec32b26458b9c2d169106acc3f3
parent 09b68b04987cae506b4f953b8d3887ba1d443e70
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 13 Oct 2016 12:49:33 +0200

Clean up code

Delete dead code and ensure that no private headers are included into
the solver tests.

Diffstat:
Mcmake/CMakeLists.txt | 1-
Msrc/ssol_atmosphere.c | 2+-
Msrc/ssol_c.h | 16++++------------
Msrc/ssol_scene.c | 4++--
Msrc/ssol_solver.c | 777+------------------------------------------------------------------------------
Dsrc/ssol_solver_c.h | 145-------------------------------------------------------------------------------
Msrc/test_ssol_estimator.c | 2--
Msrc/test_ssol_solver1.c | 2--
Msrc/test_ssol_solver2.c | 2--
Msrc/test_ssol_solver2b.c | 2--
Msrc/test_ssol_solver3.c | 2--
Msrc/test_ssol_solver3N.c | 3---
Msrc/test_ssol_solver4.c | 2--
Msrc/test_ssol_solver5.c | 2--
14 files changed, 9 insertions(+), 953 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -85,7 +85,6 @@ set(SSOL_FILES_INC ssol_scene_c.h ssol_shape_c.h ssol_spectrum_c.h - ssol_solver_c.h ssol_sun_c.h) set(SSOL_FILES_DOC COPYING README.md) diff --git a/src/ssol_atmosphere.c b/src/ssol_atmosphere.c @@ -46,7 +46,7 @@ atmosphere_release(ref_T* ref) /******************************************************************************* * Exported ssol_atmosphere functions -******************************************************************************/ + ******************************************************************************/ res_T ssol_atmosphere_create_uniform (struct ssol_device* dev, diff --git a/src/ssol_c.h b/src/ssol_c.h @@ -24,20 +24,12 @@ #include <math.h> +/* Map from SSOL attributes to Star-3D ones */ #define SSOL_TO_S3D_POSITION S3D_POSITION #define SSOL_TO_S3D_NORMAL S3D_ATTRIB_0 #define SSOL_TO_S3D_TEXCOORD S3D_ATTRIB_1 -#ifndef NDEBUG - #define ASSERT_NAN(x, sz) { \ - int i__; \ - FOR_EACH(i__, 0, sz) \ - ASSERT(!IS_NaN((x)[i__])); \ - } (void)0 -#else - #define ASSERT_NAN(x, sz) -#endif - +/* Data sent to the Star-3D filter function */ struct ray_data { struct ssol_scene* scn; /* The scene into which the ray is traced */ struct s3d_primitive prim_from; /* Primitive from which the ray starts */ @@ -47,8 +39,8 @@ struct ray_data { float range_min; /* Output data */ - double N[3]; - double dst; + double N[3]; /* Normal of the nearest punched surface point */ + double dst; /* Hit distance of the nearest punced surface point */ }; static const struct ray_data RAY_DATA_NULL = { diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -17,7 +17,6 @@ #include "ssol_c.h" #include "ssol_atmosphere_c.h" #include "ssol_scene_c.h" -#include "ssol_solver_c.h" #include "ssol_sun_c.h" #include "ssol_device_c.h" #include "ssol_material_c.h" @@ -30,7 +29,7 @@ #include <rsys/rsys.h> #include <rsys/float2.h> #include <rsys/float3.h> -#include <rsys/double33.h> +#include <rsys/double3.h> /******************************************************************************* * Helper functions @@ -438,3 +437,4 @@ hit_filter_function return 0; } + diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -18,7 +18,6 @@ #include "ssol.h" #include "ssol_c.h" #include "ssol_atmosphere_c.h" -#include "ssol_solver_c.h" #include "ssol_device_c.h" #include "ssol_estimator_c.h" #include "ssol_scene_c.h" @@ -34,41 +33,16 @@ #include <rsys/float2.h> #include <rsys/float3.h> #include <rsys/double3.h> -#include <rsys/double44.h> #include <rsys/mem_allocator.h> #include <rsys/ref_count.h> #include <rsys/rsys.h> #include <star/ssf.h> +#include <star/ssp.h> /******************************************************************************* * Helper functions ******************************************************************************/ -#if 0 -static FINLINE void -solstice_trace_ray(struct realisation* rs) -{ - float org[3], dir[3], range[2] = { 0, FLT_MAX }; - struct segment* seg = current_segment(rs); - - f3_set_d3(org, seg->org); - f3_set_d3(dir, seg->dir); - S3D(scene_view_trace_ray - (rs->data.view_rt, org, dir, range, rs, &seg->hit)); - /* the filter function recomputes intersections on quadrics and sets seg */ -} - -static INLINE int -cmp_candidates(const void* _c1, const void* _c2) -{ - const struct receiver_record* c1 = _c1; - const struct receiver_record* c2 = _c2; - const double d1 = c1->hit_distance; - const double d2 = c2->hit_distance; - return (d1 > d2) - (d1 < d2); -} -#endif - static FINLINE res_T check_scene(const struct ssol_scene* scene, const char* caller) { @@ -103,755 +77,8 @@ check_scene(const struct ssol_scene* scene, const char* caller) } /******************************************************************************* - * Local functions - ******************************************************************************/ -#if 0 -static void -release_solver_data(struct solver_data* data) -{ - ASSERT(data); - if (data->view_rt) S3D(scene_view_ref_put(data->view_rt)); - if (data->view_samp) S3D(scene_view_ref_put(data->view_samp)); - if (data->sun_dir_ran) CHECK(ranst_sun_dir_ref_put(data->sun_dir_ran), RES_OK); - if (data->sun_wl_ran) CHECK(ranst_sun_wl_ref_put(data->sun_wl_ran), RES_OK); - if (data->bsdf) SSF(bsdf_ref_put(data->bsdf)); - if (data->receiver_record_candidates.data) - darray_receiver_record_release(&data->receiver_record_candidates); - if (data->instances_ptr.data) - darray_instances_ptr_release(&data->instances_ptr); - memset(data, 0, sizeof(struct solver_data)); -} - -res_T -create_s3d_views - (struct s3d_scene* scn, - struct s3d_scene_view** view_rt, - struct s3d_scene_) -{ - res_T res = RES_OK; - char has_sampled, has_receiver; - - if (!data) return RES_BAD_ARG; - - res = scene_setup_s3d_sampling_scene(data->scene, &has_sampled, &has_receiver); - if(res != RES_OK) goto error; - - if (!has_sampled) { - log_error(data->scene->dev, "%s: no sampled geometry defined.\n", FUNC_NAME); - res = RES_BAD_ARG; - goto error; - } - - if (!has_receiver) { - log_error(data->scene->dev, "%s: no receiver defined.\n", FUNC_NAME); - res = RES_BAD_ARG; - goto error; - } - - /* Create views from scenes */ - res = s3d_scene_view_create(data->scene->scn_rt, S3D_TRACE, &data->view_rt); - if (res != RES_OK) goto error; - res = s3d_scene_view_create(data->scene->scn_samp, S3D_SAMPLE, &data->view_samp); - if (res != RES_OK) goto error; - -exit: - return res; -error: - release_solver_data(data); - goto exit; -} -#endif - -#if 0 -struct segment* -previous_segment(struct realisation* rs) -{ - size_t idx; - ASSERT(rs); - if (rs->s_idx == 0) return NULL; - idx = rs->s_idx - 1; - ASSERT(idx < darray_segment_size_get(&rs->segments)); - return darray_segment_data_get(&rs->segments) + idx; -} - -struct segment* -current_segment(struct realisation* rs) -{ - struct segment* seg; - ASSERT(rs); - ASSERT(rs->s_idx < darray_segment_size_get(&rs->segments)); - seg = darray_segment_data_get(&rs->segments) + rs->s_idx; - ASSERT(seg); - return seg; -} - -static void -check_fst_segment(const struct segment* seg) -{ - (void) seg; - ASSERT(seg); - ASSERT_NAN(seg->dir, 3); - /* hit is not checked and can be used only for debugging purpose */ - ASSERT(seg->hit_front != NON_BOOL); - ASSERT(seg->hit_instance); - ASSERT(seg->hit_material); - ASSERT_NAN(seg->hit_normal, 3); - ASSERT_NAN(seg->hit_pos, 3); - ASSERT(seg->on_punched != NON_BOOL); - ASSERT_NAN(seg->org, 3); - ASSERT(seg->weight > 0); -} - -static void -check_segment(const struct segment* seg) -{ - check_fst_segment(seg); - ASSERT(seg->self_instance); - ASSERT(seg->self_front != NON_BOOL); - /* hit filter is supposed to work properly */ - ASSERT(seg->self_instance != seg->hit_instance - || seg->self_front != seg->hit_front); -} - -res_T -setup_next_segment(struct realisation* rs) -{ - res_T res = RES_OK; - const struct segment* prev; - const struct solver_data* data; - double wi[3]; /* Incident direction */ - double pdf; - double R; - struct segment* seg; - ASSERT(rs); - - if (++rs->s_idx >= darray_segment_size_get(&rs->segments)) { - res = darray_segment_resize(&rs->segments, rs->s_idx + 1); - if (res != RES_OK) goto error; - } - prev = previous_segment(rs); - seg = current_segment(rs); - data = &rs->data; - ASSERT(seg && prev && data); - - if(rs->s_idx == 1) - check_fst_segment(prev); - else - check_segment(prev); - reset_segment(seg); - seg->self_instance = prev->hit_instance; - seg->self_front = prev->hit_front; - seg->sun_segment = 0; - - d3_set(seg->org, prev->hit_pos); - - res = material_shade - (prev->hit_material, &data->fragment, rs->wavelength, data->bsdf); - if (res != RES_OK) goto error; - - /* By convention, Star-SF assumes that incoming and reflected directions - * point outward the surface => negate incoming dir */ - d3_minus(wi, prev->dir); - - R = ssf_bsdf_sample - (data->bsdf, data->rng, wi, data->fragment.Ns, seg->dir, &pdf); - seg->weight = prev->weight * R; - - ASSERT(d3_dot(seg->dir, seg->dir)); - if (rs->s_idx > 1) { - seg->weight *= compute_atmosphere_attenuation - (rs->data.scene->atmosphere, prev->hit_distance, rs->wavelength); - } - - end: - return res; - - error: - rs->end = 1; - rs->error = 1; - goto end; -} - -void -reset_segment(struct segment* seg) -{ - ASSERT(seg); -#ifndef NDEBUG - d3_splat(seg->dir, NaN); - seg->hit = S3D_HIT_NULL; - seg->hit_distance = 0; - seg->hit_front = NON_BOOL; - seg->hit_instance = NULL; - seg->hit_material = NULL; - d3_splat(seg->hit_normal, NaN); - d3_splat(seg->hit_pos, NaN); - seg->on_punched = NON_BOOL; - d3_splat(seg->org, NaN); - seg->self_instance = NULL; - seg->self_front = NON_BOOL; - seg->weight = NaN; -#else - seg->hit = S3D_HIT_NULL; - seg->hit_distance = 0; -#endif -} - -static void -reset_starting_point(struct starting_point* start) -{ - ASSERT(start); -#ifndef NDEBUG - start->cos_sun = NaN; - start->front_exposed = NON_BOOL; - start->instance = NULL; - start->material = NULL; - d3_splat(start->rt_normal, NaN); - d3_splat(start->sampl_normal, NaN); - start->on_punched = NON_BOOL; - d3_splat(start->pos, NaN); - start->sampl_primitive = S3D_PRIMITIVE_NULL; - d3_splat(start->sundir, NaN); - start->uv[0] = start->uv[1] = (float)NaN; -#else - start->sampl_primitive = S3D_PRIMITIVE_NULL; -#endif -} - -static void -check_starting_point(const struct starting_point* start) -{ - (void) start; - ASSERT(start); - ASSERT(start->cos_sun > 0); /* normal is flipped facing in_dir */ - ASSERT(start->front_exposed != NON_BOOL); - ASSERT(start->instance); - ASSERT(start->material); - ASSERT_NAN(start->rt_normal, 3); - ASSERT_NAN(start->sampl_normal, 3); - ASSERT(start->on_punched != NON_BOOL); - ASSERT_NAN(start->pos, 3); - ASSERT(!S3D_PRIMITIVE_EQ(&start->sampl_primitive, &S3D_PRIMITIVE_NULL)); - ASSERT_NAN(start->sundir, 3); - ASSERT_NAN(start->uv, 2); -} - -static void -reset_realisation(size_t cpt, struct realisation* rs) -{ - rs->s_idx = 0; - rs->end = 0; - rs->error = 0; - rs->shadow = 0; - rs->success = 0; - rs->rs_id = cpt; - reset_starting_point(&rs->start); - SSF(bsdf_clear(rs->data.bsdf)); - /* reset first segment (always used) */ - reset_segment(current_segment(rs)); - /* reset candidates */ - darray_receiver_record_clear(&rs->data.receiver_record_candidates); -} - -static res_T -init_realisation - (struct ssol_scene* scene, - struct ssp_rng* rng, - FILE* out, - struct realisation* rs) -{ - res_T res = RES_OK; - - if (!scene || !rng || !rs) return RES_BAD_ARG; - - darray_segment_init(scene->dev->allocator, &rs->segments); - /* set a first size; will grow up with time if needed */ - res = darray_segment_resize(&rs->segments, 16); - if (res != RES_OK) goto error; - - memset(&rs->data, 0, sizeof(rs->data)); - - rs->data.scene = scene; - rs->data.rng = rng; - rs->data.out_stream = out; - darray_receiver_record_init - (scene->dev->allocator, &rs->data.receiver_record_candidates); - darray_instances_ptr_init(scene->dev->allocator, &rs->data.instances_ptr); - /* create 2 s3d_scene_view for raytracing and sampling */ - res = set_views(&rs->data); - if (res != RES_OK) goto error; - S3D(scene_view_compute_area(rs->data.view_samp, &rs->data.sampled_area)); - /* create sun distributions */ - res = set_sun_distributions(&rs->data); - if (res != RES_OK) goto error; - res = ssf_bsdf_create(scene->dev->allocator, &rs->data.bsdf); - if (res != RES_OK) goto error; - -exit: - return res; -error: - release_solver_data(&rs->data); - goto exit; -} - -static void -release_realisation(struct realisation* rs) -{ - ASSERT(rs); - release_solver_data(&rs->data); - darray_segment_release(&rs->segments); -} -#endif - -/* partial setting of rs->start - * front_exposed, cos_sun will be set later - * material is set to NULL and will be set later */ -#if 0 -static void -sample_starting_point(struct realisation* rs) -{ - struct s3d_attrib attrib; - struct ssol_shape* shape; - float r1, r2, r3; - struct solver_data* data; - struct s3d_primitive sampl_prim; - struct starting_point* start; - size_t id; - - ASSERT(rs); - data = &rs->data; - ASSERT(data->rng && data->view_samp && data->scene); - start = &rs->start; - /* sample a point on an instance's sampling surface */ - r1 = ssp_rng_canonical_float(data->rng); - r2 = ssp_rng_canonical_float(data->rng); - r3 = ssp_rng_canonical_float(data->rng); - S3D(scene_view_sample(data->view_samp, r1, r2, r3, &sampl_prim, start->uv)); - S3D(primitive_get_attrib(&sampl_prim, S3D_POSITION, start->uv, &attrib)); - ASSERT(attrib.type == S3D_FLOAT3); - d3_set_f3(start->pos, attrib.value); - - /* find the sampled shape and project the sampled point on the actual geometry */ - start->instance = *htable_instance_find - (&data->scene->instances_samp, &sampl_prim.inst_id); - start->sampl_primitive = sampl_prim; - id = *htable_shaded_shape_find - (&start->instance->object->shaded_shapes_samp, &sampl_prim.geom_id); - start->shaded_shape = darray_shaded_shape_cdata_get - (&start->instance->object->shaded_shapes)+id; - shape = start->shaded_shape->shape; - start->on_punched = (shape->type == SHAPE_PUNCHED); - /* set sampling normal */ - S3D(primitive_get_attrib(&sampl_prim, S3D_GEOMETRY_NORMAL, start->uv, &attrib)); - ASSERT(attrib.type == S3D_FLOAT3); - d3_set_f3(start->sampl_normal, attrib.value); - switch (shape->type) { - case SHAPE_MESH: { - /* no projection needed */ - /* set geometry normal */ - d3_set(start->rt_normal, start->sampl_normal); - break; - } - case SHAPE_PUNCHED: { - struct ssol_instance* inst = start->instance; - double pos_local[3]; - double R[9]; /* Rotation matrix */ - double T[3]; /* Translation vector */ - double R_invtrans[9]; /* Inverse transpose rotation matrix */ - double T_inv[3]; /* Inverse of the translation vector */ - - if(d33_is_identity(shape->quadric.transform)) { - d33_set(R, inst->transform); - d3_set (T, inst->transform+9); - } else { - d33_muld33(R, shape->quadric.transform, inst->transform); - d33_muld3 (T, shape->quadric.transform, inst->transform+9); - } - d33_invtrans(R_invtrans, R); - d3_minus(T_inv, T); - - /* project the sampled point on the quadric */ - d3_set(pos_local, start->pos); - d3_add(pos_local, pos_local, T_inv); - d3_muld33(pos_local, pos_local, R_invtrans); - - punched_shape_set_z_local(shape, pos_local); - /* transform point to world */ - d33_muld3(start->pos, R, pos_local); - d3_add(start->pos, start->pos, T); - /* compute exact normal on the instance */ - punched_shape_set_normal_local(shape, pos_local, start->rt_normal); - /* transform normal to world */ - d33_muld3(start->rt_normal, R_invtrans, start->rt_normal); - break; - } - default: FATAL("Unreachable code.\n"); break; - } - /* TODO: transform everything to world coordinate */ - - d3_normalize(start->rt_normal, start->rt_normal); - d3_normalize(start->sampl_normal, start->sampl_normal); - /* will be defined later, depending on wich side sees the sun */ - start->material = NULL; -} -#endif - -#if 0 -static void -sample_starting_point - (struct s3d_scene_view* view, - struct ssp_rng* rng, - double pos[3]) - double pos[3], - double N[3]) -{ - struct s3d_attrib attrib; - struct s3d_primitive prim; - struct ssol_instance* inst; - struct shaded_shape* shape; - size_t id; - float uv[2]; - float r1, r2, r3; - ASSERT(rng); - - /* Sample a point into the scene view */ - r1 = ssp_rng_canonical_float(rng); - r2 = ssp_rng_canonical_float(rng); - r3 = ssp_rng_canonical_float(rng); - S3D(scene_view_sample(view, r1, r2, r3, &prim, uv)); - - /* Retrieve the position the sampled point */ - S3D(primitive_get_attrib(&prim, S3D_POSITION, uv, &attrib)); - d3_set_f3(pos, attrib.value); - - /* Retrieve the sampled shaded shape */ - inst = htable_instance_find(scn->instances_samp, prim.inst_id); - id = htable_shaded_shape_find(inst->object->shaded_shapes_samp, prim.geom_id); - shape = darray_shaded_shape_cdata_get(inst->object->shaded_shapes)[id].shape; - - switch(shape->type) { - case SHAPE_MESH: - /* Simply fetch the normal of the sampled point. Returned normal is in - * world space */ - S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, uv, &attrib)); - d3_normalize(N, d3_set_f3(N, attrib.value)); - break; - case SHAPE_PUNCHED: - /* Project the sampeld point onto the quadric and compute its associated - * normal. */ - /* FIXME Is it really necessary since this point is only used to trace a - * ray toward the sun? */ - shape_project_point_onto_quadric(shape, inst->transform, pos, pos, N); - break; - } -} -#endif - -#if 0 -static void -sample_input_sundir(struct realisation* rs) -{ - ASSERT(rs); - ranst_sun_dir_get(rs->data.sun_dir_ran, rs->data.rng, rs->start.sundir); -} - -static void -sample_wavelength(struct realisation* rs) -{ - ASSERT(rs); - rs->wavelength = ranst_sun_wl_get(rs->data.sun_wl_ran, rs->data.rng); -} -#endif - -#if 0 -/* check if the sampled point as described in rs->start receives sun light - * return 1 if positive - * if positive, fills sun_segment */ -static int -receive_sunlight(struct realisation* rs) -{ - struct segment* seg; - const struct ssol_sun* sun; - struct starting_point* start; - int is_receiver = 0; - uint32_t inst_id; - int32_t receiver_id; - - ASSERT(rs && rs->s_idx == 0); - seg = current_segment(rs); - sun = rs->data.scene->sun; - start = &rs->start; - ASSERT(d3_is_normalized(start->sundir)); - ASSERT(d3_is_normalized(start->rt_normal)); - ASSERT(d3_is_normalized(start->sampl_normal)); - - /* find which material/face is exposed to sun */ - start->geom_cos = d3_dot(start->rt_normal, start->sundir); - start->front_exposed = start->geom_cos < 0; - if (start->front_exposed) { - start->material = start->shaded_shape->mtl_front; - } else { - start->material = start->shaded_shape->mtl_back; - } - /* normals must face the sun and cos must be positive */ - if (start->geom_cos > 0) { - d3_muld(start->rt_normal, start->rt_normal, -1); - } else { - start->geom_cos *= -1; - } - start->cos_sun = d3_dot(start->sampl_normal, start->sundir); - if (start->cos_sun > 0) { - d3_muld(start->sampl_normal, start->sampl_normal, -1); - } else { - start->cos_sun *= -1; - } - - /* start must now be complete */ - check_starting_point(start); - - /* start filling seg from starting point */ - /* seg is set to cast a ray from the sampled point to the sun */ - d3_set(seg->dir, start->sundir); - d3_muld(seg->dir, seg->dir, -1); - d3_set(seg->org, start->pos); - seg->self_instance = start->instance; - seg->self_front = start->front_exposed; - seg->sun_segment = 1; - seg->weight = rs->data.sampled_area * sun->dni * start->cos_sun; - - /* search for occlusions from starting point */ - ASSERT(rs->s_idx == 0); /* sun segment */ - solstice_trace_ray(rs); - if (!S3D_HIT_NONE(&seg->hit)) { - rs->end = 1; - rs->shadow = 1; - return 0; - } - - /* fill segment to allow standard propagation - * pretend the ray was cast in the opposite direction */ - d3_set(seg->dir, start->sundir); - d3_sub(seg->org, seg->org, seg->dir); - /* hit_front will be set from the next impact (if any) */ - /* hit_instance will be set from the next impact (if any) */ - seg->hit_material = start->material; - d3_set(seg->hit_normal, start->rt_normal); - d3_set(seg->hit_pos, start->pos); - seg->on_punched = start->on_punched; - seg->hit_distance = DBL_MAX; - seg->hit_instance = seg->self_instance; - seg->self_instance = NULL; - seg->hit_front = seg->self_front; - seg->self_front = NON_BOOL; - ASSERT(seg->weight > 0); - - /* fill fragment from starting point */ - /* FIXME: is fragment->Ns orientation correct when has_normal && back_face??? */ - surface_fragment_setup(&rs->data.fragment, seg->hit_pos, seg->dir, - /* FIXME: must provide a raytracing prim, not a sampling one! */ - seg->hit_normal, &start->sampl_primitive, start->uv); - - /* if the sampled instance is a receiver, register the sampled point */ - SSOL(instance_get_id(start->instance, &inst_id)); - ASSERT(inst_id < INT32_MAX); - if(start->front_exposed) { - is_receiver = start->instance->receiver_mask & SSOL_FRONT; - receiver_id = (int32_t)inst_id; - } else { - is_receiver = start->instance->receiver_mask & SSOL_BACK; - receiver_id = -(int32_t)inst_id; - } - /* if the sampled instance holds a receiver, push a candidate */ - if(is_receiver) { - struct receiver_record candidate; - f3_set_d3(candidate.dir, seg->dir); - candidate.hit_distance = 0; /* no atmospheric attenuation for sun rays */ - f3_set_d3(candidate.hit_normal, seg->hit_normal); - f3_set_d3(candidate.hit_pos, seg->hit_pos); - candidate.instance = start->instance; - candidate.receiver_id = receiver_id; - f2_set(candidate.uv, start->uv); - darray_receiver_record_push_back - (&rs->data.receiver_record_candidates, &candidate); - } - - return 1; -} - -static void -filter_receiver_hit_candidates(struct realisation* rs) -{ - struct receiver_record* candidates; - struct receiver_record* candidates_end; - struct segment* seg; - struct darray_instances_ptr* inst_array; - size_t candidates_count; - double tmax, prev_distance; - - ASSERT(rs); - candidates_count = rs->data.receiver_record_candidates.size; - if (!candidates_count) - return; - candidates = rs->data.receiver_record_candidates.data; - inst_array = &rs->data.instances_ptr; - - /* sort candidates by distance */ - if (candidates_count > 1) { - qsort(candidates, - candidates_count, sizeof(struct receiver_record), cmp_candidates); - } - /* filter duplicates and candidates past the actual hit distance */ - seg = current_segment(rs); - tmax = seg->hit_distance; - prev_distance = -1; - darray_instances_ptr_clear(inst_array); - for (candidates_end = candidates + candidates_count; - candidates->hit_distance <= tmax && candidates < candidates_end; - candidates++) - { - struct ssol_receiver_data out; - double weight; - if (candidates->hit_distance == prev_distance) { - size_t i = 0, is_duplicate = 0; - struct ssol_instance** ptr = darray_instances_ptr_data_get(inst_array); - while (!is_duplicate && i < darray_instances_ptr_size_get(inst_array)) { - if (*ptr == candidates->instance) - is_duplicate = 1; - ptr++; - i++; - } - /* more than one candidate with same distance - can be duplicates (duplicate = same distance, same instance) */ - if (is_duplicate) continue; - darray_instances_ptr_push_back(inst_array, &candidates->instance); - } - else { - prev_distance = candidates->hit_distance; - darray_instances_ptr_clear(inst_array); - darray_instances_ptr_push_back(inst_array, &candidates->instance); - } - - /* take amosphere into account with distance to receiver */ - weight = seg->weight * compute_atmosphere_attenuation( - rs->data.scene->atmosphere, candidates->hit_distance, rs->wavelength); - out.realization_id = rs->rs_id; - out.date = 0; /* TODO */ - out.segment_id = rs->s_idx; - out.receiver_id = candidates->receiver_id; - out.wavelength = (float)rs->wavelength; - f3_set(out.pos, candidates->hit_pos); - f3_set(out.in_dir, candidates->dir); - f3_set(out.normal, candidates->hit_normal); - out.weight = weight; - f2_set(out.uv, candidates->uv); - fwrite(&out, sizeof(struct ssol_receiver_data), 1, rs->data.out_stream); - rs->success = 1; - } - /* reset candidates */ - darray_receiver_record_clear(&rs->data.receiver_record_candidates); -} - -static void -propagate(struct realisation* rs) -{ - struct segment* seg; - - ASSERT(rs); - seg = current_segment(rs); - - /* check if the ray hits something */ - solstice_trace_ray(rs); - - /* post process possible hits on receivers */ - filter_receiver_hit_candidates(rs); - - if (S3D_HIT_NONE(&seg->hit)) { - rs->end = 1; - return; - } - check_segment(seg); - - /* fill fragment and loop */ - surface_fragment_setup(&rs->data.fragment, seg->hit_pos, seg->dir, - seg->hit_normal, &seg->hit.prim, seg->hit.uv); -} -#endif - -/******************************************************************************* - * Exported function + * Exported functions ******************************************************************************/ -#if 0 -res_T -ssol_solve - (struct ssol_scene* scene, - struct ssp_rng* rng, - const size_t realisations_count, - FILE* output, - struct ssol_estimator* estimator) -{ - struct realisation rs; - size_t r; - size_t success_count = 0; - res_T res = RES_OK; - - if (!scene || !rng || !output || !estimator || !realisations_count) - return RES_BAD_ARG; - - res = check_scene(scene, FUNC_NAME); - if (res != RES_OK) return res; - - /* init realisation */ - res = init_realisation(scene, rng, output, &rs); - if (res != RES_OK) goto error; - - for (r = 0; r < realisations_count; r++) { - struct segment* seg; - double w; - reset_realisation(r, &rs); - sample_starting_point(&rs); - sample_input_sundir(&rs); - sample_wavelength(&rs); - - /* check if the point receives sun light */ - if (receive_sunlight(&rs)) { - /* start propagating from mirror */ - do { - if (RES_OK == setup_next_segment(&rs)) { - propagate(&rs); - } - } while (!rs.end); - } - if (rs.error) { - estimator->failed_count++; - /* FIXME: remove failed realisations' outputs from the output stream */ - continue; - } - - success_count++; - /* propagation ended: feed implicit MC data */ - seg = current_segment(&rs); - w = seg->weight; - - ASSERT(!rs.success | !rs.shadow); - if (rs.shadow) { - estimator->shadow.weight += w; - estimator->shadow.sqr_weight += w * w; - } - else if (!rs.success) { - estimator->missing.weight += w; - estimator->missing.sqr_weight += w * w; - } - } - - estimator->realisation_count += success_count; -exit: - release_realisation(&rs); - return res; -error: - /* TODO: release data */ - goto exit; -} -#endif - res_T ssol_solve (struct ssol_scene* scn, diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h @@ -1,145 +0,0 @@ -/* Copyright (C) CNRS 2016 - * - * 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/>. */ - -#ifndef SSOL_SOLVER_C_H -#define SSOL_SOLVER_C_H - -#include "ssol_material_c.h" -#include "ssol_instance_c.h" -#include "ssol_c.h" - -#include <rsys/ref_count.h> -#include <rsys/list.h> -#include <rsys/dynamic_array.h> - -#include <star/ssp.h> -#include <star/s3d.h> - -struct ranst_sun_dir; -struct ranst_sun_wl; - -#define DARRAY_NAME quadric -#define DARRAY_DATA struct ssol_quadric -#include <rsys/dynamic_array.h> - -#define DARRAY_NAME 3dshape -#define DARRAY_DATA struct s3d_shape* -#include <rsys/dynamic_array.h> - -#define DARRAY_DATA struct ssol_instance* -#define DARRAY_NAME instances_ptr -#include <rsys/dynamic_array.h> - -struct segment { - const struct ssol_instance* hit_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_normal[3]; /* possibly reversed to face the incoming dir */ - double hit_distance; - 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? */ - char sun_segment; -}; - -struct starting_point { - struct ssol_instance* instance; - const struct shaded_shape* shaded_shape; - const struct ssol_material* material; - struct s3d_primitive sampl_primitive; - double sundir[3]; - double pos[3]; - double rt_normal[3]; /* relative to the actual geometry; towards the sun*/ - double sampl_normal[3]; /* relative to the sampling plane; towards the sun*/ - double cos_sun; /* relative to the sampling plane; > 0 */ - double geom_cos; /* relative to the actual geometry; > 0 */ - float uv[2]; - char front_exposed; /* if false, normal has been reversed */ - char on_punched; /* is the point on a punched shape? */ -}; - -struct receiver_record { - struct ssol_instance* instance; - int32_t receiver_id; - float dir[4]; - float hit_pos[3]; - float uv[2]; - float hit_normal[3]; /* face the incoming dir */ - float hit_distance; -}; - -#define DARRAY_DATA struct segment -#define DARRAY_NAME segment -#include <rsys/dynamic_array.h> - -#define DARRAY_DATA struct receiver_record -#define DARRAY_NAME receiver_record -#include <rsys/dynamic_array.h> - -struct solver_data { - struct ssol_scene* scene; - struct ssp_rng* rng; - FILE* out_stream; - /* The s3d_scene_view used for raytracing */ - struct s3d_scene_view* view_rt; - /* The s3d_scene_view used for sampling */ - struct s3d_scene_view* view_samp; - /* The random distributions for sun sampling */ - struct ranst_sun_dir* sun_dir_ran; - struct ranst_sun_wl* sun_wl_ran; - /* Tmp data used for propagation */ - struct ssf_bsdf* bsdf; - struct surface_fragment fragment; - struct darray_receiver_record receiver_record_candidates; - struct darray_instances_ptr instances_ptr; - /* total area of the surface sampled as starting point candidate */ - float sampled_area; -}; - -struct realisation { - struct darray_segment segments; - struct starting_point start; - struct solver_data data; - double wavelength; - size_t rs_id; - uint32_t s_idx; - /* status */ - char end, error, shadow, success; -}; - -extern LOCAL_SYM res_T -set_sun_distributions(struct solver_data* data); - -extern LOCAL_SYM res_T -set_views(struct solver_data* data); - -extern LOCAL_SYM struct segment* -previous_segment(struct realisation* rs); - -extern LOCAL_SYM struct segment* -current_segment(struct realisation* rs); - -extern LOCAL_SYM res_T -setup_next_segment(struct realisation* rs); - -extern LOCAL_SYM void -reset_segment(struct segment* seg); - -#endif /* SSOL_SOLVER_C_H */ - diff --git a/src/test_ssol_estimator.c b/src/test_ssol_estimator.c @@ -21,8 +21,6 @@ #define PLANE_NAME SQUARE #include "test_ssol_rect_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver1.c b/src/test_ssol_solver1.c @@ -22,8 +22,6 @@ #define PLANE_NAME SQUARE #include "test_ssol_rect_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver2.c b/src/test_ssol_solver2.c @@ -32,8 +32,6 @@ #define HALF_Y 1 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver2b.c b/src/test_ssol_solver2b.c @@ -32,8 +32,6 @@ #define HALF_Y 1 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver3.c b/src/test_ssol_solver3.c @@ -27,8 +27,6 @@ #define HALF_Y 10 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver3N.c b/src/test_ssol_solver3N.c @@ -27,9 +27,6 @@ #define HALF_Y 1 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" -#include "ssol_scene_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver4.c b/src/test_ssol_solver4.c @@ -27,8 +27,6 @@ #define HALF_Y 10 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h> diff --git a/src/test_ssol_solver5.c b/src/test_ssol_solver5.c @@ -27,8 +27,6 @@ #define HALF_Y 10 #include "test_ssol_rect2D_geometry.h" -#include "ssol_solver_c.h" - #include <rsys/logger.h> #include <rsys/double33.h>