star-gf

Compute Gebhart factors
git clone git://git.meso-star.fr/star-gf.git
Log | Files | Refs | README | LICENSE

commit 34fa20a0f072059f098580c4a8c0a38d6847fe1c
parent 2e9b98a63d2d7eaab762a53cd6d2e8e5d278e117
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 11 Sep 2015 16:17:33 +0200

Handle radiative paths that does not intersect a geometry

Their transmissivity is accumulated into the "environment". This value
is added the overall distributed transmissivity when the "energy
conservation" property is checked.

Diffstat:
Msrc/sgf.c | 54++++++++++++++++++++----------------------------------
1 file changed, 20 insertions(+), 34 deletions(-)

diff --git a/src/sgf.c b/src/sgf.c @@ -57,16 +57,16 @@ gebhart_radiative_path { struct s3d_hit hit; struct sgf_accum* gebfac; /* Gebhart factor */ - struct s3d_primitive prim; + struct s3d_primitive prim_from, prim; struct s3d_attrib attrib; float st[2] = {0.f, 0.f}; + double sky_gebhart = 0.0; double transmissivity = 1.0; double proba_reflec_spec; double emissivity; double reflectivity; double specularity; const double trans_min = 1.e-8; - size_t iprim, iprim_from; size_t nprims; float vec0[3]; float normal[3]; @@ -99,42 +99,40 @@ gebhart_radiative_path * `normal' */ ssp_ran_hemisphere_cos(rng, normal, dir); - iprim = ctx->primitive_id; transmissivity = 1.0; + sky_gebhart = 0.0; for(;;) { /* Here we go */ - iprim_from = iprim; + prim_from = prim; - range[0] = FLT_MIN, range[1] = FLT_MAX; + range[0] = 1.e-6f, range[1] = FLT_MAX; for(;;) { S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit)); - if(hit.prim.prim_id == iprim_from) range[0] += FLT_EPSILON; /* Self hit */ + if(S3D_PRIMITIVE_EQ(&hit.prim, &prim_from)) range[0] += 1.e-6f; /* Self hit */ else break; } if(S3D_HIT_NONE(&hit)) { - if(ctx->verbose) { - logger_print(ctx->logger, LOG_OUTPUT, "Unexpected radiative path failure\n"); - return RES_BAD_OP; - } + sky_gebhart += transmissivity; + break; } f3_normalize(normal, hit.normal); /* Retrieve the hit position and the hit primitive id */ f3_mulf(vec0, dir, hit.distance); f3_add(pos, vec0, pos); - iprim = hit.prim.prim_id; + prim = hit.prim; - /* Fetch material property */ + /* Fetch material property. TODO fix the use of the prim_id */ emissivity = ctx->get_material_property - (ctx->material, SGF_MATERIAL_EMISSIVITY, iprim, ispectral_band); + (ctx->material, SGF_MATERIAL_EMISSIVITY, prim.prim_id, ispectral_band); specularity = ctx->get_material_property - (ctx->material, SGF_MATERIAL_SPECULARITY, iprim, ispectral_band); + (ctx->material, SGF_MATERIAL_SPECULARITY, prim.prim_id, ispectral_band); reflectivity = ctx->get_material_property - (ctx->material, SGF_MATERIAL_REFLECTIVITY, iprim, ispectral_band); + (ctx->material, SGF_MATERIAL_REFLECTIVITY, prim.prim_id, ispectral_band); - gebfac = result + iprim * ctx->spectral_bands_count; + gebfac = result + prim.prim_id * ctx->spectral_bands_count; if(transmissivity > trans_min) { const double weight = transmissivity * emissivity; gebfac[ispectral_band].radiative_flux += weight; @@ -169,11 +167,13 @@ gebhart_radiative_path #if !defined(NDEBUG) { /* Ensure the energy conservation property */ double sum_radiative_flux = 0.0; + size_t iprim; gebfac = result; FOR_EACH(iprim, 0, nprims) { sum_radiative_flux += gebfac[ispectral_band].radiative_flux; gebfac += ctx->spectral_bands_count; } + sum_radiative_flux += sky_gebhart; ASSERT(eq_eps(sum_radiative_flux, 1.0, 1.e-6)); } #endif @@ -188,29 +188,15 @@ gebhart_factor_integrand { struct sgf_context* ctx = context; struct sgf_accum* buf; - size_t nfailures = 0; size_t iband = 0; - res_T res = RES_OK; + res_T res = RES_OK; (void)res; ASSERT(result && rng && context); buf = darray_gfacc_data_get(result); FOR_EACH(iband, 0, ctx->spectral_bands_count) { - do { - accum_buffer_clear(result); - res = gebhart_radiative_path(buf, rng, ctx, iband); - } while(res == RES_BAD_OP && (++nfailures < MAX_FAILURES)); - - if(ctx->verbose) { - if(nfailures >= MAX_FAILURES) { - logger_print(ctx->logger, LOG_ERROR, -"Too many radiative path failures. The geometry might be wrongly setuped. The\n" -"geometry should be closed and 2D-manifold. In addition its normals must point\n" -"*into* the volume with respect to a Clock Wise vertex ordering\n"); - } else if(res != RES_OK) { - logger_print(ctx->logger, LOG_ERROR, - "Critical error in the computation of the Gebhart factor\n"); - } - } + accum_buffer_clear(result); + res = gebhart_radiative_path(buf, rng, ctx, iband); + ASSERT(res == RES_OK); } }