commit 9ccba0ca6e9ad28a2fec5b8dc4a1a5c3132cf5da
parent 94a8908662ea1b0c1faf62503db20f68cf0bb71f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 20 Mar 2017 11:06:41 +0100
Provide optional arguments to the dump radiative path option -p
Optionally configure the length of the path segment starting from the
sun or going to the infinity.
Diffstat:
7 files changed, 181 insertions(+), 79 deletions(-)
diff --git a/doc/cli b/doc/cli
@@ -6,7 +6,7 @@ solstice
-h # Short help and exit
-g <dump> # Switch in dump geometry
-o OUTPUT # defaulting to stdout if not defined
- -p # Switch in dump paths mode
+ -p [ <dump-radiative-path> ] # Switch in dump radiative paths mode
-q # don't print a message if no INPUT is submitted
-n INTEGER # Realisations count
-r <rendering> # Switch in rendering mode
@@ -43,6 +43,18 @@ solstice -g format=obj:split-group=1
<dump> ::=
format=<dump-format>[:split=<split-mode>]
+<dump-radiative-path> ::=
+ <dump-path-option>[:<dump-path-option> ... ]
+
+<dump-path-option> ::=
+ <sun-ray-len> | <inf-ray-len>
+
+<sun-ray-len> ::=
+ srlen=REAL
+
+<inf-ray-len> ::= # Length of the rays going to infinite
+ irlen=REAL
+
<dump-format> ::=
obj
diff --git a/src/solstice.c b/src/solstice.c
@@ -598,7 +598,7 @@ solstice_init
goto error;
}
- solstice->nrealisations = args->nrealisations;
+ solstice->nexperiments = args->nexperiments;
solstice->output_hits = args->output_hits;
solstice->dump_format = args->dump_format;
solstice->dump_split_mode = args->dump_split_mode;
diff --git a/src/solstice.h b/src/solstice.h
@@ -97,7 +97,7 @@ struct solstice {
struct darray_double sun_dirs; /* List of double3 */
struct darray_double sun_angles;
- size_t nrealisations; /* # realisations */
+ size_t nexperiments; /* # MC experiments */
FILE* output; /* Output stream */
int output_hits; /* Output per receiver hits */
int dump_paths;
diff --git a/src/solstice_args.c b/src/solstice_args.c
@@ -51,8 +51,8 @@ print_help(const char* program)
printf(
" -h display this help and exit.\n");
printf(
-" -n REALISATIONS number of realisations. Default is %lu.\n",
- SOLSTICE_ARGS_DEFAULT.nrealisations);
+" -n EXPERIMENTS number of Monte Carlo experiments. Default is %lu.\n",
+ SOLSTICE_ARGS_DEFAULT.nexperiments);
printf(
" -g <dump> switch in dump geometry mode and configure it.\n");
printf(
@@ -97,6 +97,37 @@ parse_fov(const char* str, double* out_fov)
return RES_OK;
}
+static res_T
+parse_multiple_options
+ (const char* str,
+ struct solstice_args* args,
+ res_T (*parse_option)(const char* str, struct solstice_args* args))
+{
+ char buf[512];
+ char* tk;
+ char* ctx;
+ res_T res = RES_OK;
+ ASSERT(args && str);
+
+ if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) {
+ fprintf(stderr, "Could not duplicate the option string `%s'.\n", str);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ strncpy(buf, str, sizeof(buf));
+
+ tk = strtok_r(buf, ":", &ctx);
+ do {
+ res = parse_option(tk, args);
+ if(res != RES_OK) goto error;
+ tk = strtok_r(NULL, ":", &ctx);
+ } while(tk);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
static res_T
parse_sun_dir_list(const char* str, struct solstice_args* args)
@@ -294,41 +325,6 @@ parse_rendering_option(const char* str, struct solstice_args* args)
res = RES_BAD_ARG;
goto error;
}
- args->rendering = 1;
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-parse_rendering_options(const char* str, struct solstice_args* args)
-{
- char buf[512];
- char* tk;
- char* ctx;
- res_T res = RES_OK;
- ASSERT(args && str);
-
- /* Setup default values of the rendering parameters */
- args->camera = SOLSTICE_ARGS_DEFAULT.camera;
- args->img = SOLSTICE_ARGS_DEFAULT.img;
-
- if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) {
- fprintf(stderr,
- "Could not duplicate the rendering options string `%s'.\n", str);
- res = RES_MEM_ERR;
- goto error;
- }
- strncpy(buf, str, sizeof(buf));
-
- tk = strtok_r(buf, ":", &ctx);
- do {
- res = parse_rendering_option(tk, args);
- if(res != RES_OK) goto error;
- tk = strtok_r(NULL, ":", &ctx);
- } while(tk);
exit:
return res;
@@ -417,12 +413,6 @@ parse_dump_option(const char* str, struct solstice_args* args)
}
if(res != RES_OK) goto error;
- if(args->dump_format == SOLSTICE_ARGS_DUMP_NONE) {
- fprintf(stderr, "No dump format is defined.\n");
- res = RES_BAD_ARG;
- goto error;
- }
-
exit:
return res;
error:
@@ -430,27 +420,52 @@ error:
}
static res_T
-parse_dump_options(const char* str, struct solstice_args* args)
+parse_dump_paths_option(const char* str, struct solstice_args* args)
{
- char buf[512];
- char* tk;
+ char buf[128];
+ char* key;
+ char* val;
char* ctx;
res_T res = RES_OK;
- ASSERT(args && str);
- (void)str, (void)args;
+ ASSERT(str && args);
if(strlen(str) >= sizeof(buf) - 1/*NULL char*/) {
fprintf(stderr,
- "Could not duplicate the dump geometry options string `%s'.\n", str);
+"Could not duplicate the dump radiative paths option string `%s'.\n", str);
res = RES_MEM_ERR;
goto error;
}
+
strncpy(buf, str, sizeof(buf));
- tk = strtok_r(buf, ":", &ctx);
- do {
- res = parse_dump_option(tk, args);
- tk = strtok_r(NULL, ":", &ctx);
- } while(tk);
+
+ key = strtok_r(buf, "=", &ctx);
+ val = strtok_r(NULL, "", &ctx);
+
+ if(!val) {
+ fprintf(stderr,
+ "Missing a value to the dump radiative paths option `%s'.\n", key);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ if(!strcmp(key, "irlen")) {
+ res = cstr_to_double(val, &args->infinite_ray_length);
+ if(res != RES_OK) {
+ fprintf(stderr, "Invalid infinite ray length `%s'.\n", val);
+ goto error;
+ }
+ } else if(!strcmp(key, "srlen")) {
+ res = cstr_to_double(val, &args->sun_ray_length);
+ if(res != RES_OK) {
+ fprintf(stderr, "Invalid sun ray length `%s'.\n", val);
+ goto error;
+ }
+ } else {
+ fprintf(stderr, "Invalid dump radiative paths option `%s'.\n", val);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(res != RES_OK) goto error;
exit:
return res;
@@ -470,33 +485,57 @@ solstice_args_init(struct solstice_args* args, const int argc, char** argv)
*args = SOLSTICE_ARGS_DEFAULT;
+ opterr = 0;
optind = 0;
- while((opt = getopt(argc, argv, "D:fg:Hhn:o:pqR:r:t:")) != -1) {
+ while((opt = getopt(argc, argv, "D:fg:Hhn:o:p:qR:r:t:")) != -1) {
switch(opt) {
- case 'D':
+ case 'D': /* Sun directions */
res = parse_sun_dir_list(optarg, args);
break;
case 'f': args->force_overwriting = 1; break;
case 'H': args->output_hits = 1; break;
- case 'h':
+ case 'h': /* Print short help and exit */
print_help(argv[0]);
solstice_args_release(args);
args->quit = 1;
goto exit;
- case 'n':
- res = cstr_to_ulong(optarg, &args->nrealisations);
- if(res == RES_OK && !args->nrealisations) res = RES_BAD_ARG;
+ case 'n': /* Define the number of experiments */
+ res = cstr_to_ulong(optarg, &args->nexperiments);
+ if(res == RES_OK && !args->nexperiments) res = RES_BAD_ARG;
+ break;
+ case 'g': /* Switch in dump geometry mode and configure it */
+ res = parse_multiple_options(optarg, args, parse_dump_option);
+ if(res == RES_OK && args->dump_format == SOLSTICE_ARGS_DUMP_NONE) {
+ fprintf(stderr, "%s: missing a dump format -- `%s'.\n",
+ argv[0], optarg);
+ res = RES_BAD_ARG;
+ }
break;
- case 'g': res = parse_dump_options(optarg, args); break;
case 'o': args->output_filename = optarg; break;
- case 'p': args->dump_paths = 1; break;
+ case 'p': /* Switch in dump radiative paths mode and configure it */
+ args->dump_paths = 1;
+ res = parse_multiple_options(optarg, args, parse_dump_paths_option);
+ break;
case 'q': args->quiet = 1; break;
case 'R': args->receivers_filename = optarg; break;
- case 'r': res = parse_rendering_options(optarg, args); break;
- case 't':
+ case 'r': /* Switch in rendering mode and configure it */
+ args->rendering = 1;
+ res = parse_multiple_options(optarg, args, parse_rendering_option);
+ break;
+ case 't': /* Submit an hint on the number of threads to use */
res = cstr_to_uint(optarg, &args->nthreads);
if(res == RES_OK && !args->nthreads) res = RES_BAD_ARG;
break;
+ case '?': /* Option with optionnal arguments */
+ switch(optopt) {
+ case 'p': args->dump_paths = 1; break;
+ default:
+ fprintf(stderr, "%s: option requires an argument -- '%c'\n",
+ argv[0], optopt);
+ res = RES_BAD_ARG;
+ break;
+ }
+ break;
default: res = RES_BAD_ARG; break;
}
if(res != RES_OK) {
diff --git a/src/solstice_args.h.in b/src/solstice_args.h.in
@@ -44,7 +44,7 @@ struct solstice_args {
const char* output_filename;
const char* input_filename; /* May be NULL <=> read data from stdin */
const char* receivers_filename;
- unsigned long nrealisations; /* #realisations */
+ unsigned long nexperiments; /* #experiments */
unsigned nthreads; /* #threads */
/* List of sun directions */
@@ -67,11 +67,16 @@ struct solstice_args {
enum solstice_args_render_mode render_mode;
+ /* Dump geometry mode */
enum solstice_args_dump_format dump_format;
enum solstice_args_dump_split_mode dump_split_mode;
+ /* Dump radiative paths options. */
+ double sun_ray_length; /* Length of the sun rays. */
+ double infinite_ray_length; /* Length of the rays going to infinity. */
+
int force_overwriting;
- int dump_paths;
+ int dump_paths; /* Dump radiative paths */
int rendering;
int output_hits; /* Output the per receiver hits */
int quiet;
@@ -110,6 +115,9 @@ static const struct solstice_args SOLSTICE_ARGS_NULL = SOLSTICE_ARGS_NULL__;
SOLSTICE_ARGS_DUMP_NONE, /* Dump format */ \
SOLSTICE_ARGS_DUMP_SPLIT_NONE, /* Dump split mode */ \
\
+ -1, /* Sun ray length */ \
+ -1, /* Infinite ray length */ \
+ \
0, /* Force overwriting */ \
0, /* Dump radiative paths */ \
0, /* Rendering */ \
diff --git a/src/solstice_solve.c b/src/solstice_solve.c
@@ -378,8 +378,9 @@ solstice_solve(struct solstice* solstice)
}
}
- res = ssol_solve(solstice->scene, rng, solstice->nrealisations,
- solstice->dump_paths, bin_stream, &estimator);
+ res = ssol_solve(solstice->scene, rng, solstice->nexperiments,
+ solstice->dump_paths ? &SSOL_PATH_TRACKER_DEFAULT : NULL, bin_stream,
+ &estimator);
if(res != RES_OK) {
fprintf(stderr, "Error in integrating the solar flux.\n");
goto error;
diff --git a/src/test_solstice_args.c b/src/test_solstice_args.c
@@ -83,7 +83,7 @@ test_rendering(void)
cmd = cmd_create(0, "test", "-r", "img=1280x720", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
CHECK(args.rendering, 1);
- CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations);
+ CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments);
CHECK(d3_eq(args.camera.pos, SOLSTICE_ARGS_DEFAULT.camera.pos), 1);
CHECK(d3_eq(args.camera.tgt, SOLSTICE_ARGS_DEFAULT.camera.tgt), 1);
CHECK(d3_eq(args.camera.up, SOLSTICE_ARGS_DEFAULT.camera.up), 1);
@@ -100,7 +100,7 @@ test_rendering(void)
cmd = cmd_create(0, "test", "-q", "-r", "img=640x480:fov=70:pos=1,2,3", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
CHECK(args.rendering, 1);
- CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations);
+ CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments);
CHECK(d3_eq(args.camera.pos, d3(tmp, 1, 2, 3)), 1);
CHECK(d3_eq(args.camera.tgt, SOLSTICE_ARGS_DEFAULT.camera.tgt), 1);
CHECK(d3_eq(args.camera.up, SOLSTICE_ARGS_DEFAULT.camera.up), 1);
@@ -116,7 +116,7 @@ test_rendering(void)
cmd = cmd_create(0, "test", "-r", "up=0,0,1:tgt=0,-10,0:rmode=draft", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
- CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations);
+ CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments);
CHECK(d3_eq(args.camera.pos, SOLSTICE_ARGS_DEFAULT.camera.pos), 1);
CHECK(d3_eq(args.camera.tgt, d3(tmp, 0,-10, 0)), 1);
CHECK(d3_eq(args.camera.up, d3(tmp, 0, 0, 1)), 1);
@@ -132,7 +132,7 @@ test_rendering(void)
cmd = cmd_create(0, "test", "-r", "up=0,0,1:rmode=pt:spp=4", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
- CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations);
+ CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments);
CHECK(d3_eq(args.camera.up, d3(tmp, 0, 0, 1)), 1);
CHECK(args.img.width, SOLSTICE_ARGS_DEFAULT.img.width);
CHECK(args.img.height, SOLSTICE_ARGS_DEFAULT.img.height);
@@ -317,19 +317,19 @@ test_realisations_count(void)
cmd = cmd_create(0, "test", "-D", "0,90", "-n", "1", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
- CHECK(args.nrealisations, 1);
+ CHECK(args.nexperiments, 1);
solstice_args_release(&args);
cmd_delete(cmd);
cmd = cmd_create(0, "test", "-D", "0,90", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
- CHECK(args.nrealisations, SOLSTICE_ARGS_DEFAULT.nrealisations);
+ CHECK(args.nexperiments, SOLSTICE_ARGS_DEFAULT.nexperiments);
solstice_args_release(&args);
cmd_delete(cmd);
cmd = cmd_create(0, "test", "-D", "0,90", "-n", "123", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
- CHECK(args.nrealisations, 123);
+ CHECK(args.nexperiments, 123);
solstice_args_release(&args);
cmd_delete(cmd);
@@ -582,10 +582,52 @@ test_dump_paths(void)
cmd = cmd_create(0, "test", "-D", "0,90", "-p", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
CHECK(args.dump_paths, 1);
+ CHECK(args.infinite_ray_length, SOLSTICE_ARGS_DEFAULT.infinite_ray_length);
+ CHECK(args.sun_ray_length, SOLSTICE_ARGS_DEFAULT.sun_ray_length);
solstice_args_release(&args);
cmd_delete(cmd);
- cmd = cmd_create(0, "test", "-p", NULL);
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=3.14:srlen=1.23", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
+ CHECK(args.dump_paths, 1);
+ CHECK(eq_eps(args.infinite_ray_length, 3.14, 1.e-6), 1);
+ CHECK(eq_eps(args.sun_ray_length, 1.23, 1.e-6), 1);
+ solstice_args_release(&args);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=0", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
+ CHECK(args.dump_paths, 1);
+ CHECK(eq_eps(args.infinite_ray_length, 0, 1.e-6), 1);
+ CHECK(args.sun_ray_length, SOLSTICE_ARGS_DEFAULT.sun_ray_length);
+ solstice_args_release(&args);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=-4", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_OK);
+ CHECK(args.dump_paths, 1);
+ CHECK(args.infinite_ray_length, SOLSTICE_ARGS_DEFAULT.infinite_ray_length);
+ CHECK(eq_eps(args.sun_ray_length, -4, 1.e-6), 1);
+ solstice_args_release(&args);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen=", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "srlen=abcd", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "irlen", NULL);
+ CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG);
+ cmd_delete(cmd);
+
+ cmd = cmd_create(0, "test", "-D", "0,90", "-p", "=abcd", NULL);
CHECK(solstice_args_init(&args, cmd_size(cmd), cmd), RES_BAD_ARG);
cmd_delete(cmd);
}