commit b4122160793a949af272d2f2070d4b44c8f3b24e
parent 684edd4dc5ba7d4e43f09e0f66d5396e2300b446
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 28 Mar 2017 14:20:40 +0200
Specify and parse the normal_map material parameter
Currently, only the matte material can have an optionnal normal map.
Diffstat:
9 files changed, 273 insertions(+), 43 deletions(-)
diff --git a/cmake/parser/CMakeLists.txt b/cmake/parser/CMakeLists.txt
@@ -32,6 +32,7 @@ include_directories(
set(SOLPARSER_FILES_SRC
solparser.c
solparser_entity.c
+ solparser_image.c
solparser_geometry.c
solparser_material.c
solparser_pivot.c
@@ -42,6 +43,7 @@ set(SOLPARSER_FILES_INC
solparser_c.h
solparser_entity.h
solparser_geometry.h
+ solparser_image.h
solparser_material.h
solparser_pivot.h
solparser_shape.h
diff --git a/doc/input b/doc/input
@@ -229,6 +229,7 @@
<matte> ::=
matte:
reflectivity: REAL # in [0, 1]
+[ <normal-map> ]
<mirror> ::=
mirror:
@@ -245,8 +246,11 @@
medium_t: <dielectric-medium>
<dielectric-medium> ::=
- refractive_index: REAL # in ]0, INF)
- absorptivity: REAL # in [0, INF)
+ refractive_index: REAL # in ]0, INF)
+ absorptivity: REAL # in [0, INF)
+
+<normal-map> ::=
+ normal_map: { path: PATH }
#----------------------------------------
<entity> ::=
diff --git a/src/parser/solparser.c b/src/parser/solparser.c
@@ -186,6 +186,7 @@ parser_clear(struct solparser* parser)
/* Materials */
htable_yaml2sols_clear(&parser->yaml2mtls);
+ darray_image_clear(&parser->images);
darray_material_clear(&parser->mtls);
darray_material2_clear(&parser->mtls2);
darray_medium_clear(&parser->mediums);
@@ -240,6 +241,7 @@ parser_release(ref_T* ref)
/* Materials */
htable_yaml2sols_release(&parser->yaml2mtls);
+ darray_image_release(&parser->images);
darray_material_release(&parser->mtls);
darray_material2_release(&parser->mtls2);
darray_medium_release(&parser->mediums);
@@ -568,6 +570,7 @@ solparser_create
/* Materials */
htable_yaml2sols_init(mem_allocator, &parser->yaml2mtls);
+ darray_image_init(mem_allocator, &parser->images);
darray_material_init(mem_allocator, &parser->mtls);
darray_material2_init(mem_allocator, &parser->mtls2);
darray_medium_init(mem_allocator, &parser->mediums);
@@ -882,6 +885,15 @@ solparser_get_entity
return darray_entity_cdata_get(&parser->entities) + entity.i;
}
+const struct solparser_image*
+solparser_get_image
+ (const struct solparser* parser,
+ const struct solparser_image_id image)
+{
+ ASSERT(parser && image.i < darray_image_size_get(&parser->images));
+ return darray_image_cdata_get(&parser->images) + image.i;
+}
+
const struct solparser_geometry*
solparser_get_geometry
(const struct solparser* parser,
diff --git a/src/parser/solparser.h b/src/parser/solparser.h
@@ -87,16 +87,16 @@ solparser_get_entity
(const struct solparser* parser,
const struct solparser_entity_id entity);
+extern LOCAL_SYM const struct solparser_image*
+solparser_get_image
+ (const struct solparser* parser,
+ const struct solparser_image_id image);
+
extern LOCAL_SYM const struct solparser_geometry*
solparser_get_geometry
(const struct solparser* parser,
const struct solparser_geometry_id geom);
-extern LOCAL_SYM const struct solparser_medium*
-solparser_get_medium
- (const struct solparser* parser,
- const struct solparser_medium_id medium);
-
extern LOCAL_SYM const struct solparser_material*
solparser_get_material
(const struct solparser* parser,
@@ -127,21 +127,16 @@ solparser_get_material_thin_dielectric
(const struct solparser* parser,
const struct solparser_material_thin_dielectric_id thin_dielectric);
+extern LOCAL_SYM const struct solparser_medium*
+solparser_get_medium
+ (const struct solparser* parser,
+ const struct solparser_medium_id medium);
+
extern LOCAL_SYM const struct solparser_object*
solparser_get_object
(const struct solparser* parser,
const struct solparser_object_id obj);
-extern LOCAL_SYM const struct solparser_x_pivot*
-solparser_get_x_pivot
- (const struct solparser* parser,
- const struct solparser_pivot_id x_pivot);
-
-extern LOCAL_SYM const struct solparser_zx_pivot*
-solparser_get_zx_pivot
- (const struct solparser* parser,
- const struct solparser_pivot_id zx_pivot);
-
extern LOCAL_SYM const struct solparser_shape*
solparser_get_shape
(const struct solparser* parser,
@@ -196,6 +191,16 @@ extern LOCAL_SYM const struct solparser_sun*
solparser_get_sun
(const struct solparser* parser);
+extern LOCAL_SYM const struct solparser_x_pivot*
+solparser_get_x_pivot
+ (const struct solparser* parser,
+ const struct solparser_pivot_id x_pivot);
+
+extern LOCAL_SYM const struct solparser_zx_pivot*
+solparser_get_zx_pivot
+ (const struct solparser* parser,
+ const struct solparser_pivot_id zx_pivot);
+
/*******************************************************************************
* Entity interator
******************************************************************************/
diff --git a/src/parser/solparser_c.h b/src/parser/solparser_c.h
@@ -18,6 +18,7 @@
#include "solparser.h"
#include "solparser_entity.h"
+#include "solparser_image.h"
#include "solparser_material.h"
#include "solparser_pivot.h"
#include "solparser_shape.h"
@@ -53,6 +54,7 @@ struct target_alias {
/* Declare the array of matte materials */
#define DARRAY_NAME matte
#define DARRAY_DATA struct solparser_material_matte
+#define DARRAY_FUNCTOR_INIT solparser_material_matte_init
#include <rsys/dynamic_array.h>
/* Declare the array of mirror materials */
@@ -90,6 +92,15 @@ struct target_alias {
#define DARRAY_DATA struct solparser_shape_cylinder
#include <rsys/dynamic_array.h>
+/* Declare the array of images */
+#define DARRAY_NAME image
+#define DARRAY_DATA struct solparser_image
+#define DARRAY_FUNCTOR_INIT solparser_image_init
+#define DARRAY_FUNCTOR_RELEASE solparser_image_release
+#define DARRAY_FUNCTOR_COPY solparser_image_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE solparser_image_copy_and_release
+#include <rsys/dynamic_array.h>
+
/* Declare the array of imported geometries */
#define DARRAY_NAME impgeom
#define DARRAY_DATA struct solparser_shape_imported_geometry
@@ -192,6 +203,7 @@ struct solparser {
/* Materia data */
struct htable_yaml2sols yaml2mtls; /* Cache of materials */
+ struct darray_image images;
struct darray_material mtls;
struct darray_material2 mtls2; /* Double sided materials */
struct darray_medium mediums;
@@ -328,13 +340,6 @@ parse_transform
* Main parsing functions
******************************************************************************/
extern LOCAL_SYM res_T
-parse_material
- (struct solparser* parser,
- yaml_document_t* doc,
- yaml_node_t* mtl,
- struct solparser_material_double_sided_id* out_imtl2);
-
-extern LOCAL_SYM res_T
parse_entity
(struct solparser* parser,
yaml_document_t* doc,
@@ -343,6 +348,13 @@ parse_entity
struct solparser_entity_id* out_isolent);
extern LOCAL_SYM res_T
+parse_image
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* image,
+ struct solparser_image_id* out_img);
+
+extern LOCAL_SYM res_T
parse_focals_description
(struct solparser* parser,
yaml_document_t* doc,
@@ -357,18 +369,20 @@ parse_geometry
struct solparser_geometry_id* out_isolgeom);
extern LOCAL_SYM res_T
-parse_x_pivot
+parse_material
(struct solparser* parser,
yaml_document_t* doc,
- const yaml_node_t* x_pivot,
- struct solparser_pivot_id* out_isolpivot);
+ yaml_node_t* mtl,
+ struct solparser_material_double_sided_id* out_imtl2);
extern LOCAL_SYM res_T
-parse_zx_pivot
+parse_spectrum
(struct solparser* parser,
yaml_document_t* doc,
- const yaml_node_t* zx_pivot,
- struct solparser_pivot_id* out_isolpivot);
+ const double lower_bound,
+ const double upper_bound,
+ const yaml_node_t* spectrum,
+ struct darray_spectrum_data* data);
extern LOCAL_SYM res_T
parse_sun
@@ -378,12 +392,17 @@ parse_sun
struct solparser_sun** out_solsun);
extern LOCAL_SYM res_T
-parse_spectrum
+parse_x_pivot
(struct solparser* parser,
yaml_document_t* doc,
- const double lower_bound,
- const double upper_bound,
- const yaml_node_t* spectrum,
- struct darray_spectrum_data* data);
+ const yaml_node_t* x_pivot,
+ struct solparser_pivot_id* out_isolpivot);
+
+extern LOCAL_SYM res_T
+parse_zx_pivot
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* zx_pivot,
+ struct solparser_pivot_id* out_isolpivot);
#endif /* SOLPARSER_C_H */
diff --git a/src/parser/solparser_image.c b/src/parser/solparser_image.c
@@ -0,0 +1,106 @@
+/* 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_c.h"
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+parse_image
+ (struct solparser* parser,
+ yaml_document_t* doc,
+ const yaml_node_t* img,
+ struct solparser_image_id* out_iimg)
+{
+ enum { PATH };
+ struct solparser_image* solimg = NULL;
+ size_t isolimg = SIZE_MAX;
+ intptr_t i, n;
+ int mask = 0; /* Register the parsed attributes */
+ res_T res = RES_OK;
+ ASSERT(parser && doc && img &&out_iimg);
+
+ if(img->type != YAML_MAPPING_NODE) {
+ log_err(parser, img, "expect a mapping of image parameters.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Allocate an image */
+ isolimg = darray_image_size_get(&parser->images);
+ res = darray_image_resize(&parser->images, isolimg + 1);
+ if(res != RES_OK) {
+ log_err(parser, img, "could not allocate the image.\n");
+ goto error;
+ }
+ solimg = darray_image_data_get(&parser->images) + isolimg;
+
+ n = img->data.mapping.pairs.top - img->data.mapping.pairs.start;
+ FOR_EACH(i, 0, n) {
+ yaml_node_t* key;
+ yaml_node_t* val;
+
+ key = yaml_document_get_node(doc, img->data.mapping.pairs.start[i].key);
+ val = yaml_document_get_node(doc, img->data.mapping.pairs.start[i].value);
+ if(key->type != YAML_SCALAR_NODE) {
+ log_err(parser, key, "expect image parameters.\n");
+ goto error;
+ }
+ #define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the image parameter `"Name"' is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "path")) {
+ SETUP_MASK(PATH, "path");
+ res = parse_string(parser, val, &solimg->filename);
+ } else {
+ log_err(parser, key, "unknown image 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, img, \
+ "the image parameter `"Name"' is missing.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } (void)0
+ CHECK_PARAM(PATH, "path");
+ #undef CHECK_PARAM
+
+exit:
+ out_iimg->i = isolimg;
+error:
+ if(solimg) {
+ darray_image_pop_back(&parser->images);
+ isolimg = SIZE_MAX;
+ }
+ goto exit;
+}
+
diff --git a/src/parser/solparser_image.h b/src/parser/solparser_image.h
@@ -0,0 +1,62 @@
+/* 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/>. */
+
+#ifndef SOLPARSER_IMAGE_H
+#define SOLPARSER_IMAGE_H
+
+#include <rsys/str.h>
+
+struct solparser_image {
+ struct str filename;
+};
+
+struct solparser_image_id { size_t i; };
+
+static INLINE void
+solparser_image_init
+ (struct mem_allocator* allocator,
+ struct solparser_image* img)
+{
+ ASSERT(img);
+ str_init(allocator, &img->filename);
+}
+
+static INLINE void
+solparser_image_release(struct solparser_image* img)
+{
+ ASSERT(img);
+ str_release(&img->filename);
+}
+
+static INLINE res_T
+solparser_image_copy
+ (struct solparser_image* dst,
+ const struct solparser_image* src)
+{
+ ASSERT(dst && src);
+ return str_copy(&dst->filename, &src->filename);
+}
+
+static INLINE res_T
+solparser_image_copy_and_release
+ (struct solparser_image* dst,
+ struct solparser_image* src)
+{
+ ASSERT(dst && src);
+ return str_copy_and_release(&dst->filename, &src->filename);
+}
+
+#endif /* SOLPARSER_IMAGE_H */
+
diff --git a/src/parser/solparser_material.c b/src/parser/solparser_material.c
@@ -214,7 +214,7 @@ parse_material_matte
const yaml_node_t* matte,
struct solparser_material_matte_id* out_imtl)
{
- enum { REFLECTIVITY };
+ enum { NORMAL_MAP, REFLECTIVITY };
struct solparser_material_matte* mtl = NULL;
size_t imtl = SIZE_MAX;
intptr_t i, n;
@@ -250,13 +250,20 @@ parse_material_matte
goto error;
}
- if(!strcmp((char*)key->data.scalar.value, "reflectivity")) {
- if(mask & BIT(REFLECTIVITY)) {
- log_err(parser, key, "the matte reflectivity is already defined.\n");
- res = RES_BAD_ARG;
- goto error;
- }
- mask |= BIT(REFLECTIVITY);
+ #define SETUP_MASK(Flag, Name) { \
+ if(mask & BIT(Flag)) { \
+ log_err(parser, key, \
+ "the "Name" of the matte material is already defined.\n"); \
+ res = RES_BAD_ARG; \
+ goto error; \
+ } \
+ mask |= BIT(Flag); \
+ } (void)0
+ if(!strcmp((char*)key->data.scalar.value, "normal_map")) {
+ SETUP_MASK(NORMAL_MAP, "normal_map");
+ res = parse_image(parser, doc, val, &mtl->normal_map);
+ } else if(!strcmp((char*)key->data.scalar.value, "reflectivity")) {
+ SETUP_MASK(REFLECTIVITY, "reflectivity");
res = parse_real(parser, val, 0, 1, &mtl->reflectivity);
} else {
log_err(parser, key, "unknown matte parameter `%s'.\n",
@@ -268,6 +275,7 @@ parse_material_matte
log_node(parser, key);
goto error;
}
+ #undef SETUP_MASK
}
if(!(mask & BIT(REFLECTIVITY))) {
diff --git a/src/parser/solparser_material.h b/src/parser/solparser_material.h
@@ -16,6 +16,7 @@
#ifndef SOLPARSER_MATERIAL_H
#define SOLPARSER_MATERIAL_H
+#include "solparser_image.h"
#include <stddef.h>
enum solparser_material_type {
@@ -42,10 +43,21 @@ struct solparser_material_dielectric_id { size_t i; };
struct solparser_material_matte {
double reflectivity; /* In [0, 1] */
+ struct solparser_image_id normal_map;
};
struct solparser_material_matte_id { size_t i; };
+static INLINE void
+solparser_material_matte_init
+ (struct mem_allocator* allocator,
+ struct solparser_material_matte* matte)
+{
+ ASSERT(matte);
+ (void)allocator;
+ matte->normal_map.i = SIZE_MAX;
+}
+
struct solparser_material_mirror {
double roughness; /* In [0, 1] */
double reflectivity; /* In [0, 1] */