htrdr

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

commit 0e7f4454c103ce4272a9257b2e0c02ba79ba2d30
parent f9b6f7071138180f6b1141ea53a8646e31aab709
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 21 Oct 2022 16:49:24 +0200

Parse the arguments of the htrdr-planeto command

Diffstat:
Msrc/planeto/htrdr_planeto_args.c | 286+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/planeto/htrdr_planeto_args.h | 11++++++++++-
2 files changed, 296 insertions(+), 1 deletion(-)

diff --git a/src/planeto/htrdr_planeto_args.c b/src/planeto/htrdr_planeto_args.c @@ -19,6 +19,10 @@ #include "planeto/htrdr_planeto_args.h" +#include <rsys/cstr.h> +#include <rsys/stretchy_array.h> +#include <rsys/mem_allocator.h> + #include <getopt.h> #include <string.h> @@ -78,6 +82,232 @@ print_help(const char* cmd) htrdr_fprint_license(cmd, stdout); } +static INLINE char* +str_dup(const char* str) +{ + size_t len = 0; + char* dup = NULL; + ASSERT(str); + len = strlen(str) + 1/*NULL char*/; + dup = mem_alloc(len); + if(!dup) { + return NULL; + } else { + return memcpy(dup, str, len); + } +} + +static res_T +parse_aerosol_parameters(const char* str, void* ptr) +{ + enum { MESH, NAME, RADPROP, PHASEFN, PHASEIDS } iparam; + struct rnatm_aerosol_args* aerosol = NULL; + char buf[BUFSIZ]; + struct htrdr_planeto_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the aerosol parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "name")) iparam = NAME; + else if(!strcmp(key, "radprop")) iparam = RADPROP; + else if(!strcmp(key, "phasefn")) iparam = PHASEFN; + else if(!strcmp(key, "phaseids")) iparam = PHASEIDS; + else { + fprintf(stderr, "Invalid aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for aerosol parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + ASSERT(args->naerosols); + aerosol = args->aerosols + (args->naerosols - 1); + + switch(iparam) { + case MESH: + aerosol->smsh_filename = str_dup(val); + if(!aerosol->smsh_filename) res = RES_MEM_ERR; + break; + case NAME: + aerosol->name = str_dup(val); + if(!aerosol->name) res = RES_MEM_ERR; + break; + case RADPROP: + aerosol->sars_filename = str_dup(val); + if(!aerosol->sars_filename) res = RES_MEM_ERR; + break; + case PHASEFN: + aerosol->phase_fn_lst_filename = str_dup(val); + if(!aerosol->phase_fn_lst_filename) res = RES_MEM_ERR; + break; + case PHASEIDS: + aerosol->phase_fn_ids_filename = str_dup(val); + if(!aerosol->phase_fn_ids_filename) res = RES_MEM_ERR; + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the aerosol parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_ground_parameters(const char* str, void* ptr) +{ + enum { BRDF, MESH, NAME, PROP } iparam; + char buf[BUFSIZ]; + struct htrdr_planeto_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the ground parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "brdf")) iparam = BRDF; + else if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "name")) iparam = NAME; + else if(!strcmp(key, "prop")) iparam = PROP; + else { + fprintf(stderr, "Invalid ground parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for ground parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + switch(iparam) { + case BRDF: + args->ground.mtllst_filename = str_dup(val); + if(!args->ground.mtllst_filename) res = RES_MEM_ERR; + goto error; + case MESH: + args->ground.smsh_filename = str_dup(val); + if(!args->ground.smsh_filename) res = RES_MEM_ERR; + break; + case NAME: + args->ground.name = str_dup(val); + if(!args->ground.name) res = RES_MEM_ERR; + break; + case PROP: + args->ground.props_filename = str_dup(val); + if(!args->ground.props_filename) res = RES_MEM_ERR; + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the ground parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +parse_gas_parameters(const char* str, void* ptr) +{ + enum { MESH, CK, TEMP } iparam; + char buf[BUFSIZ]; + struct htrdr_planeto_args* args = ptr; + char* key; + char* val; + char* tk_ctx; + res_T res = RES_OK; + ASSERT(args && str); + + if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { + fprintf(stderr, "Could not duplicate the gas parameter `%s'\n", str); + res = RES_MEM_ERR; + goto error; + } + strncpy(buf, str, sizeof(buf)); + + key = strtok_r(buf, "=", &tk_ctx); + val = strtok_r(NULL, "", &tk_ctx); + + if(!strcmp(key, "mesh")) iparam = MESH; + else if(!strcmp(key, "ck")) iparam = CK; + else if(!strcmp(key, "temp")) iparam = TEMP; + else { + fprintf(stderr, "Invalid gas parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + if(!val) { + fprintf(stderr, "Invalid null value for gas parameter `%s'\n", key); + res = RES_BAD_ARG; + goto error; + } + + switch(iparam) { + case MESH: + args->gas.smsh_filename = str_dup(val); + if(!args->gas.smsh_filename) res = RES_MEM_ERR; + break; + case CK: + args->gas.sck_filename = str_dup(val); + if(!args->gas.sck_filename) res = RES_MEM_ERR; + break; + case TEMP: + args->gas.temperatures_filename = str_dup(val); + if(!args->gas.temperatures_filename) res = RES_MEM_ERR; + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) { + fprintf(stderr, "Unable to parse the gas parameter `%s' -- %s\n", + str, res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + /******************************************************************************* * Local functions ******************************************************************************/ @@ -92,11 +322,47 @@ htrdr_planeto_args_init(struct htrdr_planeto_args* args, int argc, char** argv) while((opt = getopt(argc, argv, "a:dfG:g:hO:o:s:T:t:V:v")) != -1) { switch(opt) { + case 'a': + sa_add(args->aerosols, 1); + args->aerosols[args->naerosols] = RNATM_AEROSOL_ARGS_NULL; + args->naerosols += 1; + res = cstr_parse_list(optarg, ':', parse_aerosol_parameters, args); + break; + case 'd': + args->output_type = HTRDR_PLANETO_ARGS_OUTPUT_OCTREES; + break; + case 'f': + args->force_output_overwrite = 1; + break; + case 'G': + res = cstr_parse_list(optarg, ':', parse_ground_parameters, args); + break; + case 'g': + res = cstr_parse_list(optarg, ':', parse_gas_parameters, args); + break; case 'h': print_help(argv[0]); htrdr_planeto_args_release(args); args->quit = 1; goto exit; + case 'O': args->octrees_storage = optarg; break; + case 'o': args->output = optarg; break; + case 's': + res = htrdr_args_spectral_parse(&args->spectral_domain, optarg); + break; + case 'T': + res = cstr_to_double(optarg, &args->optical_thickness); + if(res != RES_OK && args->optical_thickness < 0) res = RES_BAD_ARG; + break; + case 't': + res = cstr_to_uint(optarg, &args->nthreads); + if(res != RES_OK && !args->nthreads) res = RES_BAD_ARG; + break; + case 'V': + res = cstr_to_uint(optarg, &args->octree_definition_hint); + if(res != RES_OK && !args->octree_definition_hint) res = RES_BAD_ARG; + break; + case 'v': args->verbose = 1; break; default: res = RES_BAD_ARG; goto error; } if(res != RES_OK) { @@ -118,6 +384,26 @@ error: void htrdr_planeto_args_release(struct htrdr_planeto_args* args) { + size_t i; ASSERT(args); + + if(args->gas.smsh_filename) mem_rm(args->gas.smsh_filename); + if(args->gas.sck_filename) mem_rm(args->gas.sck_filename); + if(args->gas.temperatures_filename) mem_rm(args->gas.temperatures_filename); + if(args->ground.smsh_filename) mem_rm(args->ground.smsh_filename); + if(args->ground.props_filename) mem_rm(args->ground.props_filename); + if(args->ground.mtllst_filename) mem_rm(args->ground.mtllst_filename); + if(args->ground.name) mem_rm(args->ground.name); + + FOR_EACH(i, 0, args->naerosols) { + struct rnatm_aerosol_args* aerosol = args->aerosols + i; + if(aerosol->name) mem_rm(aerosol->name); + if(aerosol->smsh_filename) mem_rm(aerosol->smsh_filename); + if(aerosol->sars_filename) mem_rm(aerosol->sars_filename); + if(aerosol->phase_fn_ids_filename) mem_rm(aerosol->phase_fn_ids_filename); + if(aerosol->phase_fn_lst_filename) mem_rm(aerosol->phase_fn_lst_filename); + } + sa_release(args->aerosols); + *args = HTRDR_PLANETO_ARGS_DEFAULT; } diff --git a/src/planeto/htrdr_planeto_args.h b/src/planeto/htrdr_planeto_args.h @@ -25,12 +25,19 @@ #include <limits.h> /* UINT_MAX */ +enum htrdr_planeto_args_output_type { + HTRDR_PLANETO_ARGS_OUTPUT_IMAGE, + HTRDR_PLANETO_ARGS_OUTPUT_OCTREES, + HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__ +}; + struct htrdr_planeto_ground_args { char* smsh_filename; /* The Star-Mesh geometry */ char* props_filename; /* Per triangle physical properties */ char* mtllst_filename; /* List of used materials */ + char* name; }; -#define HTRDR_PLANETO_GROUND_ARGS_NULL__ {NULL,NULL,NULL} +#define HTRDR_PLANETO_GROUND_ARGS_NULL__ {NULL,NULL,NULL,NULL} static const struct htrdr_planeto_ground_args HTRDR_PLANETO_GROUND_ARGS_NULL = HTRDR_PLANETO_GROUND_ARGS_NULL__; @@ -55,6 +62,7 @@ struct htrdr_planeto_args { /* Miscellaneous arguments */ unsigned nthreads; /* Hint on the nimber of threads to use */ + enum htrdr_planeto_args_output_type output_type; int force_output_overwrite; /* Replace output if it exists */ int verbose; /* Verbose level */ int quit; /* Stop the command */ @@ -75,6 +83,7 @@ struct htrdr_planeto_args { HTRDR_ARGS_SPECTRAL_DEFAULT__, /* Spectral domain */ \ \ UINT_MAX, /* Number of threads */ \ + HTRDR_PLANETO_ARGS_OUTPUT_TYPES_COUNT__, \ 0, /* Force output overwrite */ \ 0, /* Verbosity level */ \ 0 /* Stop the command */ \