commit 84540b42fb0a9d0106fe58277f70665db3fc6382
parent 372a1886184ad1a96aed51966e8c6030130a3390
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 15 Apr 2016 16:15:12 +0200
Adapt to the new StarMC API
Diffstat:
3 files changed, 52 insertions(+), 67 deletions(-)
diff --git a/src/s4vs.c b/src/s4vs.c
@@ -75,8 +75,6 @@ compute_4v_s(struct s3d_scene* scene, const size_t max_steps, const double ks)
/* Initialize context for MC computation */
ctx.scene = scene;
- ctx.nfailures = 0;
- ctx.error = 0;
ctx.ks = ks;
/* Setup Star-MC */
@@ -84,28 +82,30 @@ compute_4v_s(struct s3d_scene* scene, const size_t max_steps, const double ks)
integrator.integrand = &s4vs_realization; /* Realization function */
integrator.type = &smc_double; /* Type of the Monte Carlo weight */
integrator.max_steps = max_steps; /* Realization count */
+ integrator.max_failures = max_steps / 1000; /* cancel if 0.1% of the realization fail */
/* Solve */
time_current(&begin);
SMC(solve(smc, &integrator, &ctx, &estimator));
time_current(&end);
-
- if(ctx.error) {
- fprintf(stderr,
- "Too many failures. The scene might not match the prerequisites:\n"
- "it must be closed and its normals must point *into* the volume.\n");
- goto error;
- }
-
time_sub(&elapsed, &end, &begin);
time_dump(&elapsed, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf));
/* Print the simulation results */
SMC(estimator_get_status(estimator, &estimator_status));
+
+ if(estimator_status.NF >= integrator.max_failures) {
+ fprintf(stderr,
+ "Too many failures (%lu). The scene might not match the prerequisites:\n"
+ "it must be closed and its normals must point *into* the volume.\n",
+ (unsigned long)estimator_status.NF);
+ goto error;
+ }
length = SMC_DOUBLE(estimator_status.E);
sig_length = SMC_DOUBLE(estimator_status.SE);
- printf("4V/S = %g ~ %g +/- %g\n# failures: %d/%lu\nElapsed time: %s\n",
- reference, length, sig_length, ctx.nfailures, max_steps, buf);
+ printf("4V/S = %g ~ %g +/- %g\n# failures: %lu/%lu\nElapsed time: %s\n",
+ reference, length, sig_length,
+ (unsigned long)estimator_status.NF, (unsigned long)max_steps, buf);
exit:
/* Clean-up data */
diff --git a/src/s4vs_realization.c b/src/s4vs_realization.c
@@ -34,10 +34,7 @@
#include "s4vs_realization.h"
-/* Maximum number of failures before an error occurs */
-#define MAX_FAILURES 10
-
-void
+res_T
s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
{
struct s4vs_context* ctx = (struct s4vs_context*)context;
@@ -47,39 +44,36 @@ s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
struct s3d_hit hit;
double length = 0;
double lambda = 0;
- int nfailures = 0;
-
- do { /* Sample the scene surface to define the random walk starting point */
- float u, v, w;
-
- /* Sample a surface location, i.e. primitive ID and parametric coordinates */
- u = ssp_rng_canonical_float(rng);
- v = ssp_rng_canonical_float(rng);
- w = ssp_rng_canonical_float(rng);
- S3D(scene_sample(ctx->scene, u, v, w, &prim, st));
-
- /* retrieve the sampled geometric normal and position */
- S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib));
- f3_normalize(normal, attrib.value);
- S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attrib));
- f3_set(pos, attrib.value);
-
- /* Cosine weighted sampling of the hemisphere around the sampled normal */
- ssp_ran_hemisphere_cos(rng, normal, dir);
-
- /* Find the 1st hit from the sampled location along the sampled direction */
- range[0] = 1.e-6f;
- range[1] = FLT_MAX;
- do {
- S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit));
- range[0] += 1.e-6f;
- } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim)); /* Handle self-hit */
+ float u, v, w;
- /* No intersection <=> numerical imprecision or geometry leakage */
- } while(S3D_HIT_NONE(&hit) && ++nfailures < MAX_FAILURES);
+ /* Sample the scene surface to define the random walk starting point */
+
+ /* Sample a surface location, i.e. primitive ID and parametric coordinates */
+ u = ssp_rng_canonical_float(rng);
+ v = ssp_rng_canonical_float(rng);
+ w = ssp_rng_canonical_float(rng);
+ S3D(scene_sample(ctx->scene, u, v, w, &prim, st));
+
+ /* retrieve the sampled geometric normal and position */
+ S3D(primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, st, &attrib));
+ f3_normalize(normal, attrib.value);
+ S3D(primitive_get_attrib(&prim, S3D_POSITION, st, &attrib));
+ f3_set(pos, attrib.value);
- /* Too many ray-tracing failures => the geometry is inconsistent */
- if(nfailures >= MAX_FAILURES) goto error;
+ /* Cosine weighted sampling of the hemisphere around the sampled normal */
+ ssp_ran_hemisphere_cos(rng, normal, dir);
+
+ /* Find the 1st hit from the sampled location along the sampled direction */
+ range[0] = 1.e-6f;
+ range[1] = FLT_MAX;
+ do {
+ S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit));
+ range[0] += 1.e-6f;
+ } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim)); /* Handle self-hit */
+
+ /* No intersection <=> numerical imprecision or geometry leakage */
+ if(S3D_HIT_NONE(&hit))
+ return RES_UNKNOWN_ERR; /* failed realization */
/* Here the starting point and a propagation direction have been sampled */
/* and we have determined the distance of the geometry in this direction */
@@ -98,27 +92,18 @@ s4vs_realization(void* out_length, struct ssp_rng* rng, void* context)
length += lambda;
f3_add(pos, pos, f3_mulf(dir, dir, (float)lambda));
- do {
/* sample a new direction */
- ssp_ran_sphere_uniform(rng, dir);
- range[0] = 0;
- /* find the first intersection with the geometry */
- /* to refresh the geometry's distance */
- S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit));
+ ssp_ran_sphere_uniform(rng, dir);
+ range[0] = 0;
+ /* find the first intersection with the geometry */
+ /* to refresh the geometry's distance */
+ S3D(scene_trace_ray(ctx->scene, pos, dir, range, &hit));
/* No intersection <=> numerical imprecision or geometry leakage */
- } while(S3D_HIT_NONE(&hit) && ++nfailures < MAX_FAILURES);
-
- /* Too many ray-tracing failures => the geometry is inconsistent */
- if(nfailures >= MAX_FAILURES) goto error;
+ if(S3D_HIT_NONE(&hit))
+ return RES_UNKNOWN_ERR; /* failed realization */
}
-exit:
- ATOMIC_ADD(&ctx->nfailures, nfailures); /* Register the number of failures */
SMC_DOUBLE(out_length) = length;
- return;
-error:
- ctx->error = 1; /* Notify that an error occurs */
- length = 0; /* Reset the path length */
- goto exit;
+ return RES_OK;
}
diff --git a/src/s4vs_realization.h b/src/s4vs_realization.h
@@ -29,6 +29,8 @@
#ifndef S4V_S_REALIZATION_H
#define S4V_S_REALIZATION_H
+#include <rsys/rsys.h>
+
/* forward definition */
struct ssp_rng;
@@ -36,13 +38,11 @@ struct s4vs_context {
struct s3d_sampler* sampler;
struct s3d_scene* scene;
double ks;
- int nfailures;
- int error;
};
/*******************************************************************************
* MC realization function
******************************************************************************/
-extern void s4vs_realization(void* length, struct ssp_rng* rng, void* context);
+extern res_T s4vs_realization(void* length, struct ssp_rng* rng, void* context);
#endif /* REALIZATION_H */