htrdr

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

commit 2ed9e2d029ab57811f294812b9abb2b6c271fd26
parent a6afdad1576ceb0ce47553399fbf259b25b6566a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 13 Oct 2020 11:38:58 +0200

Take into account very thin materials (e.g. leaves)

Diffstat:
Msrc/htrdr_ground.c | 26+++++++++++++++++++++-----
Msrc/htrdr_interface.c | 39+++++++++++++++++++++------------------
Msrc/htrdr_interface.h | 1+
3 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/src/htrdr_ground.c b/src/htrdr_ground.c @@ -162,6 +162,7 @@ parse_shape_interface { struct str str; char* mtl_name_front = NULL; + char* mtl_name_thin = NULL; char* mtl_name_back = NULL; char* tk_ctx = NULL; res_T res = RES_OK; @@ -181,7 +182,11 @@ parse_shape_interface /* Parse the name of the front/back faces */ mtl_name_front = strtok_r(str_get(&str), ":", &tk_ctx); ASSERT(mtl_name_front); /* This can't be NULL */ + + /* Parse the back/thin material names */ + mtl_name_thin = strtok_r(NULL, ":", &tk_ctx); mtl_name_back = strtok_r(NULL, ":", &tk_ctx); + if(!mtl_name_back) mtl_name_back = mtl_name_thin; if(!mtl_name_back) { htrdr_log_err(htrdr, "The material name of the shape back faces are missing `%s'.\n", name); @@ -189,17 +194,28 @@ parse_shape_interface goto error; } + /* Fetch the interface material */ + if(mtl_name_thin) { + interf->mtl_thin = htrdr_mtl_get(htrdr->mtl, mtl_name_thin); + if(!interf->mtl_thin) { + htrdr_log_err(htrdr, + "Invalid interface `%s:%s:%s'. " + "The material of the interface is unknown.\n", + mtl_name_front, mtl_name_thin, mtl_name_back); + res = RES_BAD_ARG; + goto error; + } + } + /* Fetch the front/back materials */ interf->mtl_front = htrdr_mtl_get(htrdr->mtl, mtl_name_front); interf->mtl_back = htrdr_mtl_get(htrdr->mtl, mtl_name_back); - if(!interf->mtl_front && !interf->mtl_back) { - htrdr_log_err(htrdr, - "Invalid interface `%s:%s'. " - "The front and the back materials are both uknown.\n", - mtl_name_front, mtl_name_back); + if(!interf->mtl_front && !interf->mtl_back && !interf->mtl_thin) { + htrdr_log_err(htrdr, "Invalid interface `%s'.\n", name); res = RES_BAD_ARG; goto error; } + exit: str_release(&str); return res; diff --git a/src/htrdr_interface.c b/src/htrdr_interface.c @@ -123,33 +123,36 @@ htrdr_interface_create_bsdf res_T res = RES_OK; (void)pos; ASSERT(htrdr && pos && hit && out_bsdf); - ASSERT(interf && (interf->mtl_front || interf->mtl_back)); + ASSERT(interf && (interf->mtl_front || interf->mtl_back || interf->mtl_thin)); ASSERT(htrdr && interf && pos && dir && hit && out_bsdf); ASSERT(d3_is_normalized(dir)); - d3_normalize(N, d3_set_f3(N, hit->normal)); + if(interf->mtl_thin) { + mat = interf->mtl_thin; + } else { + d3_normalize(N, d3_set_f3(N, hit->normal)); + hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK; - hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK; - - /* Retrieve the brdf of the material on the other side of the hit side */ - switch(hit_side) { - case BACK: mat = interf->mtl_front; break; - case FRONT: mat = interf->mtl_back; break; - default: FATAL("Unreachable code.\n"); break; - } - - /* Due to numerical issue the hit side might be wrong and thus the fetched - * material might be undefined (e.g. semi-transparent materials). Handle this - * issue by fetching the other material. */ - if(!mat) { + /* Retrieve the brdf of the material on the other side of the hit side */ switch(hit_side) { - case BACK: mat = interf->mtl_back; break; - case FRONT: mat = interf->mtl_front; break; + case BACK: mat = interf->mtl_front; break; + case FRONT: mat = interf->mtl_back; break; default: FATAL("Unreachable code.\n"); break; } + + /* Due to numerical issue the hit side might be wrong and thus the fetched + * material might be undefined (e.g. semi-transparent materials). Handle this + * issue by fetching the other material. */ + if(!mat) { + switch(hit_side) { + case BACK: mat = interf->mtl_back; break; + case FRONT: mat = interf->mtl_front; break; + default: FATAL("Unreachable code.\n"); break; + } + } + ASSERT(mat); } - ASSERT(mat); r = ssp_rng_canonical(rng); diff --git a/src/htrdr_interface.h b/src/htrdr_interface.h @@ -28,6 +28,7 @@ struct ssp_rng; struct htrdr_interface { const struct mrumtl* mtl_front; const struct mrumtl* mtl_back; + const struct mrumtl* mtl_thin; /* != NULL <=> thin material */ }; static const struct htrdr_interface HTRDR_INTERFACE_NULL;