star-vx

Structuring voxels for ray-tracing
git clone git://git.meso-star.fr/star-vx.git
Log | Files | Refs | README | LICENSE

commit bec26ec0f030659f51f3eb6bb186ffb58d8889e8
parent 0b3a64e9f6af41c7cbc3cc6c8b66c7dc3526f4e8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  6 Feb 2018 11:47:51 +0100

Update the profile of the `for_each_voxel' functor

Add the voxel indentifier as input parameter.

Diffstat:
Msrc/htvox.h | 6+++++-
Msrc/htvox_scene.c | 18++++++++++++++++--
Msrc/test_htvox_scene.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 164 insertions(+), 24 deletions(-)

diff --git a/src/htvox.h b/src/htvox.h @@ -111,7 +111,11 @@ HTVOX_API res_T htvox_scene_for_each_voxel (struct htvox_scene* scn, void (*functor) - (const double val, const double low[3], const double upp[3], void* ctx), + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* ctx), void* context); HTVOX_API res_T diff --git a/src/htvox_scene.c b/src/htvox_scene.c @@ -550,10 +550,22 @@ htvox_scene_get_aabb } res_T +htvox_scene_get_voxels_count(const struct htvox_scene* scn, size_t* nvoxels) +{ + if(!scn || !nvoxels) return RES_BAD_ARG; + *nvoxels = scn->nvoxels; + return RES_OK; +} + +res_T htvox_scene_for_each_voxel (struct htvox_scene* scn, void (*func) - (const double val, const double low[3], const double upp[3], void* ctx), + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* ctx), void* ctx) { struct stack_entry { @@ -562,6 +574,7 @@ htvox_scene_for_each_voxel double upp[3]; } stack[OCTREE_DEPTH_MAX*8]; int istack; + size_t ivoxel = 0; if(!scn || !func) return RES_BAD_ARG; @@ -594,7 +607,8 @@ htvox_scene_for_each_voxel ASSERT(entry.low[1] >= scn->lower[1]); ASSERT(entry.low[2] >= scn->lower[2]); - func(val, entry.low, entry.upp, ctx); + func(val, ivoxel, entry.low, entry.upp, ctx); + ++ivoxel; } else if(!OCTREE_XNODE_IS_EMPTY(node)) { double half_sz[3]; /* Half size of the current node */ diff --git a/src/test_htvox_scene.c b/src/test_htvox_scene.c @@ -19,20 +19,30 @@ #include <rsys/double3.h> -struct context { +struct check_context { double* lower; double* upper; size_t* nvoxels; }; + + static int -merge(const double min_val, const double max_val, void* ctx) +no_merge(const double min_val, const double max_val, void* ctx) { - (void)min_val, (void)max_val; + CHK(min_val <= max_val); CHK((intptr_t)ctx == 0xDECAFBAD); return 0; /* Merge nothing */ } +static int +merge(const double min_val, const double max_val, void* ctx) +{ + CHK(min_val <= max_val); + CHK((intptr_t)ctx == 0xDECAFBAD); + return max_val < 128 && (max_val - min_val) < 8; +} + static void get(const size_t xyz[3], double* val, void* ctx) { @@ -52,9 +62,13 @@ get(const size_t xyz[3], double* val, void* ctx) static void check_voxel - (const double val, const double low[3], const double upp[3], void* context) + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* context) { - struct context* ctx = context; + struct check_context* ctx = context; uint64_t mcode; uint32_t xyz[3]; double lower[3]; @@ -67,6 +81,7 @@ check_voxel CHK(low[0] < upp[0]); CHK(low[1] < upp[1]); CHK(low[2] < upp[2]); + CHK(ivoxel < ctx->nvoxels[0]*ctx->nvoxels[1]*ctx->nvoxels[2]); mcode = (uint64_t)val; CHK(val == (double)mcode); @@ -88,6 +103,104 @@ check_voxel CHK(eq_eps(lower[2] + delta[2], upp[2], 1.e-6)); } +static void +write_points + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* context) +{ + FILE* stream = context; + (void)val, (void)ivoxel; + CHK(stream != NULL); + CHK(low != NULL); + CHK(upp != NULL); + fprintf(stream, + "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n" + "%g %g %g\n%g %g %g\n%g %g %g\n%g %g %g\n", + low[0], low[1], low[2], + upp[0], low[1], low[2], + low[0], upp[1], low[2], + upp[0], upp[1], low[2], + low[0], low[1], upp[2], + upp[0], low[1], upp[2], + low[0], upp[1], upp[2], + upp[0], upp[1], upp[2]); +} + +static void +write_cells + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* context) +{ + FILE* stream = context; + (void)ivoxel, (void)val; + CHK(stream != NULL); + CHK(low != NULL); + CHK(upp != NULL); + fprintf(stream, "8 %lu %lu %lu %lu %lu %lu %lu %lu\n", + (unsigned long)(ivoxel*8 + 0), + (unsigned long)(ivoxel*8 + 1), + (unsigned long)(ivoxel*8 + 2), + (unsigned long)(ivoxel*8 + 3), + (unsigned long)(ivoxel*8 + 4), + (unsigned long)(ivoxel*8 + 5), + (unsigned long)(ivoxel*8 + 6), + (unsigned long)(ivoxel*8 + 7)); +} + +static void +write_scalars + (const double val, + const size_t ivoxel, + const double low[3], + const double upp[3], + void* context) +{ + FILE* stream = context; + (void)ivoxel; + CHK(stream != NULL); + CHK(low != NULL); + CHK(upp != NULL); + fprintf(stream, "%g\n", val); +} + +static void +dump_data(FILE* stream, struct htvox_scene* scn) +{ + size_t ivxl; + size_t nvxls; + + CHK(stream != NULL); + CHK(scn != NULL); + + fprintf(stream, "# vtk DataFile Version 2.0\n"); + fprintf(stream, "Volume\n"); + fprintf(stream, "ASCII\n"); + fprintf(stream, "DATASET UNSTRUCTURED_GRID\n"); + + CHK(htvox_scene_get_voxels_count(scn, &nvxls) == RES_OK); + fprintf(stream, "POINTS %lu float\n", (unsigned long)(nvxls * 8)); + CHK(htvox_scene_for_each_voxel(scn, write_points, stream) == RES_OK); + + fprintf(stream, "CELLS %lu %lu\n", + (unsigned long)nvxls, + (unsigned long)(nvxls*(8/*#verts per voxel*/ + 1/*1st field of a cell*/))); + CHK(htvox_scene_for_each_voxel(scn, write_cells, stream) == RES_OK); + + fprintf(stream, "CELL_TYPES %lu\n", (unsigned long)nvxls); + FOR_EACH(ivxl, 0, nvxls ) fprintf(stream, "11\n"); + + fprintf(stream, "CELL_DATA %lu\n", (unsigned long)nvxls); + fprintf(stream, "SCALARS K float 1\n"); + fprintf(stream, "LOOKUP_TABLE default\n"); + CHK(htvox_scene_for_each_voxel(scn, write_scalars, stream) == RES_OK); +} + int main(int argc, char** argv) { @@ -97,7 +210,8 @@ main(int argc, char** argv) double low[3]; double upp[3]; size_t nvxls[3]; - struct context ctx; + size_t nvoxels; + struct check_context ctx; void* ptr = (void*)0xDECAFBAD; (void)argc, (void)argv; @@ -115,7 +229,7 @@ main(int argc, char** argv) #define NEW_SCN htvox_scene_create - CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, &scn) == RES_OK); + CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_OK); CHK(htvox_scene_ref_get(NULL) == RES_BAD_ARG); CHK(htvox_scene_ref_get(scn) == RES_OK); @@ -124,36 +238,44 @@ main(int argc, char** argv) CHK(htvox_scene_ref_put(scn) == RES_OK); upp[0] = low[0]; - CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG); upp[0] = 1.0; nvxls[2] = 0; - CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG); nvxls[2] = nvxls[0]; - CHK(NEW_SCN(NULL, low, upp, nvxls, get, merge, ptr, &scn) == RES_BAD_ARG); - CHK(NEW_SCN(dev, NULL, upp, nvxls, get, merge, ptr, &scn) == RES_BAD_ARG); - CHK(NEW_SCN(dev, low, NULL, nvxls, get, merge, ptr, &scn) == RES_BAD_ARG); - CHK(NEW_SCN(dev, low, upp, NULL, get, merge, ptr, &scn) == RES_BAD_ARG); - CHK(NEW_SCN(dev, low, upp, nvxls, NULL, merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(NULL, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, NULL, upp, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, low, NULL, nvxls, get, no_merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, low, upp, NULL, get, no_merge, ptr, &scn) == RES_BAD_ARG); + CHK(NEW_SCN(dev, low, upp, nvxls, NULL, no_merge, ptr, &scn) == RES_BAD_ARG); CHK(NEW_SCN(dev, low, upp, nvxls, get, NULL, ptr, &scn) == RES_BAD_ARG); - CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, NULL) == RES_BAD_ARG); - - CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, &scn) == RES_OK); + CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, NULL) == RES_BAD_ARG); - #undef NEW_SCN + CHK(NEW_SCN(dev, low, upp, nvxls, get, no_merge, ptr, &scn) == RES_OK); CHK(htvox_scene_for_each_voxel(scn, check_voxel, &ctx) == RES_OK); + CHK(htvox_scene_get_voxels_count(NULL, &nvoxels) == RES_BAD_ARG); + CHK(htvox_scene_get_voxels_count(scn, NULL) == RES_BAD_ARG); + CHK(htvox_scene_get_voxels_count(scn, &nvoxels) == RES_OK); + CHK(nvoxels == nvxls[0]*nvxls[1]*nvxls[2]); + d3_splat(low, DBL_MAX); d3_splat(upp,-DBL_MAX); + CHK(htvox_scene_get_aabb(NULL, low, upp) == RES_BAD_ARG); + CHK(htvox_scene_get_aabb(scn, NULL, upp) == RES_BAD_ARG); + CHK(htvox_scene_get_aabb(scn, low, NULL) == RES_BAD_ARG); CHK(htvox_scene_get_aabb(scn, low, upp) == RES_OK); CHK(low[0] == 0 && low[1] == 0 && low[2] == 0); CHK(upp[0] == 1 && upp[1] == 1 && upp[2] == 1); - CHK(htvox_scene_get_aabb(NULL, low, upp) == RES_BAD_ARG); - CHK(htvox_scene_get_aabb(scn, NULL, upp) == RES_BAD_ARG); - CHK(htvox_scene_get_aabb(scn, low, NULL) == RES_BAD_ARG); + CHK(htvox_scene_ref_put(scn) == RES_OK); + CHK(NEW_SCN(dev, low, upp, nvxls, get, merge, ptr, &scn) == RES_OK); + dump_data(stdout, scn); + + #undef NEW_SCN CHK(htvox_device_ref_put(dev) == RES_OK); CHK(htvox_scene_ref_put(scn) == RES_OK);