commit 24411e5ac1dcd821281c7218960c6c1cde261da9
parent a5d0b804bd05a397c1b8ca9c19f89ed4d8cc0f36
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 16 Jan 2017 11:13:05 +0100
Load the provided receivers into Solstice
Diffstat:
5 files changed, 108 insertions(+), 84 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -110,7 +110,7 @@ endif()
add_library(sollib STATIC ${SOLSTICE_FILES_SRC} ${SOLSTICE_FILES_INC})
add_executable(solstice ${SOLSTICE_SOURCE_DIR}/main.c)
target_link_libraries(solstice ${MATH_LIB} ${GETOPT_LIB}
- LibYAML RSys sollib solparser SolAnim SolSolver Star3DUT)
+ LibYAML RSys sollib solparser SolAnim SolSolver srcvl Star3DUT)
set_target_properties(solstice PROPERTIES
VERSION ${VERSION}
SOVERSION ${VERSION_MAJOR})
diff --git a/src/solstice.c b/src/solstice.c
@@ -235,12 +235,6 @@ load_data(struct solstice* solstice, const struct solstice_args* args)
res = solparser_load(solstice->parser);
if(res != RES_OK) goto error;
- res = solstice_setup_entities(solstice);
- if(res != RES_OK) {
- fprintf(stderr, "Could not setup the Solstice entities.\n");
- goto error;
- }
-
exit:
if(file && file != stdin) fclose(file);
return res;
@@ -249,81 +243,84 @@ error:
}
static res_T
-parse_receiver_file(struct solstice* solstice, const char* filename)
+setup_receivers(struct solstice* solstice, struct srcvl* srcvl)
{
- char line[256];
- FILE* file = NULL;
- unsigned long iline = 0;
+ size_t i, n;
res_T res = RES_OK;
- ASSERT(solstice && filename);
+ ASSERT(solstice && srcvl);
- file = fopen(filename, "r");
- if(!file) {
- fprintf(stderr, "Could not open the file `%s'.\n", filename);
- res = RES_IO_ERR;
- goto error;
- }
-
- while(fgets(line, sizeof(line)/sizeof(char), file)) {
+ n = srcvl_count(srcvl);
+ FOR_EACH(i, 0, n) {
+ struct srcvl_receiver rcv;
+ struct solstice_receiver receiver;
const struct solparser_entity* entity;
- struct solstice_node* node = NULL;
- char* str;
- char* p;
- size_t last_char;
- size_t first_char;
-
- ++iline;
- if(!strrchr(line, '\n')) {
- fprintf(stderr,
- "%s:%lu: insufficient memory. Could not parse the receiver name.\n",
- filename, iline);
- return RES_MEM_ERR;
+ srcvl_get(srcvl, i, &rcv);
+ entity = solparser_find_entity(solstice->parser, rcv.name);
+ if(!entity) {
+ fprintf(stderr, "Invalid entity `%s'.\n", rcv.name);
+ res = RES_BAD_ARG;
+ goto error;
}
- /* Remove the new line character(s) */
- last_char = strlen(line);
- while(last_char-- && (line[last_char] == '\n' || line[last_char]=='\r'));
- line[last_char+1] = '\0';
-
- /* Strip beginning white spaces */
- first_char = 0;
- while(first_char < last_char
- && (line[first_char]==' ' || line[first_char]=='\t')) {
- ++first_char;
+ if(entity->type != SOLPARSER_ENTITY_GEOMETRY) {
+ fprintf(stderr,
+ "The entity `%s' is not geometry. It cannot be a receiver.\n",
+ rcv.name);
+ res = RES_BAD_ARG;
+ goto error;
}
- str = line + first_char;
-
- /* Discard comments */
- if((p = strchr(str, '#'))) *p = '\0';
- /* Strip ending white spaces */
- last_char = strlen(str);
- while(last_char-- && (line[last_char] == ' ' || line[last_char] == '\t'));
- str[last_char+1] = '\0';
+ receiver.node = NULL;
+ receiver.side = rcv.side;
- /* Discard empty lines */
- if(str[0] == '\0') continue;
-
- /* Retrieve the entity */
- entity = solparser_find_entity(solstice->parser, str);
- if(!entity) {
- fprintf(stderr, "%s:%lu: invalid entity `%s'.\n",
- filename, iline, str);
- }
-
- /* Register the entity as a receiver */
- res = htable_entity_set(&solstice->receivers, &entity, &node);
+ res = htable_receiver_set(&solstice->receivers, &entity, &receiver);
if(res != RES_OK) {
fprintf(stderr,
- "%s:%lu could not register the entity `%s' as a receiver.\n",
- filename, iline, str);
+ "Could not register the receiver `%s' against Solstice.\n",
+ rcv.name);
goto error;
}
}
exit:
+ return res;
+error:
+ htable_receiver_clear(&solstice->receivers);
+ goto exit;
+}
+
+static res_T
+load_receivers(struct solstice* solstice, const struct solstice_args* args)
+{
+ FILE* file = NULL;
+ struct srcvl* srcvl = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && args);
+
+ file = fopen(args->receivers_filename, "r");
+ if(!file) {
+ fprintf(stderr, "Could not open the list of receivers `%s'.\n",
+ args->receivers_filename);
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ res = srcvl_create(solstice->allocator, &srcvl);
+ if(res != RES_OK) goto error;
+ res = srcvl_setup_stream(srcvl, args->receivers_filename, file);
+ if(res != RES_OK) goto error;
+ res = srcvl_load(srcvl);
+ if(res != RES_OK) goto error;
+ res = setup_receivers(solstice, srcvl);
+ if(res != RES_OK) goto error;
+
+exit:
if(file) fclose(file);
+ if(srcvl) {
+ srcvl_ref_put(srcvl);
+ srcvl = NULL;
+ }
return res;
error:
goto exit;
@@ -345,7 +342,7 @@ solstice_init
htable_material_init(allocator, &solstice->materials);
htable_object_init(allocator, &solstice->objects);
htable_anchor_init(allocator, &solstice->anchors);
- htable_entity_init(allocator, &solstice->receivers);
+ htable_receiver_init(allocator, &solstice->receivers);
darray_nodes_init(allocator, &solstice->roots);
darray_nodes_init(allocator, &solstice->pivots);
darray_double_init(allocator, &solstice->sun_dirs);
@@ -396,6 +393,17 @@ solstice_init
res = load_data(solstice, args);
if(res != RES_OK) goto error;
+ if(args->receivers_filename) {
+ res = load_receivers(solstice, args);
+ if(res != RES_OK) goto error;
+ }
+
+ res = solstice_setup_entities(solstice);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not setup the Solstice entities.\n");
+ goto error;
+ }
+
exit:
return res;
error:
@@ -420,7 +428,7 @@ solstice_release(struct solstice* solstice)
htable_material_release(&solstice->materials);
htable_object_release(&solstice->objects);
htable_anchor_release(&solstice->anchors);
- htable_entity_release(&solstice->receivers);
+ htable_receiver_release(&solstice->receivers);
darray_nodes_release(&solstice->roots);
darray_nodes_release(&solstice->pivots);
darray_double_release(&solstice->sun_dirs);
diff --git a/src/solstice.h b/src/solstice.h
@@ -17,6 +17,7 @@
#define SOLSTICE_H
#include "parser/solparser_material.h"
+#include "receivers/srcvl.h"
#include <rsys/dynamic_array_double.h>
#include <rsys/hash_table.h>
@@ -30,6 +31,11 @@ struct ssol_material;
struct ssol_object;
struct sanim_node;
+struct solstice_receiver {
+ struct solstice_node* node;
+ enum srcvl_side side;
+};
+
#define DARRAY_NAME nodes
#define DARRAY_DATA struct solstice_node*
#include <rsys/dynamic_array.h>
@@ -50,9 +56,9 @@ struct sanim_node;
#define HTABLE_DATA struct solstice_node*
#include <rsys/hash_table.h>
-#define HTABLE_NAME entity
+#define HTABLE_NAME receiver
#define HTABLE_KEY const struct solparser_entity*
-#define HTABLE_DATA struct solstice_node*
+#define HTABLE_DATA struct solstice_receiver
#include <rsys/hash_table.h>
struct solstice {
@@ -64,7 +70,7 @@ struct solstice {
struct htable_material materials;
struct htable_object objects;
struct htable_anchor anchors;
- struct htable_entity receivers;
+ struct htable_receiver receivers;
struct darray_nodes roots;
struct darray_nodes pivots;
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -297,7 +297,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv)
*args = SOLSTICE_ARGS_DEFAULT;
optind = 1;
- while((opt = getopt(argc, argv, "D:hn:o:qr:")) != -1) {
+ while((opt = getopt(argc, argv, "D:hn:o:qR:r:")) != -1) {
switch(opt) {
case 'D':
res = parse_sun_dir_list(optarg, args);
diff --git a/src/solstice_entity.c b/src/solstice_entity.c
@@ -35,6 +35,19 @@ update_instance_transform
return ssol_instance_set_transform(node->instance, transform);
}
+static INLINE int
+srcvl_side_to_ssol_mask(const enum srcvl_side side)
+{
+ int mask = 0;
+ switch(side) {
+ case SRCVL_BACK: mask = SSOL_BACK; break;
+ case SRCVL_FRONT: mask = SSOL_FRONT; break;
+ case SRCVL_FRONT_AND_BACK: mask = SSOL_BACK | SSOL_FRONT; break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ return mask;
+}
+
static struct solstice_node*
create_empty_node
(struct solstice* solstice, const struct solparser_entity* entity)
@@ -150,7 +163,7 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity)
struct solstice_node* node = NULL;
struct solstice_node* tgt = NULL;
struct solstice_node* child = NULL;
- struct solstice_node** pnode = NULL;
+ struct solstice_receiver* rcv = NULL;
size_t i;
res_T res = RES_OK;
ASSERT(solstice && entity);
@@ -174,21 +187,18 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity)
}
/* Setup the entity receiver flags */
- pnode = htable_entity_find(&solstice->receivers, &entity);
- if(pnode) {
- if(node->type != SOLSTICE_NODE_GEOMETRY) {
- fprintf(stderr,
- "The entity `%s' is not a geometry. It cannot be a receiver.\n",
+ rcv = htable_receiver_find(&solstice->receivers, &entity);
+ if(rcv) {
+ const int mask = srcvl_side_to_ssol_mask(rcv->side);
+ ASSERT(rcv->node == NULL); /* Receiver is not attached to a node */
+
+ res = solstice_node_geometry_set_receiver(node, mask);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not define the entity `%s' as a receiver.\n",
str_cget(&entity->name));
- } else {
- *pnode = node;
- res = solstice_node_geometry_set_receiver(node, SSOL_FRONT|SSOL_BACK);
- if(res != RES_OK) {
- fprintf(stderr, "Could not define the entity `%s' as a receiver.\n",
- str_cget(&entity->name));
- goto error;
- }
+ goto error;
}
+ rcv->node = node;
}
/* Setup the entity transform */