htsky

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

commit a86dcc6891db81321f6ce0cc4f4f9a323d2acd27
parent 351eb0beac9155956fccc84b704cc318b7dadbba
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue, 28 Jan 2020 15:15:29 +0100

Add the StarMTL binding

Diffstat:
Mcmake/CMakeLists.txt | 9+++++++++
Msrc/htsky.c | 16++++++++++++++++
Msrc/htsky.h | 10++++++++--
Msrc/htsky_c.h | 3+++
Msrc/htsky_cloud.c | 1-
Asrc/htsky_smtl.c | 303+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/htsky_smtl.h | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 476 insertions(+), 3 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -29,6 +29,7 @@ find_package(HTMIE REQUIRED) find_package(OpenMP 1.2 REQUIRED) find_package(RCMake 0.3 REQUIRED) find_package(RSys 0.7 REQUIRED) +find_package(StarMTL) find_package(StarVX REQUIRED) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) @@ -67,6 +68,14 @@ set(HTSKY_FILES_INC_API htsky.h) set(HTSKY_FILES_DOC COPYING README.md) +if(NOT StarMTL_FOUND) + message(WARNING "Cannot find StarMTL. " + "Build the HTSky library without the StarMTL binding.") +else() + set(HTSKY_FILES_SRC ${HTSKY_FILES_SRC} htsky_smtl.c) + set(HTSKY_FILES_INC_API ${HTSKY_FILES_INC_API} htsky_smtl.h) +endif() + # Prepend each file in the `HTSKY_FILES_<SRC|INC>' list by `HTSKY_SOURCE_DIR' rcmake_prepend_path(HTSKY_FILES_SRC ${HTSKY_SOURCE_DIR}) rcmake_prepend_path(HTSKY_FILES_INC ${HTSKY_SOURCE_DIR}) diff --git a/src/htsky.c b/src/htsky.c @@ -42,6 +42,7 @@ check_args(const struct htsky_args* args) && args->grid_max_definition[0] && args->grid_max_definition[1] && args->grid_max_definition[2] + && args->name && args->nthreads && args->optical_thickness >= 0; } @@ -129,6 +130,7 @@ release_sky(ref_T* ref) if(sky->htmie) HTMIE(ref_put(sky->htmie)); if(sky->sw_bands) MEM_RM(sky->allocator, sky->sw_bands); darray_split_release(&sky->svx2htcp_z); + str_release(&sky->name); ASSERT(MEM_ALLOCATED_SIZE(&sky->svx_allocator) == 0); mem_shutdown_proxy_allocator(&sky->svx_allocator); MEM_RM(sky->allocator, sky); @@ -178,6 +180,7 @@ htsky_create 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); @@ -188,6 +191,12 @@ htsky_create 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) { @@ -309,6 +318,13 @@ htsky_ref_put(struct htsky* sky) return RES_OK; } +const char* +htsky_get_name(const struct htsky* sky) +{ + ASSERT(sky); + return str_cget(&sky->name); +} + double htsky_fetch_particle_phase_function_asymmetry_parameter (const struct htsky* sky, diff --git a/src/htsky.h b/src/htsky.h @@ -24,7 +24,7 @@ /* Library symbol management */ #if defined(HTSKY_SHARED_BUILD) /* Build shared library */ #define HTSKY_API extern EXPORT_SYM -#elif defined(SMTL_STATIC) /* Use/build static library */ +#elif defined(HTSKY_STATIC) /* Use/build static library */ #define HTSKY_API extern LOCAL_SYM #else /* Use shared library */ #define HTSKY_API extern IMPORT_SYM @@ -67,6 +67,7 @@ struct htsky_args { const char* htcp_filename; const char* htgop_filename; const char* htmie_filename; + const char* name; /* Name of the sky. Used by the Star-MTL binding */ unsigned grid_max_definition[3]; /* Maximum definition of the grid */ double optical_thickness; /* Threshold used during octree building */ unsigned nthreads; /* Hint on the number of threads to use */ @@ -78,11 +79,12 @@ struct htsky_args { NULL, /* htcp_filename */ \ NULL, /* htgop_filename */ \ NULL, /* htmie filename */ \ + "sky", /* Name */ \ {UINT_MAX, UINT_MAX, UINT_MAX}, /* Maximum definition of the grid */ \ 1, /* Optical thickness a*/ \ (unsigned)~0, /* #threads */ \ 0, /* Repeat clouds */ \ - 0, /* Verbosity level */ \ + 0 /* Verbosity level */ \ } static const struct htsky_args HTSKY_ARGS_DEFAULT = HTSKY_ARGS_DEFAULT__; @@ -115,6 +117,10 @@ HTSKY_API res_T htsky_ref_put (struct htsky* htsky); +HTSKY_API const char* +htsky_get_name + (const struct htsky* htsky); + HTSKY_API double htsky_fetch_particle_phase_function_asymmetry_parameter (const struct htsky* sky, diff --git a/src/htsky_c.h b/src/htsky_c.h @@ -22,6 +22,7 @@ #include <rsys/logger.h> #include <rsys/mem_allocator.h> #include <rsys/ref_count.h> +#include <rsys/str.h> /* Declare some constants */ #define DRY_AIR_MOLAR_MASS 0.0289644 /* In kg.mol^-1 */ @@ -88,6 +89,8 @@ struct htsky { unsigned nthreads; /* #threads */ + struct str name; /* Name of the sky used by the Star-MTL binding */ + struct mem_allocator* allocator; struct mem_allocator svx_allocator; struct logger* logger; diff --git a/src/htsky_cloud.c b/src/htsky_cloud.c @@ -191,7 +191,6 @@ compute_k_bounds_regular_z } } - static void compute_k_bounds_irregular_z (const struct htsky* sky, diff --git a/src/htsky_smtl.c b/src/htsky_smtl.c @@ -0,0 +1,303 @@ +/* Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier + * Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* getopt support */ + +#include "htsky.h" +#include "htsky_smtl.h" + +#include <rsys/cstr.h> + +#include <getopt.h> +#include <string.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static res_T +parse_grid_definition + (const char* cmd, + struct htsky_args* args, + const char* str) +{ + unsigned def[3]; + size_t len; + res_T res = RES_OK; + ASSERT(cmd && args && str); + + res = cstr_to_list_uint(str, ',', def, &len, 3); + if(res == RES_OK && len != 3) res = RES_BAD_ARG; + if(res != RES_OK) { + fprintf(stderr, "%s: invalid grid definition `%s'.\n", cmd, str); + goto error; + } + + if(!def[0] || !def[1] || !def[2]) { + fprintf(stderr, + "%s: invalid null grid definition {%u, %u, %u}.\n", cmd, SPLIT3(def)); + res = RES_BAD_ARG; + goto error; + } + + args->grid_max_definition[0] = def[0]; + args->grid_max_definition[1] = def[1]; + args->grid_max_definition[2] = def[2]; + +exit: + return res; +error: + goto exit; +} + +static void +args_release(struct htsky_args* args) +{ + ASSERT(args); + *args = HTSKY_ARGS_DEFAULT; +} + +static res_T +args_init(struct htsky_args* args, int argc, char** argv) +{ + int opt; + res_T res = RES_OK; + ASSERT(args); + + *args = HTSKY_ARGS_DEFAULT; + + /* Reset the getopt global variables */ + optind = 0; + opterr = 0; + + while((opt = getopt(argc, argv, "a:c:m:n:rT:t:V:v")) != -1) { + switch(opt) { + case 'a': args->htgop_filename = optarg; break; + case 'c': args->htcp_filename = optarg; break; + case 'm': args->htmie_filename = optarg; break; + case 'n': args->name = optarg; break; + case 'r': args->repeat_clouds = 1; 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 = parse_grid_definition(argv[0], args, optarg); break; + case 'v': args->verbose = 1; break; + default: res = RES_BAD_ARG; break; + } + if(res != RES_OK) { + if(optarg) { + fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", + argv[0], optarg, opt); + } + goto error; + } + } + if(!args->htgop_filename) { + fprintf(stderr, + "%s: missing the path of the gas optical properties file -- option '-a'\n", + argv[0]); + res = RES_BAD_ARG; + goto error; + } + if(args->htcp_filename && !args->htmie_filename) { + fprintf(stderr, + "%s: missing the path toward the file of the Mie's data -- option '-m'\n", + argv[0]); + res = RES_BAD_ARG; + goto error; + } + +exit: + return res; +error: + args_release(args); + goto exit; +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +smtl_program_init + (struct logger* logger, /* NULL <=> use default logger */ + struct mem_allocator* allocator, /* NULL <=> use default allocator */ + int argc, + char* argv[], + void** out_prog) +{ + struct htsky* sky = NULL; + struct htsky_args args = HTSKY_ARGS_DEFAULT; + res_T res = RES_OK; + + if(!argc || !argv || !out_prog) { + res = RES_BAD_ARG; + goto error; + } + + res = args_init(&args, argc, argv); + if(res != RES_OK) goto error; + + res = htsky_create(logger, allocator, &args, &sky); + if(res != RES_OK) goto error; + +exit: + if(out_prog) *out_prog = sky; + return res; +error: + if(sky) { + HTSKY(ref_put(sky)); + sky = NULL; + } + goto exit; +} + +void +smtl_program_release(void* program) +{ + HTSKY(ref_put(program)); +} + +const char* +smtl_program_get_mtl_name(void* program) +{ + return htsky_get_name(program); +} + +enum smtl_mtl_type +smtl_prgram_get_mtl_type(void* program) +{ + (void)program; + return SMTL_MTL_SEMI_TRANSPARENT; +} + +size_t +smtl_program_get_cpnts_count(void* program) +{ + (void)program; + return HTSKY_CPNTS_COUNT__; +} + +int +smtl_program_find_cpnt(void* program, const char* cpnt_name) +{ + int i; + FOR_EACH(i, 0, HTSKY_CPNTS_COUNT__) { + if(!strcmp(cpnt_name, smtl_program_cpnt_get_name(program, i))) + return i; + } + return -1; +} + +const char* +smtl_program_cpnt_get_name(void* program, const int cpnt_id) +{ + const char* name = NULL; + (void)program; + switch(cpnt_id) { + case HTSKY_CPNT_GAS: name = "gas"; break; + case HTSKY_CPNT_PARTICLES: name = "particles"; break; + default: FATAL("Unreachable code.\n"); break; + } + return name; +} + +double +smtl_program_cpnt_get_ka + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx) +{ + struct htsky* sky = program; + ASSERT(program && (unsigned)cpnt_id < HTSKY_CPNTS_COUNT__); + ASSERT(spec && spec->type == SMTL_SPECTRAL_KDISTRIB); + return htsky_fetch_raw_property(sky, HTSKY_Ka, BIT(cpnt_id), + spec->value.kdistrib.iband, spec->value.kdistrib.iquad, vtx->pos, + -DBL_MAX, DBL_MAX); +} + +enum smtl_spectral_type +smtl_program_cpnt_get_ka_spectral_type(void* program, const int cpnt_id) +{ + (void)program, (void)cpnt_id; + return SMTL_SPECTRAL_KDISTRIB; +} + +double +smtl_program_cpnt_get_ks + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx) +{ + struct htsky* sky = program; + ASSERT(program && (unsigned)cpnt_id < HTSKY_CPNTS_COUNT__); + ASSERT(spec && spec->type == SMTL_SPECTRAL_KDISTRIB); + return htsky_fetch_raw_property(sky, HTSKY_Ks, BIT(cpnt_id), + spec->value.kdistrib.iband, spec->value.kdistrib.iquad, vtx->pos, + -DBL_MAX, DBL_MAX); +} + +enum smtl_spectral_type +smtl_program_cpnt_get_ks_spectral_type(void* program, const int cpnt_id) +{ + (void)program, (void)cpnt_id; + return SMTL_SPECTRAL_KDISTRIB; +} + +enum smtl_phasefn_type +smtl_program_cpnt_get_phasefn_type(void* program, const int cpnt_id) +{ + enum smtl_phasefn_type phasefn = SMTL_PHASEFN_NONE__; + (void)program; + switch(cpnt_id) { + case HTSKY_CPNT_GAS: + phasefn = SMTL_PHASEFN_RAYLEIGH; + break; + case HTSKY_CPNT_PARTICLES: + phasefn = SMTL_PHASEFN_HG; + break; + default: FATAL("Unreachable code.\n"); break; + } + return phasefn; +} + +double +smtl_program_cpnt_phasefn_hg_get_g + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx) +{ + struct htsky* sky = program; + (void)vtx, (void)cpnt_id; + ASSERT(program && cpnt_id == HTSKY_CPNT_PARTICLES); + ASSERT(spec && spec->type == SMTL_SPECTRAL_KDISTRIB); + return htsky_fetch_particle_phase_function_asymmetry_parameter + (sky, spec->value.kdistrib.iband, spec->value.kdistrib.iquad); +} + +HTSKY_SMTL_API enum smtl_spectral_type +smtl_program_cpnt_phasefn_hg_get_g_spectral_type(void* program, const int cpnt_id) +{ + (void)program, (void)cpnt_id; + return SMTL_SPECTRAL_KDISTRIB; +} + diff --git a/src/htsky_smtl.h b/src/htsky_smtl.h @@ -0,0 +1,137 @@ +/* Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier + * Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef HTSKY_SMTL_H +#define HTSKY_SMTL_H + +#include <star/smtl.h> +#include <rsys/rsys.h> + +/* Library symbol management */ +#if defined(HTSKY_SMTL_SHARED_BUILD) /* Build shared library */ + #define HTSKY_SMTL_API extern EXPORT_SYM +#elif defined(HTSKY_SMTL_STATIC) /* Use/build static library */ + #define HTSKY_SMTL_API extern LOCAL_SYM +#else /* Use shared library */ + #define HTSKY_SMTL_API extern IMPORT_SYM +#endif + +/* + * Usage: htsky [OPTION]... -a ATMOSPHERE + * Manage the data representing a clear/cloudy sky. + * + * -a ATMOSPHERE HTGOP file of the gas optical properties of the atmosphere + * -c CLOUDS HTCP file storing the properties of the clouds. + * -m MIE HTMie file storing the optical properties of the clouds. + * -n NAME name of the sky. BY default it is "sky" + * -r infinitely repeat the clouds along the X and Y axis. + * -T THRESHOLD optical thickness used as threshold during the octree\n" + * building. By default its value is 1. + * -t THREADS hint on the number of threads to use. By default use as + * -V X,Y,Z maximum definition of the cloud acceleration grids along + * the 3 axis. By default use the definition of the raw data. + * -v make htsky verbose. + */ + +BEGIN_DECLS + +/******************************************************************************* + * Common functions + ******************************************************************************/ +HTSKY_SMTL_API res_T +smtl_program_init + (struct logger* logger, /* NULL <=> use default logger */ + struct mem_allocator* allocator, /* NULL <=> use default allocator */ + int argc, + char* argv[], + void** out_prog); + +HTSKY_SMTL_API void +smtl_program_release + (void* program); + +/******************************************************************************* + * General material attribs + ******************************************************************************/ +HTSKY_SMTL_API const char* +smtl_program_get_mtl_name + (void* program); + +HTSKY_SMTL_API enum smtl_mtl_type +smtl_prgram_get_mtl_type + (void* program); + +/******************************************************************************* + * Component attributes + ******************************************************************************/ +HTSKY_SMTL_API size_t +smtl_program_get_cpnts_count + (void* program); + +HTSKY_SMTL_API int +smtl_program_find_cpnt + (void* program, + const char* cpnt_name); + +HTSKY_SMTL_API const char* +smtl_program_cpnt_get_name + (void* program, + const int cpnt_id); + +HTSKY_SMTL_API double +smtl_program_cpnt_get_ka + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx); + +HTSKY_SMTL_API enum smtl_spectral_type +smtl_program_cpnt_get_ka_spectral_type + (void* program, + const int cpnt_id); + +HTSKY_SMTL_API double +smtl_program_cpnt_get_ks + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx); + +HTSKY_SMTL_API enum smtl_spectral_type +smtl_program_cpnt_get_ks_spectral_type + (void* program, + const int cpnt_id); + +HTSKY_SMTL_API double +smtl_program_cpnt_phasefn_hg_get_g + (void* program, + const int cpnt_id, + const struct smtl_spectral_data* spec, + const struct smtl_vertex* vtx); + +HTSKY_SMTL_API enum smtl_spectral_type +smtl_program_cpnt_phasefn_hg_get_g_spectral_type + (void* program, + const int cpnt_id); + +HTSKY_SMTL_API enum smtl_phasefn_type +smtl_program_cpnt_get_phasefn_type + (void* program, + const int cpnt_id); + +END_DECLS + +#endif /* HTSKY_SMTL_H */