Blender V4.3
BLI_kdopbvh_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7/* TODO: ray intersection, overlap ... etc. */
8
9#include "MEM_guardedalloc.h"
10
11#include "BLI_compiler_attrs.h"
12#include "BLI_kdopbvh.h"
13#include "BLI_math_vector.h"
14#include "BLI_rand.h"
15
16/* -------------------------------------------------------------------- */
17/* Helper Functions */
18
19static void rng_v3_round(float *coords, int coords_len, RNG *rng, int round, float scale)
20{
21 for (int i = 0; i < coords_len; i++) {
22 float f = BLI_rng_get_float(rng) * 2.0f - 1.0f;
23 coords[i] = (float(int(f * round)) / float(round)) * scale;
24 }
25}
26
27/* -------------------------------------------------------------------- */
28/* Tests */
29
30TEST(kdopbvh, Empty)
31{
32 BVHTree *tree = BLI_bvhtree_new(0, 0.0, 8, 8);
36}
37
38TEST(kdopbvh, Single)
39{
40 BVHTree *tree = BLI_bvhtree_new(1, 0.0, 8, 8);
41 {
42 float co[3] = {0};
43 BLI_bvhtree_insert(tree, 0, co, 1);
44 }
45
47
50}
51
52static void optimal_check_callback(void *userdata,
53 int index,
54 const float co[3],
55 BVHTreeNearest *nearest)
56{
57 float(*points)[3] = (float(*)[3])userdata;
58
59 /* BVH_NEAREST_OPTIMAL_ORDER should hit the right node on the first try */
60 EXPECT_EQ(nearest->index, -1);
61 EXPECT_EQ_ARRAY(co, points[index], 3);
62
63 nearest->index = index;
64 nearest->dist_sq = len_squared_v3v3(co, points[index]);
65}
66
72 int points_len, float scale, int round, int random_seed, bool optimal = false)
73{
74 RNG *rng = BLI_rng_new(random_seed);
75 BVHTree *tree = BLI_bvhtree_new(points_len, 0.0, 8, 8);
76
77 void *mem = MEM_mallocN(sizeof(float[3]) * points_len, __func__);
78 float(*points)[3] = (float(*)[3])mem;
79
80 for (int i = 0; i < points_len; i++) {
81 rng_v3_round(points[i], 3, rng, round, scale);
82 BLI_bvhtree_insert(tree, i, points[i], 1);
83 }
85
86 /* first find each point */
88 int flags = optimal ? BVH_NEAREST_OPTIMAL_ORDER : 0;
89
90 for (int i = 0; i < points_len; i++) {
91 const int j = BLI_bvhtree_find_nearest_ex(tree, points[i], nullptr, callback, points, flags);
92 if (j != i) {
93#if 0
94 const float dist = len_v3v3(points[i], points[j]);
95 if (dist > (1.0f / float(round))) {
96 printf("%.15f (%d %d)\n", dist, i, j);
97 print_v3_id(points[i]);
98 print_v3_id(points[j]);
99 fflush(stdout);
100 }
101#endif
102 EXPECT_GE(j, 0);
103 EXPECT_LT(j, points_len);
104 EXPECT_EQ_ARRAY(points[i], points[j], 3);
105 }
106 }
108 BLI_rng_free(rng);
109 MEM_freeN(points);
110}
111
112TEST(kdopbvh, FindNearest_1)
113{
114 find_nearest_points_test(1, 1.0, 1000, 1234);
115}
116TEST(kdopbvh, FindNearest_2)
117{
118 find_nearest_points_test(2, 1.0, 1000, 123);
119}
120TEST(kdopbvh, FindNearest_500)
121{
122 find_nearest_points_test(500, 1.0, 1000, 12);
123}
124
125TEST(kdopbvh, OptimalFindNearest_1)
126{
127 find_nearest_points_test(1, 1.0, 1000, 1234, true);
128}
129TEST(kdopbvh, OptimalFindNearest_2)
130{
131 find_nearest_points_test(2, 1.0, 1000, 123, true);
132}
133TEST(kdopbvh, OptimalFindNearest_500)
134{
135 find_nearest_points_test(500, 1.0, 1000, 12, true);
136}
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
@ BVH_NEAREST_OPTIMAL_ORDER
Definition BLI_kdopbvh.h:85
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
int BLI_bvhtree_get_len(const BVHTree *tree)
void(* BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
Definition BLI_kdopbvh.h:97
int BLI_bvhtree_find_nearest_ex(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag)
static void optimal_check_callback(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
TEST(kdopbvh, Empty)
static void rng_v3_round(float *coords, int coords_len, RNG *rng, int round, float scale)
static void find_nearest_points_test(int points_len, float scale, int round, int random_seed, bool optimal=false)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
#define print_v3_id(v)
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
Random number functions.
struct RNG * BLI_rng_new(unsigned int seed)
Definition rand.cc:39
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition rand.cc:58
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition rand.cc:93
Read Guarded memory(de)allocation.
#define printf
DEGForeachIDComponentCallback callback
KDTree_3d * tree
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
Definition rand.cc:33