commit 558ed6fc0554eb24d1d1c6add4d00532a473f2f6
parent a895f034092faa6eea8b4ea17d5730c21c927336
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 7 Mar 2018 11:06:19 +0100
Update the profile of svx_octree_for_each_leaf
Diffstat:
3 files changed, 73 insertions(+), 71 deletions(-)
diff --git a/src/svx.h b/src/svx.h
@@ -41,13 +41,17 @@
#define SVX_MAX_SIZEOF_VOXEL (sizeof(double)*16)
struct svx_voxel {
+ double lower[3], upper[3]; /* AABB of the voxel */
const void* data; /* Data of the voxel */
size_t id; /* Indentifier of the voxel */
size_t depth; /* Depth of the voxel, in [0, svx_octree_desc.depth[ */
int is_leaf; /* Define if the voxel is a leaf into the hierarchy */
};
-#define SVX_VOXEL_NULL__ { NULL, SIZE_MAX, SIZE_MAX, 0 }
+#define SVX_VOXEL_NULL__ { \
+ { DBL_MAX, DBL_MAX, DBL_MAX}, \
+ {-DBL_MAX,-DBL_MAX,-DBL_MAX}, \
+ NULL, SIZE_MAX, SIZE_MAX, 0 }
static const struct svx_voxel SVX_VOXEL_NULL = SVX_VOXEL_NULL__;
#define SVX_VOXEL_NONE(Voxel) ((Voxel)->id == SVX_VOXEL_NULL.id)
@@ -165,10 +169,8 @@ SVX_API res_T
svx_octree_for_each_leaf
(struct svx_octree* octree,
void (*functor)
- (const void* val, /* Value of the voxel */
+ (const struct svx_voxel* leaf,
const size_t ileaf, /* Identifier of the leaf in [0, #leafs[ */
- const double low[3], /* World space lower bound of the voxel */
- const double upp[3], /* World space upper bound of the voxel */
void* ctx), /* Client data */
void* context); /* Client data sent as the last argument of the callback */
@@ -186,8 +188,8 @@ svx_octree_at
const double position[3],
int (*filter) /* Filter function. May be NULL <=> traverse up to leaves */
(const struct svx_voxel* voxel,
- const double position[3],
- void* ctx),
+ const double position[3], /* Submitted position */
+ void* ctx), /* Client data */
void* context, /* Client data sent as the last argument of the filter func */
struct svx_voxel* voxel);
diff --git a/src/svx_octree.c b/src/svx_octree.c
@@ -627,23 +627,24 @@ res_T
svx_octree_for_each_leaf
(struct svx_octree* oct,
void (*func)
- (const void* val,
+ (const struct svx_voxel* leaf,
const size_t ileaf,
- const double low[3],
- const double upp[3],
void* ctx),
void* ctx)
{
struct stack_entry {
struct octree_index inode;
+ size_t depth;
double low[3];
double upp[3];
} stack[OCTREE_DEPTH_MAX*8];
int istack;
+ struct svx_voxel leaf = SVX_VOXEL_NULL;
size_t ileaf = 0;
if(!oct || !func) return RES_BAD_ARG;
+ stack[0].depth = 0;
stack[0].inode = oct->root;
stack[0].low[0] = oct->oclow[0];
stack[0].low[1] = oct->oclow[1];
@@ -655,6 +656,7 @@ svx_octree_for_each_leaf
do {
const struct stack_entry entry = stack[--istack];
+ const size_t child_depth = entry.depth + 1;
struct octree_xnode* node;
int ichild;
@@ -684,11 +686,9 @@ svx_octree_for_each_leaf
if(node->is_leaf & ichild_flag) {
struct octree_index iattr;
- const void* val;
iattr = octree_buffer_get_child_attr_index
(&oct->buffer, entry.inode, ichild);
- val = octree_buffer_get_attr(&oct->buffer, iattr);
ASSERT(upp[0] <= oct->upper[0]);
ASSERT(upp[1] <= oct->upper[1]);
@@ -697,8 +697,14 @@ svx_octree_for_each_leaf
ASSERT(low[1] >= oct->lower[1]);
ASSERT(low[2] >= oct->lower[2]);
- func(val, ileaf, low, upp, ctx);
- ileaf++;
+ d3_set(leaf.lower, low);
+ d3_set(leaf.upper, upp);
+ leaf.data = octree_buffer_get_attr(&oct->buffer, iattr);
+ leaf.id = absolute_attr_index(&oct->buffer, iattr);
+ leaf.depth = child_depth;
+ leaf.is_leaf = 1;
+
+ func(&leaf, ileaf++, ctx);
} else {
struct stack_entry* top = stack + istack;
@@ -710,6 +716,7 @@ svx_octree_for_each_leaf
top->upp[0] = upp[0];
top->upp[1] = upp[1];
top->upp[2] = upp[2];
+ top->depth = child_depth;
++istack;
}
}
diff --git a/src/test_svx_octree.c b/src/test_svx_octree.c
@@ -23,6 +23,7 @@ struct check_context {
double* lower;
double* upper;
size_t* nvoxels;
+ size_t depth;
};
static int
@@ -91,28 +92,27 @@ get(const size_t xyz[3], void* dst, void* ctx)
}
static void
-check_voxel
- (const void* val,
- const size_t ivoxel,
- const double low[3],
- const double upp[3],
+check_leaves
+ (const struct svx_voxel* leaf,
+ const size_t ileaf,
void* context)
{
- const double* dbl = val;
+ const double* dbl = NULL;
struct check_context* ctx = context;
uint64_t mcode;
uint32_t xyz[3];
double lower[3];
double delta[3];
- CHK(val != NULL);
- CHK(low != NULL);
- CHK(upp != NULL);
+ CHK(leaf != NULL);
+ CHK(leaf->data != NULL);
CHK(ctx != NULL);
- 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]);
+ CHK(leaf->lower[0] < leaf->upper[0]);
+ CHK(leaf->lower[1] < leaf->upper[1]);
+ CHK(leaf->lower[2] < leaf->upper[2]);
+ CHK(ileaf < ctx->nvoxels[0]*ctx->nvoxels[1]*ctx->nvoxels[2]);
+
+ dbl = leaf->data;
CHK(*dbl >= 0);
mcode = (uint64_t)(*dbl);
@@ -127,78 +127,70 @@ check_voxel
lower[1] = xyz[1] * delta[1];
lower[2] = xyz[2] * delta[2];
- CHK(eq_eps(lower[0], low[0], 1.e-6));
- CHK(eq_eps(lower[1], low[1], 1.e-6));
- CHK(eq_eps(lower[2], low[2], 1.e-6));
- CHK(eq_eps(lower[0] + delta[0], upp[0], 1.e-6));
- CHK(eq_eps(lower[1] + delta[1], upp[1], 1.e-6));
- CHK(eq_eps(lower[2] + delta[2], upp[2], 1.e-6));
+ CHK(eq_eps(lower[0], leaf->lower[0], 1.e-6));
+ CHK(eq_eps(lower[1], leaf->lower[1], 1.e-6));
+ CHK(eq_eps(lower[2], leaf->lower[2], 1.e-6));
+ CHK(eq_eps(lower[0] + delta[0], leaf->upper[0], 1.e-6));
+ CHK(eq_eps(lower[1] + delta[1], leaf->upper[1], 1.e-6));
+ CHK(eq_eps(lower[2] + delta[2], leaf->upper[2], 1.e-6));
+
+ CHK(leaf->depth == ctx->depth - 1);
}
static void
write_points
- (const void* val,
- const size_t ivoxel,
- const double low[3],
- const double upp[3],
+ (const struct svx_voxel* leaf,
+ const size_t ileaf,
void* context)
{
FILE* stream = context;
- (void)val, (void)ivoxel;
+ (void)ileaf;
CHK(stream != NULL);
- CHK(low != NULL);
- CHK(upp != NULL);
+ CHK(leaf != 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]);
+ leaf->lower[0], leaf->lower[1], leaf->lower[2],
+ leaf->upper[0], leaf->lower[1], leaf->lower[2],
+ leaf->lower[0], leaf->upper[1], leaf->lower[2],
+ leaf->upper[0], leaf->upper[1], leaf->lower[2],
+ leaf->lower[0], leaf->lower[1], leaf->upper[2],
+ leaf->upper[0], leaf->lower[1], leaf->upper[2],
+ leaf->lower[0], leaf->upper[1], leaf->upper[2],
+ leaf->upper[0], leaf->upper[1], leaf->upper[2]);
}
static void
write_cells
- (const void* val,
- const size_t ivoxel,
- const double low[3],
- const double upp[3],
+ (const struct svx_voxel* leaf,
+ const size_t ileaf,
void* context)
{
FILE* stream = context;
- (void)ivoxel, (void)val;
CHK(stream != NULL);
- CHK(low != NULL);
- CHK(upp != NULL);
+ CHK(leaf != 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));
+ (unsigned long)(ileaf*8 + 0),
+ (unsigned long)(ileaf*8 + 1),
+ (unsigned long)(ileaf*8 + 2),
+ (unsigned long)(ileaf*8 + 3),
+ (unsigned long)(ileaf*8 + 4),
+ (unsigned long)(ileaf*8 + 5),
+ (unsigned long)(ileaf*8 + 6),
+ (unsigned long)(ileaf*8 + 7));
}
static void
write_scalars
- (const void* val,
- const size_t ivoxel,
- const double low[3],
- const double upp[3],
+ (const struct svx_voxel* leaf,
+ const size_t ileaf,
void* context)
{
FILE* stream = context;
- (void)ivoxel;
+ (void)ileaf;
CHK(stream != NULL);
- CHK(low != NULL);
- CHK(upp != NULL);
- fprintf(stream, "%g\n", *(double*)val);
+ CHK(leaf != NULL);
+ fprintf(stream, "%g\n", *(double*)leaf->data);
}
static void
@@ -341,6 +333,7 @@ main(int argc, char** argv)
ctx.lower = low;
ctx.upper = upp;
ctx.nvoxels = nvxls;
+ ctx.depth = 4;
#define NEW_SCN svx_octree_create
@@ -393,7 +386,7 @@ main(int argc, char** argv)
CHK(NEW_SCN(dev, low, upp, nvxls, &voxdesc, &oct) == RES_OK);
- CHK(svx_octree_for_each_leaf(oct, check_voxel, &ctx) == RES_OK);
+ CHK(svx_octree_for_each_leaf(oct, check_leaves, &ctx) == RES_OK);
CHK(svx_octree_get_desc(NULL, &octdesc) == RES_BAD_ARG);
CHK(svx_octree_get_desc(oct, NULL) == RES_BAD_ARG);