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 2fb51204e554ee93d00bc012972f984ccc1c8acb
parent e82cb1e46f7a2b6f148955bf0d412c134f750277
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 16 Nov 2016 18:09:17 +0100

Update the input file specification

Replace the "tree" & "instance" node by the entity node and the
"object" node by the "geometry" node. Make the parser compliant with
this new specification.

Diffstat:
Mcmake/CMakeLists.txt | 18+++++++++---------
Mdoc/input | 184++++++++++++++++++++++++++++++++++++-------------------------------------------
Asrc/solstice_entity.h | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/solstice_geometry.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/solstice_instance.h | 40----------------------------------------
Dsrc/solstice_node.h | 88-------------------------------------------------------------------------------
Msrc/solstice_parser.c | 403++++++++++++++++++++++++++++---------------------------------------------------
Msrc/solstice_shape.h | 9---------
Msrc/yaml/test_ok_0.yaml | 71+++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/yaml/test_ok_1.yaml | 59++++++++++++++++++++++++++++++++---------------------------
Msrc/yaml/test_ok_2.yaml | 49+++++++++++++++++++++++++++----------------------
11 files changed, 487 insertions(+), 589 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -51,10 +51,9 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(SOLSTICE_FILES_SRC solstice_parser.c) -set(SOLSTICE_FILES_INC - solstice_instance.h +set(SOLSTICE_FILES_INC + solstice_entity.h solstice_material.h - solstice_node.h solstice_parser.h solstice_shape.h solstice_sun.h) @@ -95,12 +94,13 @@ if(NOT NO_TEST) ${SOLSTICE_SOURCE_DIR}/yaml/test_ok_1.yaml) add_test(test_solstice_parser_ok_2 test_solstice_parser ${SOLSTICE_SOURCE_DIR}/yaml/test_ok_2.yaml) - add_test(test_solstice_parser_ko_0 test_solstice_parser -e - ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_0.yaml) - add_test(test_solstice_parser_ko_1 test_solstice_parser -e - ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_1.yaml) - add_test(test_solstice_parser_ko_2 test_solstice_parser -e - ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_2.yaml) +# TODO rewrite them wrt the update of the input specification +# add_test(test_solstice_parser_ko_0 test_solstice_parser -e +# ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_0.yaml) +# add_test(test_solstice_parser_ko_1 test_solstice_parser -e +# ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_1.yaml) +# add_test(test_solstice_parser_ko_2 test_solstice_parser -e +# ${SOLSTICE_SOURCE_DIR}/yaml/test_ko_2.yaml) endif() ################################################################################ diff --git a/doc/input b/doc/input @@ -7,69 +7,71 @@ - material: &mirror mirror: { reflectivity: 1, roughness: 0 } -# Declare entities -- object: &house - stl: { path: "house.stl" } - material: *lambertian - -- object: &cylinder - cylinder: { height: 5, radius: 0.5 } - material: *lambertian - -- object: &cylinder2 - cylinder: { height: 5, radius: 0.5 } - material: *lambertian - transform: { translation: [2.5, 11, 0], rotation: [90, 0, 0] } -- object: &parabol - material: *mirror - parabol: - focal: 1 - clip: - - operation: SUB - vertices: [ [1, 2, 3], [3, 4, 5], [6, 7, 8] ] - -- instance: - name: "inst" - object: *cylinder2 - -# Declare a composition -- tree: &heliostat0 - transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } - geometries: - - object: *cylinder - children: - - transform: { rotation: [0, 0, 0], translation: [0, 0, 0] } - pivot: - point: [0, 0, 0] - normal: [0, 1, 0] - target: { alias: self.anchor0 } - children: - - transform: { translation: [0, 0, 0] } - geometries: - - object: *cylinder - - object: *cylinder2 - children: - - transform: { translation: [2.5, 11, 0], rotation: [90, 0, 0] } - geometries: - - object: *parabol +# Declare geometries +- geometry: &cylinders + - cylinder: { height: 5, radius: 0.5 } + material: *lambertian + transform: { rotation: [0, 90, 0] } + - cylinder: { height: 5, radius: 0.5 } + material: *lambertian + +- geometry: &parabol + - material: *mirror + parabol: + focal: 1 + clip: + - operation: SUB + vertices: [ [1, 2, 3], [3, 4, 5], [6, 7, 8] ] # Create the solar factory -- instance: - name: "inst" - transform: { translation: [0, 0, 0] } - tree : *heliostat0 -- instance: - transform: { translation: [0, 0, 10] } - tree : *heliostat0 -- instance: - transform: { translation: [0, 0, 20] } - tree : *heliostat0 -- instante: - transform: { translation: [0, 0, 30] } - tree : *heliostat0 -- instance: - transform: { translation: [0, 0, -10] } - object : *house +- entity: + name: "entity0" + transform: { rotation: [0, 90, 0] } + anchors: + - name: "anchor0" + position: [1, 2, 3] + - name: "anchor2" + position: [3, 4, 5] + geometry: + - stl: { path: "house.stl" } + transform: { translation: [0, 1, 2] } + material: *lambertian + - cylinder: { height: 5, radius: 0.5 } + material: *mirror + +- entity: &composition + name: "composition" + transform: { translation: [1, 2, 3 ] } + geometry: + - cylinder: { height: 5, radius: 0.5 } + material: *mirror + children: + - name: "hop" + transform: { translation: [1, 2, 3 ] } + geometry: *cylinders + - name: "hop2" + geometry: *parabol + children: + - transform: { rotation: [0, 0, 0] } + pivot: + point: [0, 0, 0] + normal: [0, 1, 0] + target: "entity0.anchor0" + +- entity: + <<: *composition + name: "entity2" + transform: { translation: [4, 5, 6] } + +- entity: + <<: *composition + name: "entity3" + transform: { translation: [7, 8, 9] } + +- entity: + <<: *composition + name: "entity4" + transform: { translation: [10, 11, 12] } -------------------------------------------------------------------------------- 2/ Grammar @@ -82,20 +84,21 @@ [ - <item> ... ] <items> ::= - <object> + <geometry> | <material> - | <root>> - | <instance> + | <entity> | <sun> ---------------------------------------- +<geometry> ::= + geometry: + - <object> +[ - <object> ... ] + <object> ::= - object: - <shape> - <material> -[ <identifier> ] -[ <transform> ] -[ <anchors> ] + <shape> + <material> +[ <transform> ] <pivot> ::= pivot: @@ -104,21 +107,9 @@ <target> [ <transform> ] -<anchors> ::= - anchors: - - <anchor> -[ - <anchor> ... ] - -<anchor> ::= - <identifier> - position: <real3> - <target> ::= target: - alias: <anchor-identifier> - | position: <real3> - | direction: <real3> - | <sun> + <anchor-identifier> | <real3> | <sun> ---------------------------------------- <shape> ::= @@ -204,24 +195,21 @@ reflectivity: REAL # in [0, 1] ---------------------------------------- -<tree> ::= - tree: - <node> +<entity> ::= + entity: + <entity-data> -<node-data> ::= - <geometries> | <pivot> +<entity-data> ::= + name: STRING + <geometry> | <pivot> +[ <anchors> ] [ <transform> ] [ <children> ] -<geometries> ::= - geometries: - - <object> -[ - <object> ... ] - <children> ::= children: - - <node> -[ - <node> ... ] + - <entity-data> +[ - <entity-data> ... ] ---------------------------------------- <sun> ::= @@ -242,12 +230,6 @@ aperture: REAL # in ]0, PI/2] ---------------------------------------- -instance: - <tree> | <object> -[ <identifier> ] -[ <transform> ] - ----------------------------------------- <transform> ::= transform: translation: <real3> diff --git a/src/solstice_entity.h b/src/solstice_entity.h @@ -0,0 +1,81 @@ +/* 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_ENTITY_H +#define SOLSTICE_ENTITY_H + +#include "solstice_shape.h" +#include "solstice_geometry.h" + +#include <rsys/double3.h> +#include <rsys/dynamic_array.h> +#include <rsys/list.h> + +struct solstice_entity_id { size_t i; }; + +#define DARRAY_NAME child +#define DARRAY_DATA struct solstice_entity_id +#include <rsys/dynamic_array.h> + +struct solstice_entity { + double rotation[3]; + double translation[3]; + + struct solstice_geometry_id geometry; + struct darray_child children; /* List of children nodes */ +}; + +static INLINE void +solstice_entity_init + (struct mem_allocator* allocator, struct solstice_entity* entity) +{ + ASSERT(entity); + d3_splat(entity->rotation, 0); + d3_splat(entity->translation, 0); + entity->geometry.i = SIZE_MAX; + darray_child_init(allocator, &entity->children); +} + +static INLINE void +solstice_entity_release(struct solstice_entity* entity) +{ + ASSERT(entity); + darray_child_release(&entity->children); +} + +static INLINE res_T +solstice_entity_copy + (struct solstice_entity* dst, const struct solstice_entity* src) +{ + ASSERT(dst && src); + d3_set(dst->translation, src->translation); + d3_set(dst->rotation, src->rotation); + dst->geometry = src->geometry; + return darray_child_copy(&dst->children, &src->children); +} + +static INLINE res_T +solstice_entity_copy_and_release + (struct solstice_entity* dst, struct solstice_entity* src) +{ + ASSERT(dst && src); + d3_set(dst->translation, src->translation); + d3_set(dst->rotation, src->rotation); + dst->geometry = src->geometry; + return darray_child_copy_and_release(&dst->children, &src->children); +} + +#endif /* SOLSTICE_ENTITY_H */ + diff --git a/src/solstice_geometry.h b/src/solstice_geometry.h @@ -0,0 +1,74 @@ +/* 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_GEOMETRY_H +#define SOLSTICE_GEOMETRY_H + +#include "solstice_material.h" +#include "solstice_shape.h" + +#include <rsys/dynamic_array.h> + +struct solstice_object { + struct solstice_material_double_sided_id mtl2; + struct solstice_shape_id shape; + double translation[3]; + double rotation[3]; +}; + +struct solstice_object_id { size_t i; }; + +#define DARRAY_NAME object_id +#define DARRAY_DATA struct solstice_object_id +#include <rsys/dynamic_array.h> + +struct solstice_geometry { + struct darray_object_id objects; +}; + +struct solstice_geometry_id { size_t i; }; + +static INLINE void +solstice_geometry_init + (struct mem_allocator* allocator, struct solstice_geometry* geom) +{ + ASSERT(geom); + darray_object_id_init(allocator, &geom->objects); +} + +static INLINE void +solstice_geometry_release(struct solstice_geometry* geom) +{ + ASSERT(geom); + darray_object_id_release(&geom->objects); +} + +static INLINE res_T +solstice_geometry_copy + (struct solstice_geometry* dst, const struct solstice_geometry* src) +{ + ASSERT(dst && src); + return darray_object_id_copy(&dst->objects, &src->objects); +} + +static INLINE res_T +solstice_geometry_copy_and_release + (struct solstice_geometry* dst, struct solstice_geometry* src) +{ + ASSERT(dst && src); + return darray_object_id_copy_and_release(&dst->objects, &src->objects); +} + +#endif /* SOLSTICE_GEOMETRY_H */ diff --git a/src/solstice_instance.h b/src/solstice_instance.h @@ -1,40 +0,0 @@ -/* 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_INSTANCE_H -#define SOLSTICE_INSTANCE_H - -#include "solstice_node.h" -#include "solstice_shape.h" - -enum solstice_instance_type { - SOLSTICE_INSTANCE_OBJECT, - SOLSTICE_INSTANCE_TREE -}; - -struct solstice_instance { - double rotation[3]; - double translation[3]; - enum solstice_instance_type type; - union { - struct solstice_object_id object; - struct solstice_node_id tree; - } data; -}; - -struct solstice_instance_id { size_t i; }; - -#endif /* SOLSTICE_INSTANCE_H */ - diff --git a/src/solstice_node.h b/src/solstice_node.h @@ -1,88 +0,0 @@ -/* 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_NODE_H -#define SOLSTICE_NODE_H - -#include "solstice_shape.h" - -#include <rsys/double3.h> -#include <rsys/dynamic_array.h> -#include <rsys/list.h> - -struct solstice_node_id { size_t i; }; - -#define DARRAY_NAME geometry -#define DARRAY_DATA struct solstice_object_id -#include <rsys/dynamic_array.h> - -#define DARRAY_NAME child -#define DARRAY_DATA struct solstice_node_id -#include <rsys/dynamic_array.h> - -struct solstice_node { - double rotation[3]; - double translation[3]; - - /* TODO pivot */ - struct darray_geometry geometries; /* List of geometries */ - struct darray_child children; /* List of children nodes */ -}; - -static INLINE void -solstice_node_init(struct mem_allocator* allocator, struct solstice_node* node) -{ - ASSERT(node); - d3_splat(node->rotation, 0); - d3_splat(node->translation, 0); - darray_geometry_init(allocator, &node->geometries); - darray_child_init(allocator, &node->children); -} - -static INLINE void -solstice_node_release(struct solstice_node* node) -{ - ASSERT(node); - darray_geometry_release(&node->geometries); - darray_child_release(&node->children); -} - -static INLINE res_T -solstice_node_copy(struct solstice_node* dst, const struct solstice_node* src) -{ - res_T res = RES_OK; - ASSERT(dst && src); - d3_set(dst->translation, src->translation); - d3_set(dst->rotation, src->rotation); - res = darray_geometry_copy(&dst->geometries, &src->geometries); - if(res != RES_OK) return res; - return darray_child_copy(&dst->children, &src->children); -} - -static INLINE res_T -solstice_node_copy_and_release - (struct solstice_node* dst, struct solstice_node* src) -{ - res_T res = RES_OK; - ASSERT(dst && src); - d3_set(dst->translation, src->translation); - d3_set(dst->rotation, src->rotation); - res = darray_geometry_copy_and_release(&dst->geometries, &src->geometries); - if(res != RES_OK) return res; - return darray_child_copy_and_release(&dst->children, &src->children); -} - -#endif /* SOLSTICE_NODE_H */ - diff --git a/src/solstice_parser.c b/src/solstice_parser.c @@ -15,9 +15,8 @@ #define _POSIX_C_SOURCE 200112L /* nextafter support */ -#include "solstice_instance.h" +#include "solstice_entity.h" #include "solstice_material.h" -#include "solstice_node.h" #include "solstice_parser.h" #include "solstice_shape.h" #include "solstice_sun.h" @@ -108,18 +107,22 @@ #define DARRAY_DATA struct solstice_object #include <rsys/dynamic_array.h> -/* Declare the array of nodes */ -#define DARRAY_NAME node -#define DARRAY_DATA struct solstice_node -#define DARRAY_FUNCTOR_INIT solstice_node_init -#define DARRAY_FUNCTOR_RELEASE solstice_node_release -#define DARRAY_FUNCTOR_COPY solstice_node_copy -#define DARRAY_FUNCTOR_COPY_AND_RELEASE solstice_node_copy_and_release +/* Declare the array of geometries */ +#define DARRAY_NAME geometry +#define DARRAY_DATA struct solstice_geometry +#define DARRAY_FUNCTOR_INIT solstice_geometry_init +#define DARRAY_FUNCTOR_RELEASE solstice_geometry_release +#define DARRAY_FUNCTOR_COPY solstice_geometry_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE solstice_geometry_copy_and_release #include <rsys/dynamic_array.h> -/* Declare the array of instances */ -#define DARRAY_NAME instance -#define DARRAY_DATA struct solstice_instance +/* Declare the array of entities */ +#define DARRAY_NAME entity +#define DARRAY_DATA struct solstice_entity +#define DARRAY_FUNCTOR_INIT solstice_entity_init +#define DARRAY_FUNCTOR_RELEASE solstice_entity_release +#define DARRAY_FUNCTOR_COPY solstice_entity_copy +#define DARRAY_FUNCTOR_COPY_AND_RELEASE solstice_entity_copy_and_release #include <rsys/dynamic_array.h> /* Declare the hash table that maps the address of a YAML node to the id of its @@ -160,31 +163,30 @@ struct solstice_parser { const yaml_node_t* sun_key; /* yaml_node_t ptr used to spawn the sun */ struct solstice_sun sun; /* The loaded sun */ - /* Tree */ - struct htable_yaml2sols yaml2trees; /* Cache of trees */ - struct darray_node nodes; + /* Entity */ + struct htable_yaml2sols yaml2entities; /* Cache of entities */ + struct darray_entity entities; /* Miscellaneous */ - struct darray_instance instances; + struct darray_geometry geometries; ref_T ref; struct mem_allocator* allocator; }; static res_T -parse_node +parse_entity (struct solstice_parser* parser, yaml_document_t* doc, - yaml_node_t* node, - const int is_root_node, - struct solstice_node_id* solnode); + yaml_node_t* entity, + struct solstice_entity_id* solent); static res_T -parse_object +parse_geometry (struct solstice_parser* parser, yaml_document_t* doc, - yaml_node_t* object, - struct solstice_object_id* obj); + yaml_node_t* geometry, + struct solstice_geometry_id* solgeom); static res_T parse_pivot @@ -197,7 +199,7 @@ parse_sun (struct solstice_parser* parser, yaml_document_t* doc, const yaml_node_t* sun, - struct solstice_sun** out_solsun); + struct solstice_sun** solsun); /******************************************************************************* * Helper functions @@ -254,11 +256,11 @@ parser_clear(struct solstice_parser* parser) parser->sun_key = 0; /* Tree */ - htable_yaml2sols_clear(&parser->yaml2trees); - darray_node_clear(&parser->nodes); + htable_yaml2sols_clear(&parser->yaml2entities); + darray_entity_clear(&parser->entities); /* Miscellaneous */ - darray_instance_clear(&parser->instances); + darray_geometry_clear(&parser->geometries); } static void @@ -297,11 +299,11 @@ parser_release(ref_T* ref) solstice_sun_release(&parser->sun); /* Tree */ - htable_yaml2sols_release(&parser->yaml2trees); - darray_node_release(&parser->nodes); + htable_yaml2sols_release(&parser->yaml2entities); + darray_entity_release(&parser->entities); /* Instance */ - darray_instance_release(&parser->instances); + darray_geometry_release(&parser->geometries); MEM_RM(parser->allocator, parser); } @@ -637,102 +639,6 @@ error: } /******************************************************************************* - * Instance - ******************************************************************************/ -static res_T -parse_instance - (struct solstice_parser* parser, - yaml_document_t* doc, - const yaml_node_t* inst, - struct solstice_instance_id* out_isolinst) -{ - enum { GEOMETRY, TRANSFORM }; - struct solstice_instance* solinst = NULL; - size_t isolinst = SIZE_MAX; - intptr_t i, n; - int mask = 0; /* Register the parsed attributes */ - res_T res = RES_OK; - ASSERT(doc && inst); - - if(inst->type != YAML_MAPPING_NODE) { - log_err(parser, inst, "expect an instance definition.\n"); - res = RES_BAD_ARG; - goto error; - } - - /* Allocate an instance */ - isolinst = darray_instance_size_get(&parser->instances); - res = darray_instance_resize(&parser->instances, isolinst + 1); - if(res != RES_OK) { - log_err(parser, inst, "could not allocate the instance.\n"); - goto error; - } - solinst = darray_instance_data_get(&parser->instances) + isolinst; - d3_splat(solinst->translation, 0); - d3_splat(solinst->rotation, 0); - - n = inst->data.mapping.pairs.top - inst->data.mapping.pairs.start; - FOR_EACH(i, 0, n) { - yaml_node_t* key; - yaml_node_t* val; - - key = yaml_document_get_node(doc, inst->data.mapping.pairs.start[i].key); - val = yaml_document_get_node(doc, inst->data.mapping.pairs.start[i].value); - if(key->type != YAML_SCALAR_NODE) { - log_err(parser, key, "expect instance parameters.\n"); - res = RES_BAD_ARG; - goto error; - } - #define SETUP_MASK(Flag, Name) { \ - if(mask & BIT(Flag)) { \ - log_err(parser, key, "the instance "Name" is already defined.\n"); \ - res = RES_BAD_ARG; \ - goto error; \ - } \ - mask |= BIT(Flag); \ - } (void)0 - if(!strcmp((char*)key->data.scalar.value, "object")) { - SETUP_MASK(GEOMETRY, "geometry"); - solinst->type = SOLSTICE_INSTANCE_OBJECT; - res = parse_object(parser, doc, val, &solinst->data.object); - } else if(!strcmp((char*)key->data.scalar.value, "transform")) { - SETUP_MASK(TRANSFORM, "transform"); - res = parse_transform - (parser, doc, val, solinst->translation, solinst->rotation); - } else if(!strcmp((char*)key->data.scalar.value, "tree")) { - SETUP_MASK(GEOMETRY, "geometry"); - solinst->type = SOLSTICE_INSTANCE_TREE; - res = parse_node(parser, doc, val, 1, &solinst->data.tree); - } else { - log_err(parser, key, "unknown instance parameter `%s'.\n", - key->data.scalar.value); - res = RES_BAD_ARG; - } - if(res != RES_OK) goto error; - #undef SETUP_MASK - } - - #define CHECK_PARAM(Flag, Name) \ - if(!(mask & BIT(Flag))) { \ - log_err(parser, inst, "the instance "Name" is missing.\n"); \ - res = RES_BAD_ARG; \ - goto error; \ - } (void)0 - CHECK_PARAM(GEOMETRY, "geometry"); - #undef CHECK_PARAM - -exit: - out_isolinst->i = isolinst; - return res; -error: - if(solinst) { - darray_instance_pop_back(&parser->instances); - solinst = NULL; - } - goto exit; -} - -/******************************************************************************* * Material ******************************************************************************/ static res_T @@ -806,7 +712,7 @@ exit: error: if(mtl) { darray_matte_pop_back(&parser->mattes); - mtl = NULL; + imtl = SIZE_MAX; } goto exit; } @@ -895,7 +801,7 @@ exit: error: if(mtl) { darray_mirror_pop_back(&parser->mirrors); - mtl = NULL; + imtl = SIZE_MAX; } goto exit; } @@ -997,7 +903,7 @@ exit: error: if(mtl) { darray_material_pop_back(&parser->mtls); - mtl = NULL; + imtl = SIZE_MAX; } goto exit; } @@ -1087,7 +993,7 @@ exit: error: if(mtl2) { darray_material2_pop_back(&parser->mtls2); - mtl2 = NULL; + imtl2 = SIZE_MAX; } goto exit; } @@ -1361,7 +1267,7 @@ exit: error: if(shape) { darray_cuboid_pop_back(&parser->cuboids); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } @@ -1452,7 +1358,7 @@ exit: error: if(shape) { darray_cylinder_pop_back(&parser->cylinders); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } @@ -1536,7 +1442,7 @@ exit: error: if(shape) { darray_impgeom_pop_back(impgeoms); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } @@ -1638,7 +1544,7 @@ exit: error: if(shape) { darray_paraboloid_pop_back(paraboloids); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } @@ -1712,7 +1618,7 @@ exit: error: if(shape) { darray_plane_pop_back(&parser->planes); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } @@ -1795,15 +1701,15 @@ exit: error: if(shape) { darray_sphere_pop_back(&parser->spheres); - shape = NULL; + ishape = SIZE_MAX; } goto exit; } /******************************************************************************* - * Object + * Geometry ******************************************************************************/ -res_T +static res_T parse_object (struct solstice_parser* parser, yaml_document_t* doc, @@ -1960,169 +1866,152 @@ error: goto exit; } -/******************************************************************************* - * Tree - ******************************************************************************/ static res_T -parse_children +parse_geometry (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* children, - struct darray_child* nodes) + yaml_node_t* geometry, + struct solstice_geometry_id* out_isolgeom) { + struct solstice_geometry* solgeom = NULL; + size_t isolgeom = SIZE_MAX; intptr_t i, n; res_T res = RES_OK; - ASSERT(doc && children && nodes); + ASSERT(doc && geometry && out_isolgeom); - if(children->type != YAML_SEQUENCE_NODE) { - log_err(parser, children, "expect a list of nodes.\n"); + if(geometry->type != YAML_SEQUENCE_NODE) { + log_err(parser, geometry, "expect a list of objects.\n"); res = RES_BAD_ARG; goto error; } - n = children->data.sequence.items.top - children->data.sequence.items.start; - res = darray_child_resize(nodes, (size_t)n); + /* Allocate the geometry */ + isolgeom = darray_geometry_size_get(&parser->geometries); + res = darray_geometry_resize(&parser->geometries, isolgeom + 1); if(res != RES_OK) { - log_err(parser, children, "could not allocate the children list.\n"); + log_err(parser, geometry, "could not allocate the geometry.\n"); + goto error; + } + solgeom = darray_geometry_data_get(&parser->geometries) + isolgeom; + + n = geometry->data.sequence.items.top - geometry->data.sequence.items.start; + res = darray_object_id_resize(&solgeom->objects, (size_t)n); + if(res != RES_OK) { + log_err(parser, geometry, "could not allocate the objects list.\n"); goto error; } FOR_EACH(i, 0, n) { - struct solstice_node_id* node_id = darray_child_data_get(nodes) + i; - yaml_node_t* child; + struct solstice_object_id* obj_id; + yaml_node_t* obj; - child = yaml_document_get_node(doc, children->data.sequence.items.start[i]); - res = parse_node(parser, doc, child, 0/*the node is not root*/, node_id); + obj_id = darray_object_id_data_get(&solgeom->objects) + i; + obj = yaml_document_get_node(doc, geometry->data.sequence.items.start[i]); + res = parse_object(parser, doc, obj, obj_id); if(res != RES_OK) goto error; } exit: + out_isolgeom->i = isolgeom; return res; error: - darray_child_clear(nodes); + if(solgeom) { + darray_geometry_pop_back(&parser->geometries); + isolgeom = SIZE_MAX; + } goto exit; } + +/******************************************************************************* + * Entity + ******************************************************************************/ static res_T -parse_geometries +parse_children (struct solstice_parser* parser, yaml_document_t* doc, - const yaml_node_t* geometries, - struct darray_geometry* objects) + const yaml_node_t* children, + struct darray_child* entities) { intptr_t i, n; res_T res = RES_OK; - ASSERT(doc && geometries && objects); + ASSERT(doc && children && entities); - if(geometries->type != YAML_SEQUENCE_NODE) { - log_err(parser, geometries, "expect a list of objects.\n"); + if(children->type != YAML_SEQUENCE_NODE) { + log_err(parser, children, "expect a list of entities.\n"); res = RES_BAD_ARG; goto error; } - n = geometries->data.sequence.items.top - geometries->data.sequence.items.start; - res = darray_geometry_resize(objects, (size_t)n); + n = children->data.sequence.items.top - children->data.sequence.items.start; + res = darray_child_resize(entities, (size_t)n); if(res != RES_OK) { - log_err(parser, geometries, "could not allocate the objects list.\n"); + log_err(parser, children, "could not allocate the children list.\n"); goto error; } FOR_EACH(i, 0, n) { - struct solstice_object_id* obj_id = darray_geometry_data_get(objects) + i; - yaml_node_t* geom; - yaml_node_t* key; - yaml_node_t* val; - intptr_t nb; - - geom = yaml_document_get_node(doc, geometries->data.sequence.items.start[i]); - - if(geom->type != YAML_MAPPING_NODE) { - log_err(parser, geom, "expect a geometry definition.\n"); - res = RES_BAD_ARG; - goto error; - } - - nb = geom->data.mapping.pairs.top - geom->data.mapping.pairs.start; - if(nb != 1) { - log_err(parser, geom, - "expect only one \"key:value\" pair while %li are provided.\n", nb); - res = RES_BAD_ARG; - goto error; - } - - key = yaml_document_get_node(doc, geom->data.mapping.pairs.start[0].key); - val = yaml_document_get_node(doc, geom->data.mapping.pairs.start[0].value); - if(key->type != YAML_SCALAR_NODE) { - log_err(parser, key, "expect a geometry name.\n"); - res = RES_BAD_ARG; - goto error; - } + struct solstice_entity_id* entity_id = darray_child_data_get(entities) + i; + yaml_node_t* child; - if(!strcmp((char*)key->data.scalar.value, "object")) { - res = parse_object(parser, doc, val, obj_id); - } else { - log_err(parser, key, "unknown geometry `%s'.\n", key->data.scalar.value); - res = RES_BAD_ARG; - } + child = yaml_document_get_node(doc, children->data.sequence.items.start[i]); + res = parse_entity(parser, doc, child, entity_id); if(res != RES_OK) goto error; } exit: return res; error: - darray_geometry_clear(objects); + darray_child_clear(entities); goto exit; } res_T -parse_node +parse_entity (struct solstice_parser* parser, yaml_document_t* doc, - yaml_node_t* node, - const int is_root_node, - struct solstice_node_id* out_isolnode) + yaml_node_t* entity, + struct solstice_entity_id* out_isolent) { - enum { CHILDREN, DATA, TRANSFORM }; - struct solstice_node* solnode = NULL; - size_t isolnode = SIZE_MAX; + enum { CHILDREN, DATA, NAME, TRANSFORM }; + struct solstice_entity* solent = NULL; + const size_t *pisolent; + size_t isolent = SIZE_MAX; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ res_T res = RES_OK; - ASSERT(doc && node && out_isolnode); - - if(is_root_node) { - const size_t *pisolnode; - pisolnode = htable_yaml2sols_find(&parser->yaml2trees, &node); - if(pisolnode) { - solnode = darray_node_data_get(&parser->nodes) + *pisolnode; - goto exit; - } + ASSERT(doc && entity && out_isolent); + + pisolent = htable_yaml2sols_find(&parser->yaml2entities, &entity); + if(pisolent) { + isolent = *pisolent; + goto exit; } - if(node->type != YAML_MAPPING_NODE) { - log_err(parser, node, "expect a node definition.\n"); + if(entity->type != YAML_MAPPING_NODE) { + log_err(parser, entity, "expect an entity definition.\n"); res = RES_BAD_ARG; goto error; } - /* Allocate the solstice node */ - isolnode = darray_node_size_get(&parser->nodes); - res = darray_node_resize(&parser->nodes, isolnode + 1); + /* Allocate the entity */ + isolent = darray_entity_size_get(&parser->entities); + res = darray_entity_resize(&parser->entities, isolent + 1); if(res != RES_OK) { - log_err(parser, node, "could not allocate the node.\n"); + log_err(parser, entity, "could not allocate the entity.\n"); goto error; } - solnode = darray_node_data_get(&parser->nodes) + isolnode; + solent = darray_entity_data_get(&parser->entities) + isolent; - n = node->data.mapping.pairs.top - node->data.mapping.pairs.start; + n = entity->data.mapping.pairs.top - entity->data.mapping.pairs.start; FOR_EACH(i, 0, n) { yaml_node_t* key; yaml_node_t* val; - key = yaml_document_get_node(doc, node->data.mapping.pairs.start[i].key); - val = yaml_document_get_node(doc, node->data.mapping.pairs.start[i].value); + key = yaml_document_get_node(doc, entity->data.mapping.pairs.start[i].key); + val = yaml_document_get_node(doc, entity->data.mapping.pairs.start[i].value); if(key->type != YAML_SCALAR_NODE) { - log_err(parser, key, "expect a node attribute.\n"); + log_err(parser, key, "expect an entity attribute.\n"); res = RES_BAD_ARG; goto error; } @@ -2130,7 +2019,7 @@ parse_node #define SETUP_MASK(Flag, Name) { \ if(mask & BIT(Flag)) { \ log_err(parser, key, \ - "the node "Name" is already defined.\n"); \ + "the entity "Name" is already defined.\n"); \ res = RES_BAD_ARG; \ goto error; \ } \ @@ -2138,19 +2027,21 @@ parse_node } (void)0 if(!strcmp((char*)key->data.scalar.value, "children")) { SETUP_MASK(CHILDREN, "children"); - res = parse_children(parser, doc, val, &solnode->children); - } else if(!strcmp((char*)key->data.scalar.value, "geometries")) { + res = parse_children(parser, doc, val, &solent->children); + } else if(!strcmp((char*)key->data.scalar.value, "geometry")) { SETUP_MASK(DATA, "data"); - res = parse_geometries(parser, doc, val, &solnode->geometries); + res = parse_geometry(parser, doc, val, &solent->geometry); + } else if(!strcmp((char*)key->data.scalar.value, "name")) { + SETUP_MASK(NAME, "name"); /* TODO parse the entity name */ } else if(!strcmp((char*)key->data.scalar.value, "pivot")) { SETUP_MASK(DATA, "data"); res = parse_pivot(parser, doc, val); } else if(!strcmp((char*)key->data.scalar.value, "transform")) { SETUP_MASK(TRANSFORM, "transform"); res = parse_transform - (parser, doc, val, solnode->translation, solnode->rotation); + (parser, doc, val, solent->translation, solent->rotation); } else { - log_err(parser, key, "unknown node parameter `%s'.\n", + log_err(parser, key, "unknown entity parameter `%s'.\n", key->data.scalar.value); res = RES_BAD_ARG; goto error; @@ -2161,28 +2052,27 @@ parse_node #define CHECK_PARAM(Flag, Name) \ if(!(mask & BIT(Flag))) { \ - log_err(parser, node, "the node "Name" is missing.\n"); \ + log_err(parser, entity, "the entity "Name" is missing.\n"); \ res = RES_BAD_ARG; \ goto error; \ } (void)0 CHECK_PARAM(DATA, "data"); + CHECK_PARAM(NAME, "name"); #undef CHECK_PARAM - if(is_root_node) { - res = htable_yaml2sols_set(&parser->yaml2trees, &node, &isolnode); - if(res != RES_OK) { - log_err(parser, node, "could not register the tree.\n"); - goto error; - } + res = htable_yaml2sols_set(&parser->yaml2entities, &entity, &isolent); + if(res != RES_OK) { + log_err(parser, entity, "could not register the entity.\n"); + goto error; } exit: - out_isolnode->i = isolnode; + out_isolent->i = isolent; return res; error: - if(solnode) { - darray_node_pop_back(&parser->nodes); - solnode = NULL; + if(solent) { + darray_entity_pop_back(&parser->entities); + isolent = SIZE_MAX; } goto exit; } @@ -2579,10 +2469,9 @@ parse_item { yaml_node_t* key; yaml_node_t* val; - struct solstice_instance_id instance; /* TODO */ struct solstice_material_double_sided_id mtl2; /* TODO */ - struct solstice_node_id node; /* TODO */ - struct solstice_object_id obj; /* TODO */ + struct solstice_entity_id entity; /* TODO */ + struct solstice_geometry_id geometry; /* TODO */ struct solstice_sun* sun; /* TODO */ intptr_t n; res_T res = RES_OK; @@ -2610,16 +2499,12 @@ parse_item goto error; } - if(!strcmp((char*)key->data.scalar.value, "instance")) { - res = parse_instance(parser, doc, val, &instance); - } else if(!strcmp((char*)key->data.scalar.value, "material")) { + if(!strcmp((char*)key->data.scalar.value, "material")) { res = parse_material(parser, doc, val, &mtl2); - } else if(!strcmp((char*)key->data.scalar.value, "tree")) { - res = parse_node(parser, doc, val, 1, &node); - } else if(!strcmp((char*)key->data.scalar.value, "object")) { - res = parse_object(parser, doc, val, &obj); - } else if(!strcmp((char*)key->data.scalar.value, "pivot")) { - res = parse_pivot(parser, doc, val); + } else if(!strcmp((char*)key->data.scalar.value, "entity")) { + res = parse_entity(parser, doc, val, &entity); + } else if(!strcmp((char*)key->data.scalar.value, "geometry")) { + res = parse_geometry(parser, doc, val, &geometry); } else if(!strcmp((char*)key->data.scalar.value, "sun")) { res = parse_sun(parser, doc, val, &sun); } else { @@ -2682,11 +2567,11 @@ solstice_parser_create solstice_sun_init(mem_allocator, &parser->sun); /* Tree */ - htable_yaml2sols_init(mem_allocator, &parser->yaml2trees); - darray_node_init(mem_allocator, &parser->nodes); + htable_yaml2sols_init(mem_allocator, &parser->yaml2entities); + darray_entity_init(mem_allocator, &parser->entities); /* Miscellaneous */ - darray_instance_init(mem_allocator, &parser->instances); + darray_geometry_init(mem_allocator, &parser->geometries); exit: *out_parser = parser; diff --git a/src/solstice_shape.h b/src/solstice_shape.h @@ -256,14 +256,5 @@ struct solstice_shape { struct solstice_shape_id { size_t i; }; -struct solstice_object { - struct solstice_material_double_sided_id mtl2; - struct solstice_shape_id shape; - double translation[3]; - double rotation[3]; -}; - -struct solstice_object_id { size_t i; }; - #endif /* SOLSTICE_SHAPE_H */ diff --git a/src/yaml/test_ok_0.yaml b/src/yaml/test_ok_0.yaml @@ -1,49 +1,52 @@ -- instance: - object: - transform: - rotation: [ 0, 1, 2 ] - translation: [ -4, 5.2, -6.5 ] - material: { matte: { reflectivity: 1 } } - cuboid: { size: [1, 2, 3] } +- entity: + name: "entity" + transform: + rotation: [ 0, 1, 2 ] + translation: [ -4, 5.2, -6.5 ] + geometry: + - cuboid: { size: [1, 2, 3] } + material: { matte: { reflectivity: 1 } } --- -- instance: +- entity: + name: "entity" transform: { translation: [ 1, 2, 0 ] } - object: - transform: - rotation: [ 0, 1, 2 ] - material: { matte: { reflectivity: 1 } } - cuboid: { size: [1, 2, 3] } + geometry: + - transform: + rotation: [ 0, 1, 2 ] + material: { matte: { reflectivity: 1 } } + cuboid: { size: [1, 2, 3] } --- -- instance: - object: - material: { matte: { reflectivity: 1 } } - cuboid: { size: [1, 2, 3] } +- entity: + name: "entity" + geometry: + - material: { matte: { reflectivity: 1 } } + cuboid: { size: [1, 2, 3] } --- - material: &lambertian matte: { reflectivity: 1 } -- instance: - object: - material: *lambertian - cuboid: { size: [1, 2, 3] } +- entity: + name: "entity" + geometry: + - material: *lambertian + cuboid: { size: [1, 2, 3] } --- - material: &front { matte: { reflectivity: 1 } } -- material: &back { matte: { reflectivity: 0.5 } } -- object: &cuboid - cuboid: { size: [1, 2, 3] } - material: { front: *front, back: *back } -- instance: { object: *cuboid } +- material: &back { matte: { reflectivity: 0.5 } } +- geometry: &cuboid + - cuboid: { size: [1, 2, 3] } + material: { front: *front, back: *back } +- entity: { name: "hop", geometry: *cuboid } --- - material: &lambertian { matte: { reflectivity: 1 } } -- instance: - object: &cuboid - cuboid: { size: [1, 2, 3] } - material: - front: *lambertian - back: *lambertian - - +- entity: + name: hop + geometry: &cuboid + - cuboid: { size: [1, 2, 3] } + material: + front: *lambertian + back: *lambertian diff --git a/src/yaml/test_ok_1.yaml b/src/yaml/test_ok_1.yaml @@ -3,15 +3,16 @@ reflectivity: 1 roughness: 0 -- object: &cylinder - material: *mirror - cylinder: - height: 1 - radius: 1 - slices: 32 +- geometry: &cylinder + - material: *mirror + cylinder: + height: 1 + radius: 1 + slices: 32 -- instance: - object: *cylinder +- entity: + name: "hop" + geometry: *cylinder transform: translation: [0, 1, 2] rotation: [0, 0, 0] @@ -21,27 +22,31 @@ reflectivity: 1 roughness: 0 -- object: &cylinder - material: *mirror - cylinder: - height: 1 - radius: 1 +- geometry: &cylinder + - material: *mirror + cylinder: + height: 1 + radius: 1 -- instance: - object: *cylinder +- entity: + name: "entity" + geometry: *cylinder --- -- instance: - object: - material: { mirror: { reflectivity: 0.314, roughness: 0.5 } } - cylinder: { height: 10.12, radius: 0.32 } +- entity: + name: entity + geometry: + - material: { mirror: { reflectivity: 0.314, roughness: 0.5 } } + cylinder: { height: 10.12, radius: 0.32 } --- -- instance: - object: - material: { mirror: { reflectivity: 0, roughness: 0.5 } } - cylinder: { height: 1, radius: 1 } +- entity: + name: entity + geometry: + - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + cylinder: { height: 1, radius: 1 } --- -- instance: - object: - material: { mirror: { reflectivity: 0, roughness: 0.5 } } - cylinder: { height: 0, radius: 0 } +- entity: + name: entity + geometry: + - material: { mirror: { reflectivity: 0, roughness: 0.5 } } + cylinder: { height: 0, radius: 0 } diff --git a/src/yaml/test_ok_2.yaml b/src/yaml/test_ok_2.yaml @@ -1,26 +1,31 @@ -- instance: - object: - material: { matte: { reflectivity: 1 } } - stl: { path: path toward } +- entity: + name: 1 + geometry: + - material: { matte: { reflectivity: 1 } } + stl: { path: path toward } --- -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: { path: "my_path" } +- entity: + name: 1a + geometry: + - material: { matte: { reflectivity: 1 } } + obj: { path: "my_path" } --- -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: { path: "path/path/path" } - transform: { translation: [1, 2, 3] } +- entity: + name: test + geometry: + - material: { matte: { reflectivity: 1 } } + obj: { path: "path/path/path" } + transform: { translation: [1, 2, 3] } --- -- instance: - object: - material: { matte: { reflectivity: 1 } } - obj: { path: "path/path/path" } - transform: { rotation: [0, 0, 0] } +- entity: + name: test + geometry: + - material: { matte: { reflectivity: 1 } } + obj: { path: "path/path/path" } + transform: { rotation: [0, 0, 0] } --- -- instance: - object: - material: { matte: { reflectivity: 1 } } - stl: { path: "path/path/path" } +- entity: + name: hop + geometry: + - material: { matte: { reflectivity: 1 } } + stl: { path: "path/path/path" }