solstice-solver

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

commit c5413f89bb43accb1391f744c959de088bd10021
parent 44a09ed7a455324f95aa80b45c01049a0dac242e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 16 Feb 2017 14:42:58 +0100

Change way areas are computed.

Diffstat:
Msrc/ssol.h | 22++++++++++++----------
Msrc/ssol_estimator.c | 20--------------------
Msrc/ssol_estimator_c.h | 12++++++------
Msrc/ssol_instance.c | 12++++++++++++
Msrc/ssol_instance_c.h | 1+
Msrc/ssol_object.c | 15+++++++++++++++
Msrc/ssol_object_c.h | 1+
Msrc/ssol_scene.c | 25+++++++------------------
Msrc/ssol_scene_c.h | 6+++---
Msrc/ssol_shape.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/ssol_shape_c.h | 1+
Msrc/ssol_solver.c | 21+++++++--------------
12 files changed, 127 insertions(+), 77 deletions(-)

diff --git a/src/ssol.h b/src/ssol.h @@ -564,6 +564,12 @@ SSOL_API res_T ssol_object_clear (struct ssol_object* object); +/* Retrieve the area of the object */ +SSOL_API res_T +ssol_object_get_area + (const struct ssol_object* object, + double* area); + /******************************************************************************* * Object Instance API - Clone of an object with a set of per instance data as * world transformation, material parameters, etc. Note that the object @@ -607,6 +613,12 @@ ssol_instance_get_id (const struct ssol_instance* instance, uint32_t* id); +/* Retrieve the area of the instance */ +SSOL_API res_T +ssol_instance_get_area + (const struct ssol_instance* instance, + double* area); + /******************************************************************************* * Param buffer API ******************************************************************************/ @@ -796,16 +808,6 @@ ssol_estimator_get_failed_count (const struct ssol_estimator* estimator, size_t* count); -SSOL_API res_T -ssol_estimator_get_sampled_area - (const struct ssol_estimator* estimator, - double* area); - -SSOL_API res_T -ssol_estimator_get_primary_area - (const struct ssol_estimator* estimator, - double* area); - /******************************************************************************* * Miscellaneous functions ******************************************************************************/ diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c @@ -254,26 +254,6 @@ ssol_estimator_get_failed_count return RES_OK; } -res_T -ssol_estimator_get_sampled_area - (const struct ssol_estimator* estimator, - double* area) -{ - if (!estimator || !area) return RES_BAD_ARG; - *area = estimator->sampled_area; - return RES_OK; -} - -res_T -ssol_estimator_get_primary_area - (const struct ssol_estimator* estimator, - double* area) -{ - if (!estimator || !area) return RES_BAD_ARG; - *area = estimator->primary_area; - return RES_OK; -} - /******************************************************************************* * Local function ******************************************************************************/ diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h @@ -101,7 +101,7 @@ struct mc_per_primary_data { struct mc_data cos_loss; struct mc_data shadow_loss; double area; - double base_sun_cos; + double sun_cos; size_t nb_samples; size_t nb_failed; /* by-receptor data for this entity */ @@ -115,7 +115,7 @@ init_mc_per_prim_data { ASSERT(alloc && data); data->area = 0; - data->base_sun_cos = 0; + data->sun_cos = 0; data->cos_loss = MC_DATA_NULL; data->shadow_loss = MC_DATA_NULL; data->nb_samples = 0; @@ -132,7 +132,7 @@ release_mc_per_prim_data(struct mc_per_primary_data* data) #define PRIM_COPY(Dst, Src) {\ Dst->area = Src->area;\ - Dst->base_sun_cos = Src->base_sun_cos;\ + Dst->sun_cos = Src->sun_cos;\ Dst->nb_failed = Src->nb_failed;\ Dst->nb_samples = Src->nb_samples;\ Dst->shadow_loss = Src->shadow_loss;\ @@ -206,7 +206,7 @@ struct ssol_estimator { /* per-primary entity MC computations */ struct htable_primary global_primaries; /* scene areas */ - double sampled_area, primary_area; + double primary_area; struct ssol_device* dev; ref_T ref; @@ -234,8 +234,8 @@ estimator_get_receiver_data static FINLINE struct mc_per_primary_data* estimator_get_primary_entity_data -(struct htable_primary* primaries, - const struct ssol_instance* instance) + (struct htable_primary* primaries, + const struct ssol_instance* instance) { struct mc_per_primary_data* data; ASSERT(primaries && instance); diff --git a/src/ssol_instance.c b/src/ssol_instance.c @@ -84,10 +84,12 @@ ssol_object_instantiate /* Create the Star-3D instance to ray-trace */ res = s3d_scene_instantiate(object->scn_rt, &instance->shape_rt); if(res != RES_OK) goto error; + instance->shape_rt_area = object->scn_rt_area; /* Create the Star-3D instance to sample */ res = s3d_scene_instantiate(object->scn_samp, &instance->shape_samp); if(res != RES_OK) goto error; + instance->shape_samp_area = object->scn_samp_area; exit: if(out_instance) *out_instance = instance; @@ -181,3 +183,13 @@ ssol_instance_get_id(const struct ssol_instance* instance, uint32_t* id) return RES_OK; } +res_T +ssol_instance_get_area + (const struct ssol_instance* instance, + double* area) +{ + if (!instance || !area) return RES_BAD_ARG;; + /* the area of the 3D surface */ + *area = instance->shape_rt_area; + return RES_OK; +} diff --git a/src/ssol_instance_c.h b/src/ssol_instance_c.h @@ -24,6 +24,7 @@ struct ssol_instance { struct ssol_object* object; /* Instantiated object */ struct s3d_shape* shape_rt; /* Instantiated Star-3D shape to ray-trace */ struct s3d_shape* shape_samp; /* Instantiated Star-3D shape to sample */ + double shape_rt_area, shape_samp_area; double transform[12]; /* Column major 4x3 affine transformation */ int receiver_mask; /* Combination of ssol_face_flag */ int sample; /* Define whether or not the instance should be sampled */ diff --git a/src/ssol_object.c b/src/ssol_object.c @@ -137,11 +137,13 @@ ssol_object_add_shaded_shape res = s3d_scene_attach_shape(object->scn_rt, shape->shape_rt); if(res != RES_OK) goto error; mask |= BIT(ATTACH_S3D_RT); + object->scn_rt_area += shape->shape_rt_area; /* Add the shape samp to the sampling scene of the object */ res = s3d_scene_attach_shape(object->scn_samp, shape->shape_samp); if(res != RES_OK) goto error; mask |= BIT(ATTACH_S3D_SAMP); + object->scn_samp_area += shape->shape_samp_area; /* Ask for a shaded shape identifier */ i = darray_shaded_shape_size_get(&object->shaded_shapes); @@ -207,6 +209,8 @@ ssol_object_clear(struct ssol_object* obj) darray_shaded_shape_clear(&obj->shaded_shapes); htable_shaded_shape_clear(&obj->shaded_shapes_rt); htable_shaded_shape_clear(&obj->shaded_shapes_samp); + + obj->scn_rt_area = 0; S3D(scene_clear(obj->scn_rt)); S3D(scene_clear(obj->scn_samp)); @@ -214,3 +218,13 @@ ssol_object_clear(struct ssol_object* obj) return RES_OK; } +res_T +ssol_object_get_area +(const struct ssol_object* object, + double* area) +{ + if (!object || !area) return RES_BAD_ARG;; + /* the area of the 3D surface */ + *area = object->scn_rt_area; + return RES_OK; +} +\ No newline at end of file diff --git a/src/ssol_object_c.h b/src/ssol_object_c.h @@ -47,6 +47,7 @@ struct ssol_object { struct s3d_scene* scn_rt; /* RT scene to instantiate */ struct s3d_scene* scn_samp; /* Sampling scene to instantiate */ + double scn_rt_area, scn_samp_area; struct ssol_device* dev; ref_T ref; diff --git a/src/ssol_scene.c b/src/ssol_scene.c @@ -45,7 +45,6 @@ scene_release(ref_T* ref) SSOL(scene_clear(scene)); if(scene->scn_rt) S3D(scene_ref_put(scene->scn_rt)); if(scene->scn_samp) S3D(scene_ref_put(scene->scn_samp)); - if(scene->scn_prim) S3D(scene_ref_put(scene->scn_prim)); if(scene->sun) SSOL(sun_ref_put(scene->sun)); if(scene->atmosphere) SSOL(atmosphere_ref_put(scene->atmosphere)); htable_instance_release(&scene->instances_rt); @@ -84,8 +83,6 @@ ssol_scene_create if(res != RES_OK) goto error; res = s3d_scene_create(dev->s3d, &scene->scn_samp); if(res != RES_OK) goto error; - res = s3d_scene_create(dev->s3d, &scene->scn_prim); - if(res != RES_OK) goto error; exit: if(out_scene) *out_scene = scene; @@ -195,7 +192,6 @@ ssol_scene_clear(struct ssol_scene* scene) htable_instance_clear(&scene->instances_samp); S3D(scene_clear(scene->scn_rt)); S3D(scene_clear(scene->scn_samp)); - S3D(scene_clear(scene->scn_prim)); if (scene->sun) ssol_scene_detach_sun(scene, scene->sun); if (scene->atmosphere) ssol_scene_detach_atmosphere(scene, scene->atmosphere); @@ -280,25 +276,25 @@ res_T scene_create_s3d_views (struct ssol_scene* scn, struct s3d_scene_view** out_view_rt, - struct s3d_scene_view** out_view_samp, - struct s3d_scene_view** out_view_prim) + struct s3d_scene_view** out_view_samp) { struct htable_instance_iterator it, end; struct s3d_scene_view* view_rt = NULL; struct s3d_scene_view* view_samp = NULL; - struct s3d_scene_view* view_prim = NULL; int has_sampled = 0; int has_receiver = 0; res_T res = RES_OK; ASSERT(scn && out_view_rt && out_view_samp); S3D(scene_clear(scn->scn_samp)); - S3D(scene_clear(scn->scn_prim)); htable_instance_clear(&scn->instances_samp); htable_instance_begin(&scn->instances_rt, &it); htable_instance_end(&scn->instances_rt, &end); + scn->sampled_area = 0; + scn->primary_area = 0; + while (!htable_instance_iterator_eq(&it, &end)) { struct ssol_instance* inst = *htable_instance_iterator_data_get(&it); unsigned id; @@ -310,6 +306,9 @@ scene_create_s3d_views if(!inst->sample) continue; + scn->sampled_area += inst->shape_samp_area; + scn->primary_area += inst->shape_rt_area; + /* Note that geometries with virtual material can be sampled without risk * since the solver avoid to shade them and simply pursue the primary ray */ has_sampled = 1; @@ -318,9 +317,6 @@ scene_create_s3d_views res = s3d_scene_attach_shape(scn->scn_samp, inst->shape_samp); if(res != RES_OK) goto error; - /* Attach the instantiated s3d raytraced shape to the s3d primary scene */ - res = s3d_scene_attach_shape(scn->scn_prim, inst->shape_rt); - if(res != RES_OK) goto error; /* Register the instantiated s3d sampling shape */ S3D(shape_get_id(inst->shape_samp, &id)); @@ -346,13 +342,10 @@ scene_create_s3d_views if(res != RES_OK) goto error; res = s3d_scene_view_create(scn->scn_samp, S3D_SAMPLE, &view_samp); if(res != RES_OK) goto error; - res = s3d_scene_view_create(scn->scn_prim, S3D_SAMPLE, &view_prim); - if (res != RES_OK) goto error; exit: *out_view_rt = view_rt; *out_view_samp = view_samp; - *out_view_prim = view_prim; return res; error: S3D(scene_clear(scn->scn_samp)); @@ -365,10 +358,6 @@ error: S3D(scene_view_ref_put(view_samp)); view_samp = NULL; } - if (view_prim) { - S3D(scene_view_ref_put(view_prim)); - view_prim = NULL; - } goto exit; } diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h @@ -42,11 +42,12 @@ struct ssol_scene { struct s3d_scene* scn_rt; /* S3D scene to ray trace */ struct s3d_scene* scn_samp; /* S3D scene to sample */ - struct s3d_scene* scn_prim; /* S3D scene of primary objects */ struct ssol_sun* sun; /* Sun of the scene */ struct ssol_atmosphere* atmosphere; /* Atmosphere of the scene */ + double sampled_area, primary_area; /* scene areas */ + struct ssol_device* dev; ref_T ref; }; @@ -57,8 +58,7 @@ extern LOCAL_SYM res_T scene_create_s3d_views (struct ssol_scene* scn, struct s3d_scene_view** view_rt, - struct s3d_scene_view** view_samp, - struct s3d_scene_view** out_view_prim); + struct s3d_scene_view** view_samp); #endif /* SSOL_SCENE_C_H */ diff --git a/src/ssol_shape.c b/src/ssol_shape.c @@ -415,6 +415,42 @@ error: goto exit; } +static double +mesh_compute_area + (const unsigned ntris, + void (*get_indices)(const unsigned itri, unsigned ids[3], void* data), + const unsigned nverts, + void (*get_position)(const unsigned ivert, float position[3], void* data), + void* ctx) +{ + unsigned itri; + double area = 0; + + FOR_EACH(itri, 0, ntris) { + float v0[3], v1[3], v2[3]; + double E0[3], E1[3], N[3]; + double V0[3], V1[3], V2[3]; + unsigned IDS[3]; + + get_indices(itri, IDS, ctx); + ASSERT(IDS[0] < nverts); + ASSERT(IDS[1] < nverts); + ASSERT(IDS[2] < nverts); + + get_position(IDS[0], v0, ctx); + get_position(IDS[1], v1, ctx); + get_position(IDS[2], v2, ctx); + d3_set_f3(V0, v0); + d3_set_f3(V1, v1); + d3_set_f3(V2, v2); + d3_sub(E0, V1, V0); + d3_sub(E1, V2, V0); + + area += d3_len(d3_cross(N, E0, E1)); + } + return area * 0.5; +} + /* Setup the Star-3D shape of the quadric to ray-trace, i.e. the clipped 2D * profile of the quadric whose vertices are displaced with respect to the * quadric equation */ @@ -423,12 +459,14 @@ quadric_setup_s3d_shape_rt (const struct ssol_quadric* quadric, const struct darray_double* coords, const struct darray_size_t* ids, - struct s3d_shape* shape) + struct s3d_shape* shape, + double * rt_area) { struct quadric_mesh_context ctx; struct s3d_vertex_data vdata; unsigned nverts; unsigned ntris; + res_T res; ASSERT(quadric && coords && ids && shape); ASSERT(darray_double_size_get(coords)%2 == 0); ASSERT(darray_size_t_size_get(ids)%3 == 0); @@ -458,8 +496,12 @@ quadric_setup_s3d_shape_rt default: FATAL("Unreachable code.\n"); break; } - return s3d_mesh_setup_indexed_vertices + res = s3d_mesh_setup_indexed_vertices (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx); + if (res != RES_OK) return res; + *rt_area = mesh_compute_area + (ntris, quadric_mesh_get_ids, nverts, quadric_mesh_parabol_get_pos, &ctx); + return RES_OK; } /* Setup the Star-3D shape of the quadric to sample, i.e. the clipped 2D @@ -469,12 +511,14 @@ quadric_setup_s3d_shape_samp (const struct ssol_quadric* quadric, const struct darray_double* coords, const struct darray_size_t* ids, - struct s3d_shape* shape) + struct s3d_shape* shape, + double *samp_area) { struct quadric_mesh_context ctx; struct s3d_vertex_data vdata; unsigned nverts; unsigned ntris; + res_T res; ASSERT(coords && ids && shape); ASSERT(darray_double_size_get(coords)%2 == 0); ASSERT(darray_size_t_size_get(ids)%3 == 0); @@ -490,8 +534,12 @@ quadric_setup_s3d_shape_samp vdata.usage = S3D_POSITION; vdata.type = S3D_FLOAT3; vdata.get = quadric_mesh_plane_get_pos; - return s3d_mesh_setup_indexed_vertices + res = s3d_mesh_setup_indexed_vertices (shape, ntris, quadric_mesh_get_ids, nverts, &vdata, 1, &ctx); + if (res != RES_OK) return res; + *samp_area = mesh_compute_area + (ntris, quadric_mesh_get_ids, nverts, quadric_mesh_plane_get_pos, &ctx); + return RES_OK; } static res_T @@ -979,11 +1027,12 @@ ssol_punched_surface_setup /* Setup the Star-3D shape to ray-trace */ res = quadric_setup_s3d_shape_rt - (psurf->quadric, &coords, &ids, shape->shape_rt); + (psurf->quadric, &coords, &ids, shape->shape_rt, &shape->shape_rt_area); if(res != RES_OK) goto error; /* Setup the Star-3D shape to sample */ - res = quadric_setup_s3d_shape_samp(psurf->quadric, &coords, &ids, shape->shape_samp); + res = quadric_setup_s3d_shape_samp + (psurf->quadric, &coords, &ids, shape->shape_samp, &shape->shape_samp_area); if(res != RES_OK) goto error; exit: @@ -1005,6 +1054,7 @@ ssol_mesh_setup void* data) { struct s3d_vertex_data attrs[SSOL_ATTRIBS_COUNT__]; + void (*get_position)(const unsigned ivert, float position[3], void* data) = NULL; res_T res = RES_OK; unsigned i; @@ -1030,6 +1080,8 @@ ssol_mesh_setup case SSOL_POSITION: attrs[i].usage = SSOL_TO_S3D_POSITION; attrs[i].type = S3D_FLOAT3; + ASSERT(!get_position); + get_position = attrs[i].get; break; case SSOL_NORMAL: attrs[i].usage = SSOL_TO_S3D_NORMAL; @@ -1042,13 +1094,17 @@ ssol_mesh_setup default: FATAL("Unreachable code.\n"); break; } } + ASSERT(get_position); + res = s3d_mesh_setup_indexed_vertices (shape->shape_rt, ntris, get_indices, nverts, attrs, nattribs, data); if(res != RES_OK) goto error; + shape->shape_rt_area = mesh_compute_area(ntris, get_indices, nverts, get_position, data); /* The Star-3D shape to sample is the same of the one to ray-traced */ res = s3d_mesh_copy(shape->shape_rt, shape->shape_samp); if(res != RES_OK) goto error; + shape->shape_samp_area = shape->shape_rt_area; exit: return res; diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h @@ -32,6 +32,7 @@ struct ssol_shape { struct s3d_shape* shape_rt; /* Star-3D shape to ray-trace */ struct s3d_shape* shape_samp; /* Star-3D shape to sample */ struct ssol_quadric quadric; + double shape_rt_area, shape_samp_area; struct ssol_device* dev; ref_T ref; diff --git a/src/ssol_solver.c b/src/ssol_solver.c @@ -121,8 +121,8 @@ point_init /* Initialise the Monte Carlo weight */ cos_sun = fabs(d3_dot(pt->N, pt->dir)); - pt->weight = scn->sun->dni * estimator->sampled_area * cos_sun; - pt->cos_loss = scn->sun->dni * estimator->sampled_area * (1 - cos_sun); + pt->weight = scn->sun->dni * scn->sampled_area * cos_sun; + pt->cos_loss = scn->sun->dni * scn->sampled_area * (1 - cos_sun); pt->absorptivity_loss = pt->reflectivity_loss = 0; /* Retrieve the sampled instance and shaded shape */ @@ -359,7 +359,6 @@ ssol_solve struct htable_primary_iterator p_it, p_end; struct s3d_scene_view* view_rt = NULL; struct s3d_scene_view* view_samp = NULL; - struct s3d_scene_view* view_prim = NULL; struct ranst_sun_dir* ran_sun_dir = NULL; struct ranst_sun_wl* ran_sun_wl = NULL; struct ssf_bsdf** bsdfs = NULL; @@ -371,7 +370,6 @@ ssol_solve struct htable_receiver* mc_rcvs = NULL; struct htable_primary* mc_prims = NULL; struct ssol_estimator* estimator = NULL; - float area; int nthreads = 0; int64_t nrealisations = 0; int i = 0; @@ -397,23 +395,19 @@ ssol_solve if(res != RES_OK) goto error; /* Create data structures shared by all threads */ - res = scene_create_s3d_views(scn, &view_rt, &view_samp, &view_prim); + res = scene_create_s3d_views(scn, &view_rt, &view_samp); if(res != RES_OK) goto error; res = sun_create_distributions(scn->sun, &ran_sun_dir, &ran_sun_wl); if(res != RES_OK) goto error; - /* Create the estimator */ - res = estimator_create(scn->dev, scn, &estimator); - if (res != RES_OK) goto error; - S3D(scene_view_compute_area(view_samp, &area)); - estimator->sampled_area = area; - S3D(scene_view_compute_area(view_prim, &area)); - estimator->primary_area = area; - /* Create a RNG proxy from the submitted RNG state */ res = ssp_rng_proxy_create_from_rng (scn->dev->allocator, rng_state, scn->dev->nthreads, &rng_proxy); if(res != RES_OK) goto error; + + /* Create the estimator */ + res = estimator_create(scn->dev, scn, &estimator); + if (res != RES_OK) goto error; /* Create per thread data structures */ #define CREATE(Data) { \ @@ -680,7 +674,6 @@ ssol_solve exit: if(view_rt) S3D(scene_view_ref_put(view_rt)); if(view_samp) S3D(scene_view_ref_put(view_samp)); - if(view_prim) S3D(scene_view_ref_put(view_prim)); if(ran_sun_dir) ranst_sun_dir_ref_put(ran_sun_dir); if(ran_sun_wl) ranst_sun_wl_ref_put(ran_sun_wl); if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy));