star-gf

Compute Gebhart factors
git clone git://git.meso-star.fr/star-gf.git
Log | Files | Refs | README | LICENSE

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:
Mcmake/CMakeLists.txt | 4++--
Msrc/sgf.h | 60+++++++++++++-----------------------------------------------
Msrc/sgf_device.c | 7+++++++
Msrc/sgf_device_c.h | 2++
Msrc/sgf_estimator.c | 37+++++++++----------------------------
Msrc/sgf_realisation.h | 11+++++------
Msrc/sgf_scene.c | 317++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/sgf_scene_c.h | 24++++++++++++++++--------
Msrc/test_sgf_cube.c | 21+++++++++++----------
Msrc/test_sgf_estimator.c | 7++++---
Asrc/test_sgf_scene.c | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/test_sgf_scene3d.c | 140-------------------------------------------------------------------------------
Msrc/test_sgf_square.c | 132+++++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/test_sgf_tetrahedron.c | 7++++---
Msrc/test_sgf_utils.h | 82++++++++++++-------------------------------------------------------------------
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,