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:
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);