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 ded931b64237f1a24c661149cedc53e2d355549f
parent 8842527f22690fee84e7e0fc2ca7f2eb7c059830
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 25 Jan 2017 10:22:11 +0100

Merge remote-tracking branch 'origin/master' into receiver

Diffstat:
MREADME.md | 2+-
Mcmake/parser/CMakeLists.txt | 5+----
Mdoc/input | 30++++++++++++++++++------------
Msrc/parser/solparser.c | 301+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msrc/parser/solparser_entity.h | 2+-
Msrc/parser/solparser_geometry.h | 2+-
Msrc/parser/test_solparser2.c | 4+---
Asrc/parser/test_solparser5.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/parser/yaml/test_ko_0.yaml | 1301++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Dsrc/parser/yaml/test_ko_1.yaml | 143-------------------------------------------------------------------------------
Dsrc/parser/yaml/test_ko_2.yaml | 30------------------------------
Msrc/parser/yaml/test_ok_1.yaml | 8--------
Msrc/solstice_args.c | 25+++++++++++++++++++++++--
Msrc/solstice_c.h | 2+-
Msrc/solstice_entity.c | 7++++++-
Msrc/solstice_object.c | 6+++++-
16 files changed, 1544 insertions(+), 465 deletions(-)

diff --git a/README.md b/README.md @@ -28,7 +28,7 @@ project from the `cmake/CMakeLists.txt` file by appending to the Solstice is developed by [|Meso|Star>](http://www.meso-star.com) for the [National Center for Scientific Research](http://www.cnrs.fr/index.php) (CNRS). -It is a free software copyright (C) CNRS 2016 and it is released under the +It is a free software copyright (C) CNRS 2016-2017 and it is released under the [OSI](http://opensource.org)-approved GPL v3+ license. You are welcome to redistribute it under certain conditions; refer to the COPYING file for details. diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt @@ -78,14 +78,11 @@ if(NOT NO_TEST) ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_3.yaml) add_test(test_solstice_parser_ko_0 test_solparser -e ${SOLPARSER_SOURCE_DIR}/yaml/test_ko_0.yaml) - add_test(test_solstice_parser_ko_1 test_solparser -e - ${SOLPARSER_SOURCE_DIR}/yaml/test_ko_1.yaml) - add_test(test_solstice_parser_ko_2 test_solparser -e - ${SOLPARSER_SOURCE_DIR}/yaml/test_ko_2.yaml) new_test(test_solparser2) new_test(test_solparser3) new_test(test_solparser4) + new_test(test_solparser5) rcmake_copy_runtime_libraries(test_solparser) endif() diff --git a/doc/input b/doc/input @@ -77,6 +77,7 @@ 2/ Grammar -------------------------------------------------------------------------------- <solar-factory> ::= + <sun> <items> <items> ::= @@ -88,7 +89,6 @@ | <material> | <entity> | <template> - | <sun> ---------------------------------------- <geometry> ::= @@ -128,12 +128,12 @@ <cuboid> ::= cuboid: - size: <real3> + size: <real3*+> <cylinder> ::= cylinder: - height: REAL - radius: REAL + height: REAL # in ]0, INF) + radius: REAL # in ]0, INF) [ slices: INTEGER ] # in [4, 4096]. Default 16 <obj> ::= @@ -142,12 +142,12 @@ <parabol> ::= parabol: # x^2 + y^2 - 4*focal*z = 0 - focal: REAL + focal: REAL # in ]0, INF) clip: <polyclip-list> <parabolic-cylinder> ::= parabolic-cylinder: # y^2 - 4*focal*z = 0 - focal: REAL + focal: REAL # in ]0, INF) clip: <polyclip-list> <plane> ::= @@ -156,8 +156,8 @@ <sphere> ::= sphere: - radius: REAL -[ slices: INTEGER ] # Default 16 + radius: REAL # in ]0, INF) +[ slices: INTEGER ] # in [4, 4096]. Default 16 <stl> ::= stl: @@ -228,8 +228,9 @@ name: STRING position: <real3> +# "self" references the first level entity <entity-identifier> ::= - STRING[.STRING ... ] + <self|STRING>[.STRING ... ] <anchor-identifier> ::= <entity-identifier>.STRING @@ -237,7 +238,7 @@ ---------------------------------------- <sun> ::= sun: - dni: REAL # Direct Normal Irradiance in ]0, INF) */ + dni: REAL # Direct Normal Irradiance in ]0, INF) <spectrum> [ <radial-angular-distribution> ] @@ -267,13 +268,18 @@ - REAL - REAL +<real3*+> ::= + - REAL # in ]0, inf) + - REAL # in ]0, inf) + - REAL # in ]0, inf) + <spectrum> ::= spectrum: - <spectrum-data> [ - <spectrum-data> ... ] <spectrum-data> ::= - wavelength: REAL - data: REAL + wavelength: REAL # in [0, INF) + data: REAL # in [0, INF) diff --git a/src/parser/solparser.c b/src/parser/solparser.c @@ -34,6 +34,16 @@ #include <string.h> #include <yaml.h> +struct target_alias { + struct solparser_pivot_id pivot; + const yaml_node_t* alias; /* Anchor */ +}; + +/* Declare the target_alias array */ +#define DARRAY_NAME tgtalias +#define DARRAY_DATA struct target_alias +#include <rsys/dynamic_array.h> + /* Declare the array of matte materials */ #define DARRAY_NAME matte #define DARRAY_DATA struct solparser_material_matte @@ -160,6 +170,9 @@ struct solparser { struct darray_matte mattes; struct darray_mirror mirrors; + /* Use to deferred the setup of the anchor targeted by a pivot */ + struct darray_tgtalias tgtaliases; + /* Shape data */ struct darray_shape shapes; /* Generic loaded shapes */ struct darray_cuboid cuboids; @@ -244,6 +257,95 @@ log_err va_end(vargs_list); } +static INLINE void +log_node(const struct solparser* parser, const yaml_node_t* node) +{ + fprintf(stderr, "\tby %s:%lu:%lu\n", + str_cget(&parser->stream_name), + (unsigned long)node->start_mark.line+1, + (unsigned long)node->start_mark.column+1); +} + +static res_T +flush_deferred_target_aliases + (struct solparser* parser, + const yaml_node_t* node, + const struct solparser_entity_id entity_id) +{ + const struct solparser_entity* entity; + struct darray_char alias; + size_t i, n; + size_t prefix_len; + res_T res = RES_OK; + ASSERT(parser); + + darray_char_init(parser->allocator, &alias); + + if(!darray_tgtalias_size_get(&parser->tgtaliases)) + goto exit; /* No deferred target alias */ + + /* Retrieve the entity referenced by the 'self' keyword */ + entity = solparser_get_entity(parser, entity_id); + + /* Copy the entity name */ + prefix_len = strlen(str_cget(&entity->name)); + res = darray_char_resize(&alias, prefix_len); + if(res != RES_OK) { + log_err(parser, node, + "could not reserve the prefix of the targeted alias name.\n"); + goto error; + } + strncpy(darray_char_data_get(&alias), str_cget(&entity->name), prefix_len); + + n = darray_tgtalias_size_get(&parser->tgtaliases); + FOR_EACH(i, 0, n) { + const struct solparser_anchor* anchor; + struct solparser_pivot* pivot; + const struct target_alias* tgt; + size_t ianchor; + size_t len; + + tgt = darray_tgtalias_cdata_get(&parser->tgtaliases) + i; + ASSERT(!strncmp((char*)tgt->alias->data.scalar.value, "self.", 5)); + + /* Copy the anchor alias */ + len = strlen((char*)tgt->alias->data.scalar.value) + - 4/*strlen(self)*/ + 1/*NULL char*/; + res = darray_char_resize(&alias, prefix_len + len); + if(res != RES_OK) { + log_err(parser, node, + "could not reserve the suffix of the targeted alias name.\n"); + goto error; + } + strcpy(darray_char_data_get(&alias) + prefix_len, + (char*)tgt->alias->data.scalar.value+4); + + /* Retrieve the anchor */ + anchor = solparser_find_anchor(parser, darray_char_cdata_get(&alias)); + if(!anchor) { + log_err(parser, tgt->alias, "undefined anchor `%s'.\n", + tgt->alias->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } + + /* Define the targeted anchor of the pivot */ + pivot = darray_pivot_data_get(&parser->pivots) + tgt->pivot.i; + ASSERT(pivot->target_type == SOLPARSER_TARGET_ANCHOR); + ianchor = (size_t)(anchor - darray_anchor_cdata_get(&parser->anchors)); + ASSERT(ianchor < darray_anchor_size_get(&parser->anchors)); + pivot->target.anchor.i = ianchor; + } + + darray_tgtalias_clear(&parser->tgtaliases); + +exit: + darray_char_release(&alias); + return res; +error: + goto exit; +} + /* Clean up loaded data */ static INLINE void parser_clear(struct solparser* parser) @@ -257,6 +359,9 @@ parser_clear(struct solparser* parser) darray_matte_clear(&parser->mattes); darray_mirror_clear(&parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_clear(&parser->tgtaliases); + /* Shapes */ darray_shape_clear(&parser->shapes); darray_cuboid_clear(&parser->cuboids); @@ -304,6 +409,9 @@ parser_release(ref_T* ref) darray_matte_release(&parser->mattes); darray_mirror_release(&parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_release(&parser->tgtaliases); + /* Shapes */ darray_shape_release(&parser->shapes); darray_cuboid_release(&parser->cuboids); @@ -369,18 +477,19 @@ parse_real double u = nextafter(upper_bound, DBL_MAX); int l_excluded = (l == (double) (int) l); int u_excluded = (u == (double) (int) u); - if (l_excluded && u_excluded) + if(l_excluded && u_excluded) { log_err(parser, real, "%g is not in ]%g, %g[.\n", *dst, l, u); - else if (l_excluded) + } else if(l_excluded) { log_err(parser, real, "%g is not in ]%g, %g].\n", *dst, l, upper_bound); - else if (u_excluded) + } else if(u_excluded) { log_err(parser, real, "%g is not in [%g, %g[.\n", *dst, lower_bound, u); - else + } else { log_err(parser, real, "%g is not in [%g, %g].\n", *dst, lower_bound, upper_bound); + } res = RES_BAD_ARG; goto error; } @@ -572,17 +681,16 @@ parse_transform } else if(!strcmp((char*)key->data.scalar.value, "rotation")) { SETUP_MASK(ROTATION, "rotation"); res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, rotation); - if(res == RES_OK) { - rotation[0] = MDEG2RAD(rotation[0]); - rotation[1] = MDEG2RAD(rotation[1]); - rotation[2] = MDEG2RAD(rotation[2]); - } } else { log_err(parser, key, "unknown transform parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } exit: @@ -644,8 +752,12 @@ parse_spectrum_data log_err(parser, key, "unknown spectrum data parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -767,8 +879,12 @@ parse_material_matte log_err(parser, key, "unknown matte parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(REFLECTIVITY))) { @@ -851,8 +967,12 @@ parse_material_mirror log_err(parser, key, "unknown mirror attribute `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -951,7 +1071,10 @@ parse_material_descriptor res = RES_BAD_ARG; goto error; } - if(res != RES_OK) goto error; + if(res != RES_OK) { + log_node(parser, key); + goto error; + } #undef SETUP_MASK } @@ -1043,8 +1166,12 @@ parse_material SETUP_MASK(BACK, "back"); res = parse_material_descriptor(parser, doc, mtl, &mtl2->front); mtl2->back = mtl2->front; + if(res != RES_OK) goto error; /* Discard log_node */ + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -1202,15 +1329,19 @@ parse_polyclip log_err(parser, key, "unknown clipping polygon parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } #define CHECK_PARAM(Flag, Name) \ if(!(mask & BIT(Flag))) { \ log_err(parser, polyclip, \ - "the clipping polygon parameter `"Name"' is missing.\n"); \ + "the clipping polygon parameter `"Name"' is missing.\n"); \ res = RES_BAD_ARG; \ goto error; \ } (void)0 @@ -1322,8 +1453,12 @@ parse_cuboid log_err(parser, key, "unknown cuboid parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(SIZE))) { @@ -1396,10 +1531,10 @@ parse_cylinder } (void)0 if(!strcmp((char*)key->data.scalar.value, "height")) { SETUP_MASK(HEIGHT, "height"); - res = parse_real(parser, val, 0, DBL_MAX, &shape->height); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &shape->height); } else if(!strcmp((char*)key->data.scalar.value, "radius")) { SETUP_MASK(RADIUS, "radius"); - res = parse_real(parser, val, 0, DBL_MAX, &shape->radius); + res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &shape->radius); } else if(!strcmp((char*)key->data.scalar.value, "slices")) { SETUP_MASK(SLICES, "slices"); res = parse_integer(parser, val, 4, 4096, &shape->nslices); @@ -1407,8 +1542,12 @@ parse_cylinder log_err(parser, key, "unknown cylinder parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -1497,8 +1636,12 @@ parse_imported_geometry log_err(parser, key, "unknown %s parameter `%s'.\n", name, key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(PATH))) { @@ -1594,8 +1737,12 @@ parse_paraboloid log_err(parser, key, "unknown %s parameter `%s'.\n", name, key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } #define CHECK_PARAM(Flag, Name) \ @@ -1674,8 +1821,12 @@ parse_plane log_err(parser, key, "unknown plane parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(CLIP))) { log_err(parser, plane, "the plane parameter `clip' is missing.\n"); @@ -1755,8 +1906,12 @@ parse_sphere log_err(parser, key, "unknown sphere parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -1894,8 +2049,12 @@ parse_object log_err(parser, key, "unknown object parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -2145,8 +2304,12 @@ parse_anchor log_err(parser, key, "unknown anchor parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -2350,7 +2513,10 @@ parse_entity res = RES_BAD_ARG; goto error; } - if(res != RES_OK) goto error; + if(res != RES_OK) { + log_node(parser, key); + goto error; + } #undef SETUP_MASK } @@ -2403,6 +2569,7 @@ static res_T parse_anchor_alias (struct solparser* parser, const yaml_node_t* alias, + const struct solparser_pivot_id pivot, struct solparser_anchor_id* out_ianchor) { const struct solparser_anchor* anchor = NULL; @@ -2416,17 +2583,28 @@ parse_anchor_alias goto error; } - anchor = solparser_find_anchor(parser, (char*)alias->data.scalar.value); - if(!anchor) { - log_err(parser, alias, "undefined anchor `%s'.\n", - alias->data.scalar.value); - res = RES_BAD_ARG; - goto error; - } + if(!strncmp((char*)alias->data.scalar.value, "self.", 5)) { + struct target_alias tgt; + tgt.pivot = pivot; + tgt.alias = alias; + res = darray_tgtalias_push_back(&parser->tgtaliases, &tgt); + if(res != RES_OK) { + log_err(parser, alias, "could not register the anchor alias.\n"); + goto error; + } + } else { + anchor = solparser_find_anchor(parser, (char*)alias->data.scalar.value); + if(!anchor) { + log_err(parser, alias, "undefined anchor `%s'.\n", + alias->data.scalar.value); + res = RES_BAD_ARG; + goto error; + } - ianchor = anchor - darray_anchor_cdata_get(&parser->anchors); - ASSERT(ianchor >= 0); - ASSERT((size_t)ianchor < darray_anchor_size_get(&parser->anchors)); + ianchor = anchor - darray_anchor_cdata_get(&parser->anchors); + ASSERT(ianchor >= 0); + ASSERT((size_t)ianchor < darray_anchor_size_get(&parser->anchors)); + } exit: out_ianchor->i = (size_t)ianchor; @@ -2446,6 +2624,7 @@ parse_target enum { POLICY }; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ + struct solparser_pivot_id pivot_id; res_T res = RES_OK; ASSERT(doc && target && pivot); @@ -2455,6 +2634,9 @@ parse_target goto error; } + /* Retrieve the pivot id */ + pivot_id.i = (size_t)(pivot - darray_pivot_cdata_get(&parser->pivots)); + n = target->data.mapping.pairs.top - target->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; @@ -2479,7 +2661,7 @@ parse_target if(!strcmp((char*)key->data.scalar.value, "anchor")) { SETUP_MASK(POLICY, "policy"); pivot->target_type = SOLPARSER_TARGET_ANCHOR; - res = parse_anchor_alias(parser, val, &pivot->target.anchor); + res = parse_anchor_alias(parser, val, pivot_id, &pivot->target.anchor); } else if(!strcmp((char*)key->data.scalar.value, "direction")) { SETUP_MASK(POLICY, "policy"); pivot->target_type = SOLPARSER_TARGET_DIRECTION; @@ -2505,7 +2687,10 @@ parse_target res = RES_BAD_ARG; goto error; } - if(res != RES_OK) goto error; + if(res != RES_OK) { + log_node(parser, key); + goto error; + } #undef SETUP_MASK } @@ -2586,8 +2771,12 @@ parse_pivot log_err(parser, key, "unknown pivot parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } #define CHECK_PARAM(Flag, Name) \ @@ -2660,8 +2849,12 @@ parse_buie log_err(parser, key, "unknown buie parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(CSR))) { @@ -2721,8 +2914,12 @@ parse_pillbox log_err(parser, pillbox, "unknown pillbox parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; } if(!(mask & BIT(APERTURE))) { @@ -2811,8 +3008,12 @@ parse_sun log_err(parser, key, "unknown sun parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; #undef SETUP_MASK } @@ -2885,6 +3086,9 @@ parse_item res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "entity")) { res = parse_entity(parser, doc, val, &parser->str2entities, &entity); + if(res == RES_OK) { + res = flush_deferred_target_aliases(parser, item, entity); + } } else if(!strcmp((char*)key->data.scalar.value, "template")) { /* The parsing of the template data is deferred to its explicit used in the * definition of an entity. If the parsing of the template becomes a @@ -2896,8 +3100,12 @@ parse_item } else { log_err(parser, key, "unknown item `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; + goto error; + } + if(res != RES_OK) { + log_node(parser, key); + goto error; } - if(res != RES_OK) goto error; exit: return res; @@ -2935,6 +3143,9 @@ solparser_create darray_matte_init(mem_allocator, &parser->mattes); darray_mirror_init(mem_allocator, &parser->mirrors); + /* Deferred targeted anchors */ + darray_tgtalias_init(mem_allocator, &parser->tgtaliases); + /* Shapes */ darray_shape_init(mem_allocator, &parser->shapes); darray_cuboid_init(mem_allocator, &parser->cuboids); diff --git a/src/parser/solparser_entity.h b/src/parser/solparser_entity.h @@ -56,7 +56,7 @@ struct solparser_entity_id { size_t i; }; #include <rsys/hash_table.h> struct solparser_entity { - double rotation[3]; + double rotation[3]; /* In degrees */ double translation[3]; struct str name; diff --git a/src/parser/solparser_geometry.h b/src/parser/solparser_geometry.h @@ -24,7 +24,7 @@ struct solparser_object { struct solparser_material_double_sided_id mtl2; struct solparser_shape_id shape; - double rotation[3]; + double rotation[3]; /* In degrees */ double translation[3]; }; diff --git a/src/parser/test_solparser2.c b/src/parser/test_solparser2.c @@ -166,9 +166,7 @@ main(int argc, char** argv) entity_id = solparser_entity_get_child(entity, 1); entity1b = solparser_get_entity(parser, entity_id); CHECK(d3_eq(entity1b->translation, d3_splat(tmp, 0)), 1); - tmp[0] = MDEG2RAD(3.14); - tmp[2] = MDEG2RAD(-1); - CHECK(d3_eq_eps(entity1b->rotation, tmp, 1.e-6), 1); + CHECK(d3_eq_eps(entity1b->rotation, d3(tmp, 3.14, 0, -1), 1.e-6), 1); CHECK(strcmp("lvl1b", str_cget(&entity1b->name)), 0); CHECK(solparser_entity_get_children_count(entity1b), 1); CHECK(entity1b->type, SOLPARSER_ENTITY_GEOMETRY); diff --git a/src/parser/test_solparser5.c b/src/parser/test_solparser5.c @@ -0,0 +1,141 @@ +/* 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" + +static const char* input[] = { + "- sun:\n", + " dni: 1\n", + " spectrum: [{wavelength: 1, data: 1}]\n", + "- geometry: &cuboid\n", + " - cuboid: { size: [1, 2, 3] }\n", + " material: { matte: { reflectivity: 1 } }\n", + "- template: &template\n", + " name: lvl1\n", + " geometry: *cuboid\n", + " anchors:\n", + " - name: anchor0\n", + " position: [1, 2, 3]\n", + " children:\n", + " - name: lvl2\n", + " pivot:\n", + " point: [1, 2, 3]\n", + " normal: [4, 5, 6]\n", + " target: { anchor: self.lvl1.anchor0 }\n", + "- entity:\n", + " name: entity0\n", + " children: [ *template ]\n", + "- entity:\n", + " name: entity1\n", + " children: [ *template ]\n", + NULL +}; + +static void +check_entity(struct solparser* parser, const struct solparser_entity* entity) +{ + const struct solparser_anchor* anchor; + const struct solparser_pivot* pivot; + struct solparser_entity_id entity_id; + double tmp[3]; + + CHECK(entity->type, SOLPARSER_ENTITY_EMPTY); + + CHECK(solparser_entity_get_children_count(entity), 1); + entity_id = solparser_entity_get_child(entity, 0); + entity = solparser_get_entity(parser, entity_id); + CHECK(strcmp(str_cget(&entity->name), "lvl1"), 0); + CHECK(entity->type, SOLPARSER_ENTITY_GEOMETRY); + + CHECK(solparser_entity_get_children_count(entity), 1); + entity_id = solparser_entity_get_child(entity, 0); + entity = solparser_get_entity(parser, entity_id); + CHECK(strcmp(str_cget(&entity->name), "lvl2"), 0); + CHECK(entity->type, SOLPARSER_ENTITY_PIVOT); + + pivot = solparser_get_pivot(parser, entity->data.pivot); + CHECK(d3_eq(pivot->point, d3(tmp, 1, 2, 3)), 1); + CHECK(d3_eq(pivot->normal, d3(tmp, 4, 5, 6)), 1); + CHECK(pivot->target_type, SOLPARSER_TARGET_ANCHOR); + + anchor = solparser_get_anchor(parser, pivot->target.anchor); + CHECK(strcmp(str_cget(&anchor->name), "anchor0"), 0); + CHECK(d3_eq(anchor->position, d3(tmp, 1, 2, 3)), 1); +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct solparser* parser; + const struct solparser_entity* entity; + struct solparser_entity_id entity_id; + struct solparser_entity_iterator it, it_end; + size_t i; + int entity0 = 0; + int entity1 = 0; + 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); + i = 0; + while(input[i]) { + const size_t len = strlen(input[i]); + CHECK(fwrite(input[i], 1, len, stream), len); + ++i; + } + 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, &it_end); + CHECK(solparser_entity_iterator_eq(&it, &it_end), 0); + + while(!solparser_entity_iterator_eq(&it, &it_end)) { + entity_id = solparser_entity_iterator_get(&it); + entity = solparser_get_entity(parser, entity_id); + if(!strcmp(str_cget(&entity->name), "entity0")) { + CHECK(entity0, 0); + entity0 = 1; + check_entity(parser, entity); + } else if(!strcmp(str_cget(&entity->name), "entity1")) { + CHECK(entity1, 0); + entity1 = 1; + check_entity(parser, entity); + } else { + FATAL("Unexpected entity name.\n"); + } + solparser_entity_iterator_next(&it); + } + CHECK(entity0, 1); + CHECK(entity1, 1); + + 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 @@ -1,318 +1,1194 @@ -# unknown item dummy -- dummy: - geometry: - - cuboid: { size: [1, 2, 3] } - material: { matte: { reflectivity: -1 } } +# +# <spectrum> ::= +# spectrum: +# - <spectrum-data> +# [ - <spectrum-data> ... ] +# +# <spectrum-data> ::= +# wavelength: REAL in [0, INF) +# data: REAL in [0, INF) +# + +# missing spectrum definition +- sun: { spectrum: } +--- +# missing wavelength +- sun: { spectrum: [{data: 1}] } +--- +# missing data +- sun: { spectrum: [{wavelength: 1}] } +--- +# 2x wavelength +- sun: { spectrum: [{wavelength: 1, wavelength: 1}] } +--- +# 2x data +- sun: { spectrum: [{data: 1, data: 1}] } +--- +# unknown dummy parameter +- sun: { spectrum: [{dummy: 1}] } +--- +# missing wavelength value +- sun: { spectrum: [{wavelength: , data: 1}] } +--- +# missing data value +- sun: { spectrum: [{wavelength: 1, data: }] } +--- +# wavelength should be a number +- sun: { spectrum: [{wavelength: "dummy", data: 1}] } +--- +# data should be a number +- sun: { spectrum: [{wavelength: 1, data: "dummy"}] } +--- +# -1 invalid +- sun: { spectrum: [{wavelength: -1, data: 1}] } +--- +# -1 invalid +- sun: { spectrum: [{wavelength: 1, data: -1}] } +--- + +# +# dni: REAL # Direct Normal Irradiance in ]0, INF) +# + +# missing dni value +- sun: { dni: } +--- +# dni should be a number +- sun: { dni: "dummy" } +--- +# 0 invalid +- sun: { dni: 0 } +--- +# 2x dni +- sun: { dni: 1, dni: 1 } +--- + +# +# <pillbox> ::= +# pillbox: +# aperture: REAL # in ]0, 90] +# + +# missing pillbox definition +- sun: { pillbox: } +--- +# missing aperture value +- sun: { pillbox: { aperture: } } +--- +# aperture should be a number +- sun: { pillbox: { aperture: "dummy"} } +--- +# 0 invalid +- sun: { pillbox: { aperture: 0} } +--- +# 91 invalid +- sun: { pillbox: { aperture: 91} } +--- +# 2x aperture +- sun: { pillbox: { aperture: 1, aperture: 1} } +--- +# unknown dummy parameter +- sun: { pillbox: { dummy: 1} } +--- + +# +# <buie> ::= +# buie: +# csr: REAL # in ]0, 1[ +# + +# missing buie definition +- sun: { buie: } +--- +# missing csr value +- sun: { buie: { csr: } } --- +# csr should be a number +- sun: { buie: { csr: "dummy"} } +--- +# 0 invalid +- sun: { buie: { csr: 0} } +--- +# 1 invalid +- sun: { buie: { csr: 1} } +--- +# 2x csr +- sun: { buie: { csr: 0.5, csr: 0.5 } } +--- +# unknown dummy parameter +- sun: { buie: { dummy: 1} } +--- + +# +# <sun> ::= +# sun: +# dni: REAL # Direct Normal Irradiance in ]0, INF) +# <spectrum> +# [ <radial-angular-distribution> ] +# +# <radial-angular-distribution> ::= +# <pillbox> | <buie> +# + # missing spectrum - sun: { dni: 1 } --- # missing dni - sun: { spectrum: [{wavelength: 1, data: 1}] } --- -# missing wavelength -- sun: { dni: 1, spectrum: [{data: 1}] } +# unknown dummy parameter +- sun: { dummy: 1 } --- -# missing data -- sun: { dni: 1, spectrum: [{wavelength: 1}] } +# 2x dni +- sun: { dni: 1, dni: 1 } +--- +# 2x spectrum +- sun: + spectrum: [{wavelength: 1, data: 1}] + spectrum: [{wavelength: 1, data: 1}] +--- +# 2x radial-angular-distribution +- sun: + pillbox: { aperture: 1} + buie: { csr: 0.5} +--- + +# +# <mirror> ::= +# mirror: +# reflectivity: REAL # in [0, 1] +# roughness: REAL # in [0, 1] +# + +# missing mirror definition +- material: { mirror: } +--- +# unknown dummy attribute +- material: { mirror: { dummy: 0 } } +--- +# missing reflectivity parameter +- material: { mirror: { roughness: 0 } } +--- +# missing roughness parameter +- material: { mirror: { reflectivity: 1 } } +--- +# roughness should be a number +- material: { mirror: { roughness: "dummy" } } +--- +# reflectivity should be a number +- material: { mirror: { reflectivity: "dummy" } } +--- +# -1 invalid +- material: { mirror: { reflectivity: -1, roughness: 0 } } +--- +# 1.5 invalid +- material: { mirror: { reflectivity: 1.5, roughness: 0 } } +--- +# -1 invalid +- material: { mirror: { reflectivity: 1, roughness: -1 } } +--- +# 1.5 invalid +- material: { mirror: { reflectivity: 1, roughness: 1.5 } } +--- +# 2x reflectivity +- material: { mirror: { reflectivity: 1, reflectivity: 1 } } +--- +# 2x roughness +- material: { mirror: { roughness: 1, roughness: 1 } } +--- + +# +# <matte> ::= +# matte: +# reflectivity: REAL # in [0, 1] +# + +# missing matte parameters +- material: { matte: } +--- +# unknown dummy attribute +- material: { matte: { dummy: 0 } } +--- +# reflectivity should be a number +- material: { matte: { reflectivity: "dummy" } } +--- +# -1 invalid +- material: { matte: { reflectivity: -1 } } +--- +# 1.5 invalid +- material: { matte: { reflectivity: 1.5 } } +--- +# 2x reflectivity +- material: { matte: { reflectivity: 1, reflectivity: 1 } } +--- + +# +# front: <material-descriptor> +# + +# missing front definition +- material: { front: } +--- +# dummy is not a material +- material: { front: "dummy" } +--- + +# +# back: <material-descriptor> +# + +# missing back parameters +- material: { back: } +--- +# dummy is not a material +- material: { back: "dummy" } +--- + +# +# <material> ::= +# <material-descriptor> | <double-sided-material> +# +# <double-sided-material> ::= +# front: <material-descriptor> +# back: <material-descriptor> +# + +# missing material definition +- material: --- # unknown dummy parameter -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], dummy: { aperture: 1} } +- material: { dummy: 123 } --- -# missing pillbox definition -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], pillbox: } +# missing back +- material: { front: { matte: { reflectivity: 0.5 } } } --- -# missing aperture value -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], pillbox: { aperture: } } +# missing front +- material: { back: { matte: { reflectivity: 0.5 } } } +--- +# 2x front +- material: + front: &mat { matte: { reflectivity: 0.5 } } + front: *mat +--- +# 2x back +- material: + back: &mat { matte: { reflectivity: 0.5 } } + back: *mat +--- +# 2x description +- material: + front: &mat { matte: { reflectivity: 0.5 } } + back: *mat + matte: { reflectivity: 0.5 } +--- +# 2x description +- material: + matte: { reflectivity: 0.5 } + front: &mat { matte: { reflectivity: 0.5 } } + back: *mat +--- + +# <polyclip-list> ::= +# - <polyclip> +# [ - <polyclip> ... ] +# +# <polyclip> ::= +# operation: <AND|SUB> +# vertices: <vertices-list> +# +# <vertices-list> ::= +# - <real2> +# - <real2> +# - <real2> +# [ - <real2> ... ] +# + +# missing clipping definition +- geometry: + - plane: + clip: +--- +# unknown dummy parameter +- geometry: + - plane: + clip: + - dummy: 1 +--- +# missing operation name +- geometry: + - plane: + clip: + - operation: +--- +# missing vertices list +- geometry: + - plane: + clip: + - vertices: +--- +# unknown dummy operation +- geometry: + - plane: + clip: + - operation: dummy +--- +# missing vertices parameter +- geometry: + - plane: + clip: + - operation: AND +--- +# missing operation parameter +- geometry: + - plane: + clip: + - vertices: [ [1, 2], [3, 4], [6, 7] ] +--- +# vertices list < 3 +- geometry: + - plane: + clip: + - vertices: [ [1, 2], [3, 4] ] +--- +# invalid number "dummy" +- geometry: + - plane: + clip: + - operation: AND + vertices: [ ["dummy", 2], [3, 4], [6, 7] ] +--- +# vertices should have 2 values +- geometry: + - plane: + clip: + - operation: AND + vertices: [ [2], [3, 4], [6, 7] ] +--- +# vertices should have 2 values +- geometry: + - plane: + clip: + - operation: AND + vertices: [ [0, 1, 2], [3, 4], [6, 7] ] +--- + +# +# <cuboid> ::= +# cuboid: +# size: <real3*+> +# + +# missing cuboid definition +- geometry: [ { cuboid: } ] +--- +# unknown dummy parameter +- geometry: [ { cuboid: { dummy: 1 } } ] +--- +# missing size values +- geometry: [ { cuboid: { size: } } ] +--- +# size should be a number +- geometry: [ { cuboid: { size: "dummy" } } ] +--- +# invalid number "dummy" +- geometry: [ { cuboid: { size: [1, "dummy", 2] } } ] +--- +# size should have 3 values +- geometry: [ { cuboid: { size: [1, 2] } } ] +--- +# size should have 3 values +- geometry: [ { cuboid: { size: [1, 2, 3, 4] } } ] +--- +# -1 invalid +- geometry: [ { cuboid: { size: [-1, 2, 3] } } ] +--- +# 0 invalid +- geometry: [ { cuboid: { size: [0, 2, 3] } } ] +--- +# 2x size +- geometry: [ { cuboid: { size: [1, 2, 3], size: [1, 2, 3] } } ] +--- + +# +# <cylinder> ::= +# cylinder: +# height: REAL # in ]0, INF) +# radius: REAL # in ]0, INF) +# [ slices: INTEGER ] # in [4, 4096]. Default 16 +# + +# missing cylinder definition +- geometry: [ { cylinder: } ] +--- +# missing height value +- geometry: [ { cylinder: { height: } } ] +--- +# missing radius value +- geometry: [ { cylinder: { radius: } } ] +--- +# unknown dummy parameter +- geometry: [ { cylinder: { dummy: 1 } } ] +--- +# missing radius +- geometry: [ { cylinder: { height: 1 } } ] +--- +# missing height +- geometry: [ { cylinder: { radius: 1 } } ] +--- +# height should be a number +- geometry: [ { cylinder: { height: "dummy" } } ] +--- +# radius should be a number +- geometry: [ { cylinder: { radius: "dummy" } } ] +--- +# slices should be a number +- geometry: [ { cylinder: { slices: "dummy" } } ] +--- +# -1 invalid +- geometry: [ { cylinder: { radius: -1 } } ] --- # -1 invalid -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], pillbox: { aperture: -1} } +- geometry: [ { cylinder: { height: -1 } } ] +--- +# 0 invalid +- geometry: [ { cylinder: { radius: 0 } } ] +--- +# 0 invalid +- geometry: [ { cylinder: { height: 0 } } ] --- -# unknown aperture parameter -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], buie: { aperture: 1} } +# 2x height +- geometry: [ { cylinder: { height: 1, height: 1 } } ] +--- +# 2x radius +- geometry: [ { cylinder: { radius: 1, radius: 1 } } ] +--- +# 2x slices +- geometry: [ { cylinder: { slices: 10, slices: 10 } } ] --- # 1 invalid -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}], buie: { csr: 1} } +- geometry: [ { cylinder: { height: 1, radius: 1, slices: 1 } } ] +--- +# 4097 invalid +- geometry: [ { cylinder: { height: 1, radius: 1, slices: 4097 } } ] +--- +# 12.5 invalid +- geometry: [ { cylinder: { height: 1, radius: 1, slices: 12.5 } } ] +--- + +# +# <obj> ::= +# obj: +# path: PATH +# + +# missing obj definition +- geometry: [ { obj: } ] +--- +# missing path +- geometry: [ { obj: { path: } } ] +--- +# unknown dummy parameter +- geometry: [ { obj: { dummy: 1 } } ] +--- +# 2x path +- geometry: [ { obj: { path: "file", path: "file" } } ] +--- + +# +# <parabol> ::= +# parabol: # x^2 + y^2 - 4*focal*z = 0 +# focal: REAL # in ]0, INF) +# clip: <polyclip-list> +# + +# missing parabol definition +- geometry: [ { parabol: } ] +--- +# unknown dummy parameter +- geometry: [ { parabol: { dummy: 1 } } ] +--- +# missing focal value +- geometry: [ { parabol: { focal: } } ] +--- +# missing clip value +- geometry: [ { parabol: { clip: } } ] +--- +# focal should be a number +- geometry: [ { parabol: { focal: "dummy" } } ] --- # -1 invalid -- sun: { dni: -1, spectrum: [{wavelength: 1, data: 1}] } +- geometry: [ { parabol: { focal: -1 } } ] +--- +# 0 invalid +- geometry: [ { parabol: { focal: 0 } } ] +--- +# missing clip parameter +- geometry: [ { parabol: { focal: 10 } } ] +--- +# missing focal parameter +- geometry: + - parabol: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- +# 2x focal +- geometry: [ { parabol: { focal: 10, focal: 10 } } ] +--- +# 2x clip +- geometry: + - parabol: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- + +# +# <parabolic-cylinder> ::= +# parabolic-cylinder: # y^2 - 4*focal*z = 0 +# focal: REAL # in ]0, INF) +# clip: <polyclip-list> +# + +# missing parabolic-cylinder definition +- geometry: [ { parabolic-cylinder: } ] +--- +# unknown dummy parameter +- geometry: [ { parabolic-cylinder: { dummy: 1 } } ] +--- +# missing focal value +- geometry: [ { parabolic-cylinder: { focal: } } ] +--- +# missing clip value +- geometry: [ { parabolic-cylinder: { clip: } } ] +--- +# focal should be a number +- geometry: [ { parabolic-cylinder: { focal: "dummy" } } ] --- # -1 invalid -- sun: { dni: 1, spectrum: [{wavelength: -1, data: 1}] } +- geometry: [ { parabolic-cylinder: { focal: -1 } } ] +--- +# 0 invalid +- geometry: [ { parabolic-cylinder: { focal: 0 } } ] +--- +# missing clip parameter +- geometry: [ { parabolic-cylinder: { focal: 10 } } ] +--- +# missing focal parameter +- geometry: + - parabolic-cylinder: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- +# 2x focal +- geometry: [ { parabolic-cylinder: { focal: 10, focal: 10 } } ] +--- +# 2x clip +- geometry: + - parabolic-cylinder: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- + +# +# <plane> ::= +# plane: +# clip: <polyclip-list> +# + +# missing plane definition +- geometry: [ { plane: } ] +--- +# unknown dummy parameter +- geometry: [ { plane: { dummy: 1 } } ] +--- +# 2x clip +- geometry: + - plane: + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] + clip: + - operation: AND + vertices: [ [1, 2], [3, 4], [6, 7] ] +--- + +# +# <sphere> ::= +# sphere: +# radius: REAL # in ]0, INF) +# [ slices: INTEGER ] # Default 16 +# + +# missing sphere definition +- geometry: [ { sphere: } ] +--- +# unknown dummy parameter +- geometry: [ { sphere: { dummy: 1 } } ] +--- +# missing radius parameter +- geometry: [ { sphere: { slices: 10 } } ] +--- +# radius should be a number +- geometry: [ { sphere: { radius: "dummy" } } ] +--- +# slices should be a number +- geometry: [ { sphere: { slices: "dummy" } } ] --- # -1 invalid -- sun: { dni: 1, spectrum: [{wavelength: 1, data: -1}] } +- geometry: [ { sphere: { radius: -1 } } ] +--- +# 0 invalid +- geometry: [ { sphere: { radius: 0 } } ] +--- +# 0 invalid +- geometry: [ { sphere: { radius: 1, slices: 0 } } ] --- +# 4097 invalid +- geometry: [ { sphere: { radius: 1, slices: 4097 } } ] +--- +# 2x radius +- geometry: [ { sphere: { radius: 1, radius: 1 } } ] +--- +# 2x slices +- geometry: [ { sphere: { slices: 10, slices: 10 } } ] +--- + +# +# <stl> ::= +# stl: +# path: PATH +# + +# missing stl definition +- geometry: [ { stl: } ] +--- +# missing path +- geometry: [ { stl: { path: } } ] +--- +# unknown dummy parameter +- geometry: [ { stl: { dummy: 1 } } ] +--- +# 2x path +- geometry: [ { stl: { path: "file", path: "file" } } ] +--- + +# +# <pivot> ::= +# pivot: +# point: <real3> +# normal: <real3> +# <target> +# +# <target> ::= +# target: +# anchor: <anchor-identifier> +# | direction: <real3> +# | position: <real3> +# | <sun> +# + +# missing pivot definition - entity: - # missing transform parameters - transform: + pivot: --- +# unknown dummy parameter - entity: - transform: - # missing rotation parameters - rotation: + pivot: + dummy: 1 --- +# missing point definition - entity: - transform: - # missing translation parameters - translation: + pivot: + point: --- +# missing normal definition - entity: - transform: - # 2x translation - translation: [ -4, 5.2, -6.5 ] - translation: [ -4, 5.2, -6.5 ] + pivot: + normal: --- +# missing target definition - entity: - transform: - # translation should have 3 parameters - translation: [ -4, 5.2 ] + pivot: + target: --- +# point should be a number - entity: - transform: - # translation should have 3 parameters - translation: [ -4, 5.2,0 ,1 ] + pivot: + point: "dummy" --- +# point should have 3 values - entity: - transform: - # 2x rotation - rotation: [ -4, 5.2, -6.5 ] - rotation: [ -4, 5.2, -6.5 ] + pivot: + point: [ -4, 5.2 ] --- +# point should have 3 values - entity: - transform: - # rotation should have 3 parameters - rotation: [ -4, 5.2 ] + pivot: + point: [ -4, 5.2, 0, 1 ] --- +# normal should be a number - entity: - transform: - # rotation should have 3 parameters - rotation: [ -4, 5.2,0 ,1 ] + pivot: + normal: "dummy" --- +# normal should have 3 values - entity: - # 2x transform - transform: - rotation: [ -4, 5.2, 1 ] - transform: - rotation: [ -4, 5.2, 1 ] + pivot: + normal: [ -4, 5.2 ] --- +# normal should have 3 values - entity: - # missing object(s) - geometry: + pivot: + normal: [ -4, 5.2, 0, 1 ] --- +# target should be a <target> - entity: - geometry: - # missing transform parameters - - transform: + pivot: + target: "dummy" --- +# missing anchor definition - entity: - geometry: - - transform: - # missing rotation parameters - rotation: + pivot: + target: + anchor: --- +# missing direction definition - entity: - geometry: - - transform: - # missing translation parameters - translation: + pivot: + target: + direction: --- - +# missing position definition - entity: - geometry: - - transform: - # 2x translation - translation: [ -4, 5.2, -6.5 ] - translation: [ -4, 5.2, -6.5 ] + pivot: + target: + position: --- +# undefined anchor - entity: - geometry: - - transform: - # translation should have 3 parameters - translation: [ -4, 5.2 ] + pivot: + target: + anchor: dummy --- +# direction should be a number - entity: - geometry: - - transform: - # translation should have 3 parameters - translation: [ -4, 5.2,0 ,1 ] + pivot: + target: + direction: "dummy" --- +# direction should have 3 values - entity: - geometry: - - transform: - # 2x rotation - rotation: [ -4, 5.2, -6.5 ] - rotation: [ -4, 5.2, -6.5 ] + pivot: + target: + direction: [ -4, 5.2 ] --- +# direction should have 3 values - entity: - geometry: - - transform: - # rotation should have 3 parameters - rotation: [ -4, 5.2 ] + pivot: + target: + direction: [ -4, 5.2, 0, 1 ] --- +# position should be a number - entity: - geometry: - - transform: - # rotation should have 3 parameters - rotation: [ -4, 5.2,0 ,1 ] + pivot: + target: + position: "dummy" --- +# position should have 3 values - entity: - geometry: - # missing shape & material - - transform: - rotation: [ -4, 5.2, 1 ] + pivot: + target: + position: [ -4, 5.2 ] --- +# position should have 3 values - entity: - geometry: - # missing size parameters - - cuboid: { size: } + pivot: + target: + position: [ -4, 5.2, 0, 1 ] --- +# sun should be a <sun> - entity: - geometry: - # size should have 3 parameters - - cuboid: { size: [1, 2] } + pivot: + target: { sun: "dummy" } --- +# missing point +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } - entity: - geometry: - # size should have 3 parameters - - cuboid: { size: [1, 2, 3, 4] } + pivot: + normal: [ -4, 5.2, 0 ] + target: { sun: *sun } --- +# missing normal +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } - entity: - geometry: - # -1 invalid - - cuboid: { size: [-1, 2, 3] } + pivot: + point: [ -4, 5.2, 0 ] + target: { sun: *sun } --- +# missing target - entity: - geometry: - # 0 invalid - - cuboid: { size: [0, 2, 3] } + pivot: + point: [ -4, 5.2, 0 ] + normal: [ -4, 5.2, 0 ] --- +# 2x point - entity: - geometry: - - cuboid: { size: [1, 2, 3] } - # missing material + pivot: + point: [ -4, 5.2, 0 ] + point: [ -4, 5.2, 0 ] --- +# 2x normal - entity: - geometry: - # missing material definition - - material: + pivot: + normal: [ -4, 5.2, 0 ] + normal: [ -4, 5.2, 0 ] --- +# 2x target +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } - entity: - geometry: - # missing matte parameters - - material: { matte: } + pivot: + target: { sun: *sun } + target: { sun: *sun } --- + +# +# <anchors> ::= +# anchors: +# - <anchor-data> +# [ - <anchor-data> ... ] +# +# <anchor-data> ::= +# name: STRING +# position: <real3> +# + +# missing anchors definition - entity: - geometry: - # missing reflectivity value - - material: { matte: { reflectivity: } } + anchors: --- +# missing position - entity: - geometry: - - cuboid: { size: [1, 2, 3] } - # -1 invalid - material: { matte: { reflectivity: -1 } } + anchors: + - name: "anchor" --- +# missing name - entity: - geometry: - - material: { matte: { reflectivity: 1 } } - # missing shape definition + anchors: + - position: [ -4, 5.2, 0 ] --- +# 2 anchors with same name +- entity: + anchors: + - name: "anchor" + position: [ -4, 5.2, 0 ] + - name: "anchor" + position: [ -4, 5.2, 0 ] +--- + +# +# <entity> ::= +# entity: +# <entity-data> +## +# <entity-data> ::= +# name: STRING +# [ <geometry> | <pivot> ] +# [ <anchors> ] +# [ <transform> ] +# [ <children> ] + +# missing entity definition +- entity: +--- +# unknown dummy parameter +- entity: { dummy: 0 } +--- +# missing name value +- entity: { name: } +--- +# missing geometry value +- entity: { geometry: } +--- +# missing pivot value +- entity: { pivot: } +--- +# missing anchors value +- entity: { anchors: } +--- +# missing transform value +- entity: { transform: } +--- +# missing children value +- entity: { children: } +--- +# missing entity name - entity: - # missing entity name geometry: - - cuboid: { size: [1, 2, 3] } + - stl: { path: "file" } material: { matte: { reflectivity: 1 } } --- -# missing sun +# 2x name +- entity: { name: "ent", name: "ent" } +--- +# cannot define both geometry and pivot +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } - entity: - name: foo + pivot: + point: [ -4, 5.2, 0 ] + normal: [ -4, 5.2, 0 ] + target: { sun: *sun } + geometry: [ { stl: { path: "file" } } ] +--- +# 2x anchors +- entity: + anchors: + - name: "anchor1" + position: [ -4, 5.2, 0 ] + anchors: + - name: "anchor2" + position: [ -4, 5.2, 0 ] +--- +# 2x transform +- entity: + transform: { rotation: [ -4, 5.2, 1 ] } + transform: { rotation: [ -4, 5.2, 1 ] } +--- +# 2x children +- entity: + children: + - name: "child1" + children: + - name: "child2" +--- +# 2 entities with the same name +- entity: + name: "foo" geometry: - - cuboid: { size: [1, 2, 3] } - transform: - rotation: [ 0, 1, 2 ] - translation: [ -4, 5.2, -6.5 ] + - stl: { path: "file" } material: { matte: { reflectivity: 1 } } ---- - entity: + name: "foo" geometry: - # unknown dummy parameter - - material: { matte: { reflectivity: 1, dummy: "none" } } + - stl: { path: "file" } + material: { matte: { reflectivity: 1 } } --- -- entity: + +# <template> ::= +# template: +# <entity-data> +# +# <entity-data> ::= +# name: STRING +# [ <geometry> | <pivot> ] +# [ <anchors> ] +# [ <transform> ] +# [ <children> ] + +# missing template definition +- template: &temp +- entity: *temp +--- +# unknown dummy parameter +- template: &temp { dummy: 0 } +- entity: *temp +--- +# missing name value +- template: &temp { name: } +- entity: *temp +--- +# missing geometry value +- template: &temp { geometry: } +- entity: *temp +--- +# missing pivot value +- template: &temp { pivot: } +- entity: *temp +--- +# missing anchors value +- template: &temp { anchors: } +- entity: *temp +--- +# missing transform value +- template: &temp { transform: } +- entity: *temp +--- +# missing children value +- template: &temp { children: } +- entity: *temp +--- +# missing template name +- template: &temp geometry: - - material: - # unknown dummy parameter - matte: { reflectivity: 1 } - dummy: 123 + - stl: { path: "file" } + material: { matte: { reflectivity: 1 } } +- entity: *temp --- -- entity: +# 2x name +- template: &temp { name: "ent", name: "ent" } +- entity: *temp +--- +# cannot define both geometry and pivot +- sun: &sun { dni: 1, spectrum: [{wavelength: 1, data: 1}] } +- template: &temp + pivot: + point: [ -4, 5.2, 0 ] + normal: [ -4, 5.2, 0 ] + target: { sun: *sun } + geometry: [ { stl: { path: "file" } } ] +- entity: *temp +--- +# 2x anchors +- template: &temp + anchors: + - name: "anchor1" + position: [ -4, 5.2, 0 ] + anchors: + - name: "anchor2" + position: [ -4, 5.2, 0 ] +- entity: *temp +--- +# 2x transform +- template: &temp + transform: { rotation: [ -4, 5.2, 1 ] } + transform: { rotation: [ -4, 5.2, 1 ] } +- entity: *temp +--- +# 2x children +- template: &temp + children: + - name: "child1" + children: + - name: "child2" +- entity: *temp +--- +# 2 templates with the same name +- template: &temp1 + name: "foo" geometry: - # unknown dummy parameter - - cuboid: { size: [1, 2, 3], dummy: 3.14 } + - stl: { path: "file" } + material: { matte: { reflectivity: 1 } } +- template: &temp2 + name: "foo" + geometry: + - stl: { path: "file" } + material: { matte: { reflectivity: 1 } } +- entity: *temp1 +- entity: *temp2 +--- + +# +# <transform> ::= +# transform: +# translation: <real3> +# rotation: <real3> +# + +# missing rotation parameters +- entity: { transform: { rotation: } } +--- +# missing translation parameters +- entity: { transform: { translation: } } +--- +# rotation should have 3 values +- entity: { transform: { rotation: [ -4, 5.2 ] } } --- +# rotation should have 3 values +- entity: { transform: { rotation: [ -4, 5.2, 0, 1 ] } } +--- +# translation should have 3 values +- entity: { transform: { translation: [ -4, 5.2 ] } } +--- +# translation should have 3 values +- entity: { transform: { translation: [ -4, 5.2, 0, 1 ] } } +--- +# 2x rotation - entity: - geometry: - - material: { matte: { reflectivity: 1 } } - cuboid: { size: [1, 2, 3] } - # unknown dummy parameter - dummy: 1 + transform: + rotation: [ -4, 5.2, -6.5 ] + rotation: [ -4, 5.2, -6.5 ] --- +# 2x translation - entity: - geometry: - - material: { matte: { reflectivity: 1 } } - cuboid: { size: [1, 2, 3] } - # unknown dummy parameter - dummy: 1 ---- -- material: &front { matte: { reflectivity: 1 } } -- material: &back { matte: { reflectivity: 0.5 } } -- geometry: &cuboid - - cuboid: { size: [1, 2, 3] } - material: - # missing back description - front: *front -- entity: { geometry: *cuboid } ---- -- material: &front { matte: { reflectivity: 1 } } -- material: &back { matte: { reflectivity: 0.5 } } -- geometry: &cuboid - - cuboid: { size: [1, 2, 3] } - material: - # missing front description - back: *back -- entity: { geometry: *cuboid } ---- -- material: &front { matte: { reflectivity: 1 } } -- material: &back { matte: { reflectivity: 0.5 } } -- geometry: &cuboid - - cuboid: { size: [1, 2, 3] } - material: - front: *front - back: *back - # 2x front - front: *front -- entity: { geometry: *cuboid } ---- -- geometry: &cuboid - - cuboid: { size: [1, 2, 3] } - material: - front: - matte: { reflectivity: 1 } - # unknown dummy parameter - dummy: 1 - back: - material: { matte: { reflectivity: 0.1 } } -- entity: { geometry: *cuboid } ---- -- geometry: &cuboid - - cuboid: { size: [1, 2, 3] } - material: - front: - matte: { reflectivity: 1 } - back: - matte: { reflectivity: 0.1 } - # unknown dummy parameter - dummy: 1234 -- entity: { geometry: *cuboid } + transform: + translation: [ -4, 5.2, -6.5 ] + translation: [ -4, 5.2, -6.5 ] +--- + +# +# <geometry> ::= +# geometry: +# - <object> +# [ - <object> ... ] +# +# <object> ::= +# <shape> +# <material> +# [ <transform> ] +# + +# missing geometry definition +- geometry: +--- +# unknown dummy parameter +- geometry: + - dummy: 1 +--- +# missing material definition +- geometry: + - stl: { path: "file" } +--- +# missing shape definition +- geometry: + - material: { matte: { reflectivity: 1 } } +--- +# 2x shape +- geometry: + - stl: { path: "file" } + stl: { path: "file" } +--- +# 2x material +- geometry: + - material: { matte: { reflectivity: 1 } } + material: { matte: { reflectivity: 1 } } +--- +# 2x transform +- geometry: + - transform: { rotation: [ -4, 5.2, -6.5 ] } + transform: { rotation: [ -4, 5.2, -6.5 ] } +--- + +# +# <solar-factory> ::= +# <sun> +# <items> +# +# <items> ::= +# - <item> +# [ - <item> ... ] +# +# <item> ::= +# <geometry> +# | <material> +# | <entity> +# | <template> +# +# unknown item dummy +- dummy: 1 +--- +# missing sun in document +- entity: + name: foo + geometry: + - cuboid: { size: [1, 2, 3] } + material: { matte: { reflectivity: 1 } } + +\ No newline at end of file diff --git a/src/parser/yaml/test_ko_1.yaml b/src/parser/yaml/test_ko_1.yaml @@ -1,143 +0,0 @@ -- instance: - object: - material: { mirror: { reflectivity: 1.1, roughness: 0 } } - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: -0.1, roughness: 0 } } - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 0, roughness: -0.1 } } - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 0, roughness: 1.000001 } } - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - reflectivity: 0 - reflectivity: 1 - roughness: 0 -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - reflectivity: 1 - roughness: 0 - roughness: 1 -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - reflectivity: - roughness: 1 -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - reflectivity: 1 - roughness: -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - reflectivity: 1 -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- material: &mirror - mirror: - roughness: 0 -- instance: - object: - material: *mirror - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: { height: -0.1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: { height: 1, radius: -0.00001 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: { height: 1, radius: 1, slices: 2 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: - radius: 1 - slices: 4 ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: - height: - radius: 1 ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: - height: 1 - radius: ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: - height: 1 - radius: 1 - slices: ---- -- instance: - object: - material: { mirror: } - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0, dummy: "none" } } - cylinder: { height: 1, radius: 1 } ---- -- instance: - object: - material: { mirror: { reflectivity: 1, roughness: 0 } } - cylinder: { height: 1, radius: 1, dummy: 3.14 } - diff --git a/src/parser/yaml/test_ko_2.yaml b/src/parser/yaml/test_ko_2.yaml @@ -1,30 +0,0 @@ -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: { path: } ---- -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: { path: "my_path", dummy: 1 } ---- -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: ---- -- instance: - object: - material: { matte: { reflectivity: 1 } } - stl: { path: } ---- -- instance: - object: - material: { matte: { reflectivity: 1 } } - stl: { path: "my_path", dummy: 1 } ---- -- instance: - object: - material: { matte: { reflectivity: 1 } } - stl: - diff --git a/src/parser/yaml/test_ok_1.yaml b/src/parser/yaml/test_ok_1.yaml @@ -49,11 +49,3 @@ geometry: - material: { mirror: { reflectivity: 0, roughness: 0.5 } } cylinder: { height: 1, radius: 1 } ---- -- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] } -- entity: - name: entity - geometry: - - material: { mirror: { reflectivity: 0, roughness: 0.5 } } - cylinder: { height: 0, radius: 0 } - diff --git a/src/solstice_args.c b/src/solstice_args.c @@ -38,9 +38,30 @@ print_help(const char* program) { printf( "Usage: %s [OPTIONS] [FILE]\n" -"Integrate the solar flux in complex solar facilities.\n", +"Integrate the solar flux in a complex solar facility described in FILE. If\n" +"not define, the solar facility is read from standard input.\n\n", program); - /* TODO print short help for the options */ + printf( +" -D <dirs> list of sun directions.\n"); + printf( +" -h display this help and exit.\n"); + printf( +" -n number of realisation. Default is %lu.\n", + SOLSTICE_ARGS_DEFAULT.nrealisations); + printf( +" -o write results to OUTPUT. If not define, write results to\n"); + printf( +" standard output.\n"); + printf( +" -q do not print the helper message when no FILE is submitted.\n"); + printf( +" -r <rendering> switch in rendering mode and configure it.\n"); + printf( +" -R RECEIVERS define the file from which the list of receivers are read.\n\n"); + printf( +"Solstice (C) 2016-2017 CNRS. This is a free software released under the GNU GPL\n" +"license, version 3 or later. You are free to change or redistribute it under\n" +"certain conditions <http://gnu.org/licenses/gpl.html>.\n"); } static res_T diff --git a/src/solstice_c.h b/src/solstice_c.h @@ -132,7 +132,7 @@ solstice_node_set_translation static INLINE void solstice_node_set_rotations (struct solstice_node* node, - const double rotations[3]) + const double rotations[3]) /* In radians */ { ASSERT(node && rotations && node->type != SOLSTICE_NODE_TARGET); SANIM(node_set_rotations(&node->anim, rotations)); diff --git a/src/solstice_entity.c b/src/solstice_entity.c @@ -164,6 +164,7 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity) struct solstice_node* tgt = NULL; struct solstice_node* child = NULL; struct solstice_receiver* rcv = NULL; + double rotation[3]; size_t i; res_T res = RES_OK; ASSERT(solstice && entity); @@ -202,8 +203,11 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity) } /* Setup the entity transform */ + rotation[0] = MDEG2RAD(entity->rotation[0]); + rotation[1] = MDEG2RAD(entity->rotation[1]); + rotation[2] = MDEG2RAD(entity->rotation[2]); solstice_node_set_translation(node, entity->translation); - solstice_node_set_rotations(node, entity->rotation); + solstice_node_set_rotations(node, rotation); /* Register entity anchors */ FOR_EACH(i, 0, solparser_entity_get_anchors_count(entity)) { @@ -224,6 +228,7 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity) res = solstice_node_add_child(node, tgt); if(res != RES_OK) goto error; + solstice_node_ref_put(tgt); tgt = NULL; } diff --git a/src/solstice_object.c b/src/solstice_object.c @@ -368,6 +368,7 @@ create_shaded_shape const struct solparser_object* obj; const struct solparser_shape* shape; double transform[12]; + double rotation[3]; res_T res = RES_OK; ASSERT(solstice && ssol_front && ssol_back && ssol_shape); @@ -378,7 +379,10 @@ create_shaded_shape solstice_create_ssol_material(solstice, mtl2->back, ssol_back); /* Define the shape transformation */ - d33_rotation(transform, obj->rotation[0], obj->rotation[1], obj->rotation[2]); + rotation[0] = MDEG2RAD(obj->rotation[0]); + rotation[1] = MDEG2RAD(obj->rotation[1]); + rotation[2] = MDEG2RAD(obj->rotation[2]); + d33_rotation(transform, rotation[0], rotation[1], rotation[2]); d3_set(transform+9, obj->translation); shape = solparser_get_shape(solstice->parser, obj->shape);