commit 7aae3e6b609c9f22fca6e8155a2547ac5c3b9965
parent 4c50d38e687d57b1fc0b82b60d7133f2a338204b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 17 Mar 2017 10:34:28 +0100
Merge remote-tracking branch 'origin/develop' into feature_outputs
Diffstat:
11 files changed, 809 insertions(+), 405 deletions(-)
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -68,8 +68,6 @@ if(NOT NO_TEST)
endfunction()
build_test(test_solparser)
- add_test(test_grammar_example test_solparser
- ${PROJECT_SOURCE_DIR}/../../doc/input)
add_test(test_solparser_ok_0 test_solparser
${SOLPARSER_SOURCE_DIR}/yaml/test_ok_0.yaml)
add_test(test_solparser_ok_1 test_solparser
@@ -82,6 +80,8 @@ if(NOT NO_TEST)
${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_ok_6 test_solparser
+ ${SOLPARSER_SOURCE_DIR}/yaml/test_ok_6.yaml)
add_test(test_solparser_ko test_solparser -e
${SOLPARSER_SOURCE_DIR}/yaml/test_ko_0.yaml)
diff --git a/doc/input b/doc/input
@@ -1,6 +1,6 @@
-# --------------------------------------------------------------------------------
-# 1/ Exemple
-# --------------------------------------------------------------------------------
+#--------------------------------------------------------------------------------
+# 1/ Example
+#--------------------------------------------------------------------------------
# Declare materials
- material: &lambertian
matte:
@@ -77,243 +77,256 @@
transform: { translation: [10, 11, 12] }
children: [ *composition ]
-# --------------------------------------------------------------------------------
+#--------------------------------------------------------------------------------
# 2/ Grammar
-# --------------------------------------------------------------------------------
-# <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>
-# | <cylinder>
-# | <obj>
-# | <parabol>
-# | <parabolic-cylinder>
-# | <hyperbol>
-# | <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>
-#
-# <hyperbol> ::= # (x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0
-# hyperbol: # with g = img_focal + real_focal; f = real_focal / g;
-# # a^2 = g^2(f - f^2); b = g(f - 1/2); z0 = |b| + g/2
-# focals: <hyperboloid_focals>
-# clip: <polyclip-list>
-#
-# <hyperboloid_focals> ::=
-# real: REAL # in ]0, INF)
-# image: REAL # in ]0, INF)
-#
-# <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> | <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, INF)
-# 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>
-#
-# <children> ::=
-# children:
-# - <entity-data>
-# [ - <entity-data> ... ]
-#
-# <anchors> ::=
-# anchors:
-# - <anchor-data>
-# [ - <anchor-data> ... ]
-#
-# <anchor-data> ::=
-# name: STRING
-# <position-description>
-#
-# <position-description> ::=
-# position: <real3> | hyperboloid_image_focals: <hyperboloid_focals>
-#
-# # "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)
-#
+#--------------------------------------------------------------------------------
+<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>
+ | <cylinder>
+ | <obj>
+ | <parabol>
+ | <parabolic-cylinder>
+ | <hyperbol>
+ | <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
+
+# x^2 + y^2 - 4*focal*z = 0
+<parabol> ::=
+ parabol:
+ focal: REAL # in ]0, INF)
+ clip: <polyclip-list>
+ # By default slices is automatically compute with respect to the parabol
+ # curvature
+[ slices: INTEGER ] # in [4, 4096)
+
+<parabolic-cylinder> ::=
+ parabolic-cylinder: # y^2 - 4*focal*z = 0
+ focal: REAL # in ]0, INF)
+ clip: <polyclip-list>
+ # By default slices is automatically compute with respect to the hyperbol
+ # curvature
+[ slices: INTEGER ] # in [4, 4096)
+
+# (x^2 + y^2) / a^2 - (z + z0 - g/2)^2 / b^2 + 1 = 0
+# with g = img_focal + real_focal; f = real_focal / g;
+# a^2 = g^2(f - f^2); b = g(f - 1/2); z0 = |b| + g/2
+<hyperbol> ::=
+ hyperbol:
+ focals: <hyperboloid_focals>
+ clip: <polyclip-list>
+ # By default slices is automatically compute with respect to the hyperbol
+ # curvature
+[ slices: INTEGER ] # in [4, 4096)
+
+<hyperboloid_focals> ::=
+ real: REAL # in ]0, INF)
+ image: REAL # in ]0, INF)
+
+<plane> ::=
+ plane:
+ clip: <polyclip-list>
+[ slices: INTEGER ] # in [1, 4096). Default 1
+
+<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> | <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, INF)
+ 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>
+
+<children> ::=
+ children:
+ - <entity-data>
+[ - <entity-data> ... ]
+
+<anchors> ::=
+ anchors:
+ - <anchor-data>
+[ - <anchor-data> ... ]
+
+<anchor-data> ::=
+ name: STRING
+ <position-description>
+
+<position-description> ::=
+ position: <real3> | hyperboloid_image_focals: <hyperboloid_focals>
+
+# "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)
+
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -1839,7 +1839,7 @@ parse_paraboloid
const enum solparser_shape_type type,
struct solparser_shape_paraboloid_id* out_ishape)
{
- enum { CLIP, FOCAL };
+ enum { CLIP, FOCAL, SLICES };
struct solparser_shape_paraboloid* shape = NULL;
struct darray_paraboloid* paraboloids;
const char* name;
@@ -1903,6 +1903,9 @@ parse_paraboloid
} else if(!strcmp((char*)key->data.scalar.value, "focal")) {
SETUP_MASK(FOCAL, "focal");
res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &shape->focal);
+ } else if(!strcmp((char*)key->data.scalar.value, "slices")) {
+ SETUP_MASK(SLICES, "slices");
+ res = parse_integer(parser, val, 4, 4096, &shape->nslices);
} else {
log_err(parser, key, "unknown %s parameter `%s'.\n",
name, key->data.scalar.value);
@@ -1942,7 +1945,7 @@ parse_focals_description
(struct solparser* parser,
yaml_document_t* doc,
const yaml_node_t* desc,
- struct hyperboloid_focals* focals)
+ struct solparser_hyperboloid_focals* focals)
{
enum { REAL, IMAGE };
intptr_t i, n;
@@ -1950,7 +1953,7 @@ parse_focals_description
res_T res = RES_OK;
ASSERT(doc && desc && focals);
- if (desc->type != YAML_MAPPING_NODE) {
+ if(desc->type != YAML_MAPPING_NODE) {
log_err(parser, desc, "expect a mapping of focal parameters.\n");
res = RES_BAD_ARG;
goto error;
@@ -1963,7 +1966,7 @@ parse_focals_description
key = yaml_document_get_node(doc, desc->data.mapping.pairs.start[i].key);
val = yaml_document_get_node(doc, desc->data.mapping.pairs.start[i].value);
- if (key->type != YAML_SCALAR_NODE) {
+ if(key->type != YAML_SCALAR_NODE) {
log_err(parser, key, "expect focal parameters.\n");
res = RES_BAD_ARG;
goto error;
@@ -1977,15 +1980,14 @@ parse_focals_description
} \
mask |= BIT(Flag); \
} (void)0
- if (!strcmp((char*) key->data.scalar.value, "real")) {
+ if(!strcmp((char*) key->data.scalar.value, "real")) {
SETUP_MASK(REAL, "real");
res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &focals->real);
- }
- else if (!strcmp((char*) key->data.scalar.value, "image")) {
+ } else if(!strcmp((char*) key->data.scalar.value, "image")) {
SETUP_MASK(IMAGE, "image");
res = parse_real(parser, val, nextafter(0, 1), DBL_MAX, &focals->image);
}
- if (res != RES_OK) {
+ if(res != RES_OK) {
log_node(parser, key);
goto error;
}
@@ -2015,7 +2017,7 @@ parse_hyperboloid
const yaml_node_t* hyperboloid,
struct solparser_shape_hyperboloid_id* out_ishape)
{
- enum { CLIP, FOCAL };
+ enum { CLIP, FOCAL, SLICES };
struct solparser_shape_hyperboloid* shape = NULL;
size_t ishape = SIZE_MAX;
intptr_t i, n;
@@ -2023,7 +2025,7 @@ parse_hyperboloid
res_T res = RES_OK;
ASSERT(doc && hyperboloid && out_ishape);
- if (hyperboloid->type != YAML_MAPPING_NODE) {
+ if(hyperboloid->type != YAML_MAPPING_NODE) {
log_err(parser, hyperboloid, "expect a mapping of hyperbol parameters.\n");
res = RES_BAD_ARG;
goto error;
@@ -2032,7 +2034,7 @@ parse_hyperboloid
/* Allocate a hyperboloid shape */
ishape = darray_hyperboloid_size_get(&parser->hyperbols);
res = darray_hyperboloid_resize(&parser->hyperbols, ishape + 1);
- if (res != RES_OK) {
+ if(res != RES_OK) {
log_err(parser, hyperboloid, "could not allocate the hyperbol shape.\n");
goto error;
}
@@ -2045,7 +2047,7 @@ parse_hyperboloid
key = yaml_document_get_node(doc, hyperboloid->data.mapping.pairs.start[i].key);
val = yaml_document_get_node(doc, hyperboloid->data.mapping.pairs.start[i].value);
- if (key->type != YAML_SCALAR_NODE) {
+ if(key->type != YAML_SCALAR_NODE) {
log_err(parser, key, "expect hyperbol parameters.\n");
res = RES_BAD_ARG;
goto error;
@@ -2059,21 +2061,22 @@ parse_hyperboloid
} \
mask |= BIT(Flag); \
} (void)0
- if (!strcmp((char*) key->data.scalar.value, "clip")) {
+ if(!strcmp((char*) key->data.scalar.value, "clip")) {
SETUP_MASK(CLIP, "clip");
res = parse_clip(parser, doc, val, &shape->polyclips);
- }
- else if (!strcmp((char*) key->data.scalar.value, "focals")) {
+ } else if(!strcmp((char*)key->data.scalar.value, "focals")) {
SETUP_MASK(FOCAL, "focals");
res = parse_focals_description(parser, doc, val, &shape->focals);
- }
- else {
+ } else if(!strcmp((char*)key->data.scalar.value, "slices")) {
+ SETUP_MASK(SLICES, "slices");
+ res = parse_integer(parser, val, 4, 4096, &shape->nslices);
+ } else {
log_err(parser, key, "unknown hyperbol parameter `%s'.\n",
key->data.scalar.value);
res = RES_BAD_ARG;
goto error;
}
- if (res != RES_OK) {
+ if(res != RES_OK) {
log_node(parser, key);
goto error;
}
@@ -2094,7 +2097,7 @@ exit :
out_ishape->i = ishape;
return res;
error:
- if (shape) {
+ if(shape) {
darray_hyperboloid_pop_back(&parser->hyperbols);
ishape = SIZE_MAX;
}
@@ -2108,7 +2111,7 @@ parse_plane
const yaml_node_t* plane,
struct solparser_shape_plane_id* out_ishape)
{
- enum { CLIP };
+ enum { CLIP, SLICES };
struct solparser_shape_plane* shape = NULL;
size_t ishape = SIZE_MAX;
intptr_t i, n;
@@ -2143,14 +2146,22 @@ parse_plane
res = RES_BAD_ARG;
goto error;
}
+ #define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the plane parameter `"Name"' is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+
if(!strcmp((char*)key->data.scalar.value, "clip")) {
- if(mask & BIT(CLIP)) {
- log_err(parser, key, "the plane clipping is already defined.\n");
- res = RES_BAD_ARG;
- goto error;
- }
- mask |= BIT(CLIP);
+ SETUP_MASK(CLIP, "clip");
res = parse_clip(parser, doc, val, &shape->polyclips);
+ } else if(!strcmp((char*)key->data.scalar.value, "slices")) {
+ SETUP_MASK(SLICES, "slices");
+ res = parse_integer(parser, val, 1, 4096, &shape->nslices);
} else {
log_err(parser, key, "unknown plane parameter `%s'.\n",
key->data.scalar.value);
@@ -2161,6 +2172,7 @@ parse_plane
log_node(parser, key);
goto error;
}
+ #undef SETUP_MASK
}
if(!(mask & BIT(CLIP))) {
log_err(parser, plane, "the plane parameter `clip' is missing.\n");
@@ -2374,8 +2386,7 @@ parse_object
shape->type = SOLPARSER_SHAPE_PARABOLIC_CYLINDER;
res = parse_paraboloid
(parser, doc, val, shape->type, &shape->data.parabolic_cylinder);
- }
- else if (!strcmp((char*) key->data.scalar.value, "hyperbol")) {
+ } else if(!strcmp((char*) key->data.scalar.value, "hyperbol")) {
SETUP_MASK(SHAPE, "shape");
shape->type = SOLPARSER_SHAPE_HYPERBOL;
res = parse_hyperboloid(parser, doc, val, &shape->data.hyperbol);
@@ -2650,13 +2661,11 @@ parse_anchor
} else if(!strcmp((char*)key->data.scalar.value, "position")) {
SETUP_MASK(POSITION, "position description");
res = parse_real3(parser, doc, val, -DBL_MAX, DBL_MAX, solanchor->position);
- }
- else if (!strcmp((char*) key->data.scalar.value, "hyperboloid_image_focals"))
- {
- struct hyperboloid_focals focals;
+ } else if(!strcmp((char*) key->data.scalar.value, "hyperboloid_image_focals")) {
+ struct solparser_hyperboloid_focals focals;
SETUP_MASK(POSITION, "position description");
res = parse_focals_description(parser, doc, val, &focals);
- if (res != RES_OK) goto error;
+ if(res != RES_OK) goto error;
d3(solanchor->position, 0, 0, focals.image);
} else {
log_err(parser, key, "unknown anchor parameter `%s'.\n",
@@ -2848,7 +2857,7 @@ parse_entity
} else if(!strcmp((char*)key->data.scalar.value, "name")) {
SETUP_MASK(NAME, "name");
res = parse_identifier_string(parser, val, &solent.name);
- if (!strcmp(str_get(&solent.name), "self")) {
+ if(!strcmp(str_get(&solent.name), "self")) {
/* self is a reserved keyword */
log_err(parser, key, "Reserved keywords cannot be used as names: %s.\n",
str_get(&solent.name));
diff --git a/src/parser/solparser_shape.h b/src/parser/solparser_shape.h
@@ -159,7 +159,8 @@ solparser_shape_imported_geometry_copy_and_release
******************************************************************************/
struct solparser_shape_paraboloid {
double focal;
- struct darray_polyclip polyclips;
+ long nslices; /* < 0 if not defined */
+ struct darray_polyclip polyclips;
};
static INLINE void
@@ -168,6 +169,7 @@ solparser_shape_paraboloid_init
struct solparser_shape_paraboloid* paraboloid)
{
ASSERT(paraboloid);
+ paraboloid->nslices = -1;
darray_polyclip_init(allocator, ¶boloid->polyclips);
}
@@ -185,6 +187,7 @@ solparser_shape_paraboloid_copy
{
ASSERT(dst && src);
dst->focal = src->focal;
+ dst->nslices = src->nslices;
return darray_polyclip_copy(&dst->polyclips, &src->polyclips);
}
@@ -195,23 +198,26 @@ solparser_shape_paraboloid_copy_and_release
{
ASSERT(dst && src);
dst->focal = src->focal;
+ dst->nslices = src->nslices;
return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips);
}
/*******************************************************************************
* Hyperboloid shape
******************************************************************************/
-struct hyperboloid_focals {
- double real, image;
+struct solparser_hyperboloid_focals {
+ double real;
+ double image;
};
-#define HYPERBOLOID_FOCALS_NULL__ { 0, 0 }
-static const struct hyperboloid_focals
-HYPERBOLOID_FOCALS_NULL = HYPERBOLOID_FOCALS_NULL__;
+#define SOLPARSER_HYPERBOLOID_FOCALS_NULL__ { 0, 0 }
+static const struct solparser_hyperboloid_focals
+SOLPARSER_HYPERBOLOID_FOCALS_NULL = SOLPARSER_HYPERBOLOID_FOCALS_NULL__;
struct solparser_shape_hyperboloid {
- struct hyperboloid_focals focals;
+ struct solparser_hyperboloid_focals focals;
struct darray_polyclip polyclips;
+ long nslices; /* < 0 if not defined */
};
static INLINE void
@@ -220,6 +226,7 @@ solparser_shape_hyperboloid_init
struct solparser_shape_hyperboloid* hyperboloid)
{
ASSERT(hyperboloid);
+ hyperboloid->nslices = -1;
darray_polyclip_init(allocator, &hyperboloid->polyclips);
}
@@ -237,6 +244,7 @@ solparser_shape_hyperboloid_copy
{
ASSERT(dst && src);
dst->focals = src->focals;
+ dst->nslices = src->nslices;
return darray_polyclip_copy(&dst->polyclips, &src->polyclips);
}
@@ -247,6 +255,7 @@ solparser_shape_hyperboloid_copy_and_release
{
ASSERT(dst && src);
dst->focals = src->focals;
+ dst->nslices = src->nslices;
return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips);
}
@@ -255,6 +264,7 @@ solparser_shape_hyperboloid_copy_and_release
******************************************************************************/
struct solparser_shape_plane {
struct darray_polyclip polyclips;
+ long nslices;
};
static INLINE void
@@ -263,6 +273,7 @@ solparser_shape_plane_init
struct solparser_shape_plane* plane)
{
ASSERT(plane);
+ plane->nslices = 1;
darray_polyclip_init(allocator, &plane->polyclips);
}
@@ -279,6 +290,7 @@ solparser_shape_plane_copy
const struct solparser_shape_plane* src)
{
ASSERT(dst && src);
+ dst->nslices = src->nslices;
return darray_polyclip_copy(&dst->polyclips, &src->polyclips);
}
@@ -288,6 +300,7 @@ solparser_shape_plane_copy_and_release
struct solparser_shape_plane* src)
{
ASSERT(dst && src);
+ dst->nslices = src->nslices;
return darray_polyclip_copy_and_release(&dst->polyclips, &src->polyclips);
}
diff --git a/src/parser/test_solparser6.c b/src/parser/test_solparser6.c
@@ -33,7 +33,10 @@ main(int argc, char** argv)
const struct solparser_shape* shape;
const struct solparser_shape_sphere* sphere;
const struct solparser_shape_paraboloid* parabol;
+ const struct solparser_shape_plane* plane;
const struct solparser_shape_hyperboloid* hyperbol;
+ const struct solparser_polyclip* polyclip;
+ double pos[2];
FILE* stream;
(void)argc, (void)argv;
@@ -52,16 +55,23 @@ main(int argc, char** argv)
fprintf(stream, " material: { ?virtual }\n");
fprintf(stream, " - parabol:\n");
fprintf(stream, " focal: 10\n");
+ fprintf(stream, " slices : 10\n");
fprintf(stream, " clip :\n");
fprintf(stream, " - operation : AND\n");
fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n");
fprintf(stream, " material: { ?virtual }\n");
fprintf(stream, " - hyperbol:\n");
fprintf(stream, " focals: { real: 10, image: 2 }\n");
+ fprintf(stream, " slices : 20\n");
fprintf(stream, " clip :\n");
fprintf(stream, " - operation : AND\n");
fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n");
fprintf(stream, " material: { ?virtual }\n");
+ fprintf(stream, " - plane:\n");
+ fprintf(stream, " clip :\n");
+ fprintf(stream, " - operation : AND\n");
+ fprintf(stream, " vertices : [[1, 2], [3, 4], [6, 7]]\n");
+ fprintf(stream, " material: { ?virtual }\n");
rewind(stream);
CHECK(solparser_setup(parser, NULL, stream), RES_OK);
@@ -78,7 +88,7 @@ main(int argc, char** argv)
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), 3);
+ CHECK(solparser_geometry_get_objects_count(geom), 4);
obj_id = solparser_geometry_get_object(geom, 0);
obj = solparser_get_object(parser, obj_id);
@@ -94,6 +104,20 @@ main(int argc, char** argv)
CHECK(shape->type, SOLPARSER_SHAPE_PARABOL);
parabol = solparser_get_shape_parabol(parser, shape->data.parabol);
CHECK(parabol->focal, 10);
+ CHECK(parabol->nslices, 10);
+ CHECK(darray_polyclip_size_get(¶bol->polyclips), 1);
+ polyclip = darray_polyclip_cdata_get(¶bol->polyclips);
+ CHECK(polyclip->op, SOLPARSER_CLIP_OP_AND);
+ CHECK(solparser_polyclip_get_vertices_count(polyclip), 3);
+ solparser_polyclip_get_vertex(polyclip, 0, pos);
+ CHECK(pos[0], 1);
+ CHECK(pos[1], 2);
+ solparser_polyclip_get_vertex(polyclip, 1, pos);
+ CHECK(pos[0], 3);
+ CHECK(pos[1], 4);
+ solparser_polyclip_get_vertex(polyclip, 2, pos);
+ CHECK(pos[0], 6);
+ CHECK(pos[1], 7);
obj_id = solparser_geometry_get_object(geom, 2);
obj = solparser_get_object(parser, obj_id);
@@ -102,12 +126,20 @@ main(int argc, char** argv)
hyperbol = solparser_get_shape_hyperbol(parser, shape->data.hyperbol);
CHECK(hyperbol->focals.real, 10);
CHECK(hyperbol->focals.image, 2);
+ CHECK(hyperbol->nslices, 20);
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_VIRTUAL);
+ obj_id = solparser_geometry_get_object(geom, 3);
+ obj = solparser_get_object(parser, obj_id);
+ shape = solparser_get_shape(parser, obj->shape);
+ CHECK(shape->type, SOLPARSER_SHAPE_PLANE);
+ plane = solparser_get_shape_plane(parser, shape->data.plane);
+ CHECK(plane->nslices, 1); /* Default value */
+
solparser_entity_iterator_next(&it);
CHECK(solparser_entity_iterator_eq(&it, &end), 1);
diff --git a/src/parser/yaml/test_ko_0.yaml b/src/parser/yaml/test_ko_0.yaml
@@ -570,6 +570,33 @@
- operation: AND
vertices: [ [1, 2], [3, 4], [6, 7] ]
---
+# invalid slices
+- geometry:
+ - parabol:
+ slices: 1
+ focal: 1
+ clip:
+ - operation: AND
+ vertices: [ [1, 2], [3, 4], [6, 7] ]
+---
+# invalid slices
+- geometry:
+ - parabol:
+ slices: 0
+ focal: 1
+ clip:
+ - operation: AND
+ vertices: [ [1, 2], [3, 4], [6, 7] ]
+---
+# invalid slices
+- geometry:
+ - parabol:
+ slices: 4097
+ focal: 1
+ clip:
+ - operation: AND
+ vertices: [ [1, 2], [3, 4], [6, 7] ]
+---
#
# <parabolic-cylinder> ::=
@@ -634,7 +661,7 @@
# <hyperboloid_focals> ::=
# real: REAL # in ]0, INF)
# image: REAL # in ]0, INF)
-#
+#
# missing hyperbol definition
- geometry: [ { hyperbol: } ]
---
@@ -735,7 +762,31 @@
- operation: AND
vertices: [ [1, 2], [3, 4], [6, 7] ]
---
+# invalid slices
+- geometry: &target
+ - plane:
+ slices: 0
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.50, -0.50]
+ - [-0.50, 0.50]
+ - [0.50, 0.50]
+ - [0.50, -0.50]
+---
+# invalid slices
+- geometry: &target
+ - plane:
+ slices: 4097
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.50, -0.50]
+ - [-0.50, 0.50]
+ - [0.50, 0.50]
+ - [0.50, -0.50]
+---
#
# <sphere> ::=
# sphere:
@@ -1160,7 +1211,7 @@
#
# <position-description> ::=
# position: <real3> | hyperboloid_image_focals: <hyperboloid_focals>
-#
+#
# missing anchors definition
- entity:
diff --git a/src/parser/yaml/test_ok_6.yaml b/src/parser/yaml/test_ok_6.yaml
@@ -0,0 +1,108 @@
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ plane:
+ slices: 4
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.50, -0.50]
+ - [-0.50, 0.50]
+ - [0.50, 0.50]
+ - [0.50, -0.50]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ plane:
+ clip:
+ - operation: AND
+ vertices:
+ - [-0.50, -0.50]
+ - [-0.50, 0.50]
+ - [0.50, 0.50]
+ - [0.50, -0.50]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ parabol:
+ slices: 40
+ focal: 18
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ parabol:
+ focal: 18
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ parabolic-cylinder:
+ slices: 40
+ focal: 18
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ parabolic-cylinder:
+ focal: 18
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ hyperbol:
+ slices: 40
+ focals: { real: 1, image: 1 }
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+---
+- sun: { dni: 1, spectrum: [{wavelength: 1, data: 1}] }
+- entity:
+ name: entity
+ primary: 1
+ geometry:
+ - material: { mirror: { reflectivity: 0, roughness: 0.5 } }
+ hyperbol:
+ focals: { real: 1, image: 1 }
+ clip:
+ - operation: AND
+ vertices: [[-30.0, -20.0], [-30.0, 20.0], [30.0, 20.0], [30.0, -20.0]]
+
+
diff --git a/src/solstice.c b/src/solstice.c
@@ -677,6 +677,8 @@ solstice_run(struct solstice* solstice)
goto error;
}
+ fprintf(solstice->output, "#--- No Sun direction\n");
+
if(dump) {
res = solstice_dump(solstice);
if(res != RES_OK) goto error;
diff --git a/src/solstice_object.c b/src/solstice_object.c
@@ -284,21 +284,21 @@ create_stl
ASSERT(str_cget(&stl->filename));
res = sstl_create(NULL, solstice->allocator, 0, &tmp_stl);
- if (res != RES_OK) {
+ if(res != RES_OK) {
fprintf(stderr, "Could not create a Solstice Solver STL shape.\n");
goto error;
}
res = sstl_load(tmp_stl, str_cget(&stl->filename));
- if (res != RES_OK) goto error;
+ if(res != RES_OK) goto error;
res = sstl_get_desc(tmp_stl, &tmp_desc);
- if (res != RES_OK) goto error;
+ if(res != RES_OK) goto error;
ASSERT(tmp_desc.triangles_count <= UINT_MAX);
ASSERT(tmp_desc.vertices_count <= UINT_MAX);
mesh_ctx.transform = transform;
mesh_ctx.desc = tmp_desc;
res = ssol_shape_create_mesh(solstice->ssol, &ssol_shape);
- if (res != RES_OK) {
+ if(res != RES_OK) {
fprintf(stderr, "Could not create the STL mesh shape.\n");
goto error;
}
@@ -308,20 +308,17 @@ create_stl
res = ssol_mesh_setup(ssol_shape, (unsigned)tmp_desc.triangles_count,
mesh_ctx_sstl_get_ids, (unsigned)tmp_desc.vertices_count, &vertex_data, 1,
&mesh_ctx);
- if (res != RES_OK) {
+ if(res != RES_OK) {
fprintf(stderr, "Could not setup STL mesh.\n");
goto error;
}
exit:
- if (tmp_stl) {
- SSTL(ref_put(tmp_stl));
- tmp_stl = NULL;
- }
+ if(tmp_stl) SSTL(ref_put(tmp_stl));
*out_stl = ssol_shape;
return res;
error:
- if (ssol_shape) {
+ if(ssol_shape) {
SSOL(shape_ref_put(ssol_shape));
ssol_shape = NULL;
}
@@ -405,7 +402,9 @@ create_parabol
quadric.data.parabol.focal = paraboloid->focal;
d33_set(quadric.transform, transform);
d3_set(quadric.transform+9, transform+9);
-
+ if(paraboloid->nslices > 0) { /* nslices is set */
+ quadric.slices_count_hint = (size_t)paraboloid->nslices;
+ }
return create_ssol_shape_punched_surface
(solstice, ¶boloid->polyclips, &quadric, out_ssol_shape);
}
@@ -424,9 +423,12 @@ create_parabolic_cylinder
paraboloid = solparser_get_shape_parabolic_cylinder(solstice->parser, id);
quadric.type = SSOL_QUADRIC_PARABOLIC_CYLINDER;
- quadric.data.parabol.focal = paraboloid->focal;
+ quadric.data.parabolic_cylinder.focal = paraboloid->focal;
d33_set(quadric.transform, transform);
d3_set(quadric.transform+9, transform+9);
+ if(paraboloid->nslices > 0) { /* nslices is set */
+ quadric.slices_count_hint = (size_t)paraboloid->nslices;
+ }
return create_ssol_shape_punched_surface
(solstice, ¶boloid->polyclips, &quadric, out_ssol_shape);
@@ -451,6 +453,9 @@ create_hyperbol
quadric.data.hyperbol.img_focal = hyperboloid->focals.image;
d33_set(quadric.transform, transform);
d3_set(quadric.transform + 9, transform + 9);
+ if(hyperboloid->nslices > 0) { /* nslices is set */
+ quadric.slices_count_hint = (size_t)hyperboloid->nslices;
+ }
return create_ssol_shape_punched_surface
(solstice, &hyperboloid->polyclips, &quadric, out_ssol_shape);
@@ -464,12 +469,14 @@ create_plane
struct ssol_shape** out_ssol_shape)
{
const struct solparser_shape_plane* plane;
- struct ssol_quadric quadric;
+ struct ssol_quadric quadric = SSOL_QUADRIC_DEFAULT;
ASSERT(solstice);
plane = solparser_get_shape_plane(solstice->parser, id);
+ ASSERT(plane->nslices > 0);
quadric.type = SSOL_QUADRIC_PLANE;
+ quadric.slices_count_hint = (size_t)plane->nslices;
d33_set(quadric.transform, transform);
d3_set(quadric.transform+9, transform+9);
diff --git a/src/solstice_solve.c b/src/solstice_solve.c
@@ -23,7 +23,7 @@
* Helper function
******************************************************************************/
static void
-write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator)
+write_mc_global(struct solstice* solstice, struct ssol_estimator* estimator)
{
struct ssol_mc_global mc_global;
struct htable_receiver_iterator r_it, r_end;
@@ -106,7 +106,7 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator)
"%s %u "
"FRONT: %g %g %g %g %g %g %g %g %g %g "
"BACK: %g %g %g %g %g %g %g %g %g %g\n",
- str_cget(name), (unsigned) id,
+ str_cget(name), (unsigned)id,
front.integrated_absorbed_irradiance.E, front.integrated_absorbed_irradiance.SE,
front.integrated_irradiance.E, front.integrated_irradiance.SE,
front.reflectivity_loss.E, front.reflectivity_loss.SE,
@@ -198,6 +198,170 @@ write_global_mc(struct solstice* solstice, struct ssol_estimator* estimator)
}
}
+static void
+dump_instantiated_shaded_shape_vertices
+ (struct solstice* solstice,
+ const struct ssol_instantiated_shaded_shape* inst_sshape)
+{
+ unsigned ivert, nverts;
+ ASSERT(solstice && inst_sshape);
+
+ SSOL(shape_get_vertices_count(inst_sshape->shape, &nverts));
+ FOR_EACH(ivert, 0, nverts) {
+ double pos[3];
+ SSOL(instantiated_shaded_shape_get_vertex_attrib
+ (inst_sshape, ivert, SSOL_POSITION, pos));
+ fprintf(solstice->output, "%f %f %f\n", SPLIT3(pos));
+ }
+}
+
+static void
+dump_shape_triangle_indices
+ (struct solstice* solstice,
+ const struct ssol_shape* shape,
+ const size_t offset)
+{
+ unsigned itri, ntris;
+ ASSERT(solstice && shape);
+
+ SSOL(shape_get_triangles_count(shape, &ntris));
+ FOR_EACH(itri, 0, ntris) {
+ unsigned ids[3];
+ SSOL(shape_get_triangle_indices(shape, itri, ids));
+ fprintf(solstice->output, "3 %lu %lu %lu\n",
+ (unsigned long)(ids[0] + offset),
+ (unsigned long)(ids[1] + offset),
+ (unsigned long)(ids[2] + offset));
+ }
+}
+
+static void
+dump_mc_shape
+ (struct solstice* solstice,
+ struct ssol_shape* shape,
+ struct ssol_mc_shape* mc_shape)
+{
+ unsigned itri, ntris;
+ ASSERT(solstice && shape && mc_shape);
+
+ SSOL(shape_get_triangles_count(shape, &ntris));
+ FOR_EACH(itri, 0, ntris) {
+ struct ssol_mc_primitive mc_prim;
+ SSOL(mc_shape_get_mc_primitive(mc_shape, itri, &mc_prim));
+ fprintf(solstice->output, "%g %g\n",
+ mc_prim.integrated_irradiance.E,
+ mc_prim.integrated_irradiance.SE);
+ }
+}
+
+static void
+dump_per_primitive_mc_estimations
+ (struct solstice* solstice,
+ struct ssol_estimator* estimator,
+ struct ssol_instance* inst,
+ const enum ssol_side_flag side)
+{
+ size_t ishape, nshapes;
+ struct ssol_mc_receiver mc_rcv;
+ const char* name;
+ ASSERT(solstice && estimator && inst);
+
+ SSOL(estimator_get_mc_receiver(estimator, inst, side, &mc_rcv));
+
+ switch(side) {
+ case SSOL_FRONT: name = "Front_faces"; break;
+ case SSOL_BACK: name = "Back_faces"; break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+
+ fprintf(solstice->output, "SCALARS %s float 2\n", name);
+ fprintf(solstice->output, "LOOKUP_TABLE default\n");
+
+ SSOL(instance_get_shaded_shapes_count(inst, &nshapes));
+ FOR_EACH(ishape, 0, nshapes) {
+ struct ssol_instantiated_shaded_shape inst_sshape;
+ struct ssol_mc_shape mc_shape;
+ SSOL(instance_get_shaded_shape(inst, ishape, &inst_sshape));
+ SSOL(mc_receiver_get_mc_shape(&mc_rcv, inst_sshape.shape, &mc_shape));
+ dump_mc_shape(solstice, inst_sshape.shape, &mc_shape);
+ }
+}
+
+static void
+write_per_receiver_mc_primitive
+ (struct solstice* solstice, struct ssol_estimator* estimator)
+{
+ struct htable_receiver_iterator it, end;
+ ASSERT(solstice && estimator);
+
+ htable_receiver_begin(&solstice->receivers, &it);
+ htable_receiver_end(&solstice->receivers, &end);
+ while(!htable_receiver_iterator_eq(&it, &end)) {
+ struct ssol_instantiated_shaded_shape inst_sshape;
+ const struct str* name = htable_receiver_iterator_key_get(&it);
+ struct solstice_receiver* rcv = htable_receiver_iterator_data_get(&it);
+ struct ssol_instance* inst = rcv->node->instance;
+ size_t ishape, nshapes;
+ size_t nverts, ntris;
+ size_t offset;
+
+ htable_receiver_iterator_next(&it);
+ SSOL(instance_get_shaded_shapes_count(inst, &nshapes));
+
+ /* Write the header */
+ fprintf(solstice->output, "# vtk DataFile Version 2.0\n");
+ fprintf(solstice->output, "%s\n", str_cget(name));
+ fprintf(solstice->output, "ASCII\n");
+ fprintf(solstice->output, "DATASET POLYDATA\n");
+
+ /* Compute the overall number of vertices & triangles of the receiver */
+ nverts = ntris = 0;
+ FOR_EACH(ishape, 0, nshapes) {
+ unsigned shape_nverts, shape_ntris;
+ SSOL(instance_get_shaded_shape(inst, ishape, &inst_sshape));
+ SSOL(shape_get_vertices_count(inst_sshape.shape, &shape_nverts));
+ SSOL(shape_get_triangles_count(inst_sshape.shape, &shape_ntris));
+ nverts += shape_nverts;
+ ntris += shape_ntris;
+ }
+
+ /* Write the positions of the receiver shaded shapes */
+ fprintf(solstice->output, "POINTS %lu float\n", (unsigned long)nverts);
+ FOR_EACH(ishape, 0, nshapes) {
+ SSOL(instance_get_shaded_shape(inst, ishape, &inst_sshape));
+ dump_instantiated_shaded_shape_vertices(solstice, &inst_sshape);
+ }
+
+ /* Write the triangles of the receiver shade shapes */
+ offset = 0;
+ fprintf(solstice->output, "POLYGONS %lu %lu\n",
+ (unsigned long)ntris, (unsigned long)ntris*4);
+ FOR_EACH(ishape, 0, nshapes) {
+ unsigned shape_nverts;
+ SSOL(instance_get_shaded_shape(inst, ishape, &inst_sshape));
+ SSOL(shape_get_vertices_count(inst_sshape.shape, &shape_nverts));
+ dump_shape_triangle_indices(solstice, inst_sshape.shape, offset);
+ offset += shape_nverts;
+ }
+
+ /* Write front faces MC estimations */
+ fprintf(solstice->output, "CELL_DATA %lu\n", (unsigned long)ntris);
+ switch(rcv->side) {
+ case SRCVL_FRONT:
+ dump_per_primitive_mc_estimations(solstice, estimator, inst, SSOL_FRONT);
+ break;
+ case SRCVL_BACK:
+ dump_per_primitive_mc_estimations(solstice, estimator, inst, SSOL_BACK);
+ break;
+ case SRCVL_FRONT_AND_BACK:
+ dump_per_primitive_mc_estimations(solstice, estimator, inst, SSOL_FRONT);
+ dump_per_primitive_mc_estimations(solstice, estimator, inst, SSOL_BACK);
+ break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ }
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
@@ -234,7 +398,8 @@ solstice_solve(struct solstice* solstice)
goto error;
}
- write_global_mc(solstice, estimator);
+ write_mc_global(solstice, estimator);
+ write_per_receiver_mc_primitive(solstice, estimator);
if(solstice->output_hits) {
sz = (size_t)ftell(bin_stream);
diff --git a/src/test_solstice_simulation.c b/src/test_solstice_simulation.c
@@ -31,106 +31,6 @@
#include <sys/stat.h>
#define fdopen _fdopen
#define open _open
- #define mktemp _mktemp
-
- /* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
- (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version. */
-
- static const char letters [] =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
- /* Generate a temporary file name based on TMPL. TMPL must match the
- rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
- does not exist at the time of the call to mkstemp. TMPL is
- overwritten with the result. */
- int
- mkstemp(char *tmpl)
- {
- size_t len;
- char *XXXXXX;
- static unsigned long long value;
- unsigned long long random_time_bits;
- unsigned int count;
- int fd = -1;
- int save_errno = errno;
-
- /* A lower bound on the number of temporary files to attempt to
- generate. The maximum total number of temporary file names that
- can exist for a given template is 62**6. It should never be
- necessary to try all these combinations. Instead if a reasonable
- number of names is tried (we define reasonable as 62**3) fail to
- give the system administrator the chance to remove the problems. */
- #define ATTEMPTS_MIN (62 * 62 * 62)
-
- /* The number of times to attempt to generate a temporary file. To
- conform to POSIX, this must be no smaller than TMP_MAX. */
- #if ATTEMPTS_MIN < TMP_MAX
- unsigned int attempts = TMP_MAX;
- #else
- unsigned int attempts = ATTEMPTS_MIN;
- #endif
-
- len = strlen(tmpl);
- if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX")) {
- errno = EINVAL;
- return -1;
- }
-
- /* This is where the Xs start. */
- XXXXXX = &tmpl[len - 6];
-
- /* Get some more or less random data. */
- {
- SYSTEMTIME stNow;
- FILETIME ftNow;
-
- /* get system time */
- GetSystemTime(&stNow);
- stNow.wMilliseconds = 500;
- if (!SystemTimeToFileTime(&stNow, &ftNow)) {
- errno = -1;
- return -1;
- }
-
- random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
- | (unsigned long long)ftNow.dwLowDateTime);
- }
- value += random_time_bits ^ (unsigned long long)GetCurrentThreadId();
-
- for (count = 0; count < attempts; value += 7777, ++count) {
- unsigned long long v = value;
-
- /* Fill in the random bits. */
- XXXXXX[0] = letters[v % 62];
- v /= 62;
- XXXXXX[1] = letters[v % 62];
- v /= 62;
- XXXXXX[2] = letters[v % 62];
- v /= 62;
- XXXXXX[3] = letters[v % 62];
- v /= 62;
- XXXXXX[4] = letters[v % 62];
- v /= 62;
- XXXXXX[5] = letters[v % 62];
-
- fd = open(tmpl, O_RDWR|O_CREAT|O_EXCL, S_IREAD|S_IWRITE);
- if (fd >= 0) {
- errno = save_errno;
- return fd;
- }
- else if (errno != EEXIST)
- return -1;
- }
-
- /* We got out of the loop because we ran out of combinations to try. */
- errno = EEXIST;
- return -1;
- }
#endif
enum side {
@@ -187,6 +87,108 @@ sundir_header [] = "#--- Sun direction:";
#define IS_NEW_BLOCK(Line, Header) (!strncmp((Line), (Header), strlen(Header)))
+
+#ifdef COMPILER_CL
+/* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
+ * (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version. */
+
+static const char letters [] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary file name based on TMPL. TMPL must match the
+ * rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
+ * does not exist at the time of the call to mkstemp. TMPL is
+ * overwritten with the result. */
+int
+mkstemp(char *tmpl)
+{
+ size_t len;
+ char *XXXXXX;
+ static unsigned long long value;
+ unsigned long long random_time_bits;
+ unsigned int count;
+ int fd = -1;
+ int save_errno = errno;
+
+ /* A lower bound on the number of temporary files to attempt to
+ * generate. The maximum total number of temporary file names that
+ * can exist for a given template is 62**6. It should never be
+ * necessary to try all these combinations. Instead if a reasonable
+ * number of names is tried (we define reasonable as 62**3) fail to
+ * give the system administrator the chance to remove the problems. */
+ #define ATTEMPTS_MIN (62 * 62 * 62)
+
+ /* The number of times to attempt to generate a temporary file. To
+ * conform to POSIX, this must be no smaller than TMP_MAX. */
+ #if ATTEMPTS_MIN < TMP_MAX
+ unsigned int attempts = TMP_MAX;
+ #else
+ unsigned int attempts = ATTEMPTS_MIN;
+ #endif
+
+ len = strlen(tmpl);
+ if (len < 6 || strcmp(&tmpl[len - 6], "XXXXXX")) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* This is where the Xs start. */
+ XXXXXX = &tmpl[len - 6];
+
+ /* Get some more or less random data. */
+ {
+ SYSTEMTIME stNow;
+ FILETIME ftNow;
+
+ /* get system time */
+ GetSystemTime(&stNow);
+ stNow.wMilliseconds = 500;
+ if (!SystemTimeToFileTime(&stNow, &ftNow)) {
+ errno = -1;
+ return -1;
+ }
+
+ random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
+ | (unsigned long long)ftNow.dwLowDateTime);
+ }
+ value += random_time_bits ^ (unsigned long long)GetCurrentThreadId();
+
+ for (count = 0; count < attempts; value += 7777, ++count) {
+ unsigned long long v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open(tmpl, O_RDWR|O_CREAT|O_EXCL, S_IREAD|S_IWRITE);
+ if (fd >= 0) {
+ errno = save_errno;
+ return fd;
+ }
+ else if (errno != EEXIST)
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ errno = EEXIST;
+ return -1;
+}
+#endif
+
static int
read_line(char* line, size_t max_line_len, FILE* stream)
{
@@ -462,6 +464,7 @@ do_check(const char* binary, const char* dir, const char* base_name)
FILE* ref_file;
struct counts ref_counts, test_counts;
int n;
+ int err;
ASSERT(base_name);
n = snprintf(ref_file_name, sizeof(ref_file_name), "%s%s.ref", dir, base_name);
@@ -490,7 +493,8 @@ do_check(const char* binary, const char* dir, const char* base_name)
dir, base_name, dir, base_name);
CHECK((unsigned)n < sizeof(cmd), 1);
- CHECK(system(cmd), RES_OK);
+ err = system(cmd);
+ CHECK(err, 0);
get_angles_and_counts(test_file, test_sun_angles, &test_counts);
CHECK(d2_eq(ref_sun_angles, test_sun_angles), 1);