commit 18490c39b9b182c13a8ee33826084692cefe644a
parent 927b5378e55615f62536cf60f18ef39f97c79fd7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 16 Nov 2016 11:39:08 +0100
Begin to load the tree data
Diffstat:
| M | doc/input | | | 57 | +++++++++++++++++++++++++++++---------------------------- |
| A | src/solstice_node.h | | | 84 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/solstice_parser.c | | | 150 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
3 files changed, 215 insertions(+), 76 deletions(-)
diff --git a/doc/input b/doc/input
@@ -37,42 +37,40 @@
object: *cylinder2
# Declare a composition
-- node: &heliostat0
+- tree: &heliostat0
transform: { rotation: [0, 0, 0], translation: [0, 0, 0] }
geometries:
- object: *cylinder
children:
- - node:
- transform: { rotation: [0, 0, 0], translation: [0, 0, 0] }
- pivot:
- point: [0, 0, 0]
- normal: [0, 1, 0]
- target: { alias: self.cylinder2.anchor0 }
- children:
- - node:
+ - transform: { rotation: [0, 0, 0], translation: [0, 0, 0] }
+ pivot:
+ point: [0, 0, 0]
+ normal: [0, 1, 0]
+ target: { alias: self.cylinder2.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: *cylinder
- - object: *cylinder2
- children:
- - node:
- transform: { translation: [2.5, 11, 0], rotation: [90, 0, 0] }
- geometries:
- - object: *parabol
+ - object: *parabol
# Create the solar factory
- instance:
name: "inst"
transform: { translation: [0, 0, 0] }
- node : *heliostat0
+ tree : *heliostat0
- instance:
transform: { translation: [0, 0, 10] }
- node : *heliostat0
+ tree : *heliostat0
- instance:
transform: { translation: [0, 0, 20] }
- node : *heliostat0
+ tree : *heliostat0
- instante:
transform: { translation: [0, 0, 30] }
- node : *heliostat0
+ tree : *heliostat0
- instance:
transform: { translation: [0, 0, -10] }
object : *house
@@ -90,7 +88,7 @@
<items> ::=
<object>
| <material>
- | <node>
+ | <root>>
| <instance>
| <sun>
@@ -210,13 +208,16 @@
reflectivity: REAL # in [0, 1]
----------------------------------------
-<node> ::=
- node:
- <geometries> | <pivot>
-[ <transform> ]
-[ <children> ]
+<tree> ::=
+ tree:
+ <node>
+
+<node-data> ::=
+ <geometries> | <pivot>
+[ <transform> ]
+[ <children> ]
-<entities> ::=
+<geometries> ::=
geometries:
- <object>
[ - <object> ... ]
@@ -246,7 +247,7 @@
----------------------------------------
instance:
- <node> | <object>
+ <tree> | <object>
[ <identifier> ]
[ <transform> ]
diff --git a/src/solstice_node.h b/src/solstice_node.h
@@ -0,0 +1,84 @@
+/* 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 <rsys/double3.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/list.h>
+
+#define DARRAY_NAME geometry
+#define DARRAY_DATA struct solstice_object*
+#include <rsys/dynamic_array.h>
+
+#define DARRAY_NAME child
+#define DARRAY_DATA struct solstice_node*
+#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
@@ -16,6 +16,7 @@
#define _POSIX_C_SOURCE 200112L /* nextafter support */
#include "solstice_material.h"
+#include "solstice_node.h"
#include "solstice_parser.h"
#include "solstice_shape.h"
#include "solstice_sun.h"
@@ -106,6 +107,15 @@
#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
+#include <rsys/dynamic_array.h>
+
/* Declare the hash table that maps the address of a YAML node to the id of its
* in memory representation. */
#define HTABLE_NAME yaml2sols
@@ -144,6 +154,10 @@ struct solstice_parser {
const yaml_node_t* sun_key; /* Value of the yaml_node_t ptr used to spawn the sun */
struct solstice_sun sun; /* The loaded sun */
+ /* Miscellaneous */
+ struct htable_yaml2sols yaml2trees; /* Cache of trees */
+ struct darray_node nodes;
+
ref_T ref;
struct mem_allocator* allocator;
};
@@ -152,7 +166,9 @@ static res_T
parse_node
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* children);
+ yaml_node_t* node,
+ const int is_root_node,
+ struct solstice_node** solnode);
static res_T
parse_object
@@ -227,6 +243,10 @@ parser_clear(struct solstice_parser* parser)
/* Sun */
solstice_sun_clear(&parser->sun);
parser->sun_key = 0;
+
+ /* Tree */
+ htable_yaml2sols_clear(&parser->yaml2trees);
+ darray_node_clear(&parser->nodes);
}
static void
@@ -261,8 +281,13 @@ parser_release(ref_T* ref)
htable_yaml2sols_release(&parser->yaml2objs);
darray_object_release(&parser->objects);
+ /* Sun */
solstice_sun_release(&parser->sun);
+ /* Tree */
+ htable_yaml2sols_release(&parser->yaml2trees);
+ darray_node_release(&parser->nodes);
+
MEM_RM(parser->allocator, parser);
}
@@ -607,6 +632,7 @@ parse_instance
{
enum { GEOMETRY, TRANSFORM };
struct solstice_object* obj = NULL; /* TODO */
+ struct solstice_node* node = NULL;
double translation[3] = {0, 0, 0};
double rotation[3] = {0, 0, 0};
intptr_t i, n;
@@ -640,9 +666,9 @@ parse_instance
} \
mask |= BIT(Flag); \
} (void)0
- if(!strcmp((char*)key->data.scalar.value, "node")) {
+ if(!strcmp((char*)key->data.scalar.value, "tree")) {
SETUP_MASK(GEOMETRY, "geometry");
- res = parse_node(parser, doc, val);
+ res = parse_node(parser, doc, val, 1, &node);
} else if(!strcmp((char*)key->data.scalar.value, "object")) {
SETUP_MASK(GEOMETRY, "geometry");
res = parse_object(parser, doc, val, &obj);
@@ -1901,17 +1927,18 @@ error:
}
/*******************************************************************************
- * Node
+ * Tree
******************************************************************************/
static res_T
parse_children
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* children)
+ const yaml_node_t* children,
+ struct darray_child* nodes)
{
intptr_t i, n;
res_T res = RES_OK;
- ASSERT(doc && children);
+ ASSERT(doc && children && nodes);
if(children->type != YAML_SEQUENCE_NODE) {
log_err(parser, children, "expect a list of nodes.\n");
@@ -1920,43 +1947,25 @@ parse_children
}
n = children->data.sequence.items.top - children->data.sequence.items.start;
+ res = darray_child_resize(nodes, (size_t)n);
+ if(res != RES_OK) {
+ log_err(parser, children, "could not allocate the children list.\n");
+ goto error;
+ }
+
FOR_EACH(i, 0, n) {
+ struct solstice_node** pnode = darray_child_data_get(nodes) + i;
yaml_node_t* child;
- yaml_node_t* key;
- yaml_node_t* val;
- intptr_t nb;
child = yaml_document_get_node(doc, children->data.sequence.items.start[i]);
- if(child->type != YAML_MAPPING_NODE) {
- log_err(parser, child, "expect a node definition.\n");
- res = RES_BAD_ARG;
- goto error;
- }
- nb = child->data.mapping.pairs.top - child->data.mapping.pairs.start;
- if(nb != 1) {
- log_err(parser, child,
- "expect only one \"key:value\" pair while %li are provided.\n", nb);
- res = RES_BAD_ARG;
- goto error;
- }
-
- key = yaml_document_get_node(doc, child->data.mapping.pairs.start[0].key);
- val = yaml_document_get_node(doc, child->data.mapping.pairs.start[0].value);
- if(!strcmp((char*)key->data.scalar.value, "node")) {
- res = parse_node(parser, doc, val);
- } else {
- log_err(parser, key, "unexpected directive `%s'. Expect a node.\n",
- key->data.scalar.value);
- res = RES_BAD_ARG;
- }
+ res = parse_node(parser, doc, child, 0/*the node is not root*/, pnode);
if(res != RES_OK) goto error;
-
- /* TODO register the child node */
}
exit:
return res;
error:
+ darray_child_clear(nodes);
goto exit;
}
@@ -1964,12 +1973,12 @@ static res_T
parse_geometries
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* geometries)
+ const yaml_node_t* geometries,
+ struct darray_geometry* objects)
{
- struct solstice_object* obj;
intptr_t i, n;
res_T res = RES_OK;
- ASSERT(doc && geometries);
+ ASSERT(doc && geometries && objects);
if(geometries->type != YAML_SEQUENCE_NODE) {
log_err(parser, geometries, "expect a list of objects.\n");
@@ -1978,7 +1987,14 @@ parse_geometries
}
n = geometries->data.sequence.items.top - geometries->data.sequence.items.start;
+ res = darray_geometry_resize(objects, (size_t)n);
+ if(res != RES_OK) {
+ log_err(parser, geometries, "could not allocate the objects list.\n");
+ goto error;
+ }
+
FOR_EACH(i, 0, n) {
+ struct solstice_object** pobj = darray_geometry_data_get(objects) + i;
yaml_node_t* geom;
yaml_node_t* key;
yaml_node_t* val;
@@ -2009,19 +2025,18 @@ parse_geometries
}
if(!strcmp((char*)key->data.scalar.value, "object")) {
- res = parse_object(parser, doc, val, &obj);
+ res = parse_object(parser, doc, val, pobj);
} else {
log_err(parser, key, "unknown geometry `%s'.\n", key->data.scalar.value);
res = RES_BAD_ARG;
}
if(res != RES_OK) goto error;
-
- /* TODO register the geometry */
}
exit:
return res;
error:
+ darray_geometry_clear(objects);
goto exit;
}
@@ -2029,15 +2044,26 @@ res_T
parse_node
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* node)
+ yaml_node_t* node,
+ const int is_root_node,
+ struct solstice_node** out_solnode)
{
enum { CHILDREN, DATA, TRANSFORM };
- double translation[3] = {0, 0, 0};
- double rotation[3] = {0, 0, 0};
+ struct solstice_node* solnode = NULL;
+ size_t isolnode;
intptr_t i, n;
int mask = 0; /* Register the parsed attributes */
res_T res = RES_OK;
- ASSERT(doc && node);
+ ASSERT(doc && node && out_solnode);
+
+ 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;
+ }
+ }
if(node->type != YAML_MAPPING_NODE) {
log_err(parser, node, "expect a node definition.\n");
@@ -2045,6 +2071,15 @@ parse_node
goto error;
}
+ /* Allocate the solstice node */
+ isolnode = darray_node_size_get(&parser->nodes);
+ res = darray_node_resize(&parser->nodes, isolnode + 1);
+ if(res != RES_OK) {
+ log_err(parser, node, "could not allocate the node.\n");
+ goto error;
+ }
+ solnode = darray_node_data_get(&parser->nodes) + isolnode;
+
n = node->data.mapping.pairs.top - node->data.mapping.pairs.start;
FOR_EACH(i, 0, n) {
yaml_node_t* key;
@@ -2069,16 +2104,17 @@ parse_node
} (void)0
if(!strcmp((char*)key->data.scalar.value, "children")) {
SETUP_MASK(CHILDREN, "children");
- res = parse_children(parser, doc, val);
+ res = parse_children(parser, doc, val, &solnode->children);
} else if(!strcmp((char*)key->data.scalar.value, "geometries")) {
SETUP_MASK(DATA, "data");
- res = parse_geometries(parser, doc, val);
+ res = parse_geometries(parser, doc, val, &solnode->geometries);
} 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, translation, rotation);
+ res = parse_transform
+ (parser, doc, val, solnode->translation, solnode->rotation);
} else {
log_err(parser, key, "unknown node parameter `%s'.\n",
key->data.scalar.value);
@@ -2098,9 +2134,22 @@ parse_node
CHECK_PARAM(DATA, "data");
#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;
+ }
+ }
+
exit:
+ *out_solnode = solnode;
return res;
error:
+ if(solnode) {
+ darray_node_pop_back(&parser->nodes);
+ solnode = NULL;
+ }
goto exit;
}
@@ -2499,6 +2548,7 @@ parse_item
struct solstice_sun* sun; /* TODO */
struct solstice_material_double_sided* mtl2; /* TODO */
struct solstice_object* obj; /* TODO */
+ struct solstice_node* node; /* TODO */
intptr_t n;
res_T res = RES_OK;
ASSERT(doc && item);
@@ -2529,8 +2579,8 @@ parse_item
res = parse_instance(parser, doc, val);
} else if(!strcmp((char*)key->data.scalar.value, "material")) {
res = parse_material(parser, doc, val, &mtl2);
- } else if(!strcmp((char*)key->data.scalar.value, "node")) {
- res = parse_node(parser, doc, val);
+ } else if(!strcmp((char*)key->data.scalar.value, "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")) {
@@ -2596,6 +2646,10 @@ 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);
+
exit:
*out_parser = parser;
return res;