commit 969b4eab6f6174fcc569a8bbd73b6493d333b5da
parent 288740d34ef6ae423beca6fdde8bc060e242eca8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 24 Mar 2017 14:50:17 +0100
Update the specification of the dielectric materials
Diffstat:
7 files changed, 198 insertions(+), 96 deletions(-)
diff --git a/doc/input b/doc/input
@@ -223,8 +223,12 @@
<dielectric> ::=
dielectric:
- eta_i: REAL # in ]0, INF)
- eta_t: 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)
<matte> ::=
matte:
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -44,6 +44,11 @@ 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
@@ -193,6 +198,7 @@ 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;
@@ -392,6 +398,7 @@ 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);
@@ -445,6 +452,7 @@ 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);
@@ -867,13 +875,105 @@ 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 { ETA_I, ETA_T };
+ enum { MEDIUM_I, MEDIUM_T };
struct solparser_material_dielectric* mtl = NULL;
size_t imtl = SIZE_MAX;
int mask = 0; /* Register the parsed attributes */
@@ -919,12 +1019,12 @@ parse_material_dielectric
} \
mask |= BIT(Flag); \
} (void)0
- if(!strcmp((char*)key->data.scalar.value, "eta_i")) {
- SETUP_MASK(ETA_I, "eta_i");
- res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &mtl->eta_i);
- } else if(!strcmp((char*)key->data.scalar.value, "eta_t")) {
- SETUP_MASK(ETA_T, "eta_t");
- res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &mtl->eta_t);
+ 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);
@@ -945,9 +1045,10 @@ parse_material_dielectric
res = RES_BAD_ARG; \
goto error; \
} (void)0
- CHECK_PARAM(ETA_I, "eta_i");
- CHECK_PARAM(ETA_T, "eta_t");
+ CHECK_PARAM(MEDIUM_I, "medium_i");
+ CHECK_PARAM(MEDIUM_T, "medium_t");
#undef CHECK_PARAM
+
exit:
out_imtl->i = imtl;
return res;
@@ -3732,6 +3833,7 @@ 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);
@@ -4052,6 +4154,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,
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,
diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h
@@ -26,9 +26,16 @@ 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 {
- double eta_i; /* Refractive index of the medium the material "looks at" */
- double eta_t; /* Refractive index of the opposite medium */
+ 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; };
diff --git a/src/parser/test_solparser8.c b/src/parser/test_solparser8.c
@@ -27,6 +27,7 @@ main(int argc, char** argv)
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;
@@ -48,8 +49,18 @@ main(int argc, char** argv)
fprintf(stream, " geometry:\n");
fprintf(stream, " - sphere: { radius: 1 }\n");
fprintf(stream, " material:\n");
- fprintf(stream, " front: { dielectric: { eta_i: 1.0, eta_t: 1.5 } }\n");
- fprintf(stream, " back: { dielectric: { eta_i: 1.5, eta_t: 1.0 } }\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);
@@ -77,14 +88,22 @@ main(int argc, char** argv)
mtl = solparser_get_material(parser, mtl2->front);
CHECK(mtl->type, SOLPARSER_MATERIAL_DIELECTRIC);
dielec = solparser_get_material_dielectric(parser, mtl->data.dielectric);
- CHECK(dielec->eta_i, 1.0);
- CHECK(dielec->eta_t, 1.5);
+ 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);
- CHECK(dielec->eta_i, 1.5);
- CHECK(dielec->eta_t, 1.0);
+ 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);
diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml
@@ -251,32 +251,43 @@
#
# <dielectric> ::=
# dielectric:
-# eta_i: REAL # in ]0, INF)
-# eta_t: REAL # in ]0, INF)
+# medium_i: <dielectric-medium>
+# medium_t: <dielectric-medium>
#
-# invalid eta_i
+# invalid refractive_index
- material:
- dielectric: { eta_i: -1, eta_t: 1 }
+ dielectric:
+ medium_i: &m { refractive_index: 0, absorptivity: 0 }
+ medium_t: *m
---
+# invalid absorptivity
- material:
- dielectric: { eta_i: 0, eta_t: 1 }
+ dielectric:
+ medium_i: &m { refractive_index: 1, absorptivity: -1 }
+ medium_t: *m
---
-# invalid eta_t
+# missing refractive_index
- material:
- dielectric: { eta_i: 1, eta_t: -1 }
+ dielectric:
+ medium_i: &m { absorptivity: 0 }
+ medium_t: *m
---
-# invalid eta_t
+# missing absorptivity
- material:
- dielectric: { eta_i: 1, eta_t: 0 }
+ dielectric:
+ medium_i: &m { refractive_index: 1 }
+ medium_t: *m
---
-# missing eta_t
+# missing medium_i
- material:
- dielectric: { eta_i: 1 }
+ dielectric:
+ medium_t: { refractive_index: 1, absorptivity: 0 }
---
-# missing eta_i
+# missing medium_t
- material:
- dielectric: { eta_t: 1 }
+ dielectric:
+ medium_i: { refractive_index: 1, absorptivity: 0 }
---
#
diff --git a/src/solstice_material.c b/src/solstice_material.c
@@ -18,11 +18,6 @@
#include <solstice/ssol.h>
-struct dielectric_param {
- double eta_i;
- double eta_t;
-};
-
struct matte_param {
double reflectivity;
};
@@ -60,40 +55,6 @@ mtl_get_normal
}
static void
-dielectric_get_eta_i
- (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 dielectric_param* param = ssol_param_buffer_get(buf);
- (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
- *val = param->eta_i;
-}
-
-static void
-dielectric_get_eta_t
- (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 dielectric_param* param = ssol_param_buffer_get(buf);
- (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
- *val = param->eta_t;
-}
-
-static void
matte_get_reflectivity
(struct ssol_device* dev,
struct ssol_param_buffer* buf,
@@ -201,10 +162,10 @@ create_material_dielectric
const struct solparser_material_dielectric* dielectric,
struct ssol_material** out_mtl)
{
+ const struct solparser_medium* medium_i;
+ const struct solparser_medium* medium_t;
struct ssol_dielectric_shader shader = SSOL_DIELECTRIC_SHADER_NULL;
struct ssol_material* mtl = NULL;
- struct ssol_param_buffer* pbuf = NULL;
- struct dielectric_param* param;
res_T res = RES_OK;
ASSERT(solstice && dielectric && out_mtl);
@@ -215,32 +176,16 @@ create_material_dielectric
goto error;
}
- res = ssol_param_buffer_create
- (solstice->ssol, sizeof(struct 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 dielectric_param),
- ALIGNOF(struct dielectric_param));
- if(!param) {
- fprintf(stderr, "Could not allocate the dielectric parameters.\n");
- res = RES_MEM_ERR;
- goto error;
- }
-
- param->eta_i = dielectric->eta_i;
- param->eta_t = dielectric->eta_t;
-
+ 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;
- shader.eta_i = dielectric_get_eta_i;
- shader.eta_t = dielectric_get_eta_t;
- SSOL(dielectric_set_shader(mtl, &shader));
- SSOL(material_set_param_buffer(mtl, pbuf));
+ SSOL(dielectric_setup(mtl, &shader,
+ medium_i->refractive_index,
+ medium_t->refractive_index,
+ medium_i->absorptivity,
+ medium_t->absorptivity));
exit:
- if(pbuf) SSOL(param_buffer_ref_put(pbuf));
*out_mtl = mtl;
return res;
error: