htsky

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

commit ed3780a496bc2138619e5c2c7bc2de45524a45c9
parent 4ae9c32d34a7e02661a84464ba374a196d9fe85e
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 24 Jan 2020 08:34:12 +0100

Setup a CMakeLists.txt file and fix compilation errors

Diffstat:
MREADME.md | 4+++-
Acmake/CMakeLists.txt | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/htsky.c | 43++++++++++++++++++++++++-------------------
Msrc/htsky.h | 43+++++++++++++++++++++++++++++++++++--------
Msrc/htsky_atmosphere.c | 7++++---
Msrc/htsky_c.h | 2+-
Msrc/htsky_cloud.c | 12++++++------
Msrc/htsky_cloud.h | 4+---
Msrc/htsky_dump_cloud_vtk.c | 40+++++++++++++++++++++++++++++++++++-----
Dsrc/htsky_file_sys.c | 233-------------------------------------------------------------------------------
Dsrc/htsky_file_sys.h | 41-----------------------------------------
Msrc/htsky_log.c | 22++++++++++------------
Msrc/htsky_log.h | 6+++++-
Msrc/htsky_svx.c | 76+++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/htsky_svx.h | 4++--
15 files changed, 270 insertions(+), 368 deletions(-)

diff --git a/README.md b/README.md @@ -23,7 +23,9 @@ on the [HTGOP](https://gitlab.com/meso-star/htgop/), [HTMie](https://gitlab.com/meso-star/htmie/), [RSys](https://gitlab.com/vaplv/rsys/) and -[Star-VX](https://gitlab.com/meso-star/star-vx/) libraries. +[Star-VX](https://gitlab.com/meso-star/star-vx/) libraries, and on +[OpenMP](http://www.openmp.org) 1.2 to parallelize its +computations. First ensure that CMake is installed on your system. Then install the RCMake package as well as the aforementioned prerequisites. Finally generate the diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -0,0 +1,101 @@ +# Copyright (C) 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/>. + +cmake_minimum_required(VERSION 2.8) +project(htsky C) +enable_testing() + +set(HTSKY_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src) +option(NO_TEST "Do not build tests" OFF) + +################################################################################ +# Check dependencies +################################################################################ +find_package(HTCP REQUIRED) +find_package(HTGOP REQUIRED) +find_package(HTMIE REQUIRED) +find_package(OpenMP 1.2 REQUIRED) +find_package(RCMake 0.3 REQUIRED) +find_package(RSys 0.7 REQUIRED) +find_package(StarVX REQUIRED) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) +include(rcmake) +include(rcmake_runtime) + +include_directories( + ${HTCP_INCLUDE_DIR} + ${HTGOP_INCLUDE_DIR} + ${HTMIE_INCLUDE_DIR} + ${RSys_INCLUDE_DIR} + ${StarVX_INCLUDE_DIR}) + +################################################################################ +# Configure and define targets +################################################################################ +set(VERSION_MAJOR 0) +set(VERSION_MINOR 0) +set(VERSION_PATCH 0) +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +set(HTSKY_FILES_SRC + htsky.c + htsky_atmosphere.c + htsky_cloud.c + htsky_dump_cloud_vtk.c + htsky_log.c + htsky_svx.c) +set(HTSKY_FILES_INC + htsky_c.h + htsky_atmosphere.h + htsky_cloud.h + htsky_log.h + htsky_svx.h) +set(HTSKY_FILES_INC_API htsky.h) + +set(HTSKY_FILES_DOC COPYING README.md) + +# 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}) +rcmake_prepend_path(HTSKY_FILES_INC_API ${HTSKY_SOURCE_DIR}) +rcmake_prepend_path(HTSKY_FILES_DOC ${PROJECT_SOURCE_DIR}/../) + +add_library(htsky SHARED ${HTSKY_FILES_SRC} ${HTSKY_FILES_INC} ${HTSKY_FILES_INC_API}) +target_link_libraries(htsky HTCP HTGOP HTMIE RSys StarVX) + +if(CMAKE_COMPILER_IS_GNUCC) + target_link_libraries(htsky m) + set_target_properties(htsky PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}") +endif() + +set_target_properties(htsky PROPERTIES + COMPILE_FLAGS "${OpenMP_C_FLAGS}" + DEFINE_SYMBOL HTSKY_SHARED_BUILD + VERSION ${VERSION} + SOVERSION ${VERSION_MAJOR}) + +rcmake_setup_devel(htsky HTSky ${VERSION} high_tune/htsky_version.h) + +################################################################################ +# Define output & install directories +################################################################################ +install(TARGETS htsky + ARCHIVE DESTINATION bin + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) +install(FILES ${HTGOP_FILES_INC_API} DESTINATION include/high_tune) +install(FILES ${HTGOP_FILES_DOC} DESTINATION share/doc/htsky) + diff --git a/src/htsky.c b/src/htsky.c @@ -16,13 +16,20 @@ #include "htsky.h" #include "htsky_c.h" +#include "htsky_atmosphere.h" +#include "htsky_cloud.h" +#include "htsky_log.h" -#include <star/svx.h> #include <high_tune/htcp.h> #include <high_tune/htgop.h> #include <high_tune/htmie.h> +#include <star/svx.h> + #include <rsys/clock_time.h> +#include <rsys/double3.h> + +#include <omp.h> /******************************************************************************* * Helper function @@ -40,7 +47,7 @@ check_args(const struct htsky_args* args) } static res_T -setup_sw_bands_properties(struct hsky* sky) +setup_sw_bands_properties(struct htsky* sky) { res_T res = RES_OK; size_t nbands; @@ -114,8 +121,8 @@ release_sky(ref_T* ref) struct htsky* sky; ASSERT(ref); sky = CONTAINER_OF(ref, struct htsky, ref); - clean_clouds(sky); - clean_atmosphere(sky); + cloud_clean(sky); + atmosphere_clean(sky); if(sky->svx) SVX(device_ref_put(sky->svx)); if(sky->htcp) HTCP(ref_put(sky->htcp)); if(sky->htgop) HTGOP(ref_put(sky->htgop)); @@ -133,7 +140,6 @@ htsky_create (struct logger* logger, /* NULL <=> use default logger */ struct mem_allocator* mem_allocator, /* NULL <=> use default allocator */ const struct htsky_args* args, - const int verbose, struct htsky** out_sky) { struct time t0, t1; @@ -149,12 +155,12 @@ htsky_create } allocator = mem_allocator ? mem_allocator : &mem_default_allocator; - sky = MEM_CALLOC(allocator, sizeof(*sky)); + sky = MEM_CALLOC(allocator, 1, sizeof(*sky)); if(!sky) { - if(verbose) { + if(args->verbose) { #define ERR_STR "Could not allocate the HTSky data structure.\n" if(logger) { - logger_print(logger, LOG_ERR, ERR_STR); + logger_print(logger, LOG_ERROR, ERR_STR); } else { fprintf(stderr, MSG_ERROR_PREFIX ERR_STR); } @@ -166,7 +172,7 @@ htsky_create nthreads_max = MMAX(omp_get_max_threads(), omp_get_num_procs()); ref_init(&sky->ref); sky->allocator = allocator; - sky->verbose = verbose; + 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); @@ -177,11 +183,11 @@ htsky_create if(logger) { sky->logger = logger; } else { - setup_log_default(htsky); + setup_log_default(sky); } /* Setup an allocator specific to the SVX library */ - res = mem_init_proxy_allocator(&sky->svx_allocator, svx->allocator); + 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; @@ -196,7 +202,7 @@ htsky_create } /* Load the gas optical properties */ - res = htgop_create(&sky->logger, sky->allocator, sky->verbose, &sky->htgop); + 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; @@ -223,20 +229,20 @@ htsky_create /* Nothing more to do */ if(!sky->is_cloudy) goto exit; - if(!sky->htmie_filename) { + if(!args->htmie_filename) { log_err(sky, "missing the HTMie filename.\n"); res = RES_BAD_ARG; goto error; } - if(!sky->htcp_filename) { + 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); + 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; @@ -251,7 +257,7 @@ htsky_create if(res != RES_OK) goto error; /* Load clouds properties */ - res = htcp_create(&sky->logger, sky->allocator, sky->verbose, &sky->htcp); + 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; @@ -264,15 +270,14 @@ htsky_create } time_current(&t0); - res = cloud_setup(sky, args->htcp_filename, args->htgop_filename, - args->htmie_filename, args->optical_thickness); + res = cloud_setup(sky, args->grid_max_definition, 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 clouds in %s\n", buf); if(sky->verbose) { - log_svx_memory_usage(htsky); + log_svx_memory_usage(sky); } exit: diff --git a/src/htsky.h b/src/htsky.h @@ -18,6 +18,8 @@ #define HTSKY_H #include <rsys/rsys.h> +#include <star/svx.h> +#include <limits.h> /* UINT_MAX support */ /* Library symbol management */ #if defined(HTSKY_SHARED_BUILD) /* Build shared library */ @@ -36,7 +38,7 @@ enum htsky_property { HTSKY_Ks, /* Scattering coefficient */ - HTSLY_Ka, /* Absorption coefficient */ + HTSKY_Ka, /* Absorption coefficient */ HTSKY_Kext, /* Extinction coefficient = Ks + Ka */ HTSKY_PROPS_COUNT__ }; @@ -51,8 +53,8 @@ enum htsky_component { /* Component of the sky for which the properties are queried */ enum htrdr_sky_component_flag { HTSKY_CPNT_FLAG_GAS = BIT(HTSKY_CPNT_GAS), - HTSKY_CPNT_FLAG_PARTICLES = BIT(HTSKY__CPNT_PARTICLES), - HTSKY_CPNT_MASK_ALL = HTRDR_CPNT_FLAG_GAS | HTSKY_CPNT_FLAG_PARTICLES + HTSKY_CPNT_FLAG_PARTICLES = BIT(HTSKY_CPNT_PARTICLES), + HTSKY_CPNT_MASK_ALL = HTSKY_CPNT_FLAG_GAS | HTSKY_CPNT_FLAG_PARTICLES }; enum htsky_svx_op { @@ -78,12 +80,21 @@ struct htsky_args { NULL, /* htmie filename */ \ {UINT_MAX, UINT_MAX, UINT_MAX}, /* Maximum definition of the grid */ \ 1, /* Optical thickness a*/ \ - (unsigned)~0, /* #threads */, \ + (unsigned)~0, /* #threads */ \ 0, /* Repeat clouds */ \ 0, /* Verbosity level */ \ } static const struct htsky_args HTSKY_ARGS_DEFAULT = HTSKY_ARGS_DEFAULT__; +/* Forward declarations of external data types */ +struct logger; +struct mem_allocator; +struct ssp_rng; +struct svx_voxel; + +/* Opaque data type */ +struct htsky; + BEGIN_DECLS /******************************************************************************* @@ -142,6 +153,19 @@ htsky_fetch_svx_voxel_property const size_t iquad, /* Index of the quadrature point in the spectral band */ const struct svx_voxel* voxel); +HTSKY_API res_T +htsky_trace_ray + (struct htsky* sky, + const double org[3], + const double dir[3], /* Must be normalized */ + const double range[2], + const svx_hit_challenge_T challenge, /* NULL <=> Traversed up to the leaves */ + const svx_hit_filter_T filter, /* NULL <=> Stop RT at the 1st hit voxel */ + void* context, /* Data sent to the filter functor */ + const size_t ispectral_band, + const size_t iquadrature_pt, + struct svx_hit* hit); + HTSKY_API size_t htsky_get_sw_spectral_bands_count (const struct htsky* sky); @@ -165,26 +189,29 @@ htsky_get_sw_spectral_band_bounds HTSKY_API void htsky_sample_sw_spectral_data_CIE_1931_X (const struct htsky* sky, - struct ssp_rng* rng, + const double r0, /* Random number in [0, 1[ */ + const double r1, /* Random number in [0, 1[ */ size_t* ispectral_band, size_t* iquadrature_pt); HTSKY_API void htsky_sample_sw_spectral_data_CIE_1931_Y (const struct htsky* sky, - struct ssp_rng* rng, + const double r0, /* Random number in [0, 1[ */ + const double r1, /* Random number in [0, 1[ */ size_t* ispectral_band, size_t* iquadrature_pt); HTSKY_API void htsky_sample_sw_spectral_data_CIE_1931_Z (const struct htsky* sky, - struct ssp_rng* rng, + const double r0, /* Random number in [0, 1[ */ + const double r1, /* Random number in [0, 1[ */ size_t* ispectral_band, size_t* iquadrature_pt); HTSKY_API res_T -htsky_dump_clouds_vtk +htsky_dump_cloud_vtk (const struct htsky* sky, const size_t iband, /* Index of the spectral band */ const size_t iquad, /* Index of the quadrature point */ diff --git a/src/htsky_atmosphere.c b/src/htsky_atmosphere.c @@ -18,6 +18,7 @@ #include "htsky_c.h" #include "htsky_atmosphere.h" +#include "htsky_log.h" #include "htsky_svx.h" #include <high_tune/htgop.h> @@ -106,18 +107,18 @@ atmosphere_vox_merge const size_t nvoxs, void* ctx) { - ASSERT(dst && voxels && nvoxs); + ASSERT(dst && voxs && nvoxs); (void)ctx; vox_merge_component(dst, HTSKY_CPNT_GAS, (const float**)voxs, nvoxs); } static int atmosphere_vox_challenge_merge - (const struct svx_voxel voxs[] + (const struct svx_voxel voxs[], const size_t nvoxs, void* ctx) { - ASSERT(voxels); + ASSERT(voxs); return vox_challenge_merge_component(HTSKY_CPNT_GAS, voxs, nvoxs, ctx); } diff --git a/src/htsky_c.h b/src/htsky_c.h @@ -57,7 +57,7 @@ struct sw_band_prop { double g_avg; }; -struct htrdr_sky { +struct htsky { struct cloud** clouds; /* Per sw_band cloud data structure */ /* Per sw_band and per quadrature point atmosphere data structure */ diff --git a/src/htsky_cloud.c b/src/htsky_cloud.c @@ -16,9 +16,12 @@ #define _POSIX_C_SOURCE 200809L /* nextafterf */ +#include "htsky_c.h" #include "htsky_cloud.h" +#include "htsky_log.h" #include "htsky_svx.h" +#include <high_tune/htgop.h> #include <rsys/dynamic_array.h> #include <star/svx.h> @@ -443,13 +446,10 @@ cloud_vox_challenge_merge /******************************************************************************* * Local functions ******************************************************************************/ -static res_T +res_T cloud_setup (struct htsky* sky, - const char* htcp_filename, - const char* htgop_filename, - const char* htmie_filename, - const double grid_max_definition[3], + const unsigned grid_max_definition[3], const double optical_thickness_threshold) { struct darray_specdata specdata; @@ -653,7 +653,7 @@ exit: darray_specdata_release(&specdata); return (res_T)res; error: - clean_clouds(sky); + cloud_clean(sky); darray_split_clear(&sky->svx2htcp_z); goto exit; } diff --git a/src/htsky_cloud.h b/src/htsky_cloud.h @@ -29,9 +29,7 @@ struct cloud { extern LOCAL_SYM res_T cloud_setup (struct htsky* sky, - const char* htcp_filename, - const char* htgop_filename, - const char* htmie_filename, + const unsigned grid_max_definition[3], const double optical_thickness_threshold); extern LOCAL_SYM void diff --git a/src/htsky_dump_cloud_vtk.c b/src/htsky_dump_cloud_vtk.c @@ -16,10 +16,13 @@ #include "htsky.h" #include "htsky_c.h" +#include "htsky_log.h" +#include "htsky_cloud.h" #include <high_tune/htgop.h> #include <rsys/dynamic_array_double.h> +#include <rsys/dynamic_array_size_t.h> #include <rsys/hash_table.h> #include <star/svx.h> @@ -133,7 +136,7 @@ register_leaf kext_max = htsky_fetch_svx_voxel_property(ctx->sky, HTSKY_Kext, HTSKY_SVX_MAX, HTSKY_CPNT_MASK_ALL, ctx->iband, ctx->iquad, leaf); kext_min = htsky_fetch_svx_voxel_property(ctx->sky, HTSKY_Kext, - HTSKY_SVX_MIN, HTSKY_ALL_COMPONENTS, ctx->iband, ctx->iquad, leaf); + HTSKY_SVX_MIN, HTSKY_CPNT_MASK_ALL, ctx->iband, ctx->iquad, leaf); CHK(RES_OK == darray_double_push_back(&ctx->data, &kext_min)); CHK(RES_OK == darray_double_push_back(&ctx->data, &kext_max)); } @@ -155,9 +158,32 @@ htsky_dump_cloud_vtk size_t nvertices; size_t ncells; size_t i; - ASSERT(sky && stream); - ASSERT(iband >= sky->sw_bands_range[0]); - ASSERT(iband <= sky->sw_bands_range[1]); + res_T res = RES_OK; + + if(!sky || !stream) { + res = RES_BAD_ARG; + goto error; + } + + if(iband >= sky->sw_bands_range[0] && iband <= sky->sw_bands_range[1]) { + log_err(sky, + "%s: invalid spectral band index `%lu'. " + "Valid short wave spectral bands lie in [%lu, %lu]\n", + FUNC_NAME, + (unsigned long)iband, + (unsigned long)sky->sw_bands_range[0], + (unsigned long)sky->sw_bands_range[1]); + res = RES_BAD_ARG; + goto error; + } + + if(iquad >= htsky_get_sw_spectral_band_quadrature_length(sky, iband)) { + log_err(sky, + "invalid quadrature point `%lu' for the spectral band `%lu'.\n", + (unsigned long)iquad, (unsigned long)iband); + res = RES_BAD_ARG; + goto error; + } if(!sky->is_cloudy) { log_warn(sky, "%s: the sky has no cloud.\n", FUNC_NAME); @@ -224,6 +250,10 @@ htsky_dump_cloud_vtk fprintf(stream, "%g %g\n", leaf_data[i*2+0], leaf_data[i*2+1]); } octree_data_release(&data); - return RES_OK; + +exit: + return res; +error: + goto exit; } diff --git a/src/htsky_file_sys.c b/src/htsky_file_sys.c @@ -1,233 +0,0 @@ -/* 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 200809L /* O_DIRECTORY support */ - -#include "htsky_c.h" -#include "htsky_file_sys.h" - -#include <rsys/str.h> - -#include <errno.h> -#include <fcntl.h> /* open */ -#include <libgen.h> /* basename */ -#include <sys/stat.h> /* S_IRUSR & S_IWUSR */ -#include <sys/time.h> /* timespec */ -#include <unistd.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static res_T -open_file_stamp - (struct htsky* sky, - const char* filename, - struct stat* out_stat, /* Stat of the submitted filename */ - int* out_fd, /* Descriptor of the opened file. Must be closed by the caller */ - struct str* stamp_filename) -{ - struct stat statbuf; - struct str str; - int err; - int fd = -1; - res_T res = RES_OK; - ASSERT(sky && filename && out_fd && out_stat && stamp_filename); - - str_init(sky->allocator, &str); - - err = stat(filename, &statbuf); - if(err) { - log_err(sky, "%s: could not stat the file -- %s.\n", - filename, strerror(errno)); - res = RES_IO_ERR; - goto error; - } - - if(!S_ISREG(statbuf.st_mode)) { - log_err(sky, "%s: not a regular file.\n", filename); - res = RES_IO_ERR; - goto error; - } - - res = create_directory(sky, ".htsky/"); - if(res != RES_OK) goto error; - - #define CHK_STR(Func, ErrMsg) { \ - res = str_##Func; \ - if(res != RES_OK) { \ - htrdr_log_err(htrdr, "%s: "ErrMsg"\n", filename); \ - goto error; \ - } \ - } (void)0 - CHK_STR(set(&str, filename), "could not copy the filename"); - CHK_STR(set(&str, basename(str_get(&str))), "could not setup the basename"); - CHK_STR(insert(&str, 0, ".htsky/"), "could not setup the stamp directory"); - CHK_STR(append(&str, ".stamp"), "could not setup the stamp extension"); - #undef CHK_STR - - fd = open(str_cget(&str), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); - if(fd < 0) { - log_err(sky, "%s: could not open/create the file -- %s.\n", - str_cget(&str), strerror(errno)); - res = RES_IO_ERR; - goto error; - } - - CHK(str_copy_and_clear(stamp_filename, &str) == RES_OK); - -exit: - str_release(&str); - *out_fd = fd; - *out_stat = statbuf; - return res; -error: - if(fd >= 0) { - CHK(close(fd) == 0); - fd = -1; - } - goto exit; -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -is_file_updated(struct htsky* sky, const char* filename, int* out_upd) -{ - struct str stamp_filename; - struct stat statbuf; - ssize_t n; - off_t size; - struct timespec mtime; - int fd = -1; - int upd = 1; - res_T res = RES_OK; - ASSERT(sky && filename && out_upd); - - str_init(sky->allocator, &stamp_filename); - - res = open_file_stamp(sky, filename, &statbuf, &fd, &stamp_filename); - if(res != RES_OK) goto error; - - n = read(fd, &mtime, sizeof(mtime)); - if(n < 0) { - log_err(sky, "%s: could not read the `mtime' data of the file -- %s.\n", - str_cget(&stamp_filename), strerror(errno)); - res = RES_IO_ERR; - goto error; - } - - upd = (size_t)n != sizeof(mtime) - || mtime.tv_nsec != statbuf.st_mtim.tv_nsec - || mtime.tv_sec != statbuf.st_mtim.tv_sec; - - if(!upd) { - n = read(fd, &size, sizeof(size)); - if(n < 0) { - log_err(sky, "%s: could not read the `size' data -- %s.\n", - str_cget(&stamp_filename), strerror(errno)); - res = RES_IO_ERR; - goto error; - } - upd = (size_t)n != sizeof(size) || statbuf.st_size != size; - } - -exit: - *out_upd = upd; - str_release(&stamp_filename); - if(fd >= 0) CHK(close(fd) == 0); - return res; -error: - goto exit; -} - -res_T -update_file_stamp(struct htsky* sky, const char* filename) -{ - struct str stamp_filename; - struct stat statbuf; - int fd = -1; - ssize_t n; - res_T res = RES_OK; - ASSERT(sky && filename); - - str_init(sky->allocator, &stamp_filename); - - res = open_file_stamp(sky, filename, &statbuf, &fd, &stamp_filename); - if(res != RES_OK) goto error; - - #define CHK_IO(Func, ErrMsg) { \ - if((Func) < 0) { \ - log_err(sky, "%s: "ErrMsg" -- %s.\n", \ - str_cget(&stamp_filename), strerror(errno)); \ - res = RES_IO_ERR; \ - goto error; \ - } \ - } (void) 0 - - CHK_IO(lseek(fd, 0, SEEK_SET), "could not rewind the file descriptor"); - - /* NOTE: Ignore n >=0 but != sizeof(DATA). In such case stamp is currupted - * and on the next invocation on the same filename, this function will - * return 1 */ - n = write(fd, &statbuf.st_mtim, sizeof(statbuf.st_mtim)); - CHK_IO(n, "could not update the `mtime' data"); - n = write(fd, &statbuf.st_size, sizeof(statbuf.st_size)); - CHK_IO(n, "could not update the `size' data"); - - CHK_IO(fsync(fd), "could not sync the file with storage device"); - - #undef CHK_IO - -exit: - str_release(&stamp_filename); - if(fd >= 0) CHK(close(fd) == 0); - return res; -error: - goto exit; -} - -res_T -create_directory(struct htsky* sky, const char* path) -{ - res_T res = RES_OK; - int err; - ASSERT(sky && path); - - err = mkdir(path, S_IRWXU); - if(!err) goto exit; - - if(errno != EEXIST) { - log_err(sky, "cannot create the `%s' directory -- %s.\n", - path, strerror(errno)); - res = RES_IO_ERR; - goto error; - } else { - const int fd = open(path, O_DIRECTORY); - if(fd < -1) { - log_err(sky, "cannot open the `%s' directory -- %s.\n", - path, strerror(errno)); - res = RES_IO_ERR; - goto error; - } - CHK(!close(fd)); - } -exit: - return res; -error: - goto exit; -} - diff --git a/src/htsky_file_sys.h b/src/htsky_file_sys.h @@ -1,41 +0,0 @@ -/* 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_FILE_SYS_H -#define HTSKY_FILE_SYS_H - -#include <rsys/rsys.h> - -struct htsky; - -extern LOCAL_SYM res_T -is_file_updated - (struct htsky* sky, - const char* filename, - int* is_upd); - -extern LOCAL_SYM res_T -update_file_stamp - (struct htsky* sky, - const char* filename); - -extern LOCAL_SYM res_T -create_directory - (struct htsky* sky, - const char* path); - -#endif /* HTSKY_FILE_SYS_H */ - diff --git a/src/htsky_log.c b/src/htsky_log.c @@ -14,6 +14,8 @@ * 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 /* snprintf support */ + #include "htsky_c.h" #include "htsky_log.h" @@ -21,24 +23,20 @@ #include <stdarg.h> -#define MSG_INFO_PREFIX "HTSky:\x1b[1m\x1b[32minfo\x1b[0m: " -#define MSG_ERROR_PREFIX "HTSky:\x1b[1m\x1b[31merror\x1b[0m: " -#define MSG_WARNING_PREFIX "HTSky:\x1b[1m\x1b[33mwarning\x1b[0m: " - /******************************************************************************* * Helper functions ******************************************************************************/ static INLINE void log_msg - (const struct smtl* smtl, + (const struct htsky* sky, const enum log_type stream, const char* msg, va_list vargs) { - ASSERT(smtl && msg); - if(smtl->verbose) { + ASSERT(sky && msg); + if(sky->verbose) { res_T res; (void)res; - res = logger_vprint(smtl->logger, stream, msg, vargs); + res = logger_vprint(sky->logger, stream, msg, vargs); ASSERT(res == RES_OK); } } @@ -88,12 +86,12 @@ setup_log_default(struct htsky* sky) res = setup_default_logger(sky->allocator, &sky->logger__); if(res != RES_OK) { - if(verbose) { + if(sky->verbose) { fprintf(stderr, MSG_ERROR_PREFIX "could not setup the HTSky logger.\n"); } goto error; } - sky->logger = sky->logger__; + sky->logger = &sky->logger__; exit: return res; @@ -124,7 +122,7 @@ log_err(const struct htsky* sky, const char* msg, ...) } void -log_warn(const struct smtl* smtl, const char* msg, ...) +log_warn(const struct htsky* sky, const char* msg, ...) { va_list vargs_list; ASSERT(sky && msg); @@ -134,7 +132,7 @@ log_warn(const struct smtl* smtl, const char* msg, ...) va_end(vargs_list); } -static void +void log_svx_memory_usage(struct htsky* sky) { char dump[128]; diff --git a/src/htsky_log.h b/src/htsky_log.h @@ -19,6 +19,10 @@ #include <rsys/rsys.h> +#define MSG_INFO_PREFIX "HTSky:\x1b[1m\x1b[32minfo\x1b[0m: " +#define MSG_ERROR_PREFIX "HTSky:\x1b[1m\x1b[31merror\x1b[0m: " +#define MSG_WARNING_PREFIX "HTSky:\x1b[1m\x1b[33mwarning\x1b[0m: " + struct htsky; extern LOCAL_SYM res_T @@ -65,4 +69,4 @@ extern LOCAL_SYM void log_svx_memory_usage (struct htsky* sky); -#endif /* HTSKY_LOG_H * +#endif /* HTSKY_LOG_H */ diff --git a/src/htsky_svx.c b/src/htsky_svx.c @@ -14,22 +14,18 @@ * 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 /* nextafter */ + #include "htsky.h" #include "htsky_atmosphere.h" #include "htsky_c.h" #include "htsky_cloud.h" +#include "htsky_log.h" #include "htsky_svx.h" #include <star/svx.h> -struct trace_cloud_context { - struct svx_tree* clouds; - struct svx_hit* hit; - svx_hit_challenge_T challenge; - svx_hit_filter_T filter; - void* context; -}; -static const struct trace_cloud_context TRACE_CLOUD_CONTEXT_NULL; +#include <math.h> /******************************************************************************* * Helper functions @@ -98,11 +94,11 @@ infinite_cloudy_slab_trace_ray int64_t xy[2]; /* 2D index of the repeated cell */ int incr[2]; /* Index increment */ res_T res = RES_OK; - ASSERT(sky && clouds && org && dir && range && ctx && hit); + ASSERT(sky && clouds && org && dir && range && context && hit); ASSERT(range[0] < range[1]); cell_low = sky->htcp_desc.lower; - cell_upp = sky->htcp_decc.upper; + cell_upp = sky->htcp_desc.upper; /* Check that the ray intersects the slab */ t_min_z = (cell_low[2] - org[2]) / dir[2]; @@ -151,7 +147,6 @@ infinite_cloudy_slab_trace_ray org_cs[2] = org[2]; FOR_EACH(istep, 0, max_steps) { int iaxis; - int hit; /* Transform the ray origin in the local cell space */ org_cs[0] = org[0] - (double)xy[0]*cell_sz[0]; @@ -160,9 +155,8 @@ infinite_cloudy_slab_trace_ray res = svx_tree_trace_ray (clouds, org_cs, dir, range, challenge, filter, context, hit); if(res != RES_OK) { - log_err(sky, - "%s: could not trace the ray in the repeated cells -- %s.\n", - FUNC_NAME, res_to_cstr(res)); + log_err(sky,"%s: could not trace the ray in the repeated cloud.\n", + FUNC_NAME); goto error; } if(!SVX_HIT_NONE(hit)) goto exit; @@ -213,6 +207,7 @@ htsky_fetch_svx_property ASSERT(comp_mask & HTSKY_CPNT_MASK_ALL); ASSERT(iband >= sky->sw_bands_range[0]); ASSERT(iband <= sky->sw_bands_range[1]); + ASSERT(iquad < htsky_get_sw_spectral_band_quadrature_length(sky, iband)); i = iband - sky->sw_bands_range[0]; cloud = sky->is_cloudy ? &sky->clouds[i][iquad] : NULL; @@ -269,7 +264,7 @@ htsky_fetch_svx_voxel_property const enum htsky_property prop, const enum htsky_svx_op op, const int components_mask, - const size_t ispectral_band, /* Index of the spectral band */ + const size_t iband, /* Index of the spectral band */ const size_t iquad, /* Index of the quadrature point in the spectral band */ const struct svx_voxel* voxel) { @@ -277,9 +272,9 @@ htsky_fetch_svx_voxel_property double par = 0; int comp_mask = components_mask; ASSERT(sky && voxel); - ASSERT((unsigned)prop < HTSKY_PROPERTIES_COUNT__); + ASSERT((unsigned)prop < HTSKY_PROPS_COUNT__); ASSERT((unsigned)op < HTSKY_SVX_OPS_COUNT__); - (void)sky, (void)ispectral_band, (void)iquad; + (void)sky, (void)iband, (void)iquad; /* Check if the voxel has infinite bounds/degenerated. In such case it is * atmospheric voxel with only gas properties */ @@ -306,24 +301,46 @@ htsky_trace_ray const svx_hit_challenge_T challenge, /* NULL <=> Traversed up to the leaves */ const svx_hit_filter_T filter, /* NULL <=> Stop RT at the 1st hit voxel */ void* context, /* Data sent to the filter functor */ - const size_t ispectral_band, - const size_t iquadrature_pt, + const size_t iband, + const size_t iquad, struct svx_hit* hit) { double cloud_range[2]; struct svx_tree* clouds; struct svx_tree* atmosphere; size_t i; + enum { AXIS_X = BIT(0), AXIS_Y = BIT(1), AXIS_Z = BIT(2) }; res_T res = RES_OK; - ASSERT(sky); - ASSERT(ispectral_band >= sky->sw_bands_range[0]); - ASSERT(ispectral_band <= sky->sw_bands_range[1]); - (void)iquadrature_pt; + + if(!sky || !org || !dir || !range || !hit) { + res = RES_BAD_ARG; + goto error; + } + + if(iband >= sky->sw_bands_range[0] && iband <= sky->sw_bands_range[1]) { + log_err(sky, + "%s: invalid spectral band index `%lu'. " + "Valid short wave spectral bands lie in [%lu, %lu]\n", + FUNC_NAME, + (unsigned long)iband, + (unsigned long)sky->sw_bands_range[0], + (unsigned long)sky->sw_bands_range[1]); + res = RES_BAD_ARG; + goto error; + } + + if(iquad >= htsky_get_sw_spectral_band_quadrature_length(sky, iband)) { + log_err(sky, + "invalid quadrature point `%lu' for the spectral band `%lu'.\n", + (unsigned long)iquad, (unsigned long)iband); + res = RES_BAD_ARG; + goto error; + } /* Fetch the clouds/atmosphere corresponding to the submitted spectral data */ - i = ispectral_band - sky->sw_bands_range[0]; - clouds = sky->is_cloudy ? sky->clouds[i][iquadrature_pt].octree : NULL; - atmosphere = sky->atmosphere[i][iquadrature_pt].bitree; + i = iband - sky->sw_bands_range[0]; + clouds = sky->is_cloudy ? sky->clouds[i][iquad].octree : NULL; + atmosphere = sky->atmosphere[i][iquad].bitree; cloud_range[0] = INF; cloud_range[1] =-INF; @@ -381,13 +398,6 @@ htsky_trace_ray /* Clouds are infinitely repeated along the X and Y axis */ } else { - struct trace_cloud_context slab_ctx = TRACE_CLOUD_CONTEXT_NULL; - - slab_ctx.clouds = clouds; - slab_ctx.challenge = challenge; - slab_ctx.filter = filter; - slab_ctx.context = context; - slab_ctx.hit = hit; res = infinite_cloudy_slab_trace_ray(sky, clouds, org, dir, cloud_range, 32, challenge, filter, context, hit); diff --git a/src/htsky_svx.h b/src/htsky_svx.h @@ -46,7 +46,7 @@ #define NFLOATS_PER_CPNT (HTSKY_SVX_OPS_COUNT__ * HTSKY_PROPS_COUNT__) /* Constant defining the overall number of floating point data of a voxel */ -#define NFLOATS_PER_VOXEL (NFLOATS_PER_CPNT * HTSY_CPNTS_COUNT__) +#define NFLOATS_PER_VOXEL (NFLOATS_PER_CPNT * HTSKY_CPNTS_COUNT__) /* Context used to build the SVX hierarchical data structures */ struct build_tree_context { @@ -117,7 +117,7 @@ vox_merge_component static INLINE int vox_challenge_merge_component - (const enum htrdr_sky_component comp, + (const enum htsky_component comp, const struct svx_voxel voxels[], const size_t nvoxs, struct build_tree_context* ctx)