commit 46552ba425acb9d9be534d66301bbb9b92482f07
parent 5aa6d008e2228d1a01de1b5befbbf899fa6c769c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 19 Apr 2017 14:26:09 +0200
Add medium to the list of first level items in the YAML format
Diffstat:
10 files changed, 225 insertions(+), 123 deletions(-)
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -35,6 +35,7 @@ set(SOLPARSER_FILES_SRC
solparser_image.c
solparser_geometry.c
solparser_material.c
+ solparser_medium.c
solparser_pivot.c
solparser_sun.c
solparser_spectrum.c)
@@ -45,6 +46,7 @@ set(SOLPARSER_FILES_INC
solparser_geometry.h
solparser_image.h
solparser_material.h
+ solparser_medium.h
solparser_pivot.h
solparser_shape.h
solparser_sun.h
@@ -110,4 +112,3 @@ if(NOT NO_TEST)
rcmake_copy_runtime_libraries(test_solparser)
endif()
-
diff --git a/doc/input b/doc/input
@@ -91,6 +91,7 @@
<item> ::=
<geometry>
| <material>
+ | <medium>
| <entity>
| <template>
@@ -212,7 +213,7 @@
#----------------------------------------
<material> ::=
- <material-descriptor> | <double-sided-material>
+ material: <material-descriptor> | <double-sided-material>
<double-sided-material> ::=
front: <material-descriptor>
@@ -223,8 +224,8 @@
<dielectric> ::=
dielectric:
- medium_i: <dielectric-medium>
- medium_t: <dielectric-medium>
+ medium_i: <medium-descriptor>
+ medium_t: <medium-descriptor>
[ <normal-map> ]
<matte> ::=
@@ -244,18 +245,22 @@
<thin-dielectric> ::=
thin_dielectric:
thickness: REAL # in [0, INF)
- medium_i: <dielectric-medium>
- medium_t: <dielectric-medium>
+ medium_i: <medium-descriptor>
+ medium_t: <medium-descriptor>
[ <normal-map> ]
-<dielectric-medium> ::=
- refractive_index: REAL # in ]0, INF)
- absorptivity: REAL # in [0, INF)
-
<normal-map> ::=
normal_map: { path: PATH }
#----------------------------------------
+<medium> ::=
+ medium: <medium-descriptor>
+
+<medium-descriptor> ::=
+ refractive_index: REAL # in ]0, INF)
+ absorptivity: REAL # in [0, INF)
+
+#----------------------------------------
<entity> ::=
entity:
<entity-data>
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -114,9 +114,10 @@ parse_item
const yaml_node_t* item)
{
/* Temporary dummy variables */
- struct solparser_material_double_sided_id mtl2;
struct solparser_entity_id entity;
struct solparser_geometry_id geometry;
+ struct solparser_material_double_sided_id mtl2;
+ struct solparser_medium_id medium;
struct solparser_sun* sun;
yaml_node_t* key;
@@ -149,6 +150,8 @@ parse_item
if(!strcmp((char*)key->data.scalar.value, "material")) {
res = parse_material(parser, doc, val, &mtl2);
+ } else if(!strcmp((char*)key->data.scalar.value, "medium")) {
+ res = parse_medium(parser, doc, val, &medium);
} else if(!strcmp((char*)key->data.scalar.value, "entity")) {
res = parse_entity(parser, doc, val, &parser->str2entities, &entity);
if(res == RES_OK) {
@@ -189,12 +192,15 @@ parser_clear(struct solparser* parser)
darray_image_clear(&parser->images);
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);
+ /* Mediums */
+ htable_yaml2sols_clear(&parser->yaml2mediums);
+ darray_medium_clear(&parser->mediums);
+
/* Deferred targeted anchors */
darray_tgtalias_clear(&parser->tgtaliases);
@@ -244,12 +250,15 @@ parser_release(ref_T* ref)
darray_image_release(&parser->images);
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);
+ /* Mediums */
+ htable_yaml2sols_release(&parser->yaml2mediums);
+ darray_medium_release(&parser->mediums);
+
/* Deferred targeted anchors */
darray_tgtalias_release(&parser->tgtaliases);
@@ -573,12 +582,15 @@ solparser_create
darray_image_init(mem_allocator, &parser->images);
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);
+ /* Mediums */
+ htable_yaml2sols_init(mem_allocator, &parser->yaml2mediums);
+ darray_medium_init(mem_allocator, &parser->mediums);
+
/* Deferred targeted anchors */
darray_tgtalias_init(mem_allocator, &parser->tgtaliases);
diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h
@@ -20,6 +20,7 @@
#include "solparser_entity.h"
#include "solparser_image.h"
#include "solparser_material.h"
+#include "solparser_medium.h"
#include "solparser_pivot.h"
#include "solparser_shape.h"
#include "solparser_sun.h"
@@ -204,17 +205,20 @@ struct solparser {
struct str stream_name;
int parser_is_init;
- /* Materia data */
+ /* Material */
struct htable_yaml2sols yaml2mtls; /* Cache of materials */
struct darray_image images;
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;
+ /* Medium */
+ struct htable_yaml2sols yaml2mediums; /* Cache of mediums */
+ struct darray_medium mediums;
+
/* Use to deferred the setup of the anchor targeted by a pivot */
struct darray_tgtalias tgtaliases;
@@ -379,6 +383,13 @@ parse_material
struct solparser_material_double_sided_id* out_imtl2);
extern LOCAL_SYM res_T
+parse_medium
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ yaml_node_t* medium,
+ struct solparser_medium_id* out_imedium);
+
+extern LOCAL_SYM res_T
parse_spectrum
(struct solparser* parser,
yaml_document_t* doc,
diff --git a/src/parser/solparser_material.c b/src/parser/solparser_material.c
@@ -22,98 +22,6 @@
* Helper functions
******************************************************************************/
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,
diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h
@@ -17,6 +17,7 @@
#define SOLPARSER_MATERIAL_H
#include "solparser_image.h"
+#include "solparser_medium.h"
#include <stddef.h>
enum solparser_material_type {
@@ -27,13 +28,6 @@ enum solparser_material_type {
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 */
diff --git a/src/parser/solparser_medium.c b/src/parser/solparser_medium.c
@@ -0,0 +1,131 @@
+/* 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_medium
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ yaml_node_t* medium,
+ struct solparser_medium_id* out_imedium)
+{
+ enum { ABSORPTIVITY, REFRACTIVE_INDEX };
+ struct solparser_medium* mdm = NULL;
+ size_t* pimedium = 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;
+ }
+
+ /* Check whether or not the YAML medium alias an already created Solstice
+ * medium */
+ pimedium = htable_yaml2sols_find(&parser->yaml2mediums, &medium);
+ if(pimedium) {
+ imedium = *pimedium;
+ goto exit;
+ }
+
+ /* 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
+
+ /* Cache the medium */
+ res = htable_yaml2sols_set(&parser->yaml2mediums, &medium, &imedium);
+ if(res != RES_OK) {
+ log_err(parser, medium, "could not register the medium.\n");
+ goto error;
+ }
+
+exit:
+ out_imedium->i = imedium;
+ return res;
+error:
+ if(imedium) {
+ darray_medium_pop_back(&parser->mediums);
+ imedium = SIZE_MAX;
+ }
+ goto exit;
+}
+
diff --git a/src/parser/solparser_medium.h b/src/parser/solparser_medium.h
@@ -0,0 +1,29 @@
+/* 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_MEDIUM_H
+#define SOLPARSER_MEDIUM_H
+
+#include <stddef.h>
+
+struct solparser_medium {
+ double refractive_index;
+ double absorptivity;
+};
+
+struct solparser_medium_id { size_t i; };
+
+#endif /* SOLPARSER_MEDIUM_H */
+
diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c
@@ -43,6 +43,8 @@ main(int argc, char** argv)
NCHECK(stream, NULL);
fprintf(stream, "- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1 }] }\n");
+ fprintf(stream, "- medium: &vacuum {refractive_index: 1, absorptivity: 0}\n");
+ fprintf(stream, "- medium: &glass {refractive_index: 1.5, absorptivity: 20}\n");
fprintf(stream, "- entity:\n");
fprintf(stream, " name: test\n");
fprintf(stream, " primary: 0\n");
@@ -51,16 +53,12 @@ main(int argc, char** argv)
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, " medium_i: *vacuum\n");
+ fprintf(stream, " medium_t: *glass\n");
fprintf(stream, " back:\n");
fprintf(stream, " dielectric:\n");
- fprintf(stream, " medium_i: *inside\n");
- fprintf(stream, " medium_t: *outside\n");
+ fprintf(stream, " medium_i: *glass\n");
+ fprintf(stream, " medium_t: *vacuum\n");
rewind(stream);
CHECK(solparser_setup(parser, NULL, stream), RES_OK);
diff --git a/src/parser/yaml/test_ok_7.yaml b/src/parser/yaml/test_ok_7.yaml
@@ -38,3 +38,16 @@
medium_i: { absorptivity: 0, refractive_index: 1 }
medium_t: { absorptivity: 20, refractive_index: 1.5 }
+---
+- sun: { dni: 1 }
+- medium: &vacuum { refractive_index: 1, absorptivity: 0 }
+- medium: &glass { refractive_index: 1.5, absorptivity: 20 }
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - cylinder: { height: 1, radius: 1 }
+ material:
+ front: {dielectric: { medium_i: *vacuum, medium_t: *glass }}
+ back: {dielectric: {medium_i: *glass, medium_t: *vacuum}}
+