commit 24b0c63edfc72d53f018c58ecaeb00b67d951751
parent ca263bca82309e52f94da0c38c01549faaef5203
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 23 Nov 2016 10:45:26 +0100
Update the pivot fileformat and load its data
Diffstat:
6 files changed, 153 insertions(+), 47 deletions(-)
diff --git a/doc/input b/doc/input
@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------
# Declare materials
- material: &lambertian
- matte:
+ matte:
reflectivity: 1
- material: &mirror
mirror: { reflectivity: 1, roughness: 0 }
@@ -57,7 +57,7 @@
pivot:
point: [0, 0, 0]
normal: [0, 1, 0]
- target: "entity0.anchor0"
+
- entity:
<<: *composition
@@ -110,7 +110,11 @@
<target> ::=
target:
- <anchor-identifier> | <real3> | <sun>
+ anchor: <anchor-identifier>
+ | direction: <real3>
+ | position: <real3>
+ | <sun>
+
----------------------------------------
<shape> ::=
@@ -221,6 +225,12 @@
name: STRING
position: <real3>
+<entity-identifier> ::=
+ STRING[.STRING ... ]
+
+<anchor-identifier> ::=
+ <entity-identifier>.STRING
+
----------------------------------------
<sun> ::=
sun:
@@ -259,9 +269,4 @@
wavelength: REAL
data: REAL
-<identifier> ::=
- name: STRING
-
-<anchor-identifier> ::=
- "<identifier>.<identifier>.<identifier>"
diff --git a/src/parser/solstice_entity.h b/src/parser/solstice_entity.h
@@ -26,6 +26,11 @@
#include <rsys/list.h>
#include <rsys/str.h>
+enum solstice_entity_type {
+ SOLSTICE_ENTITY_GEOMETRY,
+ SOLSTICE_ENTITY_PIVOT
+};
+
struct solstice_entity_id { size_t i; };
#define DARRAY_NAME child_id
@@ -54,7 +59,12 @@ struct solstice_entity {
double translation[3];
struct str name;
- struct solstice_geometry_id geometry;
+
+ enum solstice_entity_type type;
+ union {
+ struct solstice_geometry_id geometry;
+ struct solstice_pivot_id pivot;
+ } data;
/* Internal data. Should not be acceded directly. */
struct htable_str2sols str2anchors;
@@ -70,7 +80,8 @@ solstice_entity_init
ASSERT(entity);
d3_splat(entity->rotation, 0);
d3_splat(entity->translation, 0);
- entity->geometry.i = SIZE_MAX;
+ entity->type = SOLSTICE_ENTITY_GEOMETRY;
+ entity->data.geometry.i = SIZE_MAX;
str_init(allocator, &entity->name);
htable_str2sols_init(allocator, &entity->str2anchors);
htable_str2sols_init(allocator, &entity->str2children);
@@ -97,7 +108,8 @@ solstice_entity_copy
ASSERT(dst && src);
d3_set(dst->translation, src->translation);
d3_set(dst->rotation, src->rotation);
- dst->geometry = src->geometry;
+ dst->type = src->type;
+ dst->data = src->data;
res = str_copy(&dst->name, &src->name);
if(res != RES_OK) return res;
res = htable_str2sols_copy(&dst->str2anchors, &src->str2anchors);
@@ -119,7 +131,8 @@ solstice_entity_copy_and_release
ASSERT(dst && src);
d3_set(dst->translation, src->translation);
d3_set(dst->rotation, src->rotation);
- dst->geometry = src->geometry;
+ dst->type = src->type;
+ dst->data = src->data;
res = str_copy_and_release(&dst->name, &src->name);
if(res != RES_OK) return res;
res = htable_str2sols_copy_and_release(&dst->str2anchors, &src->str2anchors);
diff --git a/src/parser/solstice_parser.c b/src/parser/solstice_parser.c
@@ -135,6 +135,11 @@
#define DARRAY_FUNCTOR_COPY_AND_RELEASE solstice_anchor_copy_and_release
#include <rsys/dynamic_array.h>
+/* Declare the array of pivots */
+#define DARRAY_NAME pivot
+#define DARRAY_DATA struct solstice_pivot
+#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
@@ -179,8 +184,9 @@ struct solstice_parser {
struct htable_str2sols str2entities;
struct darray_entity entities;
- /* Anchors */
+ /* Miscellaneous */
struct darray_anchor anchors;
+ struct darray_pivot pivots;
ref_T ref;
struct mem_allocator* allocator;
@@ -205,7 +211,8 @@ static res_T
parse_pivot
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* pivot);
+ const yaml_node_t* pivot,
+ struct solstice_pivot_id* out_isolpivot);
static res_T
parse_sun
@@ -269,13 +276,14 @@ parser_clear(struct solstice_parser* parser)
solstice_sun_clear(&parser->sun);
parser->sun_key = 0;
- /* Entitiies */
+ /* Entities */
htable_yaml2sols_clear(&parser->yaml2entities);
htable_str2sols_clear(&parser->str2entities);
darray_entity_clear(&parser->entities);
- /* Anchors */
+ /* Miscellaneous */
darray_anchor_clear(&parser->anchors);
+ darray_pivot_clear(&parser->pivots);
}
static void
@@ -319,8 +327,9 @@ parser_release(ref_T* ref)
htable_str2sols_release(&parser->str2entities);
darray_entity_release(&parser->entities);
- /* Anchors */
+ /* Miscellaneous */
darray_anchor_release(&parser->anchors);
+ darray_pivot_release(&parser->pivots);
MEM_RM(parser->allocator, parser);
}
@@ -2274,13 +2283,15 @@ parse_entity
(parser, doc, val, &solent->str2children, &solent->children);
} else if(!strcmp((char*)key->data.scalar.value, "geometry")) {
SETUP_MASK(DATA, "data");
- res = parse_geometry(parser, doc, val, &solent->geometry);
+ solent->type = SOLSTICE_ENTITY_GEOMETRY;
+ res = parse_geometry(parser, doc, val, &solent->data.geometry);
} else if(!strcmp((char*)key->data.scalar.value, "name")) {
SETUP_MASK(NAME, "name");
res = parse_identifier_string(parser, val, &solent->name);
} else if(!strcmp((char*)key->data.scalar.value, "pivot")) {
SETUP_MASK(DATA, "data");
- res = parse_pivot(parser, doc, val);
+ solent->type = SOLSTICE_ENTITY_PIVOT;
+ res = parse_pivot(parser, doc, val, &solent->data.pivot);
} else if(!strcmp((char*)key->data.scalar.value, "transform")) {
SETUP_MASK(TRANSFORM, "transform");
res = parse_transform
@@ -2347,19 +2358,54 @@ error:
* Pivot
******************************************************************************/
static res_T
+parse_anchor_alias
+ (struct solstice_parser* parser,
+ const yaml_node_t* alias,
+ struct solstice_anchor_id* out_ianchor)
+{
+ const struct solstice_anchor* anchor = NULL;
+ intptr_t ianchor = INTPTR_MAX;
+ res_T res = RES_OK;
+ ASSERT(parser && alias && out_ianchor);
+
+ if(alias->type != YAML_SCALAR_NODE) {
+ log_err(parser, alias, "expect an anchor idententifier.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ anchor = solstice_parser_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));
+
+exit:
+ out_ianchor->i = (size_t)ianchor;
+ return res;
+error:
+ ianchor = INTPTR_MAX;
+ goto exit;
+}
+
+static res_T
parse_target
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* target)
+ const yaml_node_t* target,
+ struct solstice_pivot* pivot)
{
enum { POLICY };
- struct solstice_sun* sun; /* TODO */
- double direction[3];
- double position[3];
intptr_t i, n;
int mask = 0; /* Register the parsed attributes */
res_T res = RES_OK;
- ASSERT(doc && target);
+ ASSERT(doc && target && pivot);
if(target->type != YAML_MAPPING_NODE) {
log_err(parser, target, "expect a target definition.\n");
@@ -2388,14 +2434,28 @@ parse_target
} \
mask |= BIT(Flag); \
} (void)0
- if(!strcmp((char*)key->data.scalar.value, "direction")) {
+ if(!strcmp((char*)key->data.scalar.value, "anchor")) {
SETUP_MASK(POLICY, "policy");
- res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, direction);
+ pivot->target_type = SOLSTICE_TARGET_ANCHOR;
+ res = parse_anchor_alias(parser, val, &pivot->target.anchor);
+ } else if(!strcmp((char*)key->data.scalar.value, "direction")) {
+ SETUP_MASK(POLICY, "policy");
+ pivot->target_type = SOLSTICE_TARGET_DIRECTION;
+ res = parse_real3
+ (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.direction);
} else if(!strcmp((char*)key->data.scalar.value, "position")) {
SETUP_MASK(POLICY, "policy");
- res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, position);
+ pivot->target_type = SOLSTICE_TARGET_POSITION;
+ res = parse_real3
+ (parser, doc, val, -DBL_MAX, DBL_MAX, pivot->target.position);
} else if(!strcmp((char*)key->data.scalar.value, "sun")) {
+ /* There is only one sun per YAML file. It is thus sufficient to define
+ * the target_type to SOLSTICE_TARGET_SUN to indentify which data is
+ * targeted, i.e. it is not necessary to store the identifier of the sun
+ * to target */
+ struct solstice_sun* sun;
SETUP_MASK(POLICY, "policy");
+ pivot->target_type = SOLSTICE_TARGET_SUN;
res = parse_sun(parser, doc, val, &sun);
} else {
log_err(parser, key, "unknown target parameter `%s'.\n",
@@ -2423,17 +2483,16 @@ static res_T
parse_pivot
(struct solstice_parser* parser,
yaml_document_t* doc,
- const yaml_node_t* pivot)
+ const yaml_node_t* pivot,
+ struct solstice_pivot_id* out_isolpivot)
{
enum { NORMAL, POINT, TARGET, TRANSFORM };
- double point[3];
- double normal[3];
- double translation[3] = {0, 0, 0};
- double rotation[3] = {0, 0, 0};
+ struct solstice_pivot* solpivot = NULL;
+ size_t isolpivot = SIZE_MAX;
int mask = 0; /* Register the parsed attributes */
intptr_t i, n;
res_T res = RES_OK;
- ASSERT(doc && pivot);
+ ASSERT(doc && pivot && out_isolpivot);
if(pivot->type != YAML_MAPPING_NODE) {
log_err(parser, pivot, "expect a pivot definition.\n");
@@ -2441,6 +2500,16 @@ parse_pivot
goto error;
}
+ /* Allocate the solstice pivot */
+ isolpivot = darray_pivot_size_get(&parser->pivots);
+ res = darray_pivot_resize(&parser->pivots, isolpivot + 1);
+ if(res != RES_OK) {
+ log_err(parser, pivot, "could not allocate the pivot.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ solpivot = darray_pivot_data_get(&parser->pivots) + isolpivot;
+
n = pivot->data.mapping.pairs.top - pivot->data.mapping.pairs.start;
FOR_EACH(i, 0, n) {
yaml_node_t* key;
@@ -2464,16 +2533,17 @@ parse_pivot
} (void)0
if(!strcmp((char*)key->data.scalar.value, "point")) {
SETUP_MASK(POINT, "point");
- res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, point);
+ res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot->point);
} else if(!strcmp((char*)key->data.scalar.value, "normal")) {
SETUP_MASK(NORMAL, "normal");
- res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, normal);
+ res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solpivot->normal);
} else if(!strcmp((char*)key->data.scalar.value, "target")) {
SETUP_MASK(TARGET, "target");
- res = parse_target(parser, doc, val);
+ res = parse_target(parser, doc, val, solpivot);
} 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, solpivot->translation, solpivot->rotation);
} else {
log_err(parser, key, "unknown pivot parameter `%s'.\n",
key->data.scalar.value);
@@ -2491,11 +2561,17 @@ parse_pivot
} (void)0
CHECK_PARAM(POINT, "point");
CHECK_PARAM(NORMAL, "normal");
+ CHECK_PARAM(TARGET, "target");
#undef CHECK_PARAM
exit:
+ out_isolpivot->i = isolpivot;
return res;
error:
+ if(solpivot) {
+ darray_pivot_pop_back(&parser->pivots);
+ isolpivot = SIZE_MAX;
+ }
goto exit;
}
@@ -2831,6 +2907,7 @@ solstice_parser_create
darray_object_init(mem_allocator, &parser->objects);
darray_geometry_init(mem_allocator, &parser->geometries);
+ /* Sun */
solstice_sun_init(mem_allocator, &parser->sun);
/* Entities */
@@ -2840,6 +2917,7 @@ solstice_parser_create
/* Anchors */
darray_anchor_init(mem_allocator, &parser->anchors);
+ darray_pivot_init(mem_allocator, &parser->pivots);
exit:
*out_parser = parser;
diff --git a/src/parser/solstice_pivot.h b/src/parser/solstice_pivot.h
@@ -68,8 +68,8 @@ solstice_anchor_copy_and_release
struct solstice_pivot {
double point[3];
double normal[3];
- double position[3];
double rotation[3];
+ double translation[3];
enum solstice_target_type target_type;
union {
double position[3]; /* World space position */
diff --git a/src/parser/test_solstice_parser2.c b/src/parser/test_solstice_parser2.c
@@ -118,8 +118,9 @@ main(int argc, char** argv)
CHECK(d3_eq(entity->rotation, d3(tmp, 4, 5, 6)), 1);
CHECK(strcmp("lvl 0", str_cget(&entity->name)), 0);
CHECK(solstice_entity_get_children_count(entity), 2);
- geom_id = entity->geometry;
- geom = solstice_parser_get_geometry(parser, entity->geometry);
+ CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY);
+ geom_id = entity->data.geometry;
+ geom = solstice_parser_get_geometry(parser, entity->data.geometry);
CHECK(geom == geoms[0] || geom == geoms[1], 1);
CHECK(solstice_geometry_get_objects_count(geom), 1);
obj_id = solstice_geometry_get_object(geom, 0);
@@ -144,8 +145,9 @@ main(int argc, char** argv)
CHECK(d3_eq(entity1a->rotation, d3_splat(tmp, 0)), 1);
CHECK(strcmp("lvl1a", str_cget(&entity1a->name)), 0);
CHECK(solstice_entity_get_children_count(entity1a), 0);
- NCHECK(entity1a->geometry.i, geom_id.i);
- geom = solstice_parser_get_geometry(parser, entity1a->geometry);
+ CHECK(entity1a->type, SOLSTICE_ENTITY_GEOMETRY);
+ NCHECK(entity1a->data.geometry.i, geom_id.i);
+ geom = solstice_parser_get_geometry(parser, entity1a->data.geometry);
CHECK(geom == geoms[0] || geom == geoms[1], 1);
CHECK(solstice_geometry_get_objects_count(geom), 1);
obj_id = solstice_geometry_get_object(geom, 0);
@@ -171,7 +173,8 @@ main(int argc, char** argv)
CHECK(d3_eq(entity1b->rotation, d3(tmp, 3.14, 0, -1)), 1);
CHECK(strcmp("lvl1b", str_cget(&entity1b->name)), 0);
CHECK(solstice_entity_get_children_count(entity1b), 1);
- CHECK(entity1b->geometry.i, geom_id.i);
+ CHECK(entity1b->type, SOLSTICE_ENTITY_GEOMETRY);
+ CHECK(entity1b->data.geometry.i, geom_id.i);
entity_id = solstice_entity_get_child(entity1b, 0);
entity2 = solstice_parser_get_entity(parser, entity_id);
@@ -179,7 +182,8 @@ main(int argc, char** argv)
CHECK(d3_eq(entity2->rotation, d3_splat(tmp, 0)), 1);
CHECK(strcmp("lvl2", str_cget(&entity2->name)), 0);
CHECK(solstice_entity_get_children_count(entity2), 0);
- CHECK(entity2->geometry.i, geom_id.i);
+ CHECK(entity2->type, SOLSTICE_ENTITY_GEOMETRY);
+ CHECK(entity2->data.geometry.i, geom_id.i);
entity3 = solstice_parser_find_entity(parser, "lvl 0");
CHECK(entity3, entity);
diff --git a/src/parser/test_solstice_parser3.c b/src/parser/test_solstice_parser3.c
@@ -85,8 +85,9 @@ main(int argc, char** argv)
CHECK(strcmp(str_cget(&entity->name), "entity0"), 0);
CHECK(d3_eq(entity->rotation, d3_splat(tmp, 0)), 1);
CHECK(d3_eq(entity->translation, d3_splat(tmp, 0)), 1);
+ CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY);
- geom = solstice_parser_get_geometry(parser, entity->geometry);
+ geom = solstice_parser_get_geometry(parser, entity->data.geometry);
CHECK(solstice_geometry_get_objects_count(geom), 1);
obj_id = solstice_geometry_get_object(geom, 0);
@@ -127,14 +128,16 @@ main(int argc, char** argv)
entity_id = solstice_entity_get_child(entity, 0);
entity1 = solstice_parser_get_entity(parser, entity_id);
CHECK(strcmp(str_cget(&entity1->name), "entity0a"), 0);
- CHECK(entity->geometry.i, entity1->geometry.i);
+ CHECK(entity1->type, SOLSTICE_ENTITY_GEOMETRY);
+ CHECK(entity->data.geometry.i, entity1->data.geometry.i);
CHECK(solstice_entity_get_anchors_count(entity1), 0);
CHECK(solstice_entity_get_children_count(entity1), 0);
entity_id = solstice_entity_get_child(entity, 1);
entity1 = solstice_parser_get_entity(parser, entity_id);
CHECK(strcmp(str_cget(&entity1->name), "entity0b"), 0);
- CHECK(entity->geometry.i, entity1->geometry.i);
+ CHECK(entity->type, SOLSTICE_ENTITY_GEOMETRY);
+ CHECK(entity->data.geometry.i, entity1->data.geometry.i);
CHECK(solstice_entity_get_anchors_count(entity1), 2);
CHECK(solstice_entity_get_children_count(entity1), 0);
@@ -163,6 +166,9 @@ main(int argc, char** argv)
anchor4 = solstice_parser_find_anchor(parser, "entity1.entity0b.anchor1");
CHECK(anchor4, NULL);
+ solstice_entity_iterator_next(&it);
+ CHECK(solstice_entity_iterator_eq(&it, &it_end), 1);
+
CHECK(solstice_parser_load(parser), RES_BAD_OP);
solstice_parser_ref_put(parser);
fclose(stream);