htsky

Load and structure a vertically stratified atmosphere
git clone git://git.meso-star.fr/htsky.git
Log | Files | Refs | README | LICENSE

commit 646b78abc60f684b511dbf7d872c09e517311565
parent 698ca1a59dd0cfc31b4bfc185a3cd613abade814
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 12 Feb 2020 15:38:37 +0100

Add a smtl_program_setup function

Diffstat:
Msrc/htsky.c | 337+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/htsky_c.h | 30+++++++++++++++++++++++++++++-
Msrc/htsky_smtl.c | 11+++++++++--
Msrc/htsky_smtl.h | 6+++++-
4 files changed, 245 insertions(+), 139 deletions(-)

diff --git a/src/htsky.c b/src/htsky.c @@ -27,6 +27,7 @@ #include <star/svx.h> #include <rsys/clock_time.h> +#include <rsys/cstr.h> #include <rsys/double3.h> #include <omp.h> @@ -131,6 +132,9 @@ release_sky(ref_T* ref) if(sky->sw_bands) MEM_RM(sky->allocator, sky->sw_bands); darray_split_release(&sky->svx2htcp_z); str_release(&sky->name); + str_release(&sky->htcp_filename); + str_release(&sky->htmie_filename); + str_release(&sky->htgop_filename); ASSERT(MEM_ALLOCATED_SIZE(&sky->svx_allocator) == 0); mem_shutdown_proxy_allocator(&sky->svx_allocator); MEM_RM(sky->allocator, sky); @@ -146,153 +150,22 @@ htsky_create const struct htsky_args* args, struct htsky** out_sky) { - struct time t0, t1; - struct mem_allocator* allocator = NULL; struct htsky* sky = NULL; - char buf[128]; - int nthreads_max; res_T res = RES_OK; - if(!check_args(args) || !out_sky) { - res = RES_BAD_ARG; - goto error; - } - - allocator = mem_allocator ? mem_allocator : &mem_default_allocator; - sky = MEM_CALLOC(allocator, 1, sizeof(*sky)); - if(!sky) { - if(args->verbose) { - #define ERR_STR "Could not allocate the HTSky data structure.\n" - if(logger) { - logger_print(logger, LOG_ERROR, ERR_STR); - } else { - fprintf(stderr, MSG_ERROR_PREFIX ERR_STR); - } - #undef ERR_STR - } - res = RES_MEM_ERR; - goto error; - } - nthreads_max = MMAX(omp_get_max_threads(), omp_get_num_procs()); - ref_init(&sky->ref); - sky->allocator = allocator; - sky->verbose = args->verbose; - sky->repeat_clouds = args->repeat_clouds; - sky->is_cloudy = args->htcp_filename != NULL; - darray_split_init(sky->allocator, &sky->svx2htcp_z); - str_init(sky->allocator, &sky->name); - sky->sw_bands_range[0] = 1; - sky->sw_bands_range[1] = 0; - sky->nthreads = MMIN(args->nthreads, (unsigned)nthreads_max); - - if(logger) { - sky->logger = logger; - } else { - setup_log_default(sky); - } - - res = str_set(&sky->name, args->name); - if(res != RES_OK) { - log_err(sky, "cannot setup the material name to `%s'.\n", args->name); - goto error; - } - - /* Setup an allocator specific to the SVX library */ - res = mem_init_proxy_allocator(&sky->svx_allocator, sky->allocator); - if(res != RES_OK) { - log_err(sky, "cannot init the allocator used to manage the Star-VX data.\n"); - goto error; - } - - /* Create the Star-VX library device */ - res = svx_device_create - (sky->logger, &sky->svx_allocator, sky->verbose, &sky->svx); - if(res != RES_OK) { - log_err(sky, "error creating the Star-VX library device.\n"); - goto error; - } - - /* Load the gas optical properties */ - res = htgop_create(sky->logger, sky->allocator, sky->verbose, &sky->htgop); - if(res != RES_OK) { - log_err(sky, "could not create the gas optical properties loader.\n"); - goto error; - } - res = htgop_load(sky->htgop, args->htgop_filename); - if(res != RES_OK) { - log_err(sky, "error loading the gas optical properties -- `%s'.\n", - args->htgop_filename); - goto error; - } - - /* Fetch short wave bands range */ - res = htgop_get_sw_spectral_intervals_CIE_XYZ(sky->htgop, sky->sw_bands_range); - if(res != RES_OK) goto error; - - /* Setup the atmopshere */ - time_current(&t0); - res = atmosphere_setup(sky, args->optical_thickness); - if(res != RES_OK) goto error; - time_sub(&t0, time_current(&t1), &t0); - time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); - log_info(sky, "setup atmosphere in %s\n", buf); - - /* Nothing more to do */ - if(!sky->is_cloudy) goto exit; - - if(!args->htmie_filename) { - log_err(sky, "missing the HTMie filename.\n"); + if(!out_sky) { res = RES_BAD_ARG; goto error; } - if(!args->htcp_filename) { - log_err(sky, "missing the HTCP filename.\n"); - res = RES_BAD_ARG; - goto error; - } - - /* Load MIE data */ - res = htmie_create(sky->logger, sky->allocator, sky->verbose, &sky->htmie); - if(res != RES_OK) { - log_err(sky, "could not create the Mie's data loader.\n"); - goto error; - } - res = htmie_load(sky->htmie, args->htmie_filename); - if(res != RES_OK) { - log_err(sky, "error loading the Mie's data -- `%s'.\n", args->htmie_filename); - goto error; - } - - res = setup_sw_bands_properties(sky); + res = sky_create(logger, mem_allocator, args, &sky); if(res != RES_OK) goto error; - /* Load clouds properties */ - res = htcp_create(sky->logger, sky->allocator, sky->verbose, &sky->htcp); - if(res != RES_OK) { - log_err(sky, "could not create the loader of cloud properties.\n"); - goto error; - } - res = htcp_load(sky->htcp, args->htcp_filename); - if(res != RES_OK) { - log_err(sky, "error loading the cloud properties -- `%s'.\n", - args->htcp_filename); - goto error; - } - - time_current(&t0); - res = cloud_setup(sky, args->grid_max_definition, args->optical_thickness); + res = sky_setup(sky); if(res != RES_OK) goto error; - time_sub(&t0, time_current(&t1), &t0); - time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); - log_info(sky, "setup clouds in %s\n", buf); - - if(sky->verbose) { - log_svx_memory_usage(sky); - } exit: - *out_sky = sky; + if(out_sky) *out_sky = sky; return res; error: if(sky) { @@ -593,6 +466,200 @@ htsky_sample_sw_spectral_data_CIE_1931_Z /******************************************************************************* * Local functions ******************************************************************************/ +res_T +sky_create + (struct logger* logger, /* NULL <=> use default logger */ + struct mem_allocator* mem_allocator, /* NULL <=> use default allocator */ + const struct htsky_args* args, + struct htsky** out_sky) +{ + struct mem_allocator* allocator = NULL; + struct htsky* sky = NULL; + int nthreads_max; + res_T res = RES_OK; + + if(!check_args(args) || !out_sky) { + res = RES_BAD_ARG; + goto error; + } + + allocator = mem_allocator ? mem_allocator : &mem_default_allocator; + sky = MEM_CALLOC(allocator, 1, sizeof(*sky)); + if(!sky) { + if(args->verbose) { + #define ERR_STR "Could not allocate the HTSky data structure.\n" + if(logger) { + logger_print(logger, LOG_ERROR, ERR_STR); + } else { + fprintf(stderr, MSG_ERROR_PREFIX ERR_STR); + } + #undef ERR_STR + } + res = RES_MEM_ERR; + goto error; + } + nthreads_max = MMAX(omp_get_max_threads(), omp_get_num_procs()); + ref_init(&sky->ref); + sky->allocator = allocator; + sky->verbose = args->verbose; + sky->repeat_clouds = args->repeat_clouds; + sky->is_cloudy = args->htcp_filename != NULL; + darray_split_init(sky->allocator, &sky->svx2htcp_z); + str_init(sky->allocator, &sky->name); + str_init(sky->allocator, &sky->htcp_filename); + str_init(sky->allocator, &sky->htgop_filename); + str_init(sky->allocator, &sky->htmie_filename); + sky->grid_max_definition[0] = args->grid_max_definition[0]; + sky->grid_max_definition[1] = args->grid_max_definition[1]; + sky->grid_max_definition[2] = args->grid_max_definition[2]; + sky->optical_thickness = args->optical_thickness; + sky->sw_bands_range[0] = 1; + sky->sw_bands_range[1] = 0; + sky->nthreads = MMIN(args->nthreads, (unsigned)nthreads_max); + + if(logger) { + sky->logger = logger; + } else { + setup_log_default(sky); + } + + res = str_set(&sky->name, args->name); + if(res != RES_OK) { + log_err(sky, "cannot setup the material name to `%s' -- %s.\n", + args->name, res_to_cstr(res)); + goto error; + } + + if(sky->is_cloudy && !args->htmie_filename) { + log_err(sky, "missing the HTMie filename.\n"); + res = RES_BAD_ARG; + goto error; + } + + #define CP_STR(Var) { \ + res = str_set(&sky->Var##_filename, args->Var##_filename); \ + if(res != RES_OK) { \ + log_err(sky, "cannot copy the "STR(Var)" filename.\n"); \ + goto error; \ + } \ + } (void)0 + CP_STR(htgop); + if(sky->is_cloudy) { + CP_STR(htcp); + CP_STR(htmie); + } + #undef CP_STR + + /* Setup an allocator specific to the SVX library */ + res = mem_init_proxy_allocator(&sky->svx_allocator, sky->allocator); + if(res != RES_OK) { + log_err(sky, + "cannot init the allocator used to manage the Star-VX data -- %s.\n", + res_to_cstr(res)); + goto error; + } + + /* Create the Star-VX library device */ + res = svx_device_create + (sky->logger, &sky->svx_allocator, sky->verbose, &sky->svx); + if(res != RES_OK) { + log_err(sky, "error creating the Star-VX library device.\n"); + goto error; + } + +error: + if(out_sky) *out_sky = sky; + return res; +exit: + if(sky) { htsky_ref_put(sky); sky = NULL; } + goto exit; +} + +res_T +sky_setup(struct htsky* sky) +{ + struct time t0, t1; + char buf[128]; + res_T res = RES_OK; + ASSERT(sky); + + /* Load the gas optical properties */ + res = htgop_create(sky->logger, sky->allocator, sky->verbose, &sky->htgop); + if(res != RES_OK) { + log_err(sky, "could not create the gas optical properties loader.\n"); + goto error; + } + res = htgop_load(sky->htgop, str_cget(&sky->htgop_filename)); + if(res != RES_OK) { + log_err(sky, "error loading the gas optical properties -- `%s'.\n", + str_cget(&sky->htgop_filename)); + goto error; + } + + /* Fetch short wave bands range */ + res = htgop_get_sw_spectral_intervals_CIE_XYZ(sky->htgop, sky->sw_bands_range); + if(res != RES_OK) goto error; + + /* Setup the atmopshere */ + time_current(&t0); + res = atmosphere_setup(sky, sky->optical_thickness); + if(res != RES_OK) goto error; + time_sub(&t0, time_current(&t1), &t0); + time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); + log_info(sky, "setup atmosphere in %s\n", buf); + + /* Nothing more to do */ + if(!sky->is_cloudy) goto exit; + + ASSERT(!str_is_empty(&sky->htcp_filename)); + ASSERT(!str_is_empty(&sky->htmie_filename)); + + /* Load MIE data */ + res = htmie_create(sky->logger, sky->allocator, sky->verbose, &sky->htmie); + if(res != RES_OK) { + log_err(sky, "could not create the Mie's data loader.\n"); + goto error; + } + res = htmie_load(sky->htmie, str_cget(&sky->htmie_filename)); + if(res != RES_OK) { + log_err(sky, "error loading the Mie's data -- `%s'.\n", + str_cget(&sky->htmie_filename)); + goto error; + } + + res = setup_sw_bands_properties(sky); + if(res != RES_OK) goto error; + + /* Load clouds properties */ + res = htcp_create(sky->logger, sky->allocator, sky->verbose, &sky->htcp); + if(res != RES_OK) { + log_err(sky, "could not create the loader of cloud properties.\n"); + goto error; + } + res = htcp_load(sky->htcp, str_cget(&sky->htcp_filename)); + if(res != RES_OK) { + log_err(sky, "error loading the cloud properties -- `%s'.\n", + str_cget(&sky->htcp_filename)); + goto error; + } + + time_current(&t0); + res = cloud_setup(sky, sky->grid_max_definition, sky->optical_thickness); + if(res != RES_OK) goto error; + time_sub(&t0, time_current(&t1), &t0); + time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); + log_info(sky, "setup clouds in %s\n", buf); + + if(sky->verbose) { + log_svx_memory_usage(sky); + } + +exit: + return res; +error: + goto exit; +} + double* world_to_cloud (const struct htsky* sky, diff --git a/src/htsky_c.h b/src/htsky_c.h @@ -29,10 +29,11 @@ #define H2O_MOLAR_MASS 0.01801528 /* In kg.mol^-1 */ #define GAS_CONSTANT 8.3144598 /* In kg.m^2.s^-2.mol^-1.K */ -/* Forward declaration of external data types */ +/* Forward declarations */ struct htcp; struct htgop; struct htmie; +struct htsky_args; struct svx_tree; struct svx_tree_desc; @@ -58,6 +59,14 @@ struct sw_band_prop { double g_avg; }; +struct delayed_args { + struct str htcp_filename; + struct str htgop_filename; + struct str htmie_filename; + unsigned grid_max_definition[3]; /* Maximum definition of the grid */ + double optical_thickness; /* Threshold used during octree building */ +}; + struct htsky { struct cloud** clouds; /* Per sw_band cloud data structure */ @@ -91,6 +100,14 @@ struct htsky { struct str name; /* Name of the sky used by the Star-MTL binding */ + /* Filename of the input files */ + struct str htcp_filename; + struct str htgop_filename; + struct str htmie_filename; + + unsigned grid_max_definition[3]; /* Maximum definition of the grid */ + double optical_thickness; /* Threshold used during octree building */ + struct mem_allocator* allocator; struct mem_allocator svx_allocator; struct logger* logger; @@ -99,6 +116,17 @@ struct htsky { ref_T ref; }; +extern LOCAL_SYM res_T +sky_create + (struct logger* logger, /* NULL <=> use default logger */ + struct mem_allocator* mem_allocator, /* NULL <=> use default allocator */ + const struct htsky_args* args, + struct htsky** out_sky); + +extern LOCAL_SYM res_T +sky_setup + (struct htsky* sky); + static FINLINE double wavenumber_to_wavelength(const double nu/*In cm^-1*/) { diff --git a/src/htsky_smtl.c b/src/htsky_smtl.c @@ -17,6 +17,7 @@ #define _POSIX_C_SOURCE 200112L /* getopt support */ #include "htsky.h" +#include "htsky_c.h" #include "htsky_smtl.h" #include <rsys/cstr.h> @@ -154,7 +155,7 @@ smtl_program_init res = args_init(&args, argc, argv); if(res != RES_OK) goto error; - res = htsky_create(logger, allocator, &args, &sky); + res = sky_create(logger, allocator, &args, &sky); if(res != RES_OK) goto error; exit: @@ -168,6 +169,12 @@ error: goto exit; } +res_T +smtl_program_setup(void* prog) +{ + return sky_setup(prog); +} + void smtl_program_release(void* program) { @@ -181,7 +188,7 @@ smtl_program_get_mtl_name(void* program) } enum smtl_mtl_type -smtl_prgram_get_mtl_type(void* program) +smtl_program_get_mtl_type(void* program) { (void)program; return SMTL_MTL_SEMI_TRANSPARENT; diff --git a/src/htsky_smtl.h b/src/htsky_smtl.h @@ -50,6 +50,10 @@ smtl_program_init char* argv[], void** out_prog); +HTSKY_API res_T +smtl_program_setup + (void* program); + HTSKY_API void smtl_program_release (void* program); @@ -62,7 +66,7 @@ smtl_program_get_mtl_name (void* program); HTSKY_API enum smtl_mtl_type -smtl_prgram_get_mtl_type +smtl_program_get_mtl_type (void* program); /*******************************************************************************