htrdr

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

commit 86b10db03da7306447cdedc6da7831a6f5892a30
parent c46f0202562ddcc232659bf741196f9e311baa7f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  6 Dec 2019 14:07:56 +0100

Make the -g really optional

Previously, htrdr failed to run and returned an error when no ground geometry
was defined on the command line.

Diffstat:
Msrc/htrdr_ground.c | 102++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/htrdr_ground.h | 13++++++++++---
2 files changed, 104 insertions(+), 11 deletions(-)

diff --git a/src/htrdr_ground.c b/src/htrdr_ground.c @@ -26,6 +26,7 @@ #include <star/s3d.h> #include <star/s3daw.h> +#include <star/ssf.h> struct ray_context { float range[2]; @@ -48,7 +49,7 @@ struct htrdr_ground { struct s3d_scene_view* view; float lower[3]; /* Ground lower bound */ float upper[3]; /* Ground upper bound */ - double reflectivity; + struct ssf_bsdf* bsdf; int repeat; /* Make the ground infinite in X and Y */ struct htrdr* htrdr; @@ -136,7 +137,15 @@ setup_ground(struct htrdr_ground* ground, const char* obj_filename) size_t nshapes; size_t ishape; res_T res = RES_OK; - ASSERT(ground && obj_filename); + ASSERT(ground); + + if(!obj_filename) { + /* No geometry! Discard the creation of the scene view */ + htrdr_log_warn(ground->htrdr, + "%s: the scene does not have ground geometry.\n", + FUNC_NAME); + goto exit; + } res = s3daw_create(&ground->htrdr->logger, ground->htrdr->allocator, NULL, NULL, ground->htrdr->s3d, ground->htrdr->verbose, &s3daw); @@ -207,6 +216,63 @@ error: goto exit; } +static res_T +setup_bsdf_diffuse(struct htrdr_ground* ground, const double reflectivity) +{ + res_T res = RES_OK; + ASSERT(ground); + + res = ssf_bsdf_create + (ground->htrdr->allocator, &ssf_lambertian_reflection, &ground->bsdf); + if(res != RES_OK) goto error; + + res = ssf_lambertian_reflection_setup(ground->bsdf, reflectivity); + if(res != RES_OK) goto error; + +exit: + return res; +error: + htrdr_log_err(ground->htrdr, + "Could not setup the ground diffuse BSDF with a reflectivity of %g -- %s.\n", + reflectivity, res_to_cstr(res)); + if(ground->bsdf) { + SSF(bsdf_ref_put(ground->bsdf)); + ground->bsdf = NULL; + } + goto exit; +} + +static res_T +setup_bsdf_specular(struct htrdr_ground* ground, const double reflectivity) +{ + struct ssf_fresnel* fresnel = NULL; + res_T res = RES_OK; + ASSERT(ground); + + res = ssf_bsdf_create + (ground->htrdr->allocator, &ssf_specular_reflection, &ground->bsdf); + if(res != RES_OK) goto error; + res = ssf_fresnel_create + (ground->htrdr->allocator, &ssf_fresnel_constant, &fresnel); + if(res != RES_OK) goto error; + res = ssf_fresnel_constant_setup(fresnel, reflectivity); + if(res != RES_OK) goto error; + res = ssf_specular_reflection_setup(ground->bsdf, fresnel); + if(res != RES_OK) goto error; + +exit: + return res; +error: + htrdr_log_err(ground->htrdr, + "Could not setup the ground specular BSDF with a reflectivity of %g -- %s.\n", + reflectivity, res_to_cstr(res)); + if(ground->bsdf) { + SSF(bsdf_ref_put(ground->bsdf)); + ground->bsdf = NULL; + } + goto exit; +} + static void release_ground(ref_T* ref) { @@ -214,6 +280,7 @@ release_ground(ref_T* ref) ASSERT(ref); ground = CONTAINER_OF(ref, struct htrdr_ground, ref); if(ground->view) S3D(scene_view_ref_put(ground->view)); + if(ground->bsdf) SSF(bsdf_ref_put(ground->bsdf)); MEM_RM(ground->htrdr->allocator, ground); } @@ -223,7 +290,8 @@ release_ground(ref_T* ref) res_T htrdr_ground_create (struct htrdr* htrdr, - const char* obj_filename, + const char* obj_filename, /* May be NULL */ + const enum htrdr_bsdf_type bsdf_type, const double reflectivity, const int repeat_ground, /* Infinitely repeat the ground in X and Y */ struct htrdr_ground** out_ground) @@ -232,7 +300,7 @@ htrdr_ground_create struct htrdr_ground* ground = NULL; struct time t0, t1; res_T res = RES_OK; - ASSERT(htrdr && obj_filename && out_ground); + ASSERT(htrdr && out_ground); ASSERT(reflectivity >= 0 || reflectivity <= 1); ground = MEM_CALLOC(htrdr->allocator, 1, sizeof(*ground)); @@ -246,7 +314,20 @@ htrdr_ground_create ref_init(&ground->ref); ground->htrdr = htrdr; ground->repeat = repeat_ground; - ground->reflectivity = reflectivity; + f3_splat(ground->lower, (float)INF); + f3_splat(ground->upper,-(float)INF); + + switch(bsdf_type) { + case HTRDR_BSDF_DIFFUSE: + res = setup_bsdf_diffuse(ground, reflectivity); + break; + case HTRDR_BSDF_SPECULAR: + res = setup_bsdf_specular(ground, reflectivity); + break; + default: FATAL("Unreachable code\n"); + + } + if(res != RES_OK) goto error; time_current(&t0); res = setup_ground(ground, obj_filename); @@ -280,11 +361,11 @@ htrdr_ground_ref_put(struct htrdr_ground* ground) ref_put(&ground->ref, release_ground); } -double -htrdr_ground_get_reflectivity(const struct htrdr_ground* ground) +struct ssf_bsdf* +htrdr_ground_get_bsdf(const struct htrdr_ground* ground) { ASSERT(ground); - return ground->reflectivity; + return ground->bsdf; } res_T @@ -299,6 +380,11 @@ htrdr_ground_trace_ray res_T res = RES_OK; ASSERT(ground && org && dir && range && hit); + if(!ground->view) { /* No ground geometry */ + *hit = S3D_HIT_NULL; + goto exit; + } + if(!ground->repeat) { struct ray_context ray_ctx = RAY_CONTEXT_NULL; float ray_org[3]; diff --git a/src/htrdr_ground.h b/src/htrdr_ground.h @@ -18,15 +18,22 @@ #include <rsys/rsys.h> +enum htrdr_bsdf_type { + HTRDR_BSDF_DIFFUSE, + HTRDR_BSDF_SPECULAR +}; + /* Forward declarations */ struct htrdr; struct htrdr_ground; struct s3d_hit; +struct ssf_bsdf; extern LOCAL_SYM res_T htrdr_ground_create (struct htrdr* htrdr, - const char* obj_filename, + const char* obj_filename, /* May be NULL <=> No ground geometry */ + const enum htrdr_bsdf_type bsdf_type, const double reflectivity, /* In [0, 1] */ const int repeat_ground, /* Infinitely repeat the ground in X and Y */ struct htrdr_ground** ground); @@ -39,8 +46,8 @@ extern LOCAL_SYM void htrdr_ground_ref_put (struct htrdr_ground* ground); -extern LOCAL_SYM double -htrdr_ground_get_reflectivity +extern LOCAL_SYM struct ssf_bsdf* +htrdr_ground_get_bsdf (const struct htrdr_ground* ground); extern LOCAL_SYM res_T