commit 7d8b46e70367b8b09174d1a3ea8f6c68893c2441
parent 24411e5ac1dcd821281c7218960c6c1cde261da9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sat, 21 Jan 2017 14:55:54 +0100
Add a "Solver Sun" to Solstice
Diffstat:
6 files changed, 254 insertions(+), 1 deletion(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -87,7 +87,8 @@ set(SOLSTICE_FILES_SRC
solstice_entity.c
solstice_material.c
solstice_node.c
- solstice_object.c)
+ solstice_object.c
+ solstice_sun.c)
set(SOLSTICE_FILES_INC
solstice.h
solstice_args.h.in
diff --git a/src/solstice.c b/src/solstice.c
@@ -404,6 +404,14 @@ solstice_init
goto error;
}
+ res = solstice_create_sun(solstice);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not setup the Solstice sun.\n");
+ goto error;
+ }
+
+ solstice->nrealisations = args->nrealisations;
+
exit:
return res;
error:
@@ -421,6 +429,7 @@ solstice_release(struct solstice* solstice)
/* Don't clear pivots, as they are cleared from some root */
if(solstice->ssol) SSOL(device_ref_put(solstice->ssol));
if(solstice->scene) SSOL(scene_ref_put(solstice->scene));
+ if(solstice->sun) SSOL(sun_ref_put(solstice->sun));
if(solstice->parser) solparser_ref_put(solstice->parser);
if(solstice->camera) SSOL(camera_ref_put(solstice->camera));
if(solstice->framebuffer) SSOL(image_ref_put(solstice->framebuffer));
diff --git a/src/solstice.h b/src/solstice.h
@@ -64,6 +64,7 @@ struct solstice_receiver {
struct solstice {
struct ssol_device* ssol;
struct ssol_scene* scene;
+ struct ssol_sun* sun;
struct solparser* parser;
@@ -80,6 +81,7 @@ struct solstice {
struct darray_double sun_dirs; /* List of double3 */
+ size_t nrealisations; /* # realisations */
FILE* output; /* Output stream */
struct mem_allocator* allocator;
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -326,6 +326,12 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv)
}
}
+ if(!args->rendering && !args->nsun_dirs) {
+ fprintf(stderr, "Missing sun direction.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
if(optind < argc) {
args->input_filename = argv[optind];
}
diff --git a/src/solstice_c.h b/src/solstice_c.h
@@ -46,6 +46,10 @@ solstice_draw
(struct solstice* solstice);
extern LOCAL_SYM res_T
+solstice_create_sun
+ (struct solstice* solstice);
+
+extern LOCAL_SYM res_T
solstice_setup_entities
(struct solstice* solstice);
diff --git a/src/solstice_sun.c b/src/solstice_sun.c
@@ -0,0 +1,231 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * 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/>. */
+
+#include "solstice_c.h"
+#include "parser/solparser.h"
+#include "parser/solparser_sun.h"
+
+#include <solstice/ssol.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+create_sun_buie
+ (struct solstice* solstice,
+ const struct solparser_sun* solparser_sun,
+ struct ssol_sun** out_sun)
+{
+ struct ssol_sun* sun = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && solparser_sun && out_sun);
+ ASSERT(solparser_sun->radang_distrib_type == SOLPARSER_SUN_RADANG_DISTRIB_BUIE);
+
+ res = ssol_sun_create_buie(solstice->ssol, &sun);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the solver buie sun.\n");
+ goto error;
+ }
+
+ res = ssol_sun_set_buie_param(sun, solparser_sun->radang_distrib.buie.csr);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could setup the buie parameter of the solver sun.\n");
+ goto error;
+ }
+
+exit:
+ *out_sun = sun;
+ return res;
+error:
+ if(sun) {
+ SSOL(sun_ref_put(sun));
+ sun = NULL;
+ }
+ goto exit;
+}
+
+static res_T
+create_sun_dir
+ (struct solstice* solstice,
+ const struct solparser_sun* solparser_sun,
+ struct ssol_sun** out_sun)
+{
+ struct ssol_sun* sun = NULL;
+ res_T res = RES_OK;
+ (void)solparser_sun;
+ ASSERT(solstice && solparser_sun && out_sun);
+ ASSERT(solparser_sun->radang_distrib_type
+ == SOLPARSER_SUN_RADANG_DISTRIB_DIRECTIONAL);
+
+ res = ssol_sun_create_directional(solstice->ssol, &sun);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the solver directional sun.\n");
+ goto error;
+ }
+
+exit:
+ *out_sun = sun;
+ return res;
+error:
+ if(sun) {
+ SSOL(sun_ref_put(sun));
+ sun = NULL;
+ }
+ goto exit;
+}
+
+static res_T
+create_sun_pillbox
+ (struct solstice* solstice,
+ const struct solparser_sun* solparser_sun,
+ struct ssol_sun** out_sun)
+{
+ struct ssol_sun* sun = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && solparser_sun && out_sun);
+ ASSERT(solparser_sun->radang_distrib_type
+ == SOLPARSER_SUN_RADANG_DISTRIB_PILLBOX);
+
+ res = ssol_sun_create_pillbox(solstice->ssol, &sun);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the solver pillbox sun.\n");
+ goto error;
+ }
+
+ res = ssol_sun_set_pillbox_aperture
+ (sun, solparser_sun->radang_distrib.pillbox.aperture);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not setup the aperture of the solver pillbox sun.\n");
+ goto error;
+ }
+
+exit:
+ *out_sun = sun;
+ return res;
+error:
+ if(sun) {
+ SSOL(sun_ref_put(sun));
+ sun = NULL;
+ }
+ goto exit;
+}
+
+static void
+get_wavelength(const size_t i, double* wlen, double* data, void* ctx)
+{
+ const struct solparser_spectrum_data* specdata = ctx;
+ ASSERT(wlen && data && ctx);
+ *wlen = specdata[i].wavelength;
+ *data = specdata[i].data;
+}
+
+static res_T
+create_sun_spectrum
+ (struct solstice* solstice,
+ const struct solparser_sun* solparser_sun,
+ struct ssol_spectrum** out_spectrum)
+{
+ struct ssol_spectrum* spectrum = NULL;
+ const struct solparser_spectrum_data* data;
+ size_t nwlens;
+ res_T res = RES_OK;
+ ASSERT(solstice && solparser_sun && out_spectrum);
+
+ res = ssol_spectrum_create(solstice->ssol, &spectrum);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the spectrum of the solver sun.\n");
+ goto error;
+ }
+
+ nwlens = darray_spectrum_data_size_get(&solparser_sun->spectrum);
+ data = darray_spectrum_data_cdata_get(&solparser_sun->spectrum);
+ res = ssol_spectrum_setup(spectrum, get_wavelength, nwlens, (void*)data);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could no setup the spectrum of the solver sun.\n");
+ goto error;
+ }
+
+exit:
+ *out_spectrum = spectrum;
+ return res;
+error:
+ if(spectrum) {
+ SSOL(spectrum_ref_put(spectrum));
+ spectrum = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+ * Local function
+ ******************************************************************************/
+res_T
+solstice_create_sun(struct solstice* solstice)
+{
+ struct ssol_sun* sun = NULL;
+ struct ssol_spectrum* spectrum = NULL;
+ const struct solparser_sun* solparser_sun = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice);
+
+ solparser_sun = solparser_get_sun(solstice->parser);
+ switch(solparser_sun->radang_distrib_type) {
+ case SOLPARSER_SUN_RADANG_DISTRIB_BUIE:
+ res = create_sun_buie(solstice, solparser_sun, &sun);
+ break;
+ case SOLPARSER_SUN_RADANG_DISTRIB_DIRECTIONAL:
+ res = create_sun_dir(solstice, solparser_sun, &sun);
+ break;
+ case SOLPARSER_SUN_RADANG_DISTRIB_PILLBOX:
+ res = create_sun_pillbox(solstice, solparser_sun, &sun);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ if(res != RES_OK) goto error;
+
+ res = create_sun_spectrum(solstice, solparser_sun, &spectrum);
+ if(res != RES_OK) goto error;
+
+ res = ssol_sun_set_spectrum(sun, spectrum);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not attach the spectrum to the sun.\n");
+ goto error;
+ }
+
+ res = ssol_sun_set_dni(sun, solparser_sun->dni);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not setup the DNI of the sun.\n");
+ goto error;
+ }
+
+ res = ssol_scene_attach_sun(solstice->scene, sun);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not attach the sun to the scene.\n");
+ goto error;
+ }
+
+exit:
+ if(spectrum) SSOL(spectrum_ref_put(spectrum));
+ solstice->sun = sun;
+ return res;
+error:
+ if(sun) {
+ SSOL(sun_ref_put(sun));
+ sun = NULL;
+ }
+
+ goto exit;
+}
+