commit 82ac79788359da79eeef64cb26da3a80ae817787
parent 8905ab82a5f0b9ab5e05973f9354569e411125ed
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 27 Mar 2017 15:03:13 +0200
Merge branch 'feature_material_dielectric' into develop
Diffstat:
11 files changed, 589 insertions(+), 130 deletions(-)
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -82,6 +82,8 @@ if(NOT NO_TEST)
${SOLPARSER_SOURCE_DIR}/yaml/test_ok_5.yaml)
add_test(test_solparser_ok_6 test_solparser
${SOLPARSER_SOURCE_DIR}/yaml/test_ok_6.yaml)
+ add_test(test_solparser_ok_7 test_solparser
+ ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_7.yaml)
add_test(test_solparser_ko test_solparser -e
${SOLPARSER_SOURCE_DIR}/yaml/test_ko_0.yaml)
@@ -91,6 +93,7 @@ if(NOT NO_TEST)
new_test(test_solparser5)
new_test(test_solparser6)
new_test(test_solparser7)
+ new_test(test_solparser8)
rcmake_copy_runtime_libraries(test_solparser)
endif()
diff --git a/doc/input b/doc/input
@@ -219,25 +219,34 @@
back: <material-descriptor>
<material-descriptor> ::=
- <mirror> | <matte> | <thin-dielectric> | <virtual>
+ <dielectric> | <matte> | <mirror> | thin-dielectric> | <virtual>
-<mirror> ::=
- mirror:
- reflectivity: REAL # in [0, 1]
- roughness: REAL # in [0, 1]
+<dielectric> ::=
+ dielectric:
+ medium_i: <dielectric-medium>
+ medium_t: <dielectric-medium>
<matte> ::=
matte:
reflectivity: REAL # in [0, 1]
+<mirror> ::=
+ mirror:
+ reflectivity: REAL # in [0, 1]
+ roughness: REAL # in [0, 1]
+
<virtual> ::=
virtual: EMPTY-STRING
<thin-dielectric> ::=
thin_dielectric:
- absorption: REAL # in [0, INF)
thickness: REAL # in [0, INF)
+ medium_i: <dielectric-medium>
+ medium_t: <dielectric-medium>
+
+<dielectric-medium> ::=
refractive_index: REAL # in ]0, INF)
+ absorptivity: REAL # in [0, INF)
#----------------------------------------
<entity> ::=
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -44,6 +44,16 @@ struct target_alias {
#define DARRAY_DATA struct target_alias
#include <rsys/dynamic_array.h>
+/* Declare the array of mediums */
+#define DARRAY_NAME medium
+#define DARRAY_DATA struct solparser_medium
+#include <rsys/dynamic_array.h>
+
+/* Declare the array of dielectric materials */
+#define DARRAY_NAME dielectric
+#define DARRAY_DATA struct solparser_material_dielectric
+#include <rsys/dynamic_array.h>
+
/* Declare the array of matte materials */
#define DARRAY_NAME matte
#define DARRAY_DATA struct solparser_material_matte
@@ -188,6 +198,8 @@ struct solparser {
struct htable_yaml2sols yaml2mtls; /* Cache of materials */
struct darray_material mtls;
struct darray_material2 mtls2; /* Double sided materials */
+ struct darray_medium mediums;
+ struct darray_dielectric dielectrics;
struct darray_matte mattes;
struct darray_mirror mirrors;
struct darray_thin_dielectric thin_dielectrics;
@@ -386,6 +398,8 @@ parser_clear(struct solparser* parser)
htable_yaml2sols_clear(&parser->yaml2mtls);
darray_material_clear(&parser->mtls);
darray_material2_clear(&parser->mtls2);
+ darray_medium_clear(&parser->mediums);
+ darray_dielectric_clear(&parser->dielectrics);
darray_matte_clear(&parser->mattes);
darray_mirror_clear(&parser->mirrors);
darray_thin_dielectric_clear(&parser->thin_dielectrics);
@@ -438,6 +452,8 @@ parser_release(ref_T* ref)
htable_yaml2sols_release(&parser->yaml2mtls);
darray_material_release(&parser->mtls);
darray_material2_release(&parser->mtls2);
+ darray_medium_release(&parser->mediums);
+ darray_dielectric_release(&parser->dielectrics);
darray_matte_release(&parser->mattes);
darray_mirror_release(&parser->mirrors);
darray_thin_dielectric_release(&parser->thin_dielectrics);
@@ -859,6 +875,192 @@ error:
* Material
******************************************************************************/
static res_T
+parse_medium
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* medium,
+ struct solparser_medium_id* out_imedium)
+{
+ enum { ABSORPTIVITY, REFRACTIVE_INDEX };
+ struct solparser_medium* mdm = NULL;
+ size_t imedium = SIZE_MAX;
+ int mask = 0; /* Register the parsed attributes */
+ intptr_t i, n;
+ res_T res = RES_OK;
+ ASSERT(doc && medium && out_imedium);
+
+ if(medium->type != YAML_MAPPING_NODE) {
+ log_err(parser, medium, "expect a mapping of medium attributes.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Allocate the medium */
+ imedium = darray_medium_size_get(&parser->mediums);
+ res = darray_medium_resize(&parser->mediums, imedium + 1);
+ if(res != RES_OK) {
+ log_err(parser, medium, "could not allocate the medium.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ mdm = darray_medium_data_get(&parser->mediums) + imedium;
+
+ n = medium->data.mapping.pairs.top - medium->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, medium->data.mapping.pairs.start[i].value);
+ if(key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect a medium 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 medium is already defined.\n");\
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "absorptivity")) {
+ SETUP_MASK(ABSORPTIVITY, "absorptivity");
+ res = parse_real(parser, val, 0, DBL_MAX, &mdm->absorptivity);
+ } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) {
+ SETUP_MASK(REFRACTIVE_INDEX, "refractive_index");
+ res = parse_real
+ (parser, val, nextafter(0, 1), DBL_MAX, &mdm->refractive_index);
+ } else {
+ log_err(parser, key, "unknown medium 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, medium, "the "Name" of the medium is missing.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(ABSORPTIVITY, "absorptivity");
+ CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index");
+ #undef CHECK_PARAM
+
+exit:
+ out_imedium->i = imedium;
+ return res;
+error:
+ if(imedium) {
+ darray_medium_pop_back(&parser->mediums);
+ imedium = SIZE_MAX;
+ }
+ goto exit;
+}
+
+static res_T
+parse_material_dielectric
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* dielec,
+ struct solparser_material_dielectric_id* out_imtl)
+{
+ enum { MEDIUM_I, MEDIUM_T };
+ struct solparser_material_dielectric* mtl = NULL;
+ size_t imtl = SIZE_MAX;
+ int mask = 0; /* Register the parsed attributes */
+ intptr_t i, n;
+ res_T res = RES_OK;
+ ASSERT(doc && dielec && out_imtl);
+
+ if(dielec->type != YAML_MAPPING_NODE) {
+ log_err(parser, dielec,
+ "expect a mapping of dielec material attributes.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Allocate the dielec material */
+ imtl = darray_dielectric_size_get(&parser->dielectrics);
+ res = darray_dielectric_resize(&parser->dielectrics, imtl + 1);
+ if(res != RES_OK) {
+ log_err(parser, dielec,
+ "could not allocate the dielec material.\n");
+ goto error;
+ }
+ mtl = darray_dielectric_data_get(&parser->dielectrics) + imtl;
+
+ n = dielec->data.mapping.pairs.top - dielec->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, dielec->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, dielec->data.mapping.pairs.start[i].value);
+ if(key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect a dielec material 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 dielectric material is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "medium_i")) {
+ SETUP_MASK(MEDIUM_I, "medium_i");
+ res = parse_medium(parser, doc, val, &mtl->medium_i);
+ } else if(!strcmp((char*)key->data.scalar.value, "medium_t")) {
+ SETUP_MASK(MEDIUM_T, "medium_t");
+ res = parse_medium(parser, doc, val, &mtl->medium_t);
+ } else {
+ log_err(parser, key, "unknown dielectric 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, dielec, \
+ "the "Name" of the dielectric material is missing.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(MEDIUM_I, "medium_i");
+ CHECK_PARAM(MEDIUM_T, "medium_t");
+ #undef CHECK_PARAM
+
+exit:
+ out_imtl->i = imtl;
+ return res;
+error:
+ if(imtl) {
+ darray_dielectric_pop_back(&parser->dielectrics);
+ imtl = SIZE_MAX;
+ }
+ goto exit;
+}
+
+static res_T
parse_material_matte
(struct solparser* parser,
yaml_document_t* doc,
@@ -1038,7 +1240,7 @@ parse_material_thin_dielectric
yaml_node_t* thin,
struct solparser_material_thin_dielectric_id* out_imtl)
{
- enum { ABSORPTION, REFRACTIVE_INDEX, THICKNESS };
+ enum { MEDIUM_I, MEDIUM_T, THICKNESS };
struct solparser_material_thin_dielectric* mtl = NULL;
size_t imtl = SIZE_MAX;
int mask = 0; /* Register the parsed attributes */
@@ -1048,7 +1250,7 @@ parse_material_thin_dielectric
if(thin->type != YAML_MAPPING_NODE) {
log_err(parser, thin,
- "expect a mapping of thin material attributes.\n");
+ "expect a mapping of thin dielectric material attributes.\n");
res = RES_BAD_ARG;
goto error;
}
@@ -1085,13 +1287,12 @@ parse_material_thin_dielectric
} \
mask |= BIT(Flag); \
} (void)0
- if(!strcmp((char*)key->data.scalar.value, "absorption")) {
- SETUP_MASK(ABSORPTION, "absorption");
- res = parse_real(parser, val, 0, DBL_MAX, &mtl->absorption);
- } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) {
- SETUP_MASK(REFRACTIVE_INDEX, "refractive_index");
- res = parse_real
- (parser, val, nextafter(0, 1), DBL_MAX, &mtl->refractive_index);
+ if(!strcmp((char*)key->data.scalar.value, "medium_i")) {
+ SETUP_MASK(MEDIUM_I, "medium_i");
+ res = parse_medium(parser, doc, val, &mtl->medium_i);
+ } else if(!strcmp((char*)key->data.scalar.value, "medium_t")) {
+ SETUP_MASK(MEDIUM_T, "medium_t");
+ res = parse_medium(parser, doc, val, &mtl->medium_t);
} else if(!strcmp((char*)key->data.scalar.value, "thickness")) {
SETUP_MASK(THICKNESS, "thickness");
res = parse_real(parser, val, 0, DBL_MAX, &mtl->thickness);
@@ -1115,8 +1316,8 @@ parse_material_thin_dielectric
res = RES_BAD_ARG; \
goto error; \
} (void)0
- CHECK_PARAM(ABSORPTION, "absorption");
- CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index");
+ CHECK_PARAM(MEDIUM_I, "medium_i");
+ CHECK_PARAM(MEDIUM_T, "medium_t");
CHECK_PARAM(THICKNESS, "thickness");
#undef CHECK_PARAM
@@ -1211,7 +1412,11 @@ parse_material_descriptor
} \
mask |= BIT(Flag); \
} (void)0
- if(!strcmp((char*)key->data.scalar.value, "matte")) {
+ if(!strcmp((char*)key->data.scalar.value, "dielectric")) {
+ SETUP_MASK(DESCRIPTOR, "descriptor");
+ mtl->type = SOLPARSER_MATERIAL_DIELECTRIC;
+ res = parse_material_dielectric(parser, doc, val, &mtl->data.dielectric);
+ } else if(!strcmp((char*)key->data.scalar.value, "matte")) {
SETUP_MASK(DESCRIPTOR, "descriptor");
mtl->type = SOLPARSER_MATERIAL_MATTE;
res = parse_material_matte(parser, doc, val, &mtl->data.matte);
@@ -3627,6 +3832,8 @@ solparser_create
htable_yaml2sols_init(mem_allocator, &parser->yaml2mtls);
darray_material_init(mem_allocator, &parser->mtls);
darray_material2_init(mem_allocator, &parser->mtls2);
+ darray_medium_init(mem_allocator, &parser->mediums);
+ darray_dielectric_init(mem_allocator, &parser->dielectrics);
darray_matte_init(mem_allocator, &parser->mattes);
darray_mirror_init(mem_allocator, &parser->mirrors);
darray_thin_dielectric_init(mem_allocator, &parser->thin_dielectrics);
@@ -3946,6 +4153,15 @@ solparser_get_geometry
return darray_geometry_cdata_get(&parser->geometries) + geom.i;
}
+const struct solparser_medium*
+solparser_get_medium
+ (const struct solparser* parser,
+ const struct solparser_medium_id medium)
+{
+ ASSERT(parser && medium.i < darray_medium_size_get(&parser->mediums));
+ return darray_medium_cdata_get(&parser->mediums) + medium.i;
+}
+
const struct solparser_material*
solparser_get_material
(const struct solparser* parser,
@@ -3964,6 +4180,16 @@ solparser_get_material_double_sided
return darray_material2_cdata_get(&parser->mtls2) + mtl2.i;
}
+const struct solparser_material_dielectric*
+solparser_get_material_dielectric
+ (const struct solparser* parser,
+ const struct solparser_material_dielectric_id dielectric)
+{
+ ASSERT(parser);
+ ASSERT(dielectric.i < darray_dielectric_size_get(&parser->dielectrics));
+ return darray_dielectric_cdata_get(&parser->dielectrics) + dielectric.i;
+}
+
const struct solparser_material_matte*
solparser_get_material_matte
(const struct solparser* parser,
diff --git a/src/parser/solparser.h b/src/parser/solparser.h
@@ -92,6 +92,11 @@ solparser_get_geometry
(const struct solparser* parser,
const struct solparser_geometry_id geom);
+extern LOCAL_SYM const struct solparser_medium*
+solparser_get_medium
+ (const struct solparser* parser,
+ const struct solparser_medium_id medium);
+
extern LOCAL_SYM const struct solparser_material*
solparser_get_material
(const struct solparser* parser,
@@ -102,6 +107,11 @@ solparser_get_material_double_sided
(const struct solparser* parser,
const struct solparser_material_double_sided_id mtl2);
+extern LOCAL_SYM const struct solparser_material_dielectric*
+solparser_get_material_dielectric
+ (const struct solparser* parser,
+ const struct solparser_material_dielectric_id dielectric);
+
extern LOCAL_SYM const struct solparser_material_matte*
solparser_get_material_matte
(const struct solparser* parser,
diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h
@@ -19,12 +19,27 @@
#include <stddef.h>
enum solparser_material_type {
+ SOLPARSER_MATERIAL_DIELECTRIC,
SOLPARSER_MATERIAL_MATTE,
SOLPARSER_MATERIAL_MIRROR,
SOLPARSER_MATERIAL_THIN_DIELECTRIC,
SOLPARSER_MATERIAL_VIRTUAL
};
+struct solparser_medium {
+ double refractive_index;
+ double absorptivity;
+};
+
+struct solparser_medium_id { size_t i; };
+
+struct solparser_material_dielectric {
+ struct solparser_medium_id medium_i; /* Medium the material "looks at" */
+ struct solparser_medium_id medium_t; /* Opposite medium */
+};
+
+struct solparser_material_dielectric_id { size_t i; };
+
struct solparser_material_matte {
double reflectivity; /* In [0, 1] */
};
@@ -39,8 +54,8 @@ struct solparser_material_mirror {
struct solparser_material_mirror_id { size_t i; };
struct solparser_material_thin_dielectric {
- double absorption;
- double refractive_index;
+ struct solparser_medium_id medium_i; /* Outside medium */
+ struct solparser_medium_id medium_t; /* Medium of the slab */
double thickness;
};
@@ -49,6 +64,7 @@ struct solparser_material_thin_dielectric_id { size_t i; };
struct solparser_material {
enum solparser_material_type type;
union {
+ struct solparser_material_dielectric_id dielectric;
struct solparser_material_matte_id matte;
struct solparser_material_mirror_id mirror;
struct solparser_material_thin_dielectric_id thin_dielectric;
diff --git a/src/parser/test_solparser7.c b/src/parser/test_solparser7.c
@@ -30,6 +30,7 @@ main(int argc, char** argv)
const struct solparser_material_double_sided* mtl2;
const struct solparser_material* mtl;
const struct solparser_material_thin_dielectric* thin;
+ const struct solparser_medium* medium;
const struct solparser_object* obj;
const struct solparser_shape* shape;
FILE* stream;
@@ -49,9 +50,13 @@ main(int argc, char** argv)
fprintf(stream, " - sphere: { radius: 1 }\n");
fprintf(stream, " material:\n");
fprintf(stream, " thin_dielectric:\n");
- fprintf(stream, " absorption: 0.5\n");
fprintf(stream, " thickness: 0.123\n");
- fprintf(stream, " refractive_index: 1.5\n");
+ fprintf(stream, " medium_i: &outside\n");
+ fprintf(stream, " refractive_index: 1\n");
+ fprintf(stream, " absorptivity: 0\n");
+ fprintf(stream, " medium_t: &inside\n");
+ fprintf(stream, " refractive_index: 1.5\n");
+ fprintf(stream, " absorptivity: 20\n");
rewind(stream);
CHECK(solparser_setup(parser, NULL, stream), RES_OK);
@@ -79,9 +84,14 @@ main(int argc, char** argv)
CHECK(mtl->type, SOLPARSER_MATERIAL_THIN_DIELECTRIC);
thin = solparser_get_material_thin_dielectric
(parser, mtl->data.thin_dielectric);
- CHECK(thin->absorption, 0.5);
CHECK(thin->thickness, 0.123);
- CHECK(thin->refractive_index, 1.5);
+
+ medium = solparser_get_medium(parser, thin->medium_i);
+ CHECK(medium->refractive_index, 1);
+ CHECK(medium->absorptivity, 0);
+ medium = solparser_get_medium(parser, thin->medium_t);
+ CHECK(medium->refractive_index, 1.5);
+ CHECK(medium->absorptivity, 20);
CHECK(solparser_load(parser), RES_BAD_OP);
solparser_ref_put(parser);
diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.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/>. */
+
+#include "solparser.h"
+#include "solparser_sun.h"
+#include "test_solstice_utils.h"
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct solparser* parser;
+ struct solparser_entity_iterator it, end;
+ struct solparser_entity_id entity_id;
+ struct solparser_object_id obj_id;
+ const struct solparser_entity* entity;
+ const struct solparser_geometry* geom;
+ const struct solparser_medium* medium;
+ const struct solparser_material_double_sided* mtl2;
+ const struct solparser_material* mtl;
+ const struct solparser_material_dielectric* dielec;
+ const struct solparser_object* obj;
+ const struct solparser_shape* shape;
+ FILE* stream;
+ (void)argc, (void)argv;
+
+ CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK);
+ solparser_create(&allocator, &parser);
+
+ stream = tmpfile();
+ NCHECK(stream, NULL);
+
+ fprintf(stream, "- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1 }] }\n");
+ fprintf(stream, "- entity:\n");
+ fprintf(stream, " name: test\n");
+ fprintf(stream, " primary: 0\n");
+ fprintf(stream, " geometry:\n");
+ fprintf(stream, " - sphere: { radius: 1 }\n");
+ fprintf(stream, " material:\n");
+ fprintf(stream, " front:\n");
+ fprintf(stream, " dielectric:\n");
+ fprintf(stream, " medium_i: &outside\n");
+ fprintf(stream, " refractive_index: 1\n");
+ fprintf(stream, " absorptivity: 0\n");
+ fprintf(stream, " medium_t: &inside\n");
+ fprintf(stream, " refractive_index: 1.5\n");
+ fprintf(stream, " absorptivity: 20\n");
+ fprintf(stream, " back:\n");
+ fprintf(stream, " dielectric:\n");
+ fprintf(stream, " medium_i: *inside\n");
+ fprintf(stream, " medium_t: *outside\n");
+ rewind(stream);
+
+ CHECK(solparser_setup(parser, NULL, stream), RES_OK);
+ CHECK(solparser_load(parser), RES_OK);
+
+ solparser_entity_iterator_begin(parser, &it);
+ solparser_entity_iterator_end(parser, &end);
+ CHECK(solparser_entity_iterator_eq(&it, &end), 0);
+
+ entity_id = solparser_entity_iterator_get(&it);
+ entity = solparser_get_entity(parser, entity_id);
+
+ CHECK(strcmp("test", str_cget(&entity->name)), 0);
+ CHECK(solparser_entity_get_children_count(entity), 0);
+ CHECK(entity->type, SOLPARSER_ENTITY_GEOMETRY);
+ geom = solparser_get_geometry(parser, entity->data.geometry);
+ CHECK(solparser_geometry_get_objects_count(geom), 1);
+ obj_id = solparser_geometry_get_object(geom, 0);
+ obj = solparser_get_object(parser, obj_id);
+ shape = solparser_get_shape(parser, obj->shape);
+ CHECK(shape->type, SOLPARSER_SHAPE_SPHERE);
+ mtl2 = solparser_get_material_double_sided(parser, obj->mtl2);
+ NCHECK(mtl2->front.i, mtl2->back.i);
+
+ mtl = solparser_get_material(parser, mtl2->front);
+ CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC);
+ dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric);
+ medium = solparser_get_medium(parser, dielec->medium_i);
+ CHECK(medium->refractive_index, 1);
+ CHECK(medium->absorptivity, 0);
+ medium = solparser_get_medium(parser, dielec->medium_t);
+ CHECK(medium->refractive_index, 1.5);
+ CHECK(medium->absorptivity, 20);
+
+ mtl = solparser_get_material(parser, mtl2->back);
+ CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC);
+ dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric);
+ medium = solparser_get_medium(parser, dielec->medium_i);
+ CHECK(medium->refractive_index, 1.5);
+ CHECK(medium->absorptivity, 20);
+ medium = solparser_get_medium(parser, dielec->medium_t);
+ CHECK(medium->refractive_index, 1);
+ CHECK(medium->absorptivity, 0);
+
+ CHECK(solparser_load(parser), RES_BAD_OP);
+ solparser_ref_put(parser);
+
+ fclose(stream);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
+
diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml
@@ -225,26 +225,79 @@
#
# <thin-dielectric> ::=
# thin_dielectric:
-# absorption: REAL # in [0, 1]
# thickness: REAL # in [0, INF)
-# refractive_index: REAL # in ]0, INF)
+# medium_i: <dielectric-medium>
+# medium_t: <dielectric-medium>
#
-# invalid absorption
+# invalid absorptivity
- material:
- thin_dielectric: { absorption: -1, thickness: 0, refractive_index: 1 }
+ thin_dielectric:
+ thickness: 0
+ medium_i: &m { refractive_index: 1, absorptivity: -1 }
+ medium_t: *m
---
# invalid thickness
- material:
- thin_dielectric: { absorption: 0, thickness: -0.01, refractive_index: 1 }
+ thin_dielectric:
+ thickness: -0.01
+ medium_i: &m { refractive_index: 1, absorptivity: 0 }
+ medium_t: *m
---
# invalid refractive index
- material:
- thin_dielectric: { absorption: 0, thickness: 0, refractive_index: 0 }
+ thin_dielectric:
+ thickness: 0
+ medium_i: &m { refractive_index: 0, absorptivity: 0 }
+ medium_t: *m
---
-# invalid refractive index
+# missing thickness
+- material:
+ thin_dielectric:
+ medium_i: &m { refractive_index: 1, absorptivity: 0 }
+ medium_t: *m
+---
+
+#
+# <dielectric> ::=
+# dielectric:
+# medium_i: <dielectric-medium>
+# medium_t: <dielectric-medium>
+#
+
+# invalid refractive_index
+- material:
+ dielectric:
+ medium_i: &m { refractive_index: 0, absorptivity: 0 }
+ medium_t: *m
+---
+# invalid absorptivity
+- material:
+ dielectric:
+ medium_i: &m { refractive_index: 1, absorptivity: -1 }
+ medium_t: *m
+---
+# missing refractive_index
+- material:
+ dielectric:
+ medium_i: &m { absorptivity: 0 }
+ medium_t: *m
+---
+# missing absorptivity
+- material:
+ dielectric:
+ medium_i: &m { refractive_index: 1 }
+ medium_t: *m
+---
+# missing medium_i
+- material:
+ dielectric:
+ medium_t: { refractive_index: 1, absorptivity: 0 }
+---
+# missing medium_t
- material:
- thin_dielectric: { absorption: 0, thickness: 0, refractive_index: -0.0001 }
+ dielectric:
+ medium_i: { refractive_index: 1, absorptivity: 0 }
---
#
@@ -772,7 +825,7 @@
- [-0.50, -0.50]
- [-0.50, 0.50]
- [0.50, 0.50]
- - [0.50, -0.50]
+ - [0.50, -0.50]
---
# invalid slices
- geometry: &target
@@ -784,7 +837,7 @@
- [-0.50, -0.50]
- [-0.50, 0.50]
- [0.50, 0.50]
- - [0.50, -0.50]
+ - [0.50, -0.50]
---
#
diff --git a/src/parser/yaml/test_ok_5.yaml b/src/parser/yaml/test_ok_5.yaml
@@ -2,9 +2,9 @@
- material: &thin_dielectric
thin_dielectric:
- absorption: 0.1
- thickness: 0.2
- refractive_index: 1.00027
+ thickness: 1
+ medium_i: { absorptivity: 0, refractive_index: 1.00027 }
+ medium_t: { absorptivity: 0.1, refractive_index: 1.5 }
- entity:
name: "entity"
@@ -17,9 +17,9 @@
- material: &thin_dielectric
thin_dielectric:
- absorption: 0
thickness: 0
- refractive_index: 0.0001
+ medium_i: { absorptivity: 0, refractive_index: 0.00027 }
+ medium_t: { absorptivity: 0.1, refractive_index: 1.5 }
- entity:
name: "entity"
@@ -37,7 +37,7 @@
- cylinder: { height: 1, radius: 1 }
material:
thin_dielectric:
- absorption: 40
thickness: 10
- refractive_index: 0.0001
+ medium_i: { absorptivity: 0, refractive_index: 1 }
+ medium_t: { absorptivity: 20, refractive_index: 1.5 }
diff --git a/src/parser/yaml/test_ok_7.yaml b/src/parser/yaml/test_ok_7.yaml
@@ -0,0 +1,40 @@
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+
+- material: &dielectric
+ dielectric:
+ medium_i: { absorptivity: 0, refractive_index: 1.00027 }
+ medium_t: { absorptivity: 0.1, refractive_index: 1.5 }
+
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - material: *dielectric
+ cylinder: { height: 1, radius: 1 }
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+
+- material: &dielectric
+ dielectric:
+ medium_i: { absorptivity: 0, refractive_index: 0.00027 }
+ medium_t: { absorptivity: 0.1, refractive_index: 1.5 }
+
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - material: *dielectric
+ cylinder: { height: 1, radius: 1 }
+
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - cylinder: { height: 1, radius: 1 }
+ material:
+ dielectric:
+ medium_i: { absorptivity: 0, refractive_index: 1 }
+ medium_t: { absorptivity: 20, refractive_index: 1.5 }
+
diff --git a/src/solstice_material.c b/src/solstice_material.c
@@ -18,19 +18,13 @@
#include <solstice/ssol.h>
-struct mirror_param {
- double reflectivity;
- double roughness;
-};
-
struct matte_param {
double reflectivity;
};
-struct thin_dielectric_param {
- double absorption;
- double thickness;
- double refractive_index;
+struct mirror_param {
+ double reflectivity;
+ double roughness;
};
/*******************************************************************************
@@ -105,57 +99,44 @@ mirror_get_roughness
*val = param->roughness;
}
-static void
-thin_dielectric_get_absorption
- (struct ssol_device* dev,
- struct ssol_param_buffer* buf,
- const double wavelength,
- const double P[3],
- const double Ng[3],
- const double Ns[3],
- const double uv[2],
- const double w[3],
- double* val)
+static res_T
+create_material_dielectric
+ (struct solstice* solstice,
+ const struct solparser_material_dielectric* dielectric,
+ struct ssol_material** out_mtl)
{
- const struct thin_dielectric_param* param = ssol_param_buffer_get(buf);
- (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
- *val = param->absorption;
-}
+ const struct solparser_medium* medium_i;
+ const struct solparser_medium* medium_t;
+ struct ssol_medium ssol_medium_i;
+ struct ssol_medium ssol_medium_t;
+ struct ssol_dielectric_shader shader = SSOL_DIELECTRIC_SHADER_NULL;
+ struct ssol_material* mtl = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && dielectric && out_mtl);
-static void
-thin_dielectric_get_thickness
- (struct ssol_device* dev,
- struct ssol_param_buffer* buf,
- const double wavelength,
- const double P[3],
- const double Ng[3],
- const double Ns[3],
- const double uv[2],
- const double w[3],
- double* val)
-{
- const struct thin_dielectric_param* param = ssol_param_buffer_get(buf);
- (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
- *val = param->thickness;
-}
+ res = ssol_material_create_dielectric(solstice->ssol, &mtl);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Could not allocate the Solstice Solver dielectric material.\n");
+ goto error;
+ }
-static void
-thin_dielectric_get_refractive_index
- (struct ssol_device* dev,
- struct ssol_param_buffer* buf,
- const double wavelength,
- const double P[3],
- const double Ng[3],
- const double Ns[3],
- const double uv[2],
- const double w[3],
- double* val)
-{
- const struct thin_dielectric_param* param = ssol_param_buffer_get(buf);
- (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
- *val = param->refractive_index;
-}
+ medium_i = solparser_get_medium(solstice->parser, dielectric->medium_i);
+ medium_t = solparser_get_medium(solstice->parser, dielectric->medium_t);
+ shader.normal = mtl_get_normal;
+ ssol_medium_i.refractive_index = medium_i->refractive_index;
+ ssol_medium_i.absorptivity = medium_i->absorptivity;
+ ssol_medium_t.refractive_index = medium_t->refractive_index;
+ ssol_medium_t.absorptivity = medium_t->absorptivity;
+ SSOL(dielectric_setup(mtl, &shader, &ssol_medium_i, &ssol_medium_t));
+exit:
+ *out_mtl = mtl;
+ return res;
+error:
+ if(mtl) SSOL(material_ref_put(mtl)), mtl = NULL;
+ goto exit;
+}
static res_T
create_material_matte
@@ -194,7 +175,7 @@ create_material_matte
shader.normal = mtl_get_normal;
shader.reflectivity = matte_get_reflectivity;
- SSOL(matte_set_shader(mtl, &shader));
+ SSOL(matte_setup(mtl, &shader));
SSOL(material_set_param_buffer(mtl, pbuf));
exit:
@@ -245,7 +226,7 @@ create_material_mirror
shader.normal = mtl_get_normal;
shader.reflectivity = mirror_get_reflectivity;
shader.roughness = mirror_get_roughness;
- SSOL(mirror_set_shader(mtl, &shader));
+ SSOL(mirror_setup(mtl, &shader));
SSOL(material_set_param_buffer(mtl, pbuf));
exit:
@@ -264,9 +245,11 @@ create_material_thin_dielectric
struct ssol_material** out_mtl)
{
struct ssol_thin_dielectric_shader shader = SSOL_THIN_DIELECTRIC_SHADER_NULL;
+ const struct solparser_medium* medium_i;
+ const struct solparser_medium* medium_t;
+ struct ssol_medium ssol_medium_i;
+ struct ssol_medium ssol_medium_t;
struct ssol_material* mtl = NULL;
- struct ssol_param_buffer* pbuf = NULL;
- struct thin_dielectric_param* param;
res_T res = RES_OK;
ASSERT(solstice && thin && out_mtl);
@@ -277,34 +260,17 @@ create_material_thin_dielectric
goto error;
}
- res = ssol_param_buffer_create
- (solstice->ssol, sizeof(struct thin_dielectric_param), &pbuf);
- if(res != RES_OK) {
- fprintf(stderr, "Could not create the Solstice Solver parameter buffer.\n");
- goto error;
- }
-
- param = ssol_param_buffer_allocate(pbuf,
- sizeof(struct thin_dielectric_param), ALIGNOF(struct thin_dielectric_param));
- if(!param) {
- fprintf(stderr, "Could not allocate the thin dielectric parameters.\n");
- res = RES_MEM_ERR;
- goto error;
- }
-
- param->thickness = thin->thickness;
- param->absorption = thin->absorption;
- param->refractive_index = thin->refractive_index;
-
shader.normal = mtl_get_normal;
- shader.absorption = thin_dielectric_get_absorption;
- shader.thickness = thin_dielectric_get_thickness;
- shader.refractive_index = thin_dielectric_get_refractive_index;
- SSOL(thin_dielectric_set_shader(mtl, &shader));
- SSOL(material_set_param_buffer(mtl, pbuf));
+ medium_i = solparser_get_medium(solstice->parser, thin->medium_i);
+ medium_t = solparser_get_medium(solstice->parser, thin->medium_t);
+ ssol_medium_i.refractive_index = medium_i->refractive_index;
+ ssol_medium_t.refractive_index = medium_t->refractive_index;
+ ssol_medium_i.absorptivity = medium_i->absorptivity;
+ ssol_medium_t.absorptivity = medium_t->absorptivity;
+ SSOL(thin_dielectric_setup
+ (mtl, &shader, &ssol_medium_i, &ssol_medium_t, thin->thickness));
exit:
- if(pbuf) SSOL(param_buffer_ref_put(pbuf));
*out_mtl = mtl;
return res;
error:
@@ -339,19 +305,27 @@ solstice_create_ssol_material
if(pssol_mtl) {
ssol_mtl = *pssol_mtl;
} else {
+ const struct solparser_material_dielectric* dielectric;
const struct solparser_material_matte* matte;
const struct solparser_material_mirror* mirror;
const struct solparser_material_thin_dielectric* thin_dielectric;
switch(mtl->type) {
- case SOLPARSER_MATERIAL_MIRROR:
- mirror = solparser_get_material_mirror(solstice->parser, mtl->data.mirror);
- res = create_material_mirror(solstice, mirror, &ssol_mtl);
+ case SOLPARSER_MATERIAL_DIELECTRIC:
+ dielectric = solparser_get_material_dielectric
+ (solstice->parser, mtl->data.dielectric);
+ res = create_material_dielectric(solstice, dielectric, &ssol_mtl);
break;
case SOLPARSER_MATERIAL_MATTE:
- matte = solparser_get_material_matte(solstice->parser, mtl->data.matte);
+ matte = solparser_get_material_matte
+ (solstice->parser, mtl->data.matte);
res = create_material_matte(solstice, matte, &ssol_mtl);
break;
+ case SOLPARSER_MATERIAL_MIRROR:
+ mirror = solparser_get_material_mirror
+ (solstice->parser, mtl->data.mirror);
+ res = create_material_mirror(solstice, mirror, &ssol_mtl);
+ break;
case SOLPARSER_MATERIAL_THIN_DIELECTRIC:
thin_dielectric = solparser_get_material_thin_dielectric
(solstice->parser, mtl->data.thin_dielectric);