commit ae0824fb5ebe7db0870ae64dfad85444ba85dbaf
parent 5159b18b8b5d0ab2edcabed7cfa4bca0c2cd9f13
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 10 Feb 2017 16:43:33 +0100
Add primary area computation.
Diffstat:
6 files changed, 67 insertions(+), 12 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -787,6 +787,16 @@ ssol_estimator_get_failed_count
(const struct ssol_estimator* estimator,
size_t* count);
+SSOL_API res_T
+ssol_estimator_get_sampled_area
+ (const struct ssol_estimator* estimator,
+ double* area);
+
+SSOL_API res_T
+ssol_estimator_get_primary_area
+ (const struct ssol_estimator* estimator,
+ double* area);
+
/*******************************************************************************
* Miscellaneous functions
******************************************************************************/
diff --git a/src/ssol_estimator.c b/src/ssol_estimator.c
@@ -187,6 +187,26 @@ ssol_estimator_get_failed_count
return RES_OK;
}
+res_T
+ssol_estimator_get_sampled_area
+ (const struct ssol_estimator* estimator,
+ double* area)
+{
+ if (!estimator || !area) return RES_BAD_ARG;
+ *area = estimator->sampled_area;
+ return RES_OK;
+}
+
+res_T
+ssol_estimator_get_primary_area
+ (const struct ssol_estimator* estimator,
+ double* area)
+{
+ if (!estimator || !area) return RES_BAD_ARG;
+ *area = estimator->primary_area;
+ return RES_OK;
+}
+
/*******************************************************************************
* Local function
******************************************************************************/
diff --git a/src/ssol_estimator_c.h b/src/ssol_estimator_c.h
@@ -84,6 +84,8 @@ struct ssol_estimator {
struct mc_data missing;
/* 1 global MC per receiver */
struct htable_receiver global_receivers;
+ /* areas */
+ double sampled_area, primary_area;
struct ssol_device* dev;
ref_T ref;
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -44,7 +44,8 @@ scene_release(ref_T* ref)
ASSERT(dev && dev->allocator);
SSOL(scene_clear(scene));
if(scene->scn_rt) S3D(scene_ref_put(scene->scn_rt));
- if(scene->scn_samp) S3D(scene_ref_put(scene->scn_samp));
+ if (scene->scn_samp) S3D(scene_ref_put(scene->scn_samp));
+ if (scene->scn_prim) S3D(scene_ref_put(scene->scn_prim));
if(scene->sun) SSOL(sun_ref_put(scene->sun));
if(scene->atmosphere) SSOL(atmosphere_ref_put(scene->atmosphere));
htable_instance_release(&scene->instances_rt);
@@ -82,6 +83,8 @@ ssol_scene_create
res = s3d_scene_create(dev->s3d, &scene->scn_rt);
if(res != RES_OK) goto error;
res = s3d_scene_create(dev->s3d, &scene->scn_samp);
+ if (res != RES_OK) goto error;
+ res = s3d_scene_create(dev->s3d, &scene->scn_prim);
if(res != RES_OK) goto error;
exit:
@@ -192,6 +195,7 @@ ssol_scene_clear(struct ssol_scene* scene)
htable_instance_clear(&scene->instances_samp);
S3D(scene_clear(scene->scn_rt));
S3D(scene_clear(scene->scn_samp));
+ S3D(scene_clear(scene->scn_prim));
if (scene->sun) ssol_scene_detach_sun(scene, scene->sun);
if (scene->atmosphere)
ssol_scene_detach_atmosphere(scene, scene->atmosphere);
@@ -276,17 +280,20 @@ res_T
scene_create_s3d_views
(struct ssol_scene* scn,
struct s3d_scene_view** out_view_rt,
- struct s3d_scene_view** out_view_samp)
+ struct s3d_scene_view** out_view_samp,
+ struct s3d_scene_view** out_view_prim)
{
struct htable_instance_iterator it, end;
struct s3d_scene_view* view_rt = NULL;
struct s3d_scene_view* view_samp = NULL;
+ struct s3d_scene_view* view_prim = NULL;
int has_sampled = 0;
int has_receiver = 0;
res_T res = RES_OK;
ASSERT(scn && out_view_rt && out_view_samp);
S3D(scene_clear(scn->scn_samp));
+ S3D(scene_clear(scn->scn_prim));
htable_instance_clear(&scn->instances_samp);
htable_instance_begin(&scn->instances_rt, &it);
@@ -311,6 +318,10 @@ scene_create_s3d_views
res = s3d_scene_attach_shape(scn->scn_samp, inst->shape_samp);
if(res != RES_OK) goto error;
+ /* Attach the instantiated s3d raytraced shape to the s3d primary scene */
+ res = s3d_scene_attach_shape(scn->scn_prim, inst->shape_rt);
+ if (res != RES_OK) goto error;
+
/* Register the instantiated s3d sampling shape */
S3D(shape_get_id(inst->shape_samp, &id));
ASSERT(!htable_instance_find(&scn->instances_samp, &id));
@@ -335,10 +346,13 @@ scene_create_s3d_views
if(res != RES_OK) goto error;
res = s3d_scene_view_create(scn->scn_samp, S3D_SAMPLE, &view_samp);
if(res != RES_OK) goto error;
+ res = s3d_scene_view_create(scn->scn_prim, S3D_SAMPLE, &view_prim);
+ if (res != RES_OK) goto error;
exit:
*out_view_rt = view_rt;
*out_view_samp = view_samp;
+ *out_view_prim = view_prim;
return res;
error:
S3D(scene_clear(scn->scn_samp));
@@ -351,6 +365,10 @@ error:
S3D(scene_view_ref_put(view_samp));
view_samp = NULL;
}
+ if (view_prim) {
+ S3D(scene_view_ref_put(view_prim));
+ view_prim = NULL;
+ }
goto exit;
}
diff --git a/src/ssol_scene_c.h b/src/ssol_scene_c.h
@@ -42,6 +42,7 @@ struct ssol_scene {
struct s3d_scene* scn_rt; /* S3D scene to ray trace */
struct s3d_scene* scn_samp; /* S3D scene to sample */
+ struct s3d_scene* scn_prim; /* S3D scene of primary objects */
struct ssol_sun* sun; /* Sun of the scene */
struct ssol_atmosphere* atmosphere; /* Atmosphere of the scene */
@@ -50,13 +51,14 @@ struct ssol_scene {
ref_T ref;
};
-/* Create the Star-3D views of the RT and sampling scenes. Return an error if
- * the sampling scene is empty. */
+/* Create the Star-3D views of the RT, sampling, and primary items scenes.
+ * Return an error if the sampling scene is empty. */
extern LOCAL_SYM res_T
scene_create_s3d_views
(struct ssol_scene* scn,
struct s3d_scene_view** view_rt,
- struct s3d_scene_view** view_samp);
+ struct s3d_scene_view** view_samp,
+ struct s3d_scene_view** out_view_prim);
#endif /* SSOL_SCENE_C_H */
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -59,11 +59,9 @@ struct point {
enum ssol_side_flag side;
};
-
#define POINT_NULL__ { NULL, NULL, S3D_PRIMITIVE_NULL__, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0}, 0, 0, 0, 0, SSOL_FRONT }
static const struct point POINT_NULL = POINT_NULL__;
-
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -329,6 +327,7 @@ ssol_solve
struct htable_receiver_iterator it, end;
struct s3d_scene_view* view_rt = NULL;
struct s3d_scene_view* view_samp = NULL;
+ struct s3d_scene_view* view_prim = NULL;
struct ranst_sun_dir* ran_sun_dir = NULL;
struct ranst_sun_wl* ran_sun_wl = NULL;
struct ssf_bsdf** bsdfs = NULL;
@@ -338,7 +337,7 @@ ssol_solve
struct mc_data* mc_missings = NULL;
struct htable_receiver* mc_rcvs = NULL;
struct ssol_estimator* estimator = NULL;
- float sampled_area = 0;
+ float area;
int nthreads = 0;
int nrealisations = 0;
int i = 0;
@@ -364,15 +363,18 @@ ssol_solve
if(res != RES_OK) goto error;
/* Create data structures shared by all threads */
- res = scene_create_s3d_views(scn, &view_rt, &view_samp);
+ res = scene_create_s3d_views(scn, &view_rt, &view_samp, &view_prim);
if(res != RES_OK) goto error;
res = sun_create_distributions(scn->sun, &ran_sun_dir, &ran_sun_wl);
if(res != RES_OK) goto error;
- S3D(scene_view_compute_area(view_samp, &sampled_area));
/* Create the estimator */
res = estimator_create(scn->dev, scn, &estimator);
if (res != RES_OK) goto error;
+ S3D(scene_view_compute_area(view_samp, &area));
+ estimator->sampled_area = area;
+ S3D(scene_view_compute_area(view_prim, &area));
+ estimator->primary_area = area;
/* Create a RNG proxy from the submitted RNG state */
res = ssp_rng_proxy_create_from_rng
@@ -438,7 +440,7 @@ ssol_solve
receiver = mc_rcvs + ithread;
/* Find a new starting point of the radiative random walk */
- is_lit = point_init(&pt, scn, sampled_area, view_samp, view_rt,
+ is_lit = point_init(&pt, scn, estimator->sampled_area, view_samp, view_rt,
ran_sun_dir, ran_sun_wl, rng);
if(!is_lit) { /* The starting point is not lit */
@@ -582,7 +584,8 @@ ssol_solve
exit:
if(view_rt) S3D(scene_view_ref_put(view_rt));
- if(view_samp) S3D(scene_view_ref_put(view_samp));
+ if (view_samp) S3D(scene_view_ref_put(view_samp));
+ if (view_prim) S3D(scene_view_ref_put(view_prim));
if(ran_sun_dir) ranst_sun_dir_ref_put(ran_sun_dir);
if(ran_sun_wl) ranst_sun_wl_ref_put(ran_sun_wl);
if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy));