solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit e018be57db63e8dd85e816256384e641588125fc
parent 4464bcfa32d337cb609c4b63bb24927d00f74b68
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 10 Nov 2016 16:28:20 +0100

Load Solstice material data

Diffstat:
Asrc/solstice_material.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/solstice_parser.c | 137++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 157 insertions(+), 26 deletions(-)

diff --git a/src/solstice_material.h b/src/solstice_material.h @@ -0,0 +1,46 @@ +/* Copyright (C) CNRS 2016 + * + * 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 SOLSTICE_MATERIAL_H +#define SOLSTICE_MATERIAL_H + +enum solstice_material_type { + SOLSTICE_MATERIAL_MATTE, + SOLSTICE_MATERIAL_MIRROR +}; + +struct solstice_material_matte { + double reflectivity; /* In [0, 1] */ +}; + +struct solstice_material_mirror { + double roughness; /* In [0, 1] */ + double reflectivity; /* In [0, 1] */ +}; + +struct solstice_material { + enum solstice_material_type type; + union { + struct solstice_material_matte matte; + struct solstice_material_mirror mirror; + } data; +}; + +struct solstice_material_double_sided { + struct solstice_material* front; + struct solstice_material* back; +}; + +#endif /* SOLSTICE_MATERIAL_H */ diff --git a/src/solstice_parser.c b/src/solstice_parser.c @@ -16,9 +16,12 @@ #define _POSIX_C_SOURCE 200112L /* nextafter support */ #include "solstice_parser.h" +#include "solstice_material.h" #include <rsys/cstr.h> #include <rsys/double3.h> +#include <rsys/dynamic_array.h> +#include <rsys/hash_table.h> #include <rsys/ref_count.h> #include <rsys/str.h> @@ -27,11 +30,33 @@ #include <string.h> #include <yaml.h> +/* Declare the array of materials */ +#define DARRAY_NAME material +#define DARRAY_DATA struct solstice_material +#include <rsys/dynamic_array.h> + +/* Declare the array of the double sided materials */ +#define DARRAY_NAME material2 +#define DARRAY_DATA struct solstice_material_double_sided +#include <rsys/dynamic_array.h> + +/* Declare the hash table that maps the address of a YAML node to the id of its + * in memory representation. */ +#define HTABLE_NAME yaml2sols +#define HTABLE_KEY yaml_node_t* +#define HTABLE_DATA size_t +#include <rsys/hash_table.h> + struct solstice_parser { yaml_parser_t parser; struct str stream_name; int parser_is_init; + struct htable_yaml2sols yaml2mtls; /* Cache of materials */ + + struct darray_material mtls; /* Loaded materials */ + struct darray_material2 mtls2; /* Loaded double sided materials */ + ref_T ref; struct mem_allocator* allocator; }; @@ -121,6 +146,9 @@ parser_release(ref_T* ref) parser = CONTAINER_OF(ref, struct solstice_parser, ref); if(parser->parser_is_init) yaml_parser_delete(&parser->parser); str_release(&parser->stream_name); + htable_yaml2sols_release(&parser->yaml2mtls); + darray_material_release(&parser->mtls); + darray_material2_release(&parser->mtls2); MEM_RM(parser->allocator, parser); } @@ -522,14 +550,14 @@ static res_T parse_material_matte (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* matte) + const yaml_node_t* matte, + struct solstice_material* mtl) { enum { REFLECTIVITY }; - double reflectivity; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ res_T res = RES_OK; - ASSERT(doc && matte); + ASSERT(doc && matte && mtl); if(matte->type != YAML_MAPPING_NODE) { log_err(parser, matte, "expect a mapping of matte material parameters.\n"); @@ -537,6 +565,7 @@ parse_material_matte goto error; } + mtl->type = SOLSTICE_MATERIAL_MATTE; n = matte->data.mapping.pairs.top - matte->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -557,7 +586,7 @@ parse_material_matte goto error; } mask |= BIT(REFLECTIVITY); - res = parse_real(parser, val, 0, 1, &reflectivity); + res = parse_real(parser, val, 0, 1, &mtl->data.matte.reflectivity); } else { log_err(parser, key, "unknown matte parameter `%s'.\n", key->data.scalar.value); @@ -572,8 +601,6 @@ parse_material_matte goto error; } - /* TODO create the matte material */ - exit: return res; error: @@ -584,15 +611,14 @@ static res_T parse_material_mirror (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* mirror) + const yaml_node_t* mirror, + struct solstice_material* mtl) { enum { REFLECTIVITY, ROUGHNESS }; - double reflectivity; - double roughness; int mask = 0; /* Register the parsed attributes */ intptr_t i, n; res_T res = RES_OK; - ASSERT(doc && mirror); + ASSERT(doc && mirror && mtl); if(mirror->type != YAML_MAPPING_NODE) { log_err(parser, mirror, @@ -600,6 +626,8 @@ parse_material_mirror res = RES_BAD_ARG; goto error; } + + mtl->type = SOLSTICE_MATERIAL_MIRROR; n = mirror->data.mapping.pairs.top - mirror->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -624,10 +652,10 @@ parse_material_mirror } (void)0 if(!strcmp((char*)key->data.scalar.value, "reflectivity")) { SETUP_MASK(REFLECTIVITY, "reflectivity"); - res = parse_real(parser, val, 0, 1, &reflectivity); + res = parse_real(parser, val, 0, 1, &mtl->data.mirror.reflectivity); } else if(!strcmp((char*)key->data.scalar.value, "roughness")) { SETUP_MASK(ROUGHNESS, "roughness"); - res = parse_real(parser, val, 0, 1, &roughness); + res = parse_real(parser, val, 0, 1, &mtl->data.mirror.roughness); } else { log_err(parser, key, "unknown mirror attribute `%s'.\n", key->data.scalar.value); @@ -647,8 +675,6 @@ parse_material_mirror CHECK_PARAM(ROUGHNESS, "roughness"); #undef CHECK_PARAM - /* TODO create the mirror material */ - exit: return res; error: @@ -659,16 +685,34 @@ static res_T parse_material_descriptor (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* desc) + yaml_node_t* desc, + struct solstice_material** out_mtl) { enum { DESCRIPTOR }; + struct solstice_material* mtl = NULL; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ + size_t* pimtl; + size_t imtl; res_T res = RES_OK; - ASSERT(doc && desc); + ASSERT(doc && desc && out_mtl); + + /* Check whether or not the YAML descriptor alias an already created Solstice + * material */ + pimtl = htable_yaml2sols_find(&parser->yaml2mtls, &desc); + if(pimtl) { + mtl = darray_material_data_get(&parser->mtls) + *pimtl; + goto exit; + } - /* TODO If the descriptor is an alias of an already created material skip the - * parsing and return the aliased material descriptor */ + /* Allocate the solstice material */ + imtl = darray_material_size_get(&parser->mtls); + res = darray_material_resize(&parser->mtls, imtl + 1); + if(res != RES_OK) { + log_err(parser, desc, "could not allocate the material descriptor.\n"); + goto error; + } + mtl = darray_material_data_get(&parser->mtls) + imtl; if(desc->type != YAML_MAPPING_NODE) { log_err(parser, desc, "expect a material descriptor.\n"); @@ -699,10 +743,10 @@ parse_material_descriptor } (void)0 if(!strcmp((char*)key->data.scalar.value, "matte")) { SETUP_MASK(DESCRIPTOR, "descriptor"); - res = parse_material_matte(parser, doc, val); + res = parse_material_matte(parser, doc, val, mtl); } else if(!strcmp((char*)key->data.scalar.value, "mirror")) { SETUP_MASK(DESCRIPTOR, "descriptor"); - res = parse_material_mirror(parser, doc, val); + res = parse_material_mirror(parser, doc, val, mtl); } else { log_err(parser, key, "unknown material descriptor `%s'.\n", key->data.scalar.value); @@ -719,9 +763,20 @@ parse_material_descriptor goto error; } + res = htable_yaml2sols_set(&parser->yaml2mtls, &desc, &imtl); + if(res != RES_OK) { + log_err(parser, desc, "could not register the material.\n"); + goto error; + } + exit: + *out_mtl = mtl; return res; error: + if(mtl) { + darray_material_pop_back(&parser->mtls); + mtl = NULL; + } goto exit; } @@ -729,9 +784,12 @@ static res_T parse_material (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* mtl) + yaml_node_t* mtl, + struct solstice_material_double_sided** out_mtl2) { enum { FRONT, BACK }; + struct solstice_material_double_sided* mtl2; + size_t imtl2; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ res_T res = RES_OK; @@ -743,6 +801,15 @@ parse_material goto error; } + /* Allocate the double sided material */ + imtl2 = darray_material2_size_get(&parser->mtls2); + res = darray_material2_resize(&parser->mtls2, imtl2 + 1); + if(res != RES_OK) { + log_err(parser, mtl, "could not allocate the material.\n"); + goto error; + } + mtl2 = darray_material2_data_get(&parser->mtls2) + imtl2; + n = mtl->data.mapping.pairs.top - mtl->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -768,14 +835,15 @@ parse_material } (void)0 if(!strcmp((char*)key->data.scalar.value, "front")) { SETUP_MASK(FRONT, "front"); - res = parse_material_descriptor(parser, doc, val); + res = parse_material_descriptor(parser, doc, val, &mtl2->front); } else if(!strcmp((char*)key->data.scalar.value, "back")) { SETUP_MASK(BACK, "back"); - res = parse_material_descriptor(parser, doc, val); + res = parse_material_descriptor(parser, doc, val, &mtl2->back); } else { SETUP_MASK(FRONT, "front"); SETUP_MASK(BACK, "back"); - res = parse_material_descriptor(parser, doc, mtl); + res = parse_material_descriptor(parser, doc, mtl, &mtl2->front); + mtl2->back = mtl2->front; } if(res != RES_OK) goto error; #undef SETUP_MASK @@ -792,8 +860,13 @@ parse_material #undef CHECK_PARAM exit: + *out_mtl2 = mtl2; return res; error: + if(mtl2) { + darray_material2_pop_back(&parser->mtls2); + mtl2 = NULL; + } goto exit; } @@ -1387,6 +1460,7 @@ parse_object const yaml_node_t* object) { enum { MATERIAL, SHAPE, TRANSFORM }; + struct solstice_material_double_sided* mtl2; double translation[3] = {0, 0, 0}; double rotation[3] = {0, 0, 0}; intptr_t i, n; @@ -1427,7 +1501,7 @@ parse_object } (void)0 if(!strcmp((char*)key->data.scalar.value, "material")) { SETUP_MASK(MATERIAL, "material"); - res = parse_material(parser, doc, val); + res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "cuboid")) { SETUP_MASK(SHAPE, "shape"); res = parse_cuboid(parser, doc, val); @@ -2046,6 +2120,7 @@ parse_item { yaml_node_t* key; yaml_node_t* val; + struct solstice_material_double_sided* mtl2; intptr_t n; res_T res = RES_OK; ASSERT(doc && item); @@ -2075,7 +2150,7 @@ parse_item if(!strcmp((char*)key->data.scalar.value, "instance")) { res = parse_instance(parser, doc, val); } else if(!strcmp((char*)key->data.scalar.value, "material")) { - res = parse_material(parser, doc, val); + res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "node")) { res = parse_node(parser, doc, val); } else if(!strcmp((char*)key->data.scalar.value, "object")) { @@ -2119,6 +2194,11 @@ solstice_parser_create ref_init(&parser->ref); str_init(mem_allocator, &parser->stream_name); + htable_yaml2sols_init(mem_allocator, &parser->yaml2mtls); + + darray_material_init(mem_allocator, &parser->mtls); + darray_material2_init(mem_allocator, &parser->mtls2); + exit: *out_parser = parser; return res; @@ -2194,6 +2274,11 @@ solstice_parser_load(struct solstice_parser* parser) filename = str_cget(&parser->stream_name); + /* Clean up previously loaded data */ + htable_yaml2sols_clear(&parser->yaml2mtls); + darray_material_clear(&parser->mtls); + darray_material2_clear(&parser->mtls2); + if(!parser->parser_is_init) { res = RES_BAD_OP; goto error;