commit b854926a3731f2bc175b7d00b3e7fe54f22779d9
parent 619a4d04d54cd6e721736e1990d6f11c006b8c32
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 2 Mar 2017 10:06:30 +0100
Merge remote-tracking branch 'origin/develop' into feature_hyperbols
Diffstat:
14 files changed, 568 insertions(+), 224 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -86,7 +86,7 @@ set(SOLSTICE_FILES_SRC
solstice.c
solstice_args.c
solstice_draw.c
- solstice_dump_obj.c
+ solstice_dump.c
solstice_entity.c
solstice_material.c
solstice_node.c
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -80,6 +80,8 @@ if(NOT NO_TEST)
${SOLPARSER_SOURCE_DIR}/yaml/test_ok_3.yaml)
add_test(test_solparser_ok_4 test_solparser
${SOLPARSER_SOURCE_DIR}/yaml/test_ok_4.yaml)
+ add_test(test_solparser_ok_5 test_solparser
+ ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_5.yaml)
add_test(test_solparser_ko test_solparser -e
${SOLPARSER_SOURCE_DIR}/yaml/test_ko_0.yaml)
@@ -88,6 +90,7 @@ if(NOT NO_TEST)
new_test(test_solparser4)
new_test(test_solparser5)
new_test(test_solparser6)
+ new_test(test_solparser7)
rcmake_copy_runtime_libraries(test_solparser)
endif()
diff --git a/doc/input b/doc/input
@@ -83,46 +83,46 @@
# <solar-factory> ::=
# <sun>
# <items>
-#
+#
# <items> ::=
# - <item>
# [ - <item> ... ]
-#
+#
# <item> ::=
# <geometry>
# | <material>
# | <entity>
# | <template>
-#
+#
# ----------------------------------------
# <geometry> ::=
# geometry:
# - <object>
# [ - <object> ... ]
-#
+#
# <object> ::=
# <shape>
# <material>
# [ <transform> ]
-#
+#
# <x_pivot> ::=
# x_pivot:
# [ ref_point: <real3>. Default 0,0,0 ]
# <target>
-#
+#
# <zx_pivot> ::=
# zx_pivot:
# [ spacing: REAL # in [0, INF). Default 0 ]
# [ ref_point: <real3>. Default 0,0,0 ]
# <target>
-#
+#
# <target> ::=
# target:
# anchor: <anchor-identifier>
# | direction: <real3>
# | position: <real3>
# | <sun>
-#
+#
# ----------------------------------------
# <shape> ::=
# <cuboid>
@@ -133,167 +133,173 @@
# | <plane>
# | <sphere>
# | <stl>
-#
+#
# <cuboid> ::=
# cuboid:
# size: <real3*+>
-#
+#
# <cylinder> ::=
# cylinder:
# height: REAL # in ]0, INF)
# radius: REAL # in ]0, INF)
# [ slices: INTEGER ] # in [4, 4096]. Default 16
-#
+#
# <obj> ::=
# obj:
# path: PATH
-#
+#
# <parabol> ::=
# parabol: # x^2 + y^2 - 4*focal*z = 0
# focal: REAL # in ]0, INF)
# clip: <polyclip-list>
-#
+#
# <parabolic-cylinder> ::=
# parabolic-cylinder: # y^2 - 4*focal*z = 0
# focal: REAL # in ]0, INF)
# clip: <polyclip-list>
-#
+#
# <plane> ::=
# plane:
# clip: <polyclip-list>
-#
+#
# <sphere> ::=
# sphere:
# radius: REAL # in ]0, INF)
# [ slices: INTEGER ] # in [4, 4096]. Default 16
-#
+#
# <stl> ::=
# stl:
# path: PATH
-#
+#
# ----------------------------------------
# <polyclip-list> ::=
# - <polyclip>
# [ - <polyclip> ... ]
-#
+#
# <polyclip> ::=
# operation: <AND|SUB>
# vertices: <vertices-list>
-#
+#
# <vertices-list> ::=
# - <real2>
# - <real2>
# - <real2>
# [ - <real2> ... ]
-#
+#
# ----------------------------------------
# <material> ::=
# <material-descriptor> | <double-sided-material>
-#
+#
# <double-sided-material> ::=
# front: <material-descriptor>
# back: <material-descriptor>
-#
+#
# <material-descriptor> ::=
-# <mirror> | <matte> | <virtual>
-#
+# <mirror> | <matte> | <thin-dielectric> | <virtual>
+#
# <mirror> ::=
# mirror:
# reflectivity: REAL # in [0, 1]
# roughness: REAL # in [0, 1]
-#
+#
# <matte> ::=
# matte:
# reflectivity: REAL # in [0, 1]
-#
+#
# <virtual> ::=
# virtual: EMPTY-STRING
-#
+#
+# <thin-dielectric> ::=
+# thin_dielectric:
+# absorption: REAL # in [0, 1]
+# thickness: REAL # in [0, INF)
+# refractive_index: REAL # in ]0, INF)
+#
# ----------------------------------------
# <entity> ::=
# entity:
# <entity-data>
-#
+#
# <template> ::=
# template:
# <entity-data>
-#
+#
# <entity-data> ::=
# name: STRING # except "self"
# [ <geometry-data> | <x_pivot> | <zx_pivot> ]
# [ <anchors> ]
# [ <transform> ]
# [ <children> ]
-#
+#
# <geometry-data> ::=
# primary: INTEGER # in [0, 1]
-# <geometry>
-#
+# <geometry>
+#
# <children> ::=
# children:
# - <entity-data>
# [ - <entity-data> ... ]
-#
+#
# <anchors> ::=
# anchors:
# - <anchor-data>
# [ - <anchor-data> ... ]
-#
+#
# <anchor-data> ::=
# name: STRING
# position: <real3>
-#
+#
# # "self" references the first level entity
# <entity-identifier> ::=
# <self|STRING>[.STRING ... ]
-#
+#
# <anchor-identifier> ::=
# <entity-identifier>.STRING
-#
+#
# ----------------------------------------
# <sun> ::=
# sun:
# dni: REAL # Direct Normal Irradiance in ]0, INF)
# <spectrum>
# [ <radial-angular-distribution> ]
-#
+#
# <radial-angular-distribution> ::=
# <pillbox> | <buie>
-#
+#
# <buie> ::=
# buie:
# csr: REAL # in [1e-6, 0.849]
-#
+#
# <pillbox> ::=
# pillbox:
# aperture: REAL # in ]0, 90]
-#
+#
# ----------------------------------------
# <transform> ::=
# transform:
# translation: <real3>
# rotation: <real3>
-#
+#
# <real2> ::=
# - REAL
# - REAL
-#
+#
# <real3> ::=
# - REAL
# - 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 # in [0, INF)
# data: REAL # in [0, INF)
-#
-\ No newline at end of file
+#
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -54,6 +54,11 @@ struct target_alias {
#define DARRAY_DATA struct solparser_material_mirror
#include <rsys/dynamic_array.h>
+/* Declare the array of thin_dielectric materials */
+#define DARRAY_NAME thin_dielectric
+#define DARRAY_DATA struct solparser_material_thin_dielectric
+#include <rsys/dynamic_array.h>
+
/* Declare the array of materials */
#define DARRAY_NAME material
#define DARRAY_DATA struct solparser_material
@@ -185,6 +190,7 @@ struct solparser {
struct darray_material2 mtls2; /* Double sided materials */
struct darray_matte mattes;
struct darray_mirror mirrors;
+ struct darray_thin_dielectric thin_dielectrics;
/* Use to deferred the setup of the anchor targeted by a pivot */
struct darray_tgtalias tgtaliases;
@@ -383,6 +389,7 @@ parser_clear(struct solparser* parser)
darray_material2_clear(&parser->mtls2);
darray_matte_clear(&parser->mattes);
darray_mirror_clear(&parser->mirrors);
+ darray_thin_dielectric_clear(&parser->thin_dielectrics);
/* Deferred targeted anchors */
darray_tgtalias_clear(&parser->tgtaliases);
@@ -435,6 +442,7 @@ parser_release(ref_T* ref)
darray_material2_release(&parser->mtls2);
darray_matte_release(&parser->mattes);
darray_mirror_release(&parser->mirrors);
+ darray_thin_dielectric_release(&parser->thin_dielectrics);
/* Deferred targeted anchors */
darray_tgtalias_release(&parser->tgtaliases);
@@ -1027,6 +1035,106 @@ error:
}
static res_T
+parse_material_thin_dielectric
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ yaml_node_t* thin,
+ struct solparser_material_thin_dielectric_id* out_imtl)
+{
+ enum { ABSORPTION, REFRACTIVE_INDEX, THICKNESS };
+ struct solparser_material_thin_dielectric* mtl = NULL;
+ size_t imtl = SIZE_MAX;
+ int mask = 0; /* Register the parsed attributes */
+ intptr_t i, n;
+ res_T res = RES_OK;
+ ASSERT(doc && thin && out_imtl);
+
+ if(thin->type != YAML_MAPPING_NODE) {
+ log_err(parser, thin,
+ "expect a mapping of thin material attributes.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Allocate the thin dielectric material */
+ imtl = darray_thin_dielectric_size_get(&parser->thin_dielectrics);
+ res = darray_thin_dielectric_resize(&parser->thin_dielectrics, imtl + 1);
+ if(res != RES_OK) {
+ log_err(parser, thin,
+ "could not allocate the thin dielectric material.\n");
+ goto error;
+ }
+ mtl = darray_thin_dielectric_data_get(&parser->thin_dielectrics) + imtl;
+
+ n = thin->data.mapping.pairs.top - thin->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, thin->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, thin->data.mapping.pairs.start[i].value);
+ if(key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect a thin dielectric material parameter.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ #define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the "Name" of the thin dielectric material is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "absorption")) {
+ SETUP_MASK(ABSORPTION, "absorption");
+ res = parse_real(parser, val, 0, 1, &mtl->absorption);
+ } else if(!strcmp((char*)key->data.scalar.value, "refractive_index")) {
+ SETUP_MASK(REFRACTIVE_INDEX, "refractive_index");
+ res = parse_real
+ (parser, val, nextafter(0, 1), DBL_MAX, &mtl->refractive_index);
+ } else if(!strcmp((char*)key->data.scalar.value, "thickness")) {
+ SETUP_MASK(THICKNESS, "thickness");
+ res = parse_real(parser, val, 0, DBL_MAX, &mtl->thickness);
+ } else {
+ log_err(parser, key, "unknown thin dielectric parameter `%s'.\n",
+ key->data.scalar.value);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(res != RES_OK) {
+ log_node(parser, key);
+ goto error;
+ }
+ #undef SETUP_MASK
+ }
+
+ #define CHECK_PARAM(Flag, Name) \
+ if(!(mask & BIT(Flag))) { \
+ log_err(parser, thin, \
+ "the "Name" of the thin dielectric material is missing.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(ABSORPTION, "absorption");
+ CHECK_PARAM(REFRACTIVE_INDEX, "refractive_index");
+ CHECK_PARAM(THICKNESS, "thickness");
+ #undef CHECK_PARAM
+
+exit:
+ out_imtl->i = imtl;
+ return res;
+error:
+ if(mtl) {
+ darray_thin_dielectric_pop_back(&parser->thin_dielectrics);
+ imtl = SIZE_MAX;
+ }
+ goto exit;
+}
+
+static res_T
parse_material_virtual(struct solparser* parser, yaml_node_t* virtual)
{
res_T res = RES_OK;
@@ -1114,8 +1222,13 @@ parse_material_descriptor
SETUP_MASK(DESCRIPTOR, "descriptor");
mtl->type = SOLPARSER_MATERIAL_MIRROR;
res = parse_material_mirror(parser, doc, val, &mtl->data.mirror);
+ } else if(!strcmp((char*)key->data.scalar.value, "thin_dielectric")) {
+ SETUP_MASK(DESCRIPTOR, "descriptor");
+ mtl->type = SOLPARSER_MATERIAL_THIN_DIELECTRIC;
+ res = parse_material_thin_dielectric
+ (parser, doc, val, &mtl->data.thin_dielectric);
} else if(!strcmp((char*)key->data.scalar.value, "virtual")) {
- SETUP_MASK(DESCRIPTOR, "virtual");
+ SETUP_MASK(DESCRIPTOR, "descriptor");
mtl->type = SOLPARSER_MATERIAL_VIRTUAL;
res = parse_material_virtual(parser, val);
} else {
@@ -1620,7 +1733,7 @@ parse_cylinder
*(Ptr) = Value; \
} (void)0
DEFAULT_PARAM(SLICES, &shape->nslices, 16);
- #undef DEFAULT_PARAM
+ #undef DEFAULT_PARAM
exit:
out_ishape->i = ishape;
@@ -3064,7 +3177,7 @@ parse_zx_pivot
parser, doc, val, -DBL_MAX, DBL_MAX, solxzpivot->ref_point);
} else if(!strcmp((char*) key->data.scalar.value, "target")) {
struct solparser_pivot_id pivot_id;
- pivot_id.i =
+ pivot_id.i =
(size_t) (solxzpivot - darray_zx_pivot_cdata_get(&parser->zx_pivots));
SETUP_MASK(TARGET, "target");
res = parse_target(parser, doc, val, &solxzpivot->target, pivot_id);
@@ -3451,6 +3564,7 @@ solparser_create
darray_material2_init(mem_allocator, &parser->mtls2);
darray_matte_init(mem_allocator, &parser->mattes);
darray_mirror_init(mem_allocator, &parser->mirrors);
+ darray_thin_dielectric_init(mem_allocator, &parser->thin_dielectrics);
/* Deferred targeted anchors */
darray_tgtalias_init(mem_allocator, &parser->tgtaliases);
@@ -3804,6 +3918,16 @@ solparser_get_material_mirror
return darray_mirror_cdata_get(&parser->mirrors) + mirror.i;
}
+const struct solparser_material_thin_dielectric*
+solparser_get_material_thin_dielectric
+ (const struct solparser* parser,
+ const struct solparser_material_thin_dielectric_id thin)
+{
+ ASSERT(parser);
+ ASSERT(thin.i < darray_thin_dielectric_size_get(&parser->thin_dielectrics));
+ return darray_thin_dielectric_cdata_get(&parser->thin_dielectrics) + thin.i;
+}
+
const struct solparser_object*
solparser_get_object
(const struct solparser* parser,
diff --git a/src/parser/solparser.h b/src/parser/solparser.h
@@ -112,6 +112,11 @@ solparser_get_material_mirror
(const struct solparser* parser,
const struct solparser_material_mirror_id mirror);
+extern LOCAL_SYM const struct solparser_material_thin_dielectric*
+solparser_get_material_thin_dielectric
+ (const struct solparser* parser,
+ const struct solparser_material_thin_dielectric_id thin_dielectric);
+
extern LOCAL_SYM const struct solparser_object*
solparser_get_object
(const struct solparser* parser,
diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h
@@ -21,6 +21,7 @@
enum solparser_material_type {
SOLPARSER_MATERIAL_MATTE,
SOLPARSER_MATERIAL_MIRROR,
+ SOLPARSER_MATERIAL_THIN_DIELECTRIC,
SOLPARSER_MATERIAL_VIRTUAL
};
@@ -37,11 +38,20 @@ struct solparser_material_mirror {
struct solparser_material_mirror_id { size_t i; };
+struct solparser_material_thin_dielectric {
+ double absorption;
+ double refractive_index;
+ double thickness;
+};
+
+struct solparser_material_thin_dielectric_id { size_t i; };
+
struct solparser_material {
enum solparser_material_type type;
union {
struct solparser_material_matte_id matte;
struct solparser_material_mirror_id mirror;
+ struct solparser_material_thin_dielectric_id thin_dielectric;
} data;
};
diff --git a/src/parser/test_solparser2.c b/src/parser/test_solparser2.c
@@ -114,7 +114,6 @@ main(int argc, char** argv)
entity_id = solparser_entity_iterator_get(&it);
entity = solparser_get_entity(parser, entity_id);
-
CHECK(strcmp("lvl 0", str_cget(&entity->name)), 0);
CHECK(solparser_entity_get_children_count(entity), 2);
diff --git a/src/parser/test_solparser7.c b/src/parser/test_solparser7.c
@@ -0,0 +1,95 @@
+/* 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"
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct solparser* parser;
+ struct solparser_entity_iterator it, end;
+ struct solparser_entity_id entity_id;
+ struct solparser_object_id obj_id;
+ const struct solparser_entity* entity;
+ const struct solparser_geometry* geom;
+ const struct solparser_material_double_sided* mtl2;
+ const struct solparser_material* mtl;
+ const struct solparser_material_thin_dielectric* thin;
+ const struct solparser_object* obj;
+ const struct solparser_shape* shape;
+ 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);
+
+ fprintf(stream, "- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1 }] }\n");
+ fprintf(stream, "- entity:\n");
+ fprintf(stream, " name: test\n");
+ fprintf(stream, " primary: 0\n");
+ fprintf(stream, " geometry:\n");
+ fprintf(stream, " - sphere: { radius: 1 }\n");
+ fprintf(stream, " material:\n");
+ fprintf(stream, " thin_dielectric:\n");
+ fprintf(stream, " absorption: 0.5\n");
+ fprintf(stream, " thickness: 0.123\n");
+ fprintf(stream, " refractive_index: 1.5\n");
+ 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, &end);
+ CHECK(solparser_entity_iterator_eq(&it, &end), 0);
+
+ entity_id = solparser_entity_iterator_get(&it);
+ entity = solparser_get_entity(parser, entity_id);
+
+ CHECK(strcmp("test", str_cget(&entity->name)), 0);
+ CHECK(solparser_entity_get_children_count(entity), 0);
+ CHECK(entity->type, SOLPARSER_ENTITY_GEOMETRY);
+ geom = solparser_get_geometry(parser, entity->data.geometry);
+ CHECK(solparser_geometry_get_objects_count(geom), 1);
+ obj_id = solparser_geometry_get_object(geom, 0);
+ obj = solparser_get_object(parser, obj_id);
+ shape = solparser_get_shape(parser, obj->shape);
+ CHECK(shape->type, SOLPARSER_SHAPE_SPHERE);
+ mtl2 = solparser_get_material_double_sided(parser, obj->mtl2);
+ CHECK(mtl2->front.i, mtl2->back.i);
+ mtl = solparser_get_material(parser, mtl2->front);
+ CHECK(mtl->type, SOLPARSER_MATERIAL_THIN_DIELECTRIC);
+ thin = solparser_get_material_thin_dielectric
+ (parser, mtl->data.thin_dielectric);
+ CHECK(thin->absorption, 0.5);
+ CHECK(thin->thickness, 0.123);
+ CHECK(thin->refractive_index, 1.5);
+
+ CHECK(solparser_load(parser), RES_BAD_OP);
+ 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
@@ -16,7 +16,7 @@
- sun: { spectrum: [{data: 1}] }
---
# missing data
-- sun: { spectrum: [{wavelength: 1}] }
+- sun: { spectrum: [{wavelength: 1}] }
---
# 2x wavelength
- sun: { spectrum: [{wavelength: 1, wavelength: 1}] }
@@ -143,7 +143,7 @@
- sun: { dni: 1, dni: 1 }
---
# 2x spectrum
-- sun:
+- sun:
spectrum: [{wavelength: 1, data: 1}]
spectrum: [{wavelength: 1, data: 1}]
---
@@ -223,6 +223,35 @@
---
#
+# <thin-dielectric> ::=
+# thin_dielectric:
+# absorption: REAL # in [0, 1]
+# thickness: REAL # in [0, INF)
+# refractive_index: REAL # in ]0, INF)
+#
+
+# invalid absorption
+- material:
+ thin_dielectric: { absorption: -1, thickness: 0, refractive_index: 1 }
+---
+# invalid absorption
+- material:
+ thin_dielectric: { absorption: 1.001, thickness: 0, refractive_index: 1 }
+---
+# invalid thickness
+- material:
+ thin_dielectric: { absorption: 0, thickness: -0.01, refractive_index: 1 }
+---
+# invalid refractive index
+- material:
+ thin_dielectric: { absorption: 0, thickness: 0, refractive_index: 0 }
+---
+# invalid refractive index
+- material:
+ thin_dielectric: { absorption: 0, thickness: 0, refractive_index: -0.0001 }
+---
+
+#
# front: <material-descriptor>
#
@@ -254,7 +283,7 @@
#
# missing material definition
-- material:
+- material:
---
# unknown dummy parameter
- material: { dummy: 123 }
@@ -941,14 +970,14 @@
# spacing: REAL # in [0, INF)
# ref_point: <real3>
# <target>
-#
+#
# <target> ::=
# target:
# anchor: <anchor-identifier>
# | direction: <real3>
# | position: <real3>
# | <sun>
-#
+#
# missing zx_pivot definition
- entity:
@@ -1157,7 +1186,7 @@
#
# <geometry-data> ::=
# primary: INTEGER # in [0, 1]
-# <geometry>
+# <geometry>
#
# missing entity definition
@@ -1273,9 +1302,9 @@
---
# 2x children
- entity:
- children:
+ children:
- name: "child1"
- children:
+ children:
- name: "child2"
---
# 2 entities with the same name
@@ -1306,7 +1335,7 @@
#
# <geometry-data> ::=
# primary: INTEGER # in [0, 1]
-# <geometry>
+# <geometry>
#
# missing template definition
@@ -1440,9 +1469,9 @@
---
# 2x children
- template: &temp
- children:
+ children:
- name: "child1"
- children:
+ children:
- name: "child2"
- entity: *temp
---
@@ -1517,7 +1546,7 @@
- geometry:
---
# unknown dummy parameter
-- geometry:
+- geometry:
- dummy: 1
---
# missing material definition
@@ -1570,4 +1599,4 @@
geometry:
- cuboid: { size: [1, 2, 3] }
material: { matte: { reflectivity: 1 } }
-
-\ No newline at end of file
+
diff --git a/src/parser/yaml/test_ok_5.yaml b/src/parser/yaml/test_ok_5.yaml
@@ -0,0 +1,43 @@
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+
+- material: &thin_dielectric
+ thin_dielectric:
+ absorption: 0.1
+ thickness: 0.2
+ refractive_index: 1.00027
+
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - material: *thin_dielectric
+ cylinder: { height: 1, radius: 1 }
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+
+- material: &thin_dielectric
+ thin_dielectric:
+ absorption: 0
+ thickness: 0
+ refractive_index: 0.0001
+
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - material: *thin_dielectric
+ cylinder: { height: 1, radius: 1 }
+
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: "entity"
+ primary: 0
+ geometry:
+ - cylinder: { height: 1, radius: 1 }
+ material:
+ thin_dielectric:
+ absorption: 0
+ thickness: 10
+ refractive_index: 0.0001
+
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -254,7 +254,9 @@ parse_rendering_option(const char* str, struct solstice_args* args)
}
} else {
fprintf(stderr, "Invalid rendering option `%s'.\n", val);
- fprintf(stderr, "Valid options are: fov=FOV:img=WIDTHxHEIGHT:pos=X,Y,Z:tgt=X,Y,Z:up=X,Y,Z\n");
+ /* TODO remove this. The man page will be sufficient */
+ fprintf(stderr,
+"Valid options are: fov=FOV:img=WIDTHxHEIGHT:pos=X,Y,Z:tgt=X,Y,Z:up=X,Y,Z\n");
res = RES_BAD_ARG;
goto error;
}
diff --git a/src/solstice_dump.c b/src/solstice_dump.c
@@ -0,0 +1,150 @@
+/* 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 "solstice_c.h"
+#include <solstice/ssol.h>
+
+struct dump_context {
+ FILE* output;
+ size_t ids_offset;
+ enum solstice_args_dump_split_mode split_mode;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+dump_instantiated_shaded_shape
+ (struct ssol_instantiated_shaded_shape* sshape, struct dump_context* ctx)
+{
+ unsigned i, ntris, nverts;
+ enum ssol_material_type type;
+ const char* mtl;
+ ASSERT(sshape && ctx);
+
+ SSOL(material_get_type(sshape->mtl_front, &type));
+ switch(type) {
+ case SSOL_MATERIAL_MATTE: mtl = "matte"; break;
+ case SSOL_MATERIAL_MIRROR: mtl = "mirror"; break;
+ case SSOL_MATERIAL_VIRTUAL: mtl = "virtual"; break;
+ default: FATAL("Unexpected Solstice Solver material type.\n"); break;
+ }
+
+ fprintf(ctx->output, "usemtl %s\n", mtl);
+
+ SSOL(shape_get_vertices_count(sshape->shape, &nverts));
+ FOR_EACH(i, 0, nverts) {
+ double pos[3];
+ SSOL(instantiated_shaded_shape_get_vertex_attrib
+ (sshape, i, SSOL_POSITION, pos));
+ fprintf(ctx->output, "v %g %g %g\n", SPLIT3(pos));
+ }
+
+ SSOL(shape_get_triangles_count(sshape->shape, &ntris));
+ FOR_EACH(i, 0, ntris) {
+ unsigned ids[3];
+ SSOL(shape_get_triangle_indices(sshape->shape, i, ids));
+ /* Note that in the obj fileformat the first index is 1 rather than 0 */
+ fprintf(ctx->output, "f %lu %lu %lu\n",
+ (unsigned long)(ids[0] + 1 + ctx->ids_offset),
+ (unsigned long)(ids[1] + 1 + ctx->ids_offset),
+ (unsigned long)(ids[2] + 1 + ctx->ids_offset));
+ }
+
+ if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_OBJECT) {
+ fprintf(ctx->output, "---\n");
+ ctx->ids_offset = 0;
+ } else {
+ ctx->ids_offset += nverts;
+ }
+}
+
+static res_T
+dump_instance(struct ssol_instance* instance, void* context)
+{
+ struct dump_context* ctx = context;
+ size_t i, n;
+ ASSERT(instance && ctx);
+
+ SSOL(instance_get_shaded_shapes_count(instance, &n));
+ FOR_EACH(i, 0, n) {
+ struct ssol_instantiated_shaded_shape sshape;
+ SSOL(instance_get_shaded_shape(instance, i, &sshape));
+ dump_instantiated_shaded_shape(&sshape, ctx);
+ }
+
+ return RES_OK;
+}
+
+static res_T
+dump_geometry
+ (const struct sanim_node* n, const double transform[12], void* data)
+{
+ struct solstice_node* node;
+ struct dump_context* ctx = data;
+ res_T res = RES_OK;
+ ASSERT(n && data);
+ (void)transform;
+
+ node = CONTAINER_OF(n, struct solstice_node, anim);
+ if(node->type != SOLSTICE_NODE_GEOMETRY) return RES_OK;
+ fprintf(ctx->output, "g %s\n", solstice_node_get_name(node));
+ res = dump_instance(node->instance, data);
+ if(res != RES_OK) return res;
+
+ if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_GEOMETRY) {
+ fprintf(ctx->output, "---\n");
+ ctx->ids_offset = 0;
+ }
+ return RES_OK;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+solstice_dump(struct solstice* solstice)
+{
+ struct dump_context ctx;
+ double dummy_dir[3] = {0, 0, 1};
+ size_t i, n;
+ res_T res = RES_OK;
+ ASSERT(solstice && solstice->dump_format == SOLSTICE_ARGS_DUMP_OBJ);
+
+ ctx.output = solstice->output;
+ ctx.ids_offset = 0;
+ ctx.split_mode = solstice->dump_split_mode;
+
+ n = darray_nodes_size_get(&solstice->roots);
+ FOR_EACH(i, 0, n) {
+ struct solstice_node* node = darray_nodes_data_get(&solstice->roots)[i];
+
+ fprintf(solstice->output, "# %s\n", solstice_node_get_name(node));
+
+ /* TODO use a anim tree visitor that neither resolve the pivot
+ * transformations nor compute the node transforms */
+ res = sanim_node_visit_tree(&node->anim, dummy_dir, &ctx, dump_geometry);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not dump the solstice geometry.\n");
+ goto error;
+ }
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
diff --git a/src/solstice_dump_obj.c b/src/solstice_dump_obj.c
@@ -1,147 +0,0 @@
-/* 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 "solstice_c.h"
-#include <solstice/ssol.h>
-
-struct dump_context {
- FILE* output;
- size_t ids_offset;
- enum solstice_args_dump_split_mode split_mode;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static void
-dump_instantiated_shaded_shape
- (struct ssol_instantiated_shaded_shape* sshape, struct dump_context* ctx)
-{
- unsigned i, ntris, nverts;
- enum ssol_material_type type;
- const char* mtl;
- ASSERT(sshape && ctx);
-
- SSOL(material_get_type(sshape->mtl_front, &type));
- switch(type) {
- case SSOL_MATERIAL_MATTE: mtl = "matte"; break;
- case SSOL_MATERIAL_MIRROR: mtl = "mirror"; break;
- case SSOL_MATERIAL_VIRTUAL: mtl = "virtual"; break;
- default: FATAL("Unexpected Solstice Solver material type.\n"); break;
- }
-
- fprintf(ctx->output, "usemtl %s\n", mtl);
-
- SSOL(shape_get_vertices_count(sshape->shape, &nverts));
- FOR_EACH(i, 0, nverts) {
- double pos[3];
- SSOL(instantiated_shaded_shape_get_vertex_attrib
- (sshape, i, SSOL_POSITION, pos));
- fprintf(ctx->output, "v %g %g %g\n", SPLIT3(pos));
- }
-
- SSOL(shape_get_triangles_count(sshape->shape, &ntris));
- FOR_EACH(i, 0, ntris) {
- unsigned ids[3];
- SSOL(shape_get_triangle_indices(sshape->shape, i, ids));
- /* Note that in the obj fileformat the first index is 1 rather than 0 */
- fprintf(ctx->output, "f %lu %lu %lu\n",
- (unsigned long)(ids[0] + 1 + ctx->ids_offset),
- (unsigned long)(ids[1] + 1 + ctx->ids_offset),
- (unsigned long)(ids[2] + 1 + ctx->ids_offset));
- }
-
- if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_OBJECT) {
- fprintf(ctx->output, "---\n");
- ctx->ids_offset = 0;
- } else {
- ctx->ids_offset += nverts;
- }
-}
-
-static res_T
-dump_instance(struct ssol_instance* instance, void* context)
-{
- struct dump_context* ctx = context;
- size_t i, n;
- ASSERT(instance && ctx);
-
- SSOL(instance_get_shaded_shapes_count(instance, &n));
- FOR_EACH(i, 0, n) {
- struct ssol_instantiated_shaded_shape sshape;
- SSOL(instance_get_shaded_shape(instance, i, &sshape));
- dump_instantiated_shaded_shape(&sshape, ctx);
- }
-
- return RES_OK;
-}
-
-static res_T
-dump_geometry
- (const struct sanim_node* n, const double transform[12], void* data)
-{
- struct solstice_node* node;
- struct dump_context* ctx = data;
- res_T res = RES_OK;
- ASSERT(n && data);
- (void)transform;
-
- node = CONTAINER_OF(n, struct solstice_node, anim);
- if(node->type != SOLSTICE_NODE_GEOMETRY) return RES_OK;
- fprintf(ctx->output, "g %s\n", solstice_node_get_name(node));
- res = dump_instance(node->instance, data);
- if(res != RES_OK) return res;
-
- if(ctx->split_mode == SOLSTICE_ARGS_DUMP_SPLIT_GEOMETRY) {
- fprintf(ctx->output, "---\n");
- ctx->ids_offset = 0;
- }
- return RES_OK;
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-res_T
-solstice_dump(struct solstice* solstice)
-{
- struct dump_context ctx;
- double dummy_dir[3] = {0, 0, 1};
- size_t i, n;
- res_T res = RES_OK;
- ASSERT(solstice && solstice->dump_format == SOLSTICE_ARGS_DUMP_OBJ);
-
- ctx.output = solstice->output;
- ctx.ids_offset = 0;
- ctx.split_mode = solstice->dump_split_mode;
-
- n = darray_nodes_size_get(&solstice->roots);
- FOR_EACH(i, 0, n) {
- struct solstice_node* node = darray_nodes_data_get(&solstice->roots)[i];
-
- fprintf(solstice->output, "# %s\n", solstice_node_get_name(node));
- res = sanim_node_visit_tree(&node->anim, dummy_dir, &ctx, dump_geometry);
- if(res != RES_OK) {
- fprintf(stderr, "Could not dump the solstice geometry.\n");
- goto error;
- }
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
diff --git a/src/solstice_entity.c b/src/solstice_entity.c
@@ -97,6 +97,37 @@ error:
goto exit;
}
+static res_T
+get_anchor_node
+ (struct solstice* solstice,
+ struct solparser_anchor_id anchor_id,
+ struct solstice_node** out_node)
+{
+ struct solstice_node* node = NULL;
+ struct solstice_node** pnode = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && out_node);
+
+ pnode = htable_anchor_find(&solstice->anchors, &anchor_id.i);
+ if(pnode) {
+ node = *pnode;
+ } else {
+ res = solstice_node_target_create(solstice->allocator, &node);
+ if(res != RES_OK) goto error;
+
+ res = htable_anchor_set(&solstice->anchors, &anchor_id.i, &node);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ *out_node = node;
+ return res;
+error:
+ if(node) solstice_node_ref_put(node);
+ goto exit;
+}
+
+
static struct solstice_node*
create_x_pivot_node
(struct solstice* solstice,
@@ -180,8 +211,8 @@ create_zx_pivot_node
switch (parser_zx_pivot->target.type) {
case SOLPARSER_TARGET_ANCHOR:
anim_tracking.policy = TRACKING_NODE_TARGET;
- target = *htable_anchor_find
- (&solstice->anchors, &parser_zx_pivot->target.data.anchor.i);
+ CHECK(RES_OK,
+ get_anchor_node(solstice, parser_zx_pivot->target.data.anchor, &target));
solstice_node_target_get_tracking(target, &anim_tracking);
break;
case SOLPARSER_TARGET_DIRECTION:
@@ -223,7 +254,6 @@ create_node
const struct str* name)
{
struct solstice_node* node = NULL;
- struct solstice_node* tgt = NULL;
struct solstice_node* child = NULL;
struct solstice_receiver* rcv = NULL;
struct str child_name;
@@ -296,16 +326,14 @@ create_node
/* Register entity anchors */
FOR_EACH(i, 0, solparser_entity_get_anchors_count(entity)) {
+ struct solstice_node* tgt = NULL;
struct solparser_anchor_id id;
- const struct solparser_anchor* anchor = NULL;
-
- res = solstice_node_target_create(solstice->allocator, &tgt);
- if(res != RES_OK) goto error;
+ const struct solparser_anchor* anchor;
id = solparser_entity_get_anchor(entity, i);
anchor = solparser_get_anchor(solstice->parser, id);
- res = htable_anchor_set(&solstice->anchors, &id.i, &tgt);
+ res = get_anchor_node(solstice, id, &tgt);
if(res != RES_OK) goto error;
solstice_node_set_translation(tgt, anchor->position);
@@ -349,7 +377,6 @@ exit:
str_release(&child_name);
return node;
error:
- if(tgt) solstice_node_ref_put(tgt);
if(child) solstice_node_ref_put(child);
if(node) solstice_node_ref_put(node);
node = NULL;