commit 436c4e4c42ae34bc19cea8dd86b40cc2671cb0ae
parent b770f7310e1991c4dab4fa0b60fbcde64abd6fe6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 15 Mar 2017 15:54:30 +0100
Load the "slices" parameter that controls the quadric discretisation
Diffstat:
4 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/doc/input b/doc/input
@@ -1,7 +1,6 @@
#--------------------------------------------------------------------------------
# 1/ Example
#--------------------------------------------------------------------------------
-
# Declare materials
- material: &lambertian
matte:
@@ -157,7 +156,7 @@
clip: <polyclip-list>
# By default slices is automatically compute with respect to the parabol
# curvature
-[ slices: INTEGER ] # in [1, INF)
+[ slices: INTEGER ] # in [4, 4096)
<parabolic-cylinder> ::=
parabolic-cylinder: # y^2 - 4*focal*z = 0
@@ -165,7 +164,7 @@
clip: <polyclip-list>
# By default slices is automatically compute with respect to the hyperbol
# curvature
-[ slices: INTEGER ] # in [1, INF)
+[ 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;
@@ -176,7 +175,7 @@
clip: <polyclip-list>
# By default slices is automatically compute with respect to the hyperbol
# curvature
-[ slices: INTEGER ] # in [1, INF)
+[ slices: INTEGER ] # in [4, 4096)
<hyperboloid_focals> ::=
real: REAL # in ]0, INF)
@@ -185,7 +184,7 @@
<plane> ::=
plane:
clip: <polyclip-list>
-[ slices: INTEGER ] # in [1, INF). Default 1
+[ slices: INTEGER ] # in [1, 4096). Default 1
<sphere> ::=
sphere:
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);
@@ -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,14 +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;
}
@@ -2014,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;
@@ -2022,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;
@@ -2031,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;
}
@@ -2044,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;
@@ -2058,19 +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 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;
}
@@ -2091,7 +2097,7 @@ exit :
out_ishape->i = ishape;
return res;
error:
- if (shape) {
+ if(shape) {
darray_hyperboloid_pop_back(&parser->hyperbols);
ishape = SIZE_MAX;
}
@@ -2105,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;
@@ -2140,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);
@@ -2158,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");
@@ -2371,7 +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);
@@ -2646,11 +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")) {
+ } 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",
@@ -2842,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,6 +198,7 @@ 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);
}
@@ -207,12 +211,13 @@ struct solparser_hyperboloid_focals {
};
#define SOLPARSER_HYPERBOLOID_FOCALS_NULL__ { 0, 0 }
-static const struct solparser_hyperboloid_focals
+static const struct solparser_hyperboloid_focals
SOLPARSER_HYPERBOLOID_FOCALS_NULL = SOLPARSER_HYPERBOLOID_FOCALS_NULL__;
struct solparser_shape_hyperboloid {
struct solparser_hyperboloid_focals focals;
struct darray_polyclip polyclips;
+ long nslices; /* < 0 if not defined */
};
static INLINE void
@@ -221,6 +226,7 @@ solparser_shape_hyperboloid_init
struct solparser_shape_hyperboloid* hyperboloid)
{
ASSERT(hyperboloid);
+ hyperboloid->nslices = -1;
darray_polyclip_init(allocator, &hyperboloid->polyclips);
}
@@ -238,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);
}
@@ -248,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);
}
@@ -256,6 +264,7 @@ solparser_shape_hyperboloid_copy_and_release
******************************************************************************/
struct solparser_shape_plane {
struct darray_polyclip polyclips;
+ long nslices;
};
static INLINE void
@@ -264,6 +273,7 @@ solparser_shape_plane_init
struct solparser_shape_plane* plane)
{
ASSERT(plane);
+ plane->nslices = 1;
darray_polyclip_init(allocator, &plane->polyclips);
}
@@ -280,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);
}
@@ -289,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/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);
}
@@ -427,6 +426,9 @@ create_parabolic_cylinder
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);
@@ -468,8 +473,10 @@ create_plane
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);