htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit bac2794a8a10708c74ca758dc7ee2a4ab8cd17dc
parent 5d5b23c1dfe2e57b094516faf2bc833cebba2845
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  3 Nov 2020 11:53:43 +0100

Add the temperature to the htrdr-materials fileformat

Diffstat:
Msrc/htrdr_compute_radiance_lw.c | 6++++++
Msrc/htrdr_interface.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/htrdr_interface.h | 7+++++++
Msrc/htrdr_materials.c | 65++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/htrdr_materials.h | 1+
5 files changed, 126 insertions(+), 46 deletions(-)

diff --git a/src/htrdr_compute_radiance_lw.c b/src/htrdr_compute_radiance_lw.c @@ -253,10 +253,16 @@ htrdr_compute_radiance_lw SSF(bsdf_ref_put(bsdf)); if(ssp_rng_canonical(rng) >= bounce_reflectivity) { /* Absorbed at boundary */ +#if 0 /* Retrieve the temperature of the interface. Anyway, since we do not * have this data yet, we use the temperature of the sky at the current * position as the temperature of the surface. */ temperature = htsky_fetch_temperature(htrdr->sky, pos_next); +#else + /* Retrieve the temperature of the interface. */ + temperature = htrdr_interface_fetch_temperature + (htrdr, &interf, dir, &s3d_hit); +#endif if(temperature <= 0) { w = 0; } else { diff --git a/src/htrdr_interface.c b/src/htrdr_interface.c @@ -98,42 +98,21 @@ error: goto exit; } -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -htrdr_interface_create_bsdf - (struct htrdr* htrdr, - const struct htrdr_interface* interf, - const size_t ithread, - const double wavelength, - const double pos[3], +static const struct htrdr_mtl* +interface_fetch_mtl + (const struct htrdr_interface* interf, const double dir[3], - struct ssp_rng* rng, - struct s3d_hit* hit, - struct ssf_bsdf** out_bsdf) + struct s3d_hit* hit) { - enum { FRONT, BACK }; - struct ssf_bsdf* bsdf = NULL; - const struct mrumtl_brdf* brdf = NULL; const struct htrdr_mtl* mtl = NULL; - double N[3]; - double r; - int hit_side; - res_T res = RES_OK; - (void)pos; - ASSERT(htrdr && pos && hit && out_bsdf); - ASSERT(interf && - ( interf->mtl_front.mrumtl - || interf->mtl_back.mrumtl - || interf->mtl_thin.mrumtl)); - - ASSERT(htrdr && interf && pos && dir && hit && out_bsdf); - ASSERT(d3_is_normalized(dir)); + enum { FRONT, BACK }; + ASSERT(interf && dir && hit && !S3D_HIT_NONE(hit)); if(interf->mtl_thin.mrumtl) { mtl = &interf->mtl_thin; } else { + double N[3]; + int hit_side; d3_normalize(N, d3_set_f3(N, hit->normal)); hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK; @@ -157,6 +136,40 @@ htrdr_interface_create_bsdf ASSERT(mtl->mrumtl); } + return mtl; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +htrdr_interface_create_bsdf + (struct htrdr* htrdr, + const struct htrdr_interface* interf, + const size_t ithread, + const double wavelength, + const double pos[3], + const double dir[3], + struct ssp_rng* rng, + struct s3d_hit* hit, + struct ssf_bsdf** out_bsdf) +{ + struct ssf_bsdf* bsdf = NULL; + const struct mrumtl_brdf* brdf = NULL; + const struct htrdr_mtl* mtl = NULL; + double r; + res_T res = RES_OK; + (void)pos; + ASSERT(interf && + ( interf->mtl_front.mrumtl + || interf->mtl_back.mrumtl + || interf->mtl_thin.mrumtl)); + ASSERT(htrdr && interf && pos && dir && hit && out_bsdf); + ASSERT(d3_is_normalized(dir) && !S3D_HIT_NONE(hit)); + + mtl = interface_fetch_mtl(interf, dir, hit); + ASSERT(mtl != NULL); + r = ssp_rng_canonical(rng); res = mrumtl_fetch_brdf2(mtl->mrumtl, wavelength, r, &brdf); @@ -191,3 +204,25 @@ error: goto exit; } +double +htrdr_interface_fetch_temperature + (struct htrdr* htrdr, + const struct htrdr_interface* interf, + const double dir[3], + struct s3d_hit* hit) +{ + const struct htrdr_mtl* mtl = NULL; + + ASSERT(interf && + ( interf->mtl_front.mrumtl + || interf->mtl_back.mrumtl + || interf->mtl_thin.mrumtl)); + ASSERT(htrdr && interf && dir && hit); + ASSERT(d3_is_normalized(dir) && !S3D_HIT_NONE(hit)); + + mtl = interface_fetch_mtl(interf, dir, hit); + ASSERT(mtl != NULL); + + return mtl->temperature; +} + diff --git a/src/htrdr_interface.h b/src/htrdr_interface.h @@ -45,5 +45,12 @@ htrdr_interface_create_bsdf struct s3d_hit* hit, struct ssf_bsdf** bsdf); +extern LOCAL_SYM double +htrdr_interface_fetch_temperature + (struct htrdr* htrdr, + const struct htrdr_interface* interf, + const double dir[3], /* Normalized incoming direction */ + struct s3d_hit* hit); + #endif /* HTRDR_INTERFACE_H */ diff --git a/src/htrdr_materials.c b/src/htrdr_materials.c @@ -31,9 +31,15 @@ #include <string.h> #include <wordexp.h> +struct mtl { + struct mrumtl* mrumtl; + double temperature; /* In Kelvin */ +}; +static const struct mtl MTL_NULL = {NULL, -1}; + /* Generate the hash table that maps a material name to its data */ #define HTABLE_NAME name2mtl -#define HTABLE_DATA struct mrumtl* +#define HTABLE_DATA struct mtl #define HTABLE_KEY struct str #define HTABLE_KEY_FUNCTOR_INIT str_init #define HTABLE_KEY_FUNCTOR_RELEASE str_release @@ -61,7 +67,7 @@ parse_material wordexp_t wexp; char* tk = NULL; char* tk_ctx = NULL; - struct mrumtl* mrumtl = NULL; + struct mtl mtl = MTL_NULL; int err = 0; int wexp_is_allocated = 0; res_T res = RES_OK; @@ -111,7 +117,7 @@ parse_material /* Parse the mrumtl file if any */ if(strcmp(wexp.we_wordv[0], "none")) { res = mrumtl_create(&mats->htrdr->logger, mats->htrdr->allocator, - mats->htrdr->verbose, &mrumtl); + mats->htrdr->verbose, &mtl.mrumtl); if(res != RES_OK) { htrdr_log_err(mats->htrdr, "%s:%lu: error creating the MruMtl loader for the material `%s'-- %s.\n", @@ -120,12 +126,34 @@ parse_material goto error; } - res = mrumtl_load(mrumtl, wexp.we_wordv[0]); + res = mrumtl_load(mtl.mrumtl, wexp.we_wordv[0]); if(res != RES_OK) goto error; } + if(wexp.we_wordc < 2) { + if(mtl.mrumtl) { + htrdr_log_err(mats->htrdr, + "%s:%lu: missing temperature for the material `%s'.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + str_cget(str)); + res = RES_BAD_ARG; + goto error; + } + } else { + /* Parse the temperature */ + res = cstr_to_double(wexp.we_wordv[1], &mtl.temperature); + if(res != RES_OK) { + htrdr_log_err(mats->htrdr, + "%s:%lu: error parsing the temperature `%s' for the material `%s' " + "-- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + wexp.we_wordv[1], str_cget(str), res_to_cstr(res)); + goto error; + } + } + /* Register the material */ - res = htable_name2mtl_set(&mats->name2mtl, str, &mrumtl); + res = htable_name2mtl_set(&mats->name2mtl, str, &mtl); if(res != RES_OK) { htrdr_log_err(mats->htrdr, "%s:%lu: could not register the material `%s' -- %s.\n", @@ -134,17 +162,17 @@ parse_material goto error; } - if(wexp.we_wordc > 1) { + if(wexp.we_wordc > 2) { htrdr_log_warn(mats->htrdr, "%s:%lu: unexpected text `%s'.\n", txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), - wexp.we_wordv[1]); + wexp.we_wordv[2]); } exit: if(wexp_is_allocated) wordfree(&wexp); return res; error: - if(mrumtl) MRUMTL(ref_put(mrumtl)); + if(mtl.mrumtl) MRUMTL(ref_put(mtl.mrumtl)); goto exit; } @@ -193,7 +221,7 @@ error: } static void -mtl_release(ref_T* ref) +materials_release(ref_T* ref) { struct htable_name2mtl_iterator it, it_end; struct htrdr_materials* mats; @@ -203,9 +231,9 @@ mtl_release(ref_T* ref) htable_name2mtl_begin(&mats->name2mtl, &it); htable_name2mtl_end(&mats->name2mtl, &it_end); while(!htable_name2mtl_iterator_eq(&it, &it_end)) { - struct mrumtl* mrumtl = *htable_name2mtl_iterator_data_get(&it); + struct mtl* mtl = htable_name2mtl_iterator_data_get(&it); /* The mrumtl can be NULL for semi transparent materials */ - if(mrumtl) MRUMTL(ref_put(mrumtl)); + if(mtl->mrumtl) MRUMTL(ref_put(mtl->mrumtl)); htable_name2mtl_iterator_next(&it); } htable_name2mtl_release(&mats->name2mtl); @@ -262,19 +290,19 @@ void htrdr_materials_ref_put(struct htrdr_materials* mats) { ASSERT(mats); - ref_put(&mats->ref, mtl_release); + ref_put(&mats->ref, materials_release); } int htrdr_materials_find_mtl (struct htrdr_materials* mats, const char* name, - struct htrdr_mtl* mtl) + struct htrdr_mtl* htrdr_mtl) { struct str str; struct htable_name2mtl_iterator it, it_end; int found = 0; - ASSERT(mats && name && mtl); + ASSERT(mats && name && htrdr_mtl); str_init(mats->htrdr->allocator, &str); CHK(str_set(&str, name) == RES_OK); @@ -282,11 +310,14 @@ htrdr_materials_find_mtl htable_name2mtl_find_iterator(&mats->name2mtl, &str, &it); htable_name2mtl_end(&mats->name2mtl, &it_end); if(htable_name2mtl_iterator_eq(&it, &it_end)) { /* No material found */ - *mtl = HTRDR_MTL_NULL; + *htrdr_mtl = HTRDR_MTL_NULL; found = 0; } else { - mtl->name = str_cget(htable_name2mtl_iterator_key_get(&it)); - mtl->mrumtl = *htable_name2mtl_iterator_data_get(&it); + struct mtl* mtl = htable_name2mtl_iterator_data_get(&it); + ASSERT(mtl != NULL); + htrdr_mtl->name = str_cget(htable_name2mtl_iterator_key_get(&it)); + htrdr_mtl->mrumtl = mtl->mrumtl; + htrdr_mtl->temperature = mtl->temperature; found = 1; } str_release(&str); diff --git a/src/htrdr_materials.h b/src/htrdr_materials.h @@ -25,6 +25,7 @@ struct mrumtl; struct htrdr_mtl { const char* name; const struct mrumtl* mrumtl; + double temperature; }; static const struct htrdr_mtl HTRDR_MTL_NULL;