commit 7a9bf54c0abba559de8864d3900411146e766cf0
parent e1009f719d4b84131e95b5b2ac0e07cb0ac8b09f
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 19 Oct 2016 17:17:16 +0200
Major refactoring to handle 2D geometries
Diffstat:
15 files changed, 569 insertions(+), 474 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -88,8 +88,8 @@ if(NOT NO_TEST)
new_test(test_sgf_cube)
new_test(test_sgf_device)
new_test(test_sgf_estimator)
- new_test(test_sgf_scene3d)
- # new_test(test_sgf_square)
+ new_test(test_sgf_scene)
+ new_test(test_sgf_square)
new_test(test_sgf_tetrahedron)
rcmake_copy_runtime_libraries(test_sgf_tetrahedron)
diff --git a/src/sgf.h b/src/sgf.h
@@ -39,50 +39,11 @@
/* Forward declaration of external types */
struct logger;
struct mem_allocator;
-struct s3d_scene;
struct ssp_rng;
-enum sgf_material_property {
- SGF_MATERIAL_EMISSIVITY,
- SGF_MATERIAL_REFLECTIVITY,
- SGF_MATERIAL_SPECULARITY,
- SGF_MEDIUM_ABSORPTION
-};
-
-enum sgf_dimensionality {
- SGF_2D,
- SGF_3D
-};
-
-/* Descriptor of the scene */
struct sgf_scene_desc {
- /* Retrieve material properties from client side memory */
- double (*get_material_property)
- (void* material, /* Client side material */
- const enum sgf_material_property prop,
- const size_t primitive_id, /* Triangle identifier */
- const size_t spectral_band_id); /* Spectral band identifier */
- void* material; /* Client side material */
- size_t spectral_bands_count; /* Total number of spectral bands */
-
- /* Define whether or not a medium is defined onto the scene */
- int has_medium;
-
- /* Star-3D encapsulation of the geometry */
- enum sgf_dimensionality dimensionality;
- union {
- struct s3d_scene* scn3d;
- struct s2d_scene* scn2d;
- } geometry;
-};
-
-static const struct sgf_scene_desc SGF_SCENE_DESC_NULL = {
- NULL, NULL, 0, 0, SGF_3D, { NULL }
-};
-
-struct sgf_scene3d_desc {
- void (*get_indices)(const unsigned itri, unsigned ids[3], void* ctx);
- void (*get_position)(const unsigned ivert, float pos[3], void* ctx);
+ void (*get_indices)(const unsigned itri, unsigned ids[], void* ctx);
+ void (*get_position)(const unsigned ivert, float pos[], void* ctx);
double (*get_emissivity)
(const unsigned itri, const unsigned iband, void* ctx);
@@ -98,9 +59,9 @@ struct sgf_scene3d_desc {
unsigned nverts; /* #vertices */
unsigned nbands; /* #spectral bands */
};
-#define SGF_SCENE3D_DESC_NULL__ { 0 }
-static const struct sgf_scene3d_desc SGF_SCENE3D_DESC_NULL =
- SGF_SCENE3D_DESC_NULL__;
+#define SGF_SCENE_DESC_NULL__ { 0 }
+static const struct sgf_scene_desc SGF_SCENE_DESC_NULL =
+ SGF_SCENE_DESC_NULL__;
/* Estimated Gebart Factor between 2 faces */
struct sgf_status {
@@ -139,7 +100,7 @@ sgf_device_ref_put
* Scene API
******************************************************************************/
SGF_API res_T
-sgf_scene3d_create
+sgf_scene_create
(struct sgf_device* dev,
struct sgf_scene** scn);
@@ -152,9 +113,14 @@ sgf_scene_ref_put
(struct sgf_scene* scn);
SGF_API res_T
-sgf_scene3d_setup
+sgf_scene_setup_3d
+ (struct sgf_scene* scn,
+ const struct sgf_scene_desc* desc);
+
+SGF_API res_T
+sgf_scene_setup_2d
(struct sgf_scene* scn,
- const struct sgf_scene3d_desc* desc);
+ const struct sgf_scene_desc* desc);
SGF_API res_T
sgf_scene_primitives_count
diff --git a/src/sgf_device.c b/src/sgf_device.c
@@ -19,6 +19,7 @@
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
+#include <star/s2d.h>
#include <star/s3d.h>
/*******************************************************************************
@@ -30,6 +31,7 @@ device_release(ref_T* ref)
struct sgf_device* dev;
ASSERT(ref);
dev = CONTAINER_OF(ref, struct sgf_device, ref);
+ if(dev->s2d) S2D(device_ref_put(dev->s2d));
if(dev->s3d) S3D(device_ref_put(dev->s3d));
MEM_RM(dev->allocator, dev);
}
@@ -76,6 +78,11 @@ sgf_device_create
log_error(dev, "%s: couldn't create the Star-3D device.\n", FUNC_NAME);
goto error;
}
+ res = s2d_device_create(NULL, dev->allocator, 0, &dev->s2d);
+ if(res != RES_OK) {
+ log_error(dev, "%s: couldn't create the Star-2D device.\n", FUNC_NAME);
+ goto error;
+ }
exit:
if(out_dev) *out_dev = dev;
diff --git a/src/sgf_device_c.h b/src/sgf_device_c.h
@@ -20,11 +20,13 @@
struct logger;
struct mem_allocator;
+struct s2d_device;
struct s3d_device;
struct sgf_device {
int verbose;
struct logger* logger;
+ struct s2d_device* s2d;
struct s3d_device* s3d;
struct mem_allocator* allocator;
diff --git a/src/sgf_estimator.c b/src/sgf_estimator.c
@@ -33,8 +33,8 @@
#include <rsys/dynamic_array.h>
/* Generate the 2D realisation function */
-/*#define SGF_DIMENSIONALITY 2
-#include "sgf_realisation.h"*/
+#define SGF_DIMENSIONALITY 2
+#include "sgf_realisation.h"
/* Generate the 3D realisation function */
#define SGF_DIMENSIONALITY 3
@@ -60,19 +60,6 @@ struct sgf_estimator {
/*******************************************************************************
* Helper functions
******************************************************************************/
-static INLINE int
-check_scene_desc(struct sgf_scene_desc* desc)
-{
- ASSERT(desc);
- if(!desc->get_material_property) return 0;
- if(!desc->spectral_bands_count) return 0;
- switch(desc->dimensionality) {
- case SGF_2D: return desc->geometry.scn2d != NULL;
- case SGF_3D: return desc->geometry.scn3d != NULL;
- default: return 0;
- }
-}
-
static FINLINE void
setup_status
(const struct accum* acc,
@@ -147,9 +134,8 @@ sgf_integrate
const size_t steps_count,
struct sgf_estimator** out_estimator)
{
- #define SXD_FUNC(Func) (dimensionality == SGF_2D ? S2D(Func) : S3D(Func))
- #define SXD_ENUM(Enum) (dimensionality == SGF_2D ? S2D_##Enum : S3D_##Enum)
- const enum sgf_dimensionality dimensionality = SGF_3D; /* FIXME */
+ #define SXD_FUNC(Func) (scn->dimensionality == 2 ? S2D(Func) : S3D(Func))
+ #define SXD_ENUM(Enum) (scn->dimensionality == 2 ? S2D_##Enum : S3D_##Enum)
struct htable_bounce path;
struct sgf_estimator* estimator = NULL;
size_t istep;
@@ -171,22 +157,17 @@ sgf_integrate
res = estimator_create(scn->dev, &estimator);
if(res != RES_OK) goto error;
-#if 1
- scene = scn->s3d_scn;
- gebhart_radiative_path = gebhart_radiative_path_3d;
-#else
- switch(desc->dimensionality) {
- case SGF_2D:
- scene = desc->geometry.scn2d;
+ switch(scn->dimensionality) {
+ case 2:
+ scene = scn->geometry.s2d.scn;
gebhart_radiative_path = gebhart_radiative_path_2d;
break;
- case SGF_3D:
- scene = desc->geometry.scn3d;
+ case 3:
+ scene = scn->geometry.s3d.scn;
gebhart_radiative_path = gebhart_radiative_path_3d;
break;
default: FATAL("Unreachable code\n"); break;
}
-#endif
/* Check scene active sessions */
SXD_FUNC(scene_get_session_mask(scene, &mask));
diff --git a/src/sgf_realisation.h b/src/sgf_realisation.h
@@ -178,7 +178,7 @@ hit3d_get_normal(struct s3d_hit* hit, float normal[3])
S2D(scene_trace_ray_3d(Scn, Org, Dir, Range, RayData, Hit))
#define sXd_hit_get_normal(Hit, Normal) \
hit2d_get_normal(Hit, Normal)
- #define sgf_scene_get_sXd_scene(Scn) (Scn)->s3d_scn
+ #define sgf_scene_get_sXd_scene(Scn) (Scn)->geometry.s2d.scn
#elif SGF_DIMENSIONALITY == 3
#define GEBHART_RADIATIVE_PATH gebhart_radiative_path_3d
@@ -203,7 +203,7 @@ hit3d_get_normal(struct s3d_hit* hit, float normal[3])
S3D(scene_trace_ray(Scn, Org, Dir, Range, RayData, Hit))
#define sXd_hit_get_normal(Hit, Normal) \
hit3d_get_normal(Hit, Normal)
- #define sgf_scene_get_sXd_scene(Scn) (Scn)->s3d_scn
+ #define sgf_scene_get_sXd_scene(Scn) (Scn)->geometry.s3d.scn
#else
#error Unexpected dimensionility
#endif
@@ -263,11 +263,10 @@ GEBHART_RADIATIVE_PATH
transmissivity = 1.0;
for(;;) { /* Here we go */
- struct ray_data ray_data;
- ray_data.prim_from = prim;
+ sXd_primitive_T prim_from = prim;
range[0] = FLT_MIN, range[1] = FLT_MAX;
- sXd_scene_trace_ray(sXd_scn, pos, dir, range, &ray_data, &hit);
+ sXd_scene_trace_ray(sXd_scn, pos, dir, range, &prim_from, &hit);
/* Handle medium absorption */
if(absorption_coef >= 0) {
@@ -391,7 +390,7 @@ GEBHART_RADIATIVE_PATH
#undef sXd_primitive_sample_position
#undef sXd_scene_trace_ray
#undef sXd_hit_get_normal
-#undef sgf_scene_desc_get_sXd_scene
+#undef sgf_scene_get_sXd_scene
#undef SGF_DIMENSIONALITY
diff --git a/src/sgf_scene.c b/src/sgf_scene.c
@@ -17,32 +17,52 @@
#include "sgf_device_c.h"
#include "sgf_scene_c.h"
+#include <star/s2d.h>
#include <star/s3d.h>
/*******************************************************************************
* Helper functions
******************************************************************************/
static int
-hit_filter
+hit_filter_s3d
(const struct s3d_hit* hit,
const float org[3],
const float dir[3],
void* ray_data,
void* filter_data)
{
- struct ray_data* rdata = ray_data;
+ struct s3d_primitive* prim_from = ray_data;
(void)org, (void)dir, (void)filter_data;
if(!ray_data) return 0;
/* Discard primitive from which the ray starts from */
- if(S3D_PRIMITIVE_EQ(&rdata->prim_from, &hit->prim)) return 1;
+ if(S3D_PRIMITIVE_EQ(prim_from, &hit->prim)) return 1;
+ /* Ray starts on an edge and intersect the neighbor triangle */
+ if(hit->distance <= 0) return 1;
+ return 0;
+}
+
+static int
+hit_filter_s2d
+ (const struct s2d_hit* hit,
+ const float org[3],
+ const float dir[3],
+ void* ray_data,
+ void* filter_data)
+{
+ struct s2d_primitive* prim_from = ray_data;
+ (void)org, (void)dir, (void)filter_data;
+
+ if(!ray_data) return 0;
+ /* Discard primitive from which the ray starts from */
+ if(S2D_PRIMITIVE_EQ(prim_from, &hit->prim)) return 1;
/* Ray starts on an edge and intersect the neighbor triangle */
if(hit->distance <= 0) return 1;
return 0;
}
static FINLINE int
-check_scene3d_desc(const struct sgf_scene3d_desc* desc)
+check_scene_desc(const struct sgf_scene_desc* desc)
{
return desc
&& desc->get_indices
@@ -55,99 +75,98 @@ check_scene3d_desc(const struct sgf_scene3d_desc* desc)
&& desc->nbands;
}
-static void
-scene_release(ref_T* ref)
+static INLINE void
+scene_release_s3d(struct sgf_scene* scn)
{
- struct sgf_device* dev;
- struct sgf_scene* scn;
- ASSERT(ref);
- scn = CONTAINER_OF(ref, struct sgf_scene, ref);
- dev = scn->dev;
- if(scn->s3d_scn) S3D(scene_ref_put(scn->s3d_scn));
- if(scn->s3d_shape) S3D(shape_ref_put(scn->s3d_shape));
- darray_double_release(&scn->abs);
- darray_double_release(&scn->emi);
- darray_double_release(&scn->refl);
- darray_double_release(&scn->spec);
- MEM_RM(dev->allocator, scn);
- SGF(device_ref_put(dev));
+ if(scn->geometry.s3d.scn) {
+ S3D(scene_ref_put(scn->geometry.s3d.scn));
+ scn->geometry.s3d.scn = NULL;
+ }
+ if(scn->geometry.s3d.shape) {
+ S3D(shape_ref_put(scn->geometry.s3d.shape));
+ scn->geometry.s3d.shape = NULL;
+ }
+ scn->dimensionality = 0;
}
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-sgf_scene3d_create(struct sgf_device* dev, struct sgf_scene** out_scn)
+static INLINE res_T
+scene_init_s3d(struct sgf_scene* scn)
{
- struct sgf_scene* scn = NULL;
res_T res = RES_OK;
-
- if(!dev || !out_scn) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct sgf_scene));
- if(!scn) {
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&scn->ref);
- SGF(device_ref_get(dev));
- scn->dev = dev;
+ ASSERT(scn);
/* Create Star-3D data structures */
- res = s3d_scene_create(dev->s3d, &scn->s3d_scn);
+ res = s3d_scene_create(scn->dev->s3d, &scn->geometry.s3d.scn);
if(res != RES_OK) goto error;
- res = s3d_shape_create_mesh(dev->s3d, &scn->s3d_shape);
+ res = s3d_shape_create_mesh(scn->dev->s3d, &scn->geometry.s3d.shape);
if(res != RES_OK) goto error;
- res = s3d_mesh_set_hit_filter_function(scn->s3d_shape, &hit_filter, NULL);
+ res = s3d_mesh_set_hit_filter_function
+ (scn->geometry.s3d.shape, &hit_filter_s3d, NULL);
if(res != RES_OK) goto error;
- res = s3d_scene_attach_shape(scn->s3d_scn, scn->s3d_shape);
+ res = s3d_scene_attach_shape(scn->geometry.s3d.scn, scn->geometry.s3d.shape);
if(res != RES_OK) goto error;
-
- /* Initialise the buffers of material properties */
- darray_double_init(dev->allocator, &scn->abs);
- darray_double_init(dev->allocator, &scn->emi);
- darray_double_init(dev->allocator, &scn->refl);
- darray_double_init(dev->allocator, &scn->spec);
+ scn->dimensionality = 3;
exit:
- if(out_scn) *out_scn = scn;
return res;
error:
- if(scn) {
- SGF(scene_ref_put(scn));
- scn = NULL;
- }
+ scene_release_s3d(scn);
goto exit;
}
-res_T
-sgf_scene_ref_get(struct sgf_scene* scn)
+static INLINE void
+scene_release_s2d(struct sgf_scene* scn)
{
- if(!scn) return RES_BAD_ARG;
- ref_get(&scn->ref);
- return RES_OK;
+ if(scn->geometry.s2d.scn) {
+ S2D(scene_ref_put(scn->geometry.s2d.scn));
+ scn->geometry.s2d.scn = NULL;
+ }
+ if(scn->geometry.s2d.shape) {
+ S2D(shape_ref_put(scn->geometry.s2d.shape));
+ scn->geometry.s2d.shape = NULL;
+ }
+ scn->dimensionality = 0;
}
-res_T
-sgf_scene_ref_put(struct sgf_scene* scn)
+static INLINE res_T
+scene_init_s2d(struct sgf_scene* scn)
{
- if(!scn) return RES_BAD_ARG;
- ref_put(&scn->ref, scene_release);
- return RES_OK;
+ res_T res = RES_OK;
+ ASSERT(scn);
+
+ /* Create Star-3D data structures */
+ res = s2d_scene_create(scn->dev->s2d, &scn->geometry.s2d.scn);
+ if(res != RES_OK) goto error;
+ res = s2d_shape_create_line_segments(scn->dev->s2d, &scn->geometry.s2d.shape);
+ if(res != RES_OK) goto error;
+ res = s2d_line_segments_set_hit_filter_function
+ (scn->geometry.s2d.shape, &hit_filter_s2d, NULL);
+ if(res != RES_OK) goto error;
+ res = s2d_scene_attach_shape(scn->geometry.s2d.scn, scn->geometry.s2d.shape);
+ if(res != RES_OK) goto error;
+ scn->dimensionality = 2;
+
+exit:
+ return res;
+error:
+ scene_release_s2d(scn);
+ goto exit;
}
-res_T
-sgf_scene3d_setup(struct sgf_scene* scn, const struct sgf_scene3d_desc* desc)
+static res_T
+scene_setup
+ (struct sgf_scene* scn,
+ const struct sgf_scene_desc* desc,
+ const int dimensionality,
+ const char* caller)
{
- struct s3d_vertex_data vdata;
+ struct s2d_vertex_data vdata2d;
+ struct s3d_vertex_data vdata3d;
unsigned iprim, iband, i;
double* abs, *emi, *refl, *spec;
res_T res = RES_OK;
- if(!scn || !check_scene3d_desc(desc)) {
+ if(!scn || !check_scene_desc(desc)) {
res = RES_BAD_ARG;
goto error;
}
@@ -156,8 +175,7 @@ sgf_scene3d_setup(struct sgf_scene* scn, const struct sgf_scene3d_desc* desc)
#define RESIZE(V, Name) { \
res = darray_double_resize(&(V), desc->nprims*desc->nbands); \
if(res != RES_OK) { \
- log_error(scn->dev, \
- "%s: couldn't allocate the "Name" buffer.", FUNC_NAME); \
+ log_error(scn->dev, "%s: couldn't allocate the "Name" buffer.", caller); \
goto error; \
} \
} (void)0
@@ -178,8 +196,7 @@ sgf_scene3d_setup(struct sgf_scene* scn, const struct sgf_scene3d_desc* desc)
#define FETCH(Dst, Name, Low, Upp) { \
(Dst) = desc->get_##Name(iprim, iband, desc->context); \
if((Dst) < (Low) || (Dst) > (Upp)) { \
- log_error(scn->dev, "%s: invalid "STR(Name)" `%g'.\n", \
- FUNC_NAME, (Dst)); \
+ log_error(scn->dev, "%s: invalid "STR(Name)" `%g'.\n", caller, (Dst)); \
res = RES_BAD_ARG; \
goto error; \
} \
@@ -193,15 +210,38 @@ sgf_scene3d_setup(struct sgf_scene* scn, const struct sgf_scene3d_desc* desc)
++i;
}}
+ /* Initialise the Star-3D structures */
+ if(scn->dimensionality != dimensionality) {
+ if(scn->dimensionality == 2) scene_release_s2d(scn);
+ if(scn->dimensionality == 3) scene_release_s3d(scn);
+
+ if(dimensionality == 2) {
+ res = scene_init_s2d(scn);
+ } else {
+ res = scene_init_s3d(scn);
+ }
+ if(res != RES_OK) goto error;
+ }
+
/* Setup the geometry */
- vdata.usage = S3D_POSITION;
- vdata.type = S3D_FLOAT3;
- vdata.get = desc->get_position;
- res = s3d_mesh_setup_indexed_vertices(scn->s3d_shape, desc->nprims,
- desc->get_indices, desc->nverts, &vdata, 1, desc->context);
- if(res != RES_OK) {
- log_error(scn->dev, "%s: couldn't setup the geometry.\n", FUNC_NAME);
- goto error;
+ switch(scn->dimensionality) {
+ case 2:
+ vdata2d.usage = S2D_POSITION;
+ vdata2d.type = S2D_FLOAT2;
+ vdata2d.get = desc->get_position;
+ s2d_line_segments_setup_indexed_vertices(scn->geometry.s2d.shape,
+ desc->nprims, desc->get_indices, desc->nverts, &vdata2d, 1,
+ desc->context);
+ break;
+ case 3:
+ vdata3d.usage = S3D_POSITION;
+ vdata3d.type = S3D_FLOAT3;
+ vdata3d.get = desc->get_position;
+ res = s3d_mesh_setup_indexed_vertices(scn->geometry.s3d.shape,
+ desc->nprims, desc->get_indices, desc->nverts, &vdata3d, 1,
+ desc->context);
+ break;
+ default: FATAL("Unreachable code\n"); break;
}
scn->nbands = desc->nbands;
@@ -223,6 +263,96 @@ error:
goto exit;
}
+
+
+static void
+scene_release(ref_T* ref)
+{
+ struct sgf_device* dev;
+ struct sgf_scene* scn;
+ ASSERT(ref);
+ scn = CONTAINER_OF(ref, struct sgf_scene, ref);
+ dev = scn->dev;
+ switch(scn->dimensionality) {
+ case 2: scene_release_s2d(scn); break;
+ case 3: scene_release_s3d(scn); break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+ darray_double_release(&scn->abs);
+ darray_double_release(&scn->emi);
+ darray_double_release(&scn->refl);
+ darray_double_release(&scn->spec);
+ MEM_RM(dev->allocator, scn);
+ SGF(device_ref_put(dev));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sgf_scene_create(struct sgf_device* dev, struct sgf_scene** out_scn)
+{
+ struct sgf_scene* scn = NULL;
+ res_T res = RES_OK;
+
+ if(!dev || !out_scn) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ scn = MEM_CALLOC(dev->allocator, 1, sizeof(struct sgf_scene));
+ if(!scn) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&scn->ref);
+ SGF(device_ref_get(dev));
+ scn->dev = dev;
+
+ /* Initialise the buffers of material properties */
+ darray_double_init(dev->allocator, &scn->abs);
+ darray_double_init(dev->allocator, &scn->emi);
+ darray_double_init(dev->allocator, &scn->refl);
+ darray_double_init(dev->allocator, &scn->spec);
+
+exit:
+ if(out_scn) *out_scn = scn;
+ return res;
+error:
+ if(scn) {
+ SGF(scene_ref_put(scn));
+ scn = NULL;
+ }
+ goto exit;
+}
+
+res_T
+sgf_scene_ref_get(struct sgf_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_get(&scn->ref);
+ return RES_OK;
+}
+
+res_T
+sgf_scene_ref_put(struct sgf_scene* scn)
+{
+ if(!scn) return RES_BAD_ARG;
+ ref_put(&scn->ref, scene_release);
+ return RES_OK;
+}
+
+res_T
+sgf_scene_setup_3d(struct sgf_scene* scn, const struct sgf_scene_desc* desc)
+{
+ return scene_setup(scn, desc, 3, FUNC_NAME);
+}
+res_T
+sgf_scene_setup_2d(struct sgf_scene* scn, const struct sgf_scene_desc* desc)
+{
+ return scene_setup(scn, desc, 2, FUNC_NAME);
+}
+
res_T
sgf_scene_primitives_count(struct sgf_scene* scn, unsigned* nprims)
{
@@ -236,13 +366,22 @@ sgf_scene_begin_integration(struct sgf_scene* scn)
{
int session_mask;
if(!scn) return RES_BAD_ARG;
- S3D(scene_get_session_mask(scn->s3d_scn, &session_mask));
+
+ if(scn->dimensionality == 2) {
+ S2D(scene_get_session_mask(scn->geometry.s2d.scn, &session_mask));
+ } else {
+ ASSERT(scn->dimensionality == 3);
+ S3D(scene_get_session_mask(scn->geometry.s3d.scn, &session_mask));
+ }
+
if(session_mask != 0) {
log_error(scn->dev, "%s: an integration process is already active.\n",
FUNC_NAME);
return RES_BAD_OP;
}
- return s3d_scene_begin_session(scn->s3d_scn, S3D_TRACE|S3D_GET_PRIMITIVE);
+ return scn->dimensionality == 2
+ ? s2d_scene_begin_session(scn->geometry.s2d.scn, S2D_TRACE|S2D_GET_PRIMITIVE)
+ : s3d_scene_begin_session(scn->geometry.s3d.scn, S3D_TRACE|S3D_GET_PRIMITIVE);
}
res_T
@@ -250,13 +389,23 @@ sgf_scene_end_integration(struct sgf_scene* scn)
{
int session_mask;
if(!scn) return RES_BAD_ARG;
- S3D(scene_get_session_mask(scn->s3d_scn, &session_mask));
+ if(scn->dimensionality == 2) {
+ S2D(scene_get_session_mask(scn->geometry.s2d.scn, &session_mask));
+ } else {
+ ASSERT(scn->dimensionality == 3);
+ S3D(scene_get_session_mask(scn->geometry.s3d.scn, &session_mask));
+ }
+
if(session_mask == 0) {
log_error(scn->dev, "%s: there is no active integration process.\n",
FUNC_NAME);
return RES_BAD_OP;
}
- S3D(scene_end_session(scn->s3d_scn));
+ if(scn->dimensionality == 2) {
+ S2D(scene_end_session(scn->geometry.s2d.scn));
+ } else {
+ S3D(scene_end_session(scn->geometry.s3d.scn));
+ }
return RES_OK;
}
diff --git a/src/sgf_scene_c.h b/src/sgf_scene_c.h
@@ -20,17 +20,25 @@
#include <rsys/ref_count.h>
#include <rsys/rsys.h>
-#include <star/s3d.h>
-
+struct s2d_scene;
+struct s2d_shape;
+struct s3d_scene;
+struct s3d_shape;
struct sgf_device;
-struct ray_data {
- struct s3d_primitive prim_from;
-};
-
struct sgf_scene {
- struct s3d_scene* s3d_scn;
- struct s3d_shape* s3d_shape;
+ int dimensionality;
+
+ union {
+ struct {
+ struct s2d_scene* scn;
+ struct s2d_shape* shape;
+ } s2d;
+ struct {
+ struct s3d_scene* scn;
+ struct s3d_shape* shape;
+ } s3d;
+ } geometry;
struct darray_double abs; /* Per primitive absorption */
struct darray_double emi; /* Per primitive emissivity */
diff --git a/src/test_sgf_cube.c b/src/test_sgf_cube.c
@@ -150,7 +150,7 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct shape_context shape;
struct sgf_scene* scn;
- struct sgf_scene3d_desc desc = SGF_SCENE3D_DESC_NULL;
+ struct sgf_scene_desc desc = SGF_SCENE_DESC_NULL;
struct sgf_device* sgf = NULL;
struct sgf_status* status = NULL;
struct ssp_rng_proxy* proxy;
@@ -166,7 +166,7 @@ main(int argc, char** argv)
CHECK(ssp_rng_proxy_create(&allocator, &ssp_rng_threefry, nbuckets, &proxy), RES_OK);
CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
- CHECK(sgf_scene3d_create(sgf, &scn), RES_OK);
+ CHECK(sgf_scene_create(sgf, &scn), RES_OK);
shape.vertices = vertices;
shape.nvertices = nvertices;
@@ -174,6 +174,7 @@ main(int argc, char** argv)
shape.nprimitives = nprims;
shape.emissivity = emissivity;
shape.specularity = specularity;
+ shape.dim = 3;
desc.get_position = get_position;
desc.get_indices = get_indices;
@@ -185,7 +186,7 @@ main(int argc, char** argv)
desc.nbands = 1;
desc.context = &shape;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
status = sa_add(status, nprims*nprims);
rngs = sa_add(rngs, nbuckets);
@@ -242,9 +243,9 @@ main(int argc, char** argv)
CHECK(sgf_scene_end_integration(scn), RES_OK);
/*
- * Check medium attenuation with 2 parallel infinite planes. To simulate this
- * configuration, the top and bottom faces of the cube are fully emissive.
- * The other ones are fully specular and have no emissivity
+ * Check medium attenuation with 2 parallel infinite planes. To simulate
+ * this configuration, the top and bottom faces of the cube are fully
+ * emissive. The other ones are fully specular and have no emissivity
*/
shape.absorption = ka;
@@ -253,19 +254,19 @@ main(int argc, char** argv)
desc.get_absorption = get_absorption;
FOR_EACH(i, 0, 12) ka[i] = 0;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
check_bottom_top_medium_gf(scn, rngs[0], 1, 0);
FOR_EACH(i, 0, 12) ka[i] = 0.1;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
check_bottom_top_medium_gf(scn, rngs[0], 0.832583, 0.167417);
FOR_EACH(i, 0, 12) ka[i] = 1;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
check_bottom_top_medium_gf(scn, rngs[0], 0.219384, 0.780616);
FOR_EACH(i, 0, 12) ka[i] = 10;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
check_bottom_top_medium_gf(scn, rngs[0], 7.0975e-6, 0.999992902);
CHECK(ssp_rng_proxy_ref_put(proxy), RES_OK);
diff --git a/src/test_sgf_estimator.c b/src/test_sgf_estimator.c
@@ -71,7 +71,7 @@ main(int argc, char** argv)
struct shape_context shape;
struct sgf_device* sgf = NULL;
struct sgf_estimator* estimator = NULL;
- struct sgf_scene3d_desc desc = SGF_SCENE3D_DESC_NULL;
+ struct sgf_scene_desc desc = SGF_SCENE_DESC_NULL;
struct sgf_scene* scn;
struct sgf_status status;
struct ssp_rng* rng = NULL;
@@ -81,7 +81,7 @@ main(int argc, char** argv)
CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
- CHECK(sgf_scene3d_create(sgf, &scn), RES_OK);
+ CHECK(sgf_scene_create(sgf, &scn), RES_OK);
shape.vertices = vertices;
shape.nvertices = nvertices;
@@ -89,6 +89,7 @@ main(int argc, char** argv)
shape.nprimitives = nprims;
shape.emissivity = emissivity;
shape.specularity = specularity;
+ shape.dim = 3;
desc.get_position = get_position;
desc.get_indices = get_indices;
@@ -100,7 +101,7 @@ main(int argc, char** argv)
desc.nbands = 1;
desc.context = &shape;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
CHECK(sgf_scene_begin_integration(scn), RES_OK);
CHECK(sgf_integrate(NULL, SIZE_MAX, NULL, 0, NULL), RES_BAD_ARG);
diff --git a/src/test_sgf_scene.c b/src/test_sgf_scene.c
@@ -0,0 +1,192 @@
+/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.fr)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sgf.h"
+#include "test_sgf_utils.h"
+
+/*******************************************************************************
+ * Plane data
+ ******************************************************************************/
+static const float plane_verts[] = {
+ 0.f, 0.f, 0.f,
+ 1.f, 0.f, 0.f,
+ 0.f, 1.f, 0.f,
+ 1.f, 1.f, 0.f,
+};
+static const size_t plane_nverts = sizeof(plane_verts) / sizeof(float[3]);
+static const unsigned plane_ids[] = { 0, 2, 1, 1, 2, 3 };
+static const size_t plane_nprims = (int)(sizeof(plane_ids) / sizeof(unsigned[3]));
+static const double plane_emi[] = { 0.6, 0.6 };
+static const double plane_emi_bad[] = { 0.6, 1.1 };
+static const double plane_spec[] = { 0.0, 0.0 };
+static const double plane_spec_bad[] = { 1.1, 0.0 };
+static const double plane_abs[] = { 0.0, 0.0 };
+static const double plane_abs_bad[] = { -0.1, 0.0 };
+
+/*******************************************************************************
+ * Square data
+ ******************************************************************************/
+static const float square_verts[] = {
+ 1.f, 0.f,
+ 0.f, 0.f,
+ 0.f, 1.f,
+ 1.f, 1.f
+};
+const unsigned square_nverts = sizeof(square_verts)/sizeof(float[2]);
+const unsigned square_ids[] = {
+ 0, 1, /* Bottom */
+ 1, 2, /* Left */
+ 2, 3, /* Top */
+ 3, 0 /* Right */
+};
+const unsigned square_nprims = sizeof(square_ids)/sizeof(unsigned[2]);
+static const double square_emi[] = {
+ 1.0, /* Bottom */
+ 1.0, /* Left */
+ 1.0, /* Top */
+ 1.0 /* Right */
+};
+static const double square_spec[] = {
+ 0.0, /* Bottom */
+ 0.0, /* Left */
+ 0.0, /* Top */
+ 0.0 /* Right */
+};
+
+/*******************************************************************************
+ * Test function
+ ******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sgf_device* sgf;
+ struct sgf_scene* scn;
+ struct sgf_scene_desc desc = SGF_SCENE_DESC_NULL;
+ struct shape_context shape;
+ unsigned n;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
+
+ CHECK(sgf_scene_create(NULL, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_create(sgf, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_create(NULL, &scn), RES_BAD_ARG);
+ CHECK(sgf_scene_create(sgf, &scn), RES_OK);
+
+ shape.emissivity = plane_emi;
+ shape.specularity = plane_spec;
+ shape.vertices = plane_verts;
+ shape.nvertices = plane_nverts;
+ shape.indices = plane_ids;
+ shape.nprimitives = plane_nprims;
+ shape.dim = 3;
+
+ desc.get_position = get_position;
+ desc.get_indices = get_indices;
+ desc.get_emissivity = get_emissivity;
+ desc.get_reflectivity = get_reflectivity;
+ desc.get_specularity = get_specularity;
+ desc.context = &shape;
+ desc.nprims = (unsigned)plane_nprims;
+ desc.nverts = (unsigned)plane_nverts;
+ desc.nbands = 1;
+
+ CHECK(sgf_scene_setup_3d(NULL, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_setup_3d(scn, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_setup_3d(NULL, &desc), RES_BAD_ARG);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
+
+ CHECK(sgf_scene_primitives_count(NULL, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_primitives_count(scn, NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_primitives_count(NULL, &n), RES_BAD_ARG);
+ CHECK(sgf_scene_primitives_count(scn, &n), RES_OK);
+ CHECK(n, 2);
+
+ desc.get_position = NULL;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.get_position = get_position;
+ desc.get_indices = NULL;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.get_indices = get_indices;
+ desc.get_emissivity = NULL;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.get_emissivity = get_emissivity;
+ desc.get_reflectivity = NULL;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.get_reflectivity = get_reflectivity;
+ desc.get_specularity = NULL;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.get_specularity = get_specularity;
+ desc.nprims = 0;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.nprims = (unsigned)plane_nprims;
+ desc.nverts = 0;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.nverts = (unsigned)plane_nverts;
+ desc.nbands = 0;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ desc.nbands = 1;
+ shape.emissivity = plane_emi_bad;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ shape.emissivity = plane_emi;
+ shape.specularity = plane_spec_bad;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+ shape.specularity = plane_spec;
+ desc.get_absorption = get_absorption;
+ shape.absorption = plane_abs;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
+ shape.absorption = plane_abs_bad;
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_BAD_ARG);
+
+ CHECK(sgf_scene_begin_integration(NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_begin_integration(scn), RES_OK);
+ CHECK(sgf_scene_begin_integration(scn), RES_BAD_OP);
+
+ CHECK(sgf_scene_end_integration(NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_end_integration(scn), RES_OK);
+ CHECK(sgf_scene_end_integration(scn), RES_BAD_OP);
+
+ shape.emissivity = square_emi;
+ shape.specularity = square_spec;
+ shape.vertices = square_verts;
+ shape.indices = square_ids;
+ shape.nprimitives = square_nprims;
+ shape.dim = 2;
+
+ desc.nprims = (unsigned)square_nprims;
+ desc.nverts = (unsigned)square_nverts;
+
+ CHECK(sgf_scene_begin_integration(scn), RES_OK);
+ CHECK(sgf_scene_begin_integration(scn), RES_BAD_OP);
+
+ CHECK(sgf_scene_end_integration(scn), RES_OK);
+ CHECK(sgf_scene_end_integration(scn), RES_BAD_OP);
+
+ CHECK(sgf_scene_ref_get(NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_ref_get(scn), RES_OK);
+ CHECK(sgf_scene_ref_put(NULL), RES_BAD_ARG);
+ CHECK(sgf_scene_ref_put(scn), RES_OK);
+ CHECK(sgf_scene_ref_put(scn), RES_OK);
+
+ CHECK(sgf_device_ref_put(sgf), RES_OK);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return RES_OK;
+}
diff --git a/src/test_sgf_scene3d.c b/src/test_sgf_scene3d.c
@@ -1,140 +0,0 @@
-/* Copyright (C) 2015-2016 EDF S.A., France (syrthes-support@edf.fr)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include "sgf.h"
-#include "test_sgf_utils.h"
-
-static const float vertices[] = {
- 0.f, 0.f, 0.f,
- 1.f, 0.f, 0.f,
- 0.f, 1.f, 0.f,
- 1.f, 1.f, 0.f,
-};
-static const size_t nvertices = sizeof(vertices) / sizeof(float[3]);
-
-static const unsigned indices[] = { 0, 2, 1, 1, 2, 3 };
-static const size_t nprims = (int)(sizeof(indices) / sizeof(unsigned[3]));
-static const double emissivity[] = { 0.6, 0.6 };
-static const double emissivity_bad[] = { 0.6, 1.1 };
-static const double specularity[] = { 0.0, 0.0 };
-static const double specularity_bad[] = { 1.1, 0.0 };
-static const double absorption[] = { 0.0, 0.0 };
-static const double absorption_bad[] = { -0.1, 0.0 };
-
-int
-main(int argc, char** argv)
-{
- struct mem_allocator allocator;
- struct sgf_device* sgf;
- struct sgf_scene* scn;
- struct sgf_scene3d_desc desc = SGF_SCENE3D_DESC_NULL;
- struct shape_context ctx;
- unsigned n;
- (void)argc, (void)argv;
-
- mem_init_proxy_allocator(&allocator, &mem_default_allocator);
-
- CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
-
- CHECK(sgf_scene3d_create(NULL, NULL), RES_BAD_ARG);
- CHECK(sgf_scene3d_create(sgf, NULL), RES_BAD_ARG);
- CHECK(sgf_scene3d_create(NULL, &scn), RES_BAD_ARG);
- CHECK(sgf_scene3d_create(sgf, &scn), RES_OK);
-
- ctx.emissivity = emissivity;
- ctx.specularity = specularity;
- ctx.vertices = vertices;
- ctx.nvertices = nvertices;
- ctx.indices = indices;
- ctx.nprimitives = nprims;
-
- desc.get_position = get_position;
- desc.get_indices = get_indices;
- desc.get_emissivity = get_emissivity;
- desc.get_reflectivity = get_reflectivity;
- desc.get_specularity = get_specularity;
- desc.context = &ctx;
- desc.nprims = (unsigned)nprims;
- desc.nverts = (unsigned)nvertices;
- desc.nbands = 1;
-
- CHECK(sgf_scene3d_setup(NULL, NULL), RES_BAD_ARG);
- CHECK(sgf_scene3d_setup(scn, NULL), RES_BAD_ARG);
- CHECK(sgf_scene3d_setup(NULL, &desc), RES_BAD_ARG);
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
-
- CHECK(sgf_scene_primitives_count(NULL, NULL), RES_BAD_ARG);
- CHECK(sgf_scene_primitives_count(scn, NULL), RES_BAD_ARG);
- CHECK(sgf_scene_primitives_count(NULL, &n), RES_BAD_ARG);
- CHECK(sgf_scene_primitives_count(scn, &n), RES_OK);
- CHECK(n, 2);
-
- desc.get_position = NULL;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.get_position = get_pos;
- desc.get_indices = NULL;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.get_indices = get_ids;
- desc.get_emissivity = NULL;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.get_emissivity = get_emissivity;
- desc.get_reflectivity = NULL;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.get_reflectivity = get_reflectivity;
- desc.get_specularity = NULL;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.get_specularity = get_specularity;
- desc.nprims = 0;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.nprims = (unsigned)nprims;
- desc.nverts = 0;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.nverts = (unsigned)nvertices;
- desc.nbands = 0;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- desc.nbands = 1;
- ctx.emissivity = emissivity_bad;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- ctx.emissivity = emissivity;
- ctx.specularity = specularity_bad;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
- ctx.specularity = specularity;
- desc.get_absorption = get_absorption;
- ctx.absorption = absorption;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
- ctx.absorption = absorption_bad;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_BAD_ARG);
-
- CHECK(sgf_scene_begin_integration(NULL), RES_BAD_ARG);
- CHECK(sgf_scene_begin_integration(scn), RES_OK);
- CHECK(sgf_scene_begin_integration(scn), RES_BAD_OP);
-
- CHECK(sgf_scene_end_integration(NULL), RES_BAD_ARG);
- CHECK(sgf_scene_end_integration(scn), RES_OK);
- CHECK(sgf_scene_end_integration(scn), RES_BAD_OP);
-
- CHECK(sgf_scene_ref_get(NULL), RES_BAD_ARG);
- CHECK(sgf_scene_ref_get(scn), RES_OK);
- CHECK(sgf_scene_ref_put(NULL), RES_BAD_ARG);
- CHECK(sgf_scene_ref_put(scn), RES_OK);
- CHECK(sgf_scene_ref_put(scn), RES_OK);
-
- CHECK(sgf_device_ref_put(sgf), RES_OK);
-
- check_memory_allocator(&allocator);
- mem_shutdown_proxy_allocator(&allocator);
- CHECK(mem_allocated_size(), 0);
- return RES_OK;
-}
diff --git a/src/test_sgf_square.c b/src/test_sgf_square.c
@@ -70,33 +70,11 @@ static const double specularity_inf_bottom_top[] = {
1.0 /* Right */
};
-
-static void
-square_get_ids(const unsigned iseg, unsigned ids[2], void* data)
-{
- const unsigned id = iseg * 2/*#coords per segment*/;
- (void)data;
- NCHECK(ids, NULL);
- ids[0] = indices[id + 0];
- ids[1] = indices[id + 1];
-}
-
-static void
-square_get_pos(const unsigned ivert, float pos[2], void* data)
-{
- const unsigned id = ivert * 2/*#vertices per segment*/;
- (void)data;
- NCHECK(pos, NULL);
- pos[0] = vertices[id + 0];
- pos[1] = vertices[id + 1];
-}
-
/* Check the estimation of the bottom/top & bottom/medium Gebhart factors */
static void
check_bottom_top_medium_gf
- (struct sgf_device* sgf,
+ (struct sgf_scene* scn,
struct ssp_rng* rng,
- struct sgf_scene_desc* desc,
const double gf_bottom_top, /* Ref of the bottom/top Gebhart factor */
const double gf_bottom_medium) /* Ref of the bottom/medium Gebhart Factor */
{
@@ -107,8 +85,10 @@ check_bottom_top_medium_gf
struct sgf_estimator* estimator;
struct sgf_status status[2];
+ CHECK(sgf_scene_begin_integration(scn), RES_OK);
+
/* Estimate the Gebhart factors for the bottom segment */
- CHECK(sgf_integrate(sgf, rng, BOTTOM, desc, NSTEPS, &estimator), RES_OK);
+ CHECK(sgf_integrate(scn, BOTTOM, rng, NSTEPS, &estimator), RES_OK);
CHECK(sgf_estimator_get_status(estimator, TOP, 0, status + 0), RES_OK);
CHECK(sgf_estimator_get_status_medium(estimator, 0, status + 1), RES_OK);
CHECK(sgf_estimator_ref_put(estimator), RES_OK);
@@ -118,56 +98,56 @@ check_bottom_top_medium_gf
/* Check the Gebhart factor between the bottom plane and the medium */
CHECK(eq_eps(status[1].E, gf_bottom_medium, status[1].SE), 1);
+
+ CHECK(sgf_scene_end_integration(scn), RES_OK);
}
int
main(int argc, char** argv)
{
struct mem_allocator allocator;
- struct s2d_device* s2d;
- struct s2d_scene* scn;
- struct s2d_shape* shape;
- struct s2d_vertex_data vdata;
+ struct shape_context shape;
struct sgf_device* sgf;
- struct sgf_scene_desc scn_desc = SGF_SCENE_DESC_NULL;
+ struct sgf_scene* scn;
+ struct sgf_scene_desc desc = SGF_SCENE_DESC_NULL;
struct sgf_status status;
struct sgf_estimator* estimator;
struct ssp_rng* rng;
- struct material mtr;
double ka[4];
size_t iprim, i;
(void)argc, (void)argv;
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
- CHECK(s2d_device_create(NULL, &allocator, 1, &s2d), RES_OK);
- CHECK(s2d_shape_create_line_segments(s2d, &shape), RES_OK);
- CHECK(s2d_scene_create(s2d, &scn), RES_OK);
- CHECK(s2d_scene_attach_shape(scn, shape), RES_OK);
CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
-
- vdata.type = S2D_FLOAT2;
- vdata.usage = S2D_POSITION;
- vdata.get = square_get_pos;
- CHECK(s2d_line_segments_setup_indexed_vertices
- (shape, nsegs, square_get_ids, nverts, &vdata, 1, &shape), RES_OK);
-
- mtr.emissivity = emissivity;
- mtr.specularity = specularity;
-
- scn_desc.get_material_property = get_material_property;
- scn_desc.material = &mtr;
- scn_desc.spectral_bands_count = 1;
- scn_desc.dimensionality = SGF_2D;
- scn_desc.geometry.scn2d = scn;
-
- CHECK(sgf_integrate(sgf, rng, 0, &scn_desc, NSTEPS, &estimator), RES_BAD_ARG);
-
- CHECK(s2d_scene_begin_session(scn, S2D_TRACE|S2D_GET_PRIMITIVE), RES_OK);
+ CHECK(sgf_scene_create(sgf, &scn), RES_OK);
+
+ shape.vertices = vertices;
+ shape.nvertices = nverts;
+ shape.indices = indices;
+ shape.nprimitives = nsegs;
+ shape.emissivity = emissivity;
+ shape.specularity = specularity;
+ shape.dim = 2;
+
+ desc.get_position = get_position;
+ desc.get_indices = get_indices;
+ desc.get_emissivity = get_emissivity;
+ desc.get_specularity = get_specularity;
+ desc.get_reflectivity = get_reflectivity;
+ desc.nprims = (unsigned)nsegs;
+ desc.nverts = (unsigned)nverts;
+ desc.nbands = 1;
+ desc.context = &shape;
+
+ CHECK(sgf_scene_setup_2d(scn, &desc), RES_OK);
+ CHECK(sgf_integrate(scn, 0, rng, NSTEPS, &estimator), RES_BAD_OP);
+
+ CHECK(sgf_scene_begin_integration(scn), RES_OK);
FOR_EACH(iprim, 0, 3) {
- CHECK(sgf_integrate(sgf, rng, iprim, &scn_desc, NSTEPS, &estimator), RES_OK);
+ CHECK(sgf_integrate(scn, iprim, rng, NSTEPS, &estimator), RES_OK);
FOR_EACH(i, 0, 3) {
CHECK(sgf_estimator_get_status(estimator, i, 0, &status), RES_OK);
@@ -186,34 +166,40 @@ main(int argc, char** argv)
CHECK(sgf_estimator_ref_put(estimator), RES_OK);
}
- CHECK(sgf_integrate(sgf, rng, 4, &scn_desc, NSTEPS, &estimator), RES_BAD_ARG);
- scn_desc.dimensionality = INT_MAX;
- CHECK(sgf_integrate(sgf, rng, 0, &scn_desc, NSTEPS, &estimator), RES_BAD_ARG);
+ CHECK(sgf_integrate(scn, 4, rng, NSTEPS, &estimator), RES_BAD_ARG);
+
+ CHECK(sgf_scene_end_integration(scn), RES_OK);
- /* Check medium attenuation with 2 parallel infinite segments. To simulate
+ /*
+ * Check medium attenuation with 2 parallel infinite segments. To simulate
* this configuration, the top and bottom segments of the square are fully
- * emissive. The other ones are fully specular and have no emissivity */
- scn_desc.has_medium = 1;
- scn_desc.dimensionality = SGF_2D;
- mtr.emissivity = emissivity_inf_bottom_top;
- mtr.specularity = specularity_inf_bottom_top;
- mtr.absorption = ka;
+ * emissive. The other ones are fully specular and have no emissivity
+ */
+
+ shape.absorption = ka;
+ shape.emissivity = emissivity_inf_bottom_top;
+ shape.specularity = specularity_inf_bottom_top;
+ desc.get_absorption = get_absorption;
+
FOR_EACH(i, 0, 4) ka[i] = 0;
- check_bottom_top_medium_gf(sgf, rng, &scn_desc, 1, 0);
+ CHECK(sgf_scene_setup_2d(scn, &desc), RES_OK);
+ check_bottom_top_medium_gf(scn, rng, 1, 0);
+
FOR_EACH(i, 0, 4) ka[i] = 0.1;
- check_bottom_top_medium_gf(sgf, rng, &scn_desc, 0.832583, 0.167417);
+ CHECK(sgf_scene_setup_2d(scn, &desc), RES_OK);
+ check_bottom_top_medium_gf(scn, rng, 0.832583, 0.167417);
+
FOR_EACH(i, 0, 4) ka[i] = 1;
- check_bottom_top_medium_gf(sgf, rng, &scn_desc, 0.219384, 0.780616);
- FOR_EACH(i, 0, 4) ka[i] = 10;
- check_bottom_top_medium_gf(sgf, rng, &scn_desc, 7.0975e-6, 0.999992902);
+ CHECK(sgf_scene_setup_2d(scn, &desc), RES_OK);
+ check_bottom_top_medium_gf(scn, rng, 0.219384, 0.780616);
- CHECK(s2d_scene_end_session(scn), RES_OK);
+ FOR_EACH(i, 0, 4) ka[i] = 10;
+ CHECK(sgf_scene_setup_2d(scn, &desc), RES_OK);
+ check_bottom_top_medium_gf(scn, rng, 7.0975e-6, 0.999992902);
- CHECK(s2d_device_ref_put(s2d), RES_OK);
- CHECK(s2d_shape_ref_put(shape), RES_OK);
- CHECK(s2d_scene_ref_put(scn), RES_OK);
CHECK(ssp_rng_ref_put(rng), RES_OK);
CHECK(sgf_device_ref_put(sgf), RES_OK);
+ CHECK(sgf_scene_ref_put(scn), RES_OK);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
diff --git a/src/test_sgf_tetrahedron.c b/src/test_sgf_tetrahedron.c
@@ -51,7 +51,7 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct shape_context shape;
struct sgf_device* sgf = NULL;
- struct sgf_scene3d_desc desc = SGF_SCENE3D_DESC_NULL;
+ struct sgf_scene_desc desc = SGF_SCENE_DESC_NULL;
struct sgf_scene* scn = NULL;
struct sgf_status* status = NULL;
struct ssp_rng_proxy* proxy = NULL;
@@ -65,7 +65,7 @@ main(int argc, char** argv)
nbuckets = (unsigned)omp_get_num_procs();
CHECK(ssp_rng_proxy_create(&allocator, &ssp_rng_threefry, nbuckets, &proxy), RES_OK);
CHECK(sgf_device_create(NULL, &allocator, 1, &sgf), RES_OK);
- CHECK(sgf_scene3d_create(sgf, &scn), RES_OK);
+ CHECK(sgf_scene_create(sgf, &scn), RES_OK);
shape.vertices = vertices;
shape.nvertices = nvertices;
@@ -73,6 +73,7 @@ main(int argc, char** argv)
shape.nprimitives = nprims;
shape.emissivity = emissivity;
shape.specularity = specularity;
+ shape.dim = 3;
desc.get_position = get_position;
desc.get_indices = get_indices;
@@ -84,7 +85,7 @@ main(int argc, char** argv)
desc.nbands = 1;
desc.context = &shape;
- CHECK(sgf_scene3d_setup(scn, &desc), RES_OK);
+ CHECK(sgf_scene_setup_3d(scn, &desc), RES_OK);
status = sa_add(status, nprims*nprims);
rngs = sa_add(rngs, nbuckets);
diff --git a/src/test_sgf_utils.h b/src/test_sgf_utils.h
@@ -19,19 +19,6 @@
#include <rsys/mem_allocator.h>
#include <stdio.h>
-struct triangle_mesh { /* TODO remove this */
- const float* vertices;
- size_t nvertices;
- const unsigned* indices;
- size_t ntriangles;
-};
-
-struct material { /* TODO remove this */
- const double* emissivity;
- const double* specularity;
- const double* absorption;
-};
-
struct shape_context {
const float* vertices;
size_t nvertices;
@@ -40,77 +27,32 @@ struct shape_context {
const double* emissivity;
const double* specularity;
const double* absorption;
+ unsigned dim;
};
-static INLINE void /* TODO remove this */
-get_ids(const unsigned itri, unsigned ids[3], void* data)
-{
- const struct triangle_mesh* mesh = data;
- const unsigned id = itri * 3;
- NCHECK(mesh, NULL);
- NCHECK(ids, NULL);
- CHECK(itri < mesh->ntriangles, 1);
- ids[0] = mesh->indices[id + 0];
- ids[1] = mesh->indices[id + 1];
- ids[2] = mesh->indices[id + 2];
-}
-
static INLINE void
-get_indices(const unsigned itri, unsigned ids[3], void* data)
+get_indices(const unsigned itri, unsigned ids[], void* data)
{
const struct shape_context* shape = data;
- const unsigned id = itri * 3;
+ const unsigned id = itri * shape->dim;
+ unsigned i;
NCHECK(shape, NULL);
NCHECK(ids, NULL);
+ CHECK(shape->dim == 2 || shape->dim == 3, 1);
CHECK(itri < shape->nprimitives, 1);
- ids[0] = shape->indices[id + 0];
- ids[1] = shape->indices[id + 1];
- ids[2] = shape->indices[id + 2];
-}
-
-static INLINE void
-get_pos(const unsigned ivert, float pos[3], void* data)
-{
- const struct triangle_mesh* mesh = data;
- const unsigned i = ivert*3;
- NCHECK(mesh, NULL);
- NCHECK(pos, NULL);
- CHECK(ivert < mesh->nvertices, 1);
- pos[0] = mesh->vertices[i + 0];
- pos[1] = mesh->vertices[i + 1];
- pos[2] = mesh->vertices[i + 2];
+ FOR_EACH(i, 0, shape->dim) ids[i] = shape->indices[id + i];
}
static INLINE void
-get_position(const unsigned ivert, float pos[3], void* data)
+get_position(const unsigned ivert, float pos[], void* data)
{
const struct shape_context* shape = data;
- const unsigned i = ivert*3;
+ const unsigned id = ivert*shape->dim;
+ unsigned i;
NCHECK(shape, NULL);
NCHECK(pos, NULL);
CHECK(ivert < shape->nvertices, 1);
- pos[0] = shape->vertices[i + 0];
- pos[1] = shape->vertices[i + 1];
- pos[2] = shape->vertices[i + 2];
-}
-
-static INLINE double
-get_material_property
- (void* material,
- const enum sgf_material_property prop,
- const size_t iprim,
- const size_t ispec_band)
-{
- struct material* mtr = material;
- NCHECK(material, NULL);
- (void)ispec_band;
- switch(prop) {
- case SGF_MATERIAL_EMISSIVITY: return mtr->emissivity[iprim]; break;
- case SGF_MATERIAL_REFLECTIVITY: return 1.0 - mtr->emissivity[iprim]; break;
- case SGF_MATERIAL_SPECULARITY: return mtr->specularity[iprim]; break;
- case SGF_MEDIUM_ABSORPTION: return mtr->absorption[iprim]; break;
- default: FATAL("Unreachable code\n"); break;
- }
+ FOR_EACH(i, 0, shape->dim) pos[i] = shape->vertices[id + i];
}
static INLINE double
@@ -147,13 +89,13 @@ get_reflectivity(const unsigned iprim, const unsigned iband, void* ctx)
}
static INLINE void
-dump_triangle_mesh(struct triangle_mesh* mesh)
+dump_triangle_mesh(struct shape_context* mesh)
{
unsigned i;
NCHECK(mesh, NULL);
FOR_EACH(i, 0, mesh->nvertices)
printf("v %f %f %f\n", SPLIT3(mesh->vertices + i*3));
- FOR_EACH(i, 0, mesh->ntriangles) {
+ FOR_EACH(i, 0, mesh->nprimitives) {
printf("f %d %d %d\n",
mesh->indices[i*3 + 0] + 1,
mesh->indices[i*3 + 1] + 1,