commit c4fc8b85361ac902d5dd7741e0c2f9b016441b03
parent 9c11749ab9ad18b91a459dbe46ef920a55201985
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 10 May 2018 13:41:34 +0200
Test the at accessor of the binary tree
Diffstat:
5 files changed, 103 insertions(+), 8 deletions(-)
diff --git a/src/svx.h b/src/svx.h
@@ -112,10 +112,20 @@ struct svx_tree_desc {
size_t depth; /* Depth of the octree */
enum svx_tree_type type;
+
+ /* Define the axis in world space along which the tree is defined. In 1D,
+ * (i.e. bintree) only the first component of the frame is defined while in
+ * 3D (i.e. octree), the 3 components is always defined to SVX_AXIS_X,
+ * SVX_AXIS_Y and SVX_AXYS_Z. */
+ enum svx_axis frame[3];
};
-#define SVX_TREE_DESC_NULL__ \
- {{DBL_MAX, DBL_MAX, DBL_MAX}, {-DBL_MAX,-DBL_MAX,-DBL_MAX}, 0, 0, 0, 0}
+#define SVX_TREE_DESC_NULL__ { \
+ { DBL_MAX, DBL_MAX, DBL_MAX}, \
+ {-DBL_MAX,-DBL_MAX,-DBL_MAX}, \
+ 0, 0, 0, 0, \
+ {SVX_AXIS_NONE__, SVX_AXIS_NONE__, SVX_AXIS_NONE__} \
+}
static const struct svx_tree_desc SVX_TREE_DESC_NULL =
SVX_TREE_DESC_NULL__;
diff --git a/src/svx_tree.c b/src/svx_tree.c
@@ -75,6 +75,9 @@ svx_tree_get_desc
(&tree->buffer, tree->buffer.attr_head) + 1; /* Root node */
desc->depth = tree->depth;
desc->type = tree->type;
+ desc->frame[0] = tree->frame[0];
+ desc->frame[1] = tree->frame[1];
+ desc->frame[2] = tree->frame[2];
return RES_OK;
}
diff --git a/src/svx_tree_generic_func.h b/src/svx_tree_generic_func.h
@@ -163,7 +163,7 @@ TREE_FUNC(at)
/* Transform the position in the normalized octree space,
* i.e. octree lies in [0, 1]^2 */
pos[i] = (position[tree->frame[i]] - tree->tree_low[tree->frame[i]])
- / tree->tree_size[i];
+ / tree->tree_size[tree->frame[i]];
/* Initialized the lower left corner of the current node */
low[i] = 0;
}
diff --git a/src/test_svx_bintree.c b/src/test_svx_bintree.c
@@ -18,6 +18,8 @@
#include "test_svx_utils.h"
#include <rsys/math.h>
+#define AXIS SVX_AXIS_Y
+
struct leaves_context {
double lower;
double upper;
@@ -29,6 +31,11 @@ struct leaves_context {
size_t nleaves;
};
+struct at_context {
+ double position;
+ size_t depth;
+};
+
static void
get(const size_t xyz[3], void* dst, void* ctx)
{
@@ -36,7 +43,7 @@ get(const size_t xyz[3], void* dst, void* ctx)
CHK(xyz != NULL);
CHK(val != NULL);
CHK((intptr_t)ctx == 0xDECAFBAD);
- *val = (double)xyz[SVX_AXIS_Y];
+ *val = (double)xyz[AXIS];
}
static int
@@ -67,6 +74,21 @@ keep_max(void* dst, const void* voxels[], const size_t nvoxels, void* ctx)
*vox_dst = max_val;
}
+static int
+max_lod
+ (const struct svx_voxel* vox,
+ const double pos[3],
+ void* context)
+{
+ const struct at_context* ctx = context;
+ CHK(vox != NULL);
+ CHK(pos != NULL);
+ CHK(ctx != NULL);
+ CHK(vox->depth <= ctx->depth);
+ CHK(pos[AXIS] == ctx->position);
+ return vox->depth < ctx->depth;
+}
+
static void
check_leaves
(const struct svx_voxel* leaf,
@@ -99,6 +121,62 @@ check_leaves
ctx->nleaves += 1;
}
+static void
+test_at_accessor(struct svx_tree* tree, const size_t nvoxels)
+{
+ struct svx_tree_desc desc;
+ struct at_context ctx;
+ size_t nvxls;
+ double tree_sz;
+ double delta;
+ enum svx_axis axis;
+
+ CHK(svx_tree_get_desc(tree, &desc) == RES_OK);
+ CHK(desc.type == SVX_BINTREE);
+ CHK(desc.frame[0] = AXIS);
+
+ axis = desc.frame[0];
+ tree_sz = desc.upper[axis] - desc.lower[axis];
+ delta = tree_sz / (double)nvoxels;
+
+ ctx.depth = desc.depth;
+ CHK(ctx.depth > 0);
+
+ nvxls = nvoxels;
+
+ /* TODO Comment this */
+ while(ctx.depth-- != 0) {
+ double pos[3] = {0, 0, 0};
+ const size_t iter = desc.depth - ctx.depth - 1;
+ size_t i;
+
+ FOR_EACH(i, 0, nvxls) {
+ struct svx_voxel vox;
+ const double low = desc.lower[axis] + (double)i * delta;
+ const double upp = low + delta;
+ size_t mcode;
+
+ pos[axis] = desc.lower[axis] + ((double)i+1.0/(1u<<(2+iter)))*delta;
+
+ ctx.position = pos[axis];
+ CHK(svx_tree_at(tree, pos, max_lod, &ctx, &vox) == RES_OK);
+
+ mcode = i * (1u<<iter) + ((1u << iter) - 1);
+ mcode = MMIN(mcode, nvoxels-1);
+
+ CHK(*((double*)vox.data) == mcode);
+ CHK(vox.is_leaf == (desc.depth-1 == ctx.depth));
+ CHK(vox.depth == ctx.depth);
+ CHK(eq_eps(vox.lower[axis], low, 1.e-6));
+ CHK(eq_eps(vox.upper[axis], upp, 1.e-6));
+ }
+
+ nvxls = nvxls == 1 ? 0 : (nvxls + 1/*ceil*/)/2;
+ delta = MMIN(delta * 2, tree_sz);
+ }
+ CHK(nvxls == 0);
+}
+
int
main(int argc, char** argv)
{
@@ -119,7 +197,7 @@ main(int argc, char** argv)
low = 0.0;
upp = 1.0;
- axis = SVX_AXIS_Y;
+ axis = AXIS;
nvxls = 5;
vox_desc.get = get;
@@ -159,7 +237,7 @@ main(int argc, char** argv)
axis = SVX_AXIS_NONE__;
CHK(NEW_TREE(dev, low, upp, nvxls, axis, &vox_desc, &tree) == RES_BAD_ARG);
- axis = SVX_AXIS_Y;
+ axis = AXIS;
CHK(NEW_TREE(NULL, low, upp, nvxls, axis, &vox_desc, &tree) == RES_BAD_ARG);
CHK(NEW_TREE(dev, low, upp, nvxls, axis, NULL, &tree) == RES_BAD_ARG);
@@ -170,7 +248,7 @@ main(int argc, char** argv)
ctx.upper = upp;
ctx.nvoxels = nvxls;
ctx.depth = 4;
- ctx.axis = SVX_AXIS_Y;
+ ctx.axis = AXIS;
ctx.nleaves = 0;
CHK(ctx.leaves = MEM_CALLOC(&allocator, 5, 1));
@@ -188,6 +266,8 @@ main(int argc, char** argv)
CHK(tree_desc.lower[axis] == low);
CHK(tree_desc.upper[axis] == upp);
+ test_at_accessor(tree, nvxls);
+
#undef NEW_SCN
CHK(svx_tree_ref_put(tree) == RES_OK);
diff --git a/src/test_svx_octree.c b/src/test_svx_octree.c
@@ -170,7 +170,6 @@ max_lod
return vox->depth < ctx->depth;
}
-
static void
test_at_accessor(struct svx_tree* oct, const size_t nvoxels[3])
{
@@ -184,6 +183,9 @@ test_at_accessor(struct svx_tree* oct, const size_t nvoxels[3])
CHK(nvoxels != NULL);
CHK(svx_tree_get_desc(oct, &tree_desc) == RES_OK);
CHK(tree_desc.type == SVX_OCTREE);
+ CHK(tree_desc.frame[0] == SVX_AXIS_X);
+ CHK(tree_desc.frame[1] == SVX_AXIS_Y);
+ CHK(tree_desc.frame[2] == SVX_AXIS_Z);
ocsz[0] = tree_desc.upper[0] - tree_desc.lower[0];
ocsz[1] = tree_desc.upper[1] - tree_desc.lower[1];