commit 2c87a4cd52ce3b5cc896df367bc2138c32d73e4e
parent 49c064810e2be07d0f87677829521cb8380c85f1
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 3 May 2017 10:43:31 +0200
First commit for atmospheres.
Diffstat:
19 files changed, 377 insertions(+), 35 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -86,6 +86,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SOLSTICE_FILES_SRC
solstice.c
solstice_args.c
+ solstice_atmosphere.c
solstice_draw.c
solstice_dump.c
solstice_entity.c
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -31,6 +31,7 @@ include_directories(
################################################################################
set(SOLPARSER_FILES_SRC
solparser.c
+ solparser_atmosphere.c
solparser_entity.c
solparser_image.c
solparser_geometry.c
@@ -43,6 +44,7 @@ set(SOLPARSER_FILES_SRC
set(SOLPARSER_FILES_INC
solparser.h
solparser_c.h
+ solparser_atmosphere.h
solparser_entity.h
solparser_geometry.h
solparser_image.h
diff --git a/doc/input b/doc/input
@@ -83,6 +83,7 @@
<solar-factory> ::=
<sun>
<items>
+[ <atmosphere> ]
<items> ::=
- <item>
@@ -348,6 +349,11 @@
aperture: REAL # in ]0, 90]
#----------------------------------------
+<atmosphere> ::=
+ atmosphere:
+ absorption: <mtl-data> # in [0, 1]
+
+#----------------------------------------
<mtl-data> ::=
REAL | <spectrum-data-list>
@@ -380,4 +386,3 @@
<spectrum-data> ::=
wavelength: REAL # in [0, INF)
data: REAL # in [0, INF)
-
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -119,6 +119,7 @@ parse_item
struct solparser_material_double_sided_id mtl2;
struct solparser_medium_id medium;
struct solparser_sun* sun;
+ struct solparser_atmosphere* atmosphere;
yaml_node_t* key;
yaml_node_t* val;
@@ -148,7 +149,7 @@ parse_item
goto error;
}
- /* The parsing of the templates/spectraa is deferred to their explicit use */
+ /* The parsing of the templates/spectra is deferred to their explicit use */
if(!strcmp((char*)key->data.scalar.value, "material")) {
res = parse_material(parser, doc, val, &mtl2);
} else if(!strcmp((char*)key->data.scalar.value, "medium")) {
@@ -163,6 +164,8 @@ parse_item
res = parse_geometry(parser, doc, val, &geometry);
} else if(!strcmp((char*)key->data.scalar.value, "sun")) {
res = parse_sun(parser, doc, val, &sun);
+ } else if (!strcmp((char*)key->data.scalar.value, "atmosphere")) {
+ res = parse_atmosphere(parser, doc, val, &atmosphere);
} else if(!strcmp((char*)key->data.scalar.value, "spectrum")) { /* Deferred */
} else {
log_err(parser, key, "unknown item `%s'.\n", key->data.scalar.value);
@@ -1135,6 +1138,14 @@ solparser_get_sun(const struct solparser* parser)
return &parser->sun;
}
+const struct solparser_atmosphere*
+solparser_get_atmosphere(const struct solparser* parser)
+{
+ ASSERT(parser);
+ if(parser->sun_key) return &parser->atmosphere;
+ else return NULL;
+}
+
void
solparser_entity_iterator_begin
(struct solparser* parser,
diff --git a/src/parser/solparser.h b/src/parser/solparser.h
@@ -200,6 +200,10 @@ extern LOCAL_SYM const struct solparser_sun*
solparser_get_sun
(const struct solparser* parser);
+extern LOCAL_SYM const struct solparser_atmosphere*
+solparser_get_atmosphere
+ (const struct solparser* parser);
+
extern LOCAL_SYM const struct solparser_x_pivot*
solparser_get_x_pivot
(const struct solparser* parser,
diff --git a/src/parser/solparser_atmosphere.c b/src/parser/solparser_atmosphere.c
@@ -0,0 +1,118 @@
+/* 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/>. */
+
+#define _POSIX_C_SOURCE 200112L /* nextafter support */
+
+#include "solparser_c.h"
+#include <math.h> /* nextafter */
+
+/*******************************************************************************
+* Local function
+******************************************************************************/
+res_T
+parse_atmosphere
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ yaml_node_t* atm,
+ struct solparser_atmosphere** out_solatm)
+{
+ enum { ABSORPTION };
+ struct solparser_atmosphere* solatm = NULL;
+ int mask = 0; /* Register the parsed attributes */
+ intptr_t i, n;
+ res_T res = RES_OK;
+ ASSERT(doc && atm && out_solatm);
+
+ if(atm == parser->atmosphere_key) {
+ solatm = &parser->atmosphere;
+ goto exit;
+ } else if(parser->atmosphere_key != 0) {
+ log_err(parser, atm,
+ "an atmosphere is already defined. Previous definition is here %lu:%lu.\n",
+ (unsigned long)parser->atmosphere_key->start_mark.line + 1,
+ (unsigned long)parser->atmosphere_key->start_mark.column + 1);
+ res = RES_BAD_ARG;
+ goto error;
+ } else {
+ solatm = &parser->atmosphere;
+ parser->atmosphere_key = atm;
+ }
+
+ if(atm->type != YAML_MAPPING_NODE) {
+ log_err(parser, atm, "expect a mapping of atmosphere attributes.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ n = atm->data.mapping.pairs.top - atm->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, atm->data.mapping.pairs.start[i].value);
+ if(key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect an atmosphere parameter.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ #define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the "Name" of the atmosphere is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "absorption")) {
+ SETUP_MASK(ABSORPTION, "absorption");
+ res = parse_mtl_data
+ (parser, doc, val, 0, 1, &solatm->absorption);
+ } else {
+ log_err(parser, key, "unknown atmosphere parameter `%s'.\n",
+ key->data.scalar.value);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(res != RES_OK) {
+ log_node(parser, key);
+ goto error;
+ }
+ #undef SETUP_MASK
+ }
+
+ #define CHECK_PARAM(Flag, Name) \
+ if(!(mask & BIT(Flag))) { \
+ log_err(parser, atm, "the "Name" of the atmosphere is missing.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(ABSORPTION, "absorption");
+ #undef CHECK_PARAM
+
+exit:
+ *out_solatm = solatm;
+ return res;
+error:
+ if(solatm) {
+ solparser_atmosphere_clear(solatm);
+ solatm = NULL;
+ parser->atmosphere_key = 0;
+ }
+ solatm = NULL;
+ goto exit;
+}
+
diff --git a/src/parser/solparser_atmosphere.h b/src/parser/solparser_atmosphere.h
@@ -0,0 +1,49 @@
+/* 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/>. */
+
+#ifndef SOLPARSER_ATMOSPHERE_H
+#define SOLPARSER_ATMOSPHERE_H
+
+#include "solparser_mtl_data.h"
+
+struct solparser_atmosphere {
+ struct solparser_mtl_data absorption;
+};
+
+static INLINE void
+solparser_atmosphere_init
+ (struct mem_allocator* allocator, struct solparser_atmosphere* atmosphere)
+{
+ ASSERT(atmosphere);
+ (void)allocator;
+ /* Do nothing */
+}
+
+static INLINE void
+solparser_atmosphere_release(struct solparser_atmosphere* atmosphere)
+{
+ ASSERT(atmosphere);
+ (void)atmosphere;
+ /* Do nothing */
+}
+
+static INLINE void
+solparser_atmosphere_clear(struct solparser_atmosphere* atmosphere)
+{
+ ASSERT(atmosphere);
+ /* Do nothing */
+}
+#endif /* SOLPARSER_ATMOSPHERE_H */
+
diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h
@@ -17,6 +17,7 @@
#define SOLPARSER_C_H
#include "solparser.h"
+#include "solparser_atmosphere.h"
#include "solparser_entity.h"
#include "solparser_image.h"
#include "solparser_material.h"
@@ -265,6 +266,11 @@ struct solparser {
const yaml_node_t* sun_key; /* yaml_node_t ptr used to spawn the sun */
struct solparser_sun sun; /* The loaded sun */
+ /* Atmosphere. Note that at most one atmosphere is supported */
+ const yaml_node_t* atmosphere_key;
+ /* yaml_node_t ptr used to spawn the atmosphere; can be NULL */
+ struct solparser_atmosphere atmosphere; /* The loaded atmosphere, if any */
+
/* Entity */
struct htable_str2sols str2entities;
struct darray_entity entities;
@@ -438,6 +444,13 @@ parse_sun
struct solparser_sun** out_solsun);
extern LOCAL_SYM res_T
+parse_atmosphere
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ yaml_node_t* atm,
+ struct solparser_atmosphere** out_solatm);
+
+extern LOCAL_SYM res_T
parse_x_pivot
(struct solparser* parser,
yaml_document_t* doc,
diff --git a/src/parser/test_solparser2.c b/src/parser/test_solparser2.c
@@ -79,6 +79,8 @@ main(int argc, char** argv)
fprintf(stream, "- sun:\n");
fprintf(stream, " dni: 1\n");
fprintf(stream, " spectrum: [ { wavelength: 1, data: 1} ]\n");
+ fprintf(stream, "- atmosphere:\n");
+ fprintf(stream, " absorption: 0\n");
rewind(stream);
CHECK(solparser_setup(parser, NULL, stream), RES_OK);
diff --git a/src/parser/test_solparser3.c b/src/parser/test_solparser3.c
@@ -42,6 +42,8 @@ static const char* input[] = {
"- sun: \n",
" dni: 1\n",
" spectrum: [{wavelength: 1, data: 1}]\n",
+ "- atmosphere:\n",
+ " absorption: [{wavelength: 1, data: 1}]\n",
"- entity:\n",
" name: entity0\n",
" primary: 0\n",
diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml
@@ -1862,9 +1862,49 @@
---
#
+# <atmosphere> ::=
+# atmosphere:
+# absorption: <mtl-data> # in [0, 1]
+#
+
+# missing atmosphere definition
+- atmosphere:
+---
+# unknown dummy parameter
+- atmosphere:
+ dummy: 1
+---
+# missing absorption definition
+- atmosphere:
+ absorption:
+---
+# absorption should be a number
+- atmosphere:
+ absorption: "dummy"
+---
+# 2 invalid
+- atmosphere:
+ absorption: 2
+---
+# 0 invalid
+- atmosphere:
+ absorption: [{wavelength: 0, data: 1}]
+---
+# 2 invalid
+- atmosphere:
+ absorption: [{wavelength: 0, data: 2}]
+---
+# 2x absorption
+- atmosphere:
+ absorption: 0.1
+ absorption: [{wavelength: 1, data: 1}]
+---
+
+#
# <solar-factory> ::=
# <sun>
# <items>
+# [ <atmosphere> ]
#
# <items> ::=
# - <item>
@@ -1887,4 +1927,13 @@
geometry:
- cuboid: { size: [1, 2, 3] }
material: { matte: { reflectivity: 1 } }
-
+---
+# 2x sun
+- sun: { dni: 1000, spectrum: [{wavelength: 1, data: 1}] }
+- sun: { dni: 1000, spectrum: [{wavelength: 1, data: 1}] }
+---
+# 2x atmosphere
+- atmosphere:
+ absorption: 0.1
+- atmosphere:
+ absorption: 0.1
diff --git a/src/solstice.c b/src/solstice.c
@@ -608,6 +608,12 @@ solstice_init
goto error;
}
+ res = solstice_create_atmosphere(solstice);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not setup the Solstice atmosphere.\n");
+ goto error;
+ }
+
solstice->nexperiments = args->nexperiments;
solstice->output_hits = args->output_hits;
solstice->dump_format = args->dump_format;
diff --git a/src/solstice.h b/src/solstice.h
@@ -88,6 +88,7 @@ struct solstice {
struct ssol_device* ssol;
struct ssol_scene* scene;
struct ssol_sun* sun;
+ struct ssol_atmosphere* atmosphere;
struct solparser* parser;
diff --git a/src/solstice_atmosphere.c b/src/solstice_atmosphere.c
@@ -0,0 +1,63 @@
+/* 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_atmosphere.h"
+
+#include <solstice/ssol.h>
+
+res_T
+solstice_create_atmosphere(struct solstice* solstice)
+{
+ struct ssol_atmosphere* atm = NULL;
+ struct ssol_data absorption = SSOL_DATA_NULL;
+ const struct solparser_atmosphere* solparser_atm = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice);
+
+ solparser_atm = solparser_get_atmosphere(solstice->parser);
+ if(!solparser_atm) return res;
+
+ res = ssol_atmosphere_create(solstice->ssol, &atm);
+ if(res != RES_OK) goto error;
+
+ res = mtl_to_ssol_data(solstice, &solparser_atm->absorption, &absorption);
+ if(res != RES_OK) goto error;
+
+ res = ssol_atmosphere_set_absorption(atm, &absorption);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not set atmosphere absorbtion.\n");
+ goto error;
+ }
+
+ res = ssol_scene_attach_atmosphere(solstice->scene, atm);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not attach the atmosphere to the scene.\n");
+ goto error;
+ }
+
+exit:
+ ssol_data_clear(&absorption);
+ solstice->atmosphere = atm;
+ return res;
+error:
+ if(atm) {
+ SSOL(atmosphere_ref_put(atm));
+ atm = NULL;
+ }
+
+ goto exit;
+}
diff --git a/src/solstice_atmosphere.h b/src/solstice_atmosphere.h
diff --git a/src/solstice_c.h b/src/solstice_c.h
@@ -61,6 +61,10 @@ solstice_create_sun
(struct solstice* solstice);
extern LOCAL_SYM res_T
+solstice_create_atmosphere
+ (struct solstice* solstice);
+
+extern LOCAL_SYM res_T
solstice_setup_entities
(struct solstice* solstice);
@@ -76,6 +80,12 @@ solstice_create_ssol_spectrum
struct ssol_spectrum** spectrum);
extern LOCAL_SYM res_T
+mtl_to_ssol_data
+ (struct solstice* solstice,
+ const struct solparser_mtl_data* mtl_data,
+ struct ssol_data* data);
+
+extern LOCAL_SYM res_T
solstice_create_ssol_material
(struct solstice* solstice,
const struct solparser_material_id mtl_id,
diff --git a/src/solstice_material.c b/src/solstice_material.c
@@ -205,38 +205,6 @@ thin_dielectric_param_release(void* mem)
}
static res_T
-mtl_to_ssol_data
- (struct solstice* solstice,
- const struct solparser_mtl_data* mtl_data,
- struct ssol_data* data)
-{
- struct ssol_spectrum* spectrum = NULL;
- res_T res = RES_OK;
- ASSERT(mtl_data && data);
-
- ssol_data_clear(data);
- switch(mtl_data->type) {
- case SOLPARSER_MTL_DATA_REAL:
- ssol_data_set_real(data, mtl_data->value.real);
- break;
- case SOLPARSER_MTL_DATA_SPECTRUM:
- res = solstice_create_ssol_spectrum
- (solstice, mtl_data->value.spectrum, &spectrum);
- if(res != RES_OK) goto error;
- ssol_data_set_spectrum(data, spectrum);
- break;
- default: FATAL("Unreachable code.\n"); break;
- }
-
-exit:
- if(spectrum) SSOL(spectrum_ref_put(spectrum));
- return res;
-error:
- ssol_data_clear(data);
- goto exit;
-}
-
-static res_T
load_image
(struct solstice* solstice,
const char* filename,
@@ -601,6 +569,38 @@ error:
* Local functions
******************************************************************************/
res_T
+mtl_to_ssol_data
+ (struct solstice* solstice,
+ const struct solparser_mtl_data* mtl_data,
+ struct ssol_data* data)
+{
+ struct ssol_spectrum* spectrum = NULL;
+ res_T res = RES_OK;
+ ASSERT(mtl_data && data);
+
+ ssol_data_clear(data);
+ switch(mtl_data->type) {
+ case SOLPARSER_MTL_DATA_REAL:
+ ssol_data_set_real(data, mtl_data->value.real);
+ break;
+ case SOLPARSER_MTL_DATA_SPECTRUM:
+ res = solstice_create_ssol_spectrum
+ (solstice, mtl_data->value.spectrum, &spectrum);
+ if(res != RES_OK) goto error;
+ ssol_data_set_spectrum(data, spectrum);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+
+exit:
+ if(spectrum) SSOL(spectrum_ref_put(spectrum));
+ return res;
+error:
+ ssol_data_clear(data);
+ goto exit;
+}
+
+res_T
solstice_create_ssol_material
(struct solstice* solstice,
const struct solparser_material_id mtl_id,
diff --git a/yaml/test07.yaml b/yaml/test07.yaml
@@ -1,5 +1,8 @@
- sun: &sun { dni: 1 }
+- atmosphere:
+ absorption: [{wavelength: 1, data: 0},{wavelength: 10, data: 0}]
+
- material: &specular
front:
mirror: { reflectivity: 1, roughness: 0 }
diff --git a/yaml/test08.yaml b/yaml/test08.yaml
@@ -1,5 +1,8 @@
- sun: &sun { dni: 1 }
+- atmosphere:
+ absorption: 0
+
- material: &lambertian
front:
matte: { reflectivity: 1 }