commit 220579249d865e0dedbc6d87750b72697b7c5c46
parent 2a31eb851676ce76c2a635b6d55aa57533b4e751
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 11 Jan 2017 16:27:05 +0100
First draft of the receiver management
Diffstat:
7 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/src/solstice.c b/src/solstice.c
@@ -248,6 +248,87 @@ error:
goto exit;
}
+static res_T
+parse_receiver_file(struct solstice* solstice, const char* filename)
+{
+ char line[256];
+ FILE* file = NULL;
+ unsigned long iline = 0;
+ res_T res = RES_OK;
+ ASSERT(solstice && filename);
+
+ 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)) {
+ 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;
+ }
+
+ /* 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;
+ }
+ 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';
+
+ /* 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);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "%s:%lu could not register the entity `%s' as a receiver.\n",
+ filename, iline, str);
+ goto error;
+ }
+ }
+
+exit:
+ if(file) fclose(file);
+ return res;
+error:
+ goto exit;
+}
+
/*******************************************************************************
* Solstice local functions
******************************************************************************/
@@ -263,6 +344,8 @@ solstice_init
memset(solstice, 0, sizeof(struct solstice));
htable_material_init(allocator, &solstice->materials);
htable_object_init(allocator, &solstice->objects);
+ htable_anchor_init(allocator, &solstice->anchors);
+ htable_entity_init(allocator, &solstice->receivers);
darray_nodes_init(allocator, &solstice->roots);
darray_nodes_init(allocator, &solstice->pivots);
darray_double_init(allocator, &solstice->sun_dirs);
@@ -336,6 +419,8 @@ solstice_release(struct solstice* solstice)
if(solstice->output && solstice->output != stdout) fclose(solstice->output);
htable_material_release(&solstice->materials);
htable_object_release(&solstice->objects);
+ htable_anchor_release(&solstice->anchors);
+ htable_entity_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
@@ -50,6 +50,11 @@ struct sanim_node;
#define HTABLE_DATA struct solstice_node*
#include <rsys/hash_table.h>
+#define HTABLE_NAME entity
+#define HTABLE_KEY const struct solparser_entity*
+#define HTABLE_DATA struct solstice_node*
+#include <rsys/hash_table.h>
+
struct solstice {
struct ssol_device* ssol;
struct ssol_scene* scene;
@@ -59,6 +64,7 @@ struct solstice {
struct htable_material materials;
struct htable_object objects;
struct htable_anchor anchors;
+ struct htable_entity receivers;
struct darray_nodes roots;
struct darray_nodes pivots;
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -298,6 +298,7 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv)
break;
case 'o': args->output_filename = optarg; break;
case 'q': args->quiet = 1; break;
+ case 'R': args->receivers_filename = optarg; break;
case 'r': res = parse_rendering_options(optarg, args); break;
default: res = RES_BAD_ARG; break;
}
diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in
@@ -25,8 +25,9 @@ struct solstice_args_spherical {
struct solstice_args {
const char* output_filename;
- unsigned long nrealisations; /* #realisations */
const char* input_filename; /* May be NULL <=> read data from stdin */
+ const char* receivers_filename;
+ unsigned long nrealisations; /* #realisations */
/* List of sun directions */
struct solstice_args_spherical* sun_dirs;
@@ -54,8 +55,9 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__;
#define SOLSTICE_ARGS_DEFAULT__ { \
NULL, /* output_filename */ \
- @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@, \
NULL, /* input_filename */ \
+ NULL, /* receivers_filename */ \
+ @SOLSTICE_ARGS_DEFAULT_NREALISATIONS@, \
\
NULL, /* sun_dirs */ \
0, /* # nsun_dirs */ \
diff --git a/src/solstice_c.h b/src/solstice_c.h
@@ -97,6 +97,11 @@ extern LOCAL_SYM void
solstice_node_ref_put
(struct solstice_node* node);
+extern LOCAL_SYM res_T
+solstice_node_geometry_set_receiver
+ (struct solstice_node* node,
+ const int mask); /* Combination of ssol_side_flag */
+
extern LOCAL_SYM void
solstice_node_target_get_tracking
(const struct solstice_node* node,
diff --git a/src/solstice_entity.c b/src/solstice_entity.c
@@ -150,6 +150,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;
size_t i;
res_T res = RES_OK;
ASSERT(solstice && entity);
@@ -172,6 +173,24 @@ create_node(struct solstice* solstice, const struct solparser_entity* entity)
goto error;
}
+ /* 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",
+ 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;
+ }
+ }
+ }
+
/* Setup the entity transform */
solstice_node_set_translation(node, entity->translation);
solstice_node_set_rotations(node, entity->rotation);
diff --git a/src/solstice_node.c b/src/solstice_node.c
@@ -221,6 +221,13 @@ solstice_node_ref_put(struct solstice_node* node)
ref_put(&node->ref, node_release);
}
+res_T
+solstice_node_geometry_set_receiver(struct solstice_node* node, const int mask)
+{
+ ASSERT(node && node->type == SOLSTICE_NODE_GEOMETRY);
+ return ssol_instance_set_receiver(node->instance, mask);
+}
+
void
solstice_node_target_get_tracking
(const struct solstice_node* node,