Blender  V2.93
kdtree_impl.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_kdtree_impl.h"
24 #include "BLI_math.h"
25 #include "BLI_strict_flags.h"
26 #include "BLI_utildefines.h"
27 
28 #define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
29 #define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
30 #define BLI_kdtree_nd_(id) _CONCAT(KDTREE_PREFIX_ID, _##id)
31 
32 typedef struct KDTreeNode_head {
34  float co[KD_DIMS];
35  int index;
37 
38 typedef struct KDTreeNode {
40  float co[KD_DIMS];
41  int index;
42  uint d; /* range is only (0..KD_DIMS - 1) */
44 
45 struct KDTree {
49 #ifdef DEBUG
50  bool is_balanced; /* ensure we call balance first */
51  uint nodes_len_capacity; /* max size of the tree */
52 #endif
53 };
54 
55 #define KD_STACK_INIT 100 /* initial size for array (on the stack) */
56 #define KD_NEAR_ALLOC_INC 100 /* alloc increment for collecting nearest */
57 #define KD_FOUND_ALLOC_INC 50 /* alloc increment for collecting nearest */
58 
59 #define KD_NODE_UNSET ((uint)-1)
60 
65 #define KD_NODE_ROOT_IS_INIT ((uint)-2)
66 
67 /* -------------------------------------------------------------------- */
71 static void copy_vn_vn(float v0[KD_DIMS], const float v1[KD_DIMS])
72 {
73  for (uint j = 0; j < KD_DIMS; j++) {
74  v0[j] = v1[j];
75  }
76 }
77 
78 static float len_squared_vnvn(const float v0[KD_DIMS], const float v1[KD_DIMS])
79 {
80  float d = 0.0f;
81  for (uint j = 0; j < KD_DIMS; j++) {
82  d += square_f(v0[j] - v1[j]);
83  }
84  return d;
85 }
86 
87 static float len_squared_vnvn_cb(const float co_kdtree[KD_DIMS],
88  const float co_search[KD_DIMS],
89  const void *UNUSED(user_data))
90 {
91  return len_squared_vnvn(co_kdtree, co_search);
92 }
93 
99 KDTree *BLI_kdtree_nd_(new)(uint nodes_len_capacity)
100 {
101  KDTree *tree;
102 
103  tree = MEM_mallocN(sizeof(KDTree), "KDTree");
104  tree->nodes = MEM_mallocN(sizeof(KDTreeNode) * nodes_len_capacity, "KDTreeNode");
105  tree->nodes_len = 0;
106  tree->root = KD_NODE_ROOT_IS_INIT;
107 
108 #ifdef DEBUG
109  tree->is_balanced = false;
110  tree->nodes_len_capacity = nodes_len_capacity;
111 #endif
112 
113  return tree;
114 }
115 
117 {
118  if (tree) {
119  MEM_freeN(tree->nodes);
120  MEM_freeN(tree);
121  }
122 }
123 
127 void BLI_kdtree_nd_(insert)(KDTree *tree, int index, const float co[KD_DIMS])
128 {
129  KDTreeNode *node = &tree->nodes[tree->nodes_len++];
130 
131 #ifdef DEBUG
132  BLI_assert(tree->nodes_len <= tree->nodes_len_capacity);
133 #endif
134 
135  /* note, array isn't calloc'd,
136  * need to initialize all struct members */
137 
138  node->left = node->right = KD_NODE_UNSET;
139  copy_vn_vn(node->co, co);
140  node->index = index;
141  node->d = 0;
142 
143 #ifdef DEBUG
144  tree->is_balanced = false;
145 #endif
146 }
147 
148 static uint kdtree_balance(KDTreeNode *nodes, uint nodes_len, uint axis, const uint ofs)
149 {
150  KDTreeNode *node;
151  float co;
152  uint left, right, median, i, j;
153 
154  if (nodes_len <= 0) {
155  return KD_NODE_UNSET;
156  }
157  else if (nodes_len == 1) {
158  return 0 + ofs;
159  }
160 
161  /* Quick-sort style sorting around median. */
162  left = 0;
163  right = nodes_len - 1;
164  median = nodes_len / 2;
165 
166  while (right > left) {
167  co = nodes[right].co[axis];
168  i = left - 1;
169  j = right;
170 
171  while (1) {
172  while (nodes[++i].co[axis] < co) { /* pass */
173  }
174  while (nodes[--j].co[axis] > co && j > left) { /* pass */
175  }
176 
177  if (i >= j) {
178  break;
179  }
180 
181  SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[j]);
182  }
183 
184  SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[right]);
185  if (i >= median) {
186  right = i - 1;
187  }
188  if (i <= median) {
189  left = i + 1;
190  }
191  }
192 
193  /* set node and sort subnodes */
194  node = &nodes[median];
195  node->d = axis;
196  axis = (axis + 1) % KD_DIMS;
197  node->left = kdtree_balance(nodes, median, axis, ofs);
198  node->right = kdtree_balance(
199  nodes + median + 1, (nodes_len - (median + 1)), axis, (median + 1) + ofs);
200 
201  return median + ofs;
202 }
203 
205 {
206  if (tree->root != KD_NODE_ROOT_IS_INIT) {
207  for (uint i = 0; i < tree->nodes_len; i++) {
208  tree->nodes[i].left = KD_NODE_UNSET;
209  tree->nodes[i].right = KD_NODE_UNSET;
210  }
211  }
212 
213  tree->root = kdtree_balance(tree->nodes, tree->nodes_len, 0, 0);
214 
215 #ifdef DEBUG
216  tree->is_balanced = true;
217 #endif
218 }
219 
220 static uint *realloc_nodes(uint *stack, uint *stack_len_capacity, const bool is_alloc)
221 {
222  uint *stack_new = MEM_mallocN((*stack_len_capacity + KD_NEAR_ALLOC_INC) * sizeof(uint),
223  "KDTree.treestack");
224  memcpy(stack_new, stack, *stack_len_capacity * sizeof(uint));
225  // memset(stack_new + *stack_len_capacity, 0, sizeof(uint) * KD_NEAR_ALLOC_INC);
226  if (is_alloc) {
227  MEM_freeN(stack);
228  }
229  *stack_len_capacity += KD_NEAR_ALLOC_INC;
230  return stack_new;
231 }
232 
237  const float co[KD_DIMS],
238  KDTreeNearest *r_nearest)
239 {
240  const KDTreeNode *nodes = tree->nodes;
241  const KDTreeNode *root, *min_node;
242  uint *stack, stack_default[KD_STACK_INIT];
243  float min_dist, cur_dist;
244  uint stack_len_capacity, cur = 0;
245 
246 #ifdef DEBUG
247  BLI_assert(tree->is_balanced == true);
248 #endif
249 
250  if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
251  return -1;
252  }
253 
254  stack = stack_default;
255  stack_len_capacity = KD_STACK_INIT;
256 
257  root = &nodes[tree->root];
258  min_node = root;
259  min_dist = len_squared_vnvn(root->co, co);
260 
261  if (co[root->d] < root->co[root->d]) {
262  if (root->right != KD_NODE_UNSET) {
263  stack[cur++] = root->right;
264  }
265  if (root->left != KD_NODE_UNSET) {
266  stack[cur++] = root->left;
267  }
268  }
269  else {
270  if (root->left != KD_NODE_UNSET) {
271  stack[cur++] = root->left;
272  }
273  if (root->right != KD_NODE_UNSET) {
274  stack[cur++] = root->right;
275  }
276  }
277 
278  while (cur--) {
279  const KDTreeNode *node = &nodes[stack[cur]];
280 
281  cur_dist = node->co[node->d] - co[node->d];
282 
283  if (cur_dist < 0.0f) {
284  cur_dist = -cur_dist * cur_dist;
285 
286  if (-cur_dist < min_dist) {
287  cur_dist = len_squared_vnvn(node->co, co);
288  if (cur_dist < min_dist) {
289  min_dist = cur_dist;
290  min_node = node;
291  }
292  if (node->left != KD_NODE_UNSET) {
293  stack[cur++] = node->left;
294  }
295  }
296  if (node->right != KD_NODE_UNSET) {
297  stack[cur++] = node->right;
298  }
299  }
300  else {
301  cur_dist = cur_dist * cur_dist;
302 
303  if (cur_dist < min_dist) {
304  cur_dist = len_squared_vnvn(node->co, co);
305  if (cur_dist < min_dist) {
306  min_dist = cur_dist;
307  min_node = node;
308  }
309  if (node->right != KD_NODE_UNSET) {
310  stack[cur++] = node->right;
311  }
312  }
313  if (node->left != KD_NODE_UNSET) {
314  stack[cur++] = node->left;
315  }
316  }
317  if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
318  stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
319  }
320  }
321 
322  if (r_nearest) {
323  r_nearest->index = min_node->index;
324  r_nearest->dist = sqrtf(min_dist);
325  copy_vn_vn(r_nearest->co, min_node->co);
326  }
327 
328  if (stack != stack_default) {
329  MEM_freeN(stack);
330  }
331 
332  return min_node->index;
333 }
334 
343  const KDTree *tree,
344  const float co[KD_DIMS],
345  int (*filter_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq),
346  void *user_data,
347  KDTreeNearest *r_nearest)
348 {
349  const KDTreeNode *nodes = tree->nodes;
350  const KDTreeNode *min_node = NULL;
351 
352  uint *stack, stack_default[KD_STACK_INIT];
353  float min_dist = FLT_MAX, cur_dist;
354  uint stack_len_capacity, cur = 0;
355 
356 #ifdef DEBUG
357  BLI_assert(tree->is_balanced == true);
358 #endif
359 
360  if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
361  return -1;
362  }
363 
364  stack = stack_default;
365  stack_len_capacity = ARRAY_SIZE(stack_default);
366 
367 #define NODE_TEST_NEAREST(node) \
368  { \
369  const float dist_sq = len_squared_vnvn((node)->co, co); \
370  if (dist_sq < min_dist) { \
371  const int result = filter_cb(user_data, (node)->index, (node)->co, dist_sq); \
372  if (result == 1) { \
373  min_dist = dist_sq; \
374  min_node = node; \
375  } \
376  else if (result == 0) { \
377  /* pass */ \
378  } \
379  else { \
380  BLI_assert(result == -1); \
381  goto finally; \
382  } \
383  } \
384  } \
385  ((void)0)
386 
387  stack[cur++] = tree->root;
388 
389  while (cur--) {
390  const KDTreeNode *node = &nodes[stack[cur]];
391 
392  cur_dist = node->co[node->d] - co[node->d];
393 
394  if (cur_dist < 0.0f) {
395  cur_dist = -cur_dist * cur_dist;
396 
397  if (-cur_dist < min_dist) {
399 
400  if (node->left != KD_NODE_UNSET) {
401  stack[cur++] = node->left;
402  }
403  }
404  if (node->right != KD_NODE_UNSET) {
405  stack[cur++] = node->right;
406  }
407  }
408  else {
409  cur_dist = cur_dist * cur_dist;
410 
411  if (cur_dist < min_dist) {
413 
414  if (node->right != KD_NODE_UNSET) {
415  stack[cur++] = node->right;
416  }
417  }
418  if (node->left != KD_NODE_UNSET) {
419  stack[cur++] = node->left;
420  }
421  }
422  if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
423  stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
424  }
425  }
426 
427 #undef NODE_TEST_NEAREST
428 
429 finally:
430  if (stack != stack_default) {
431  MEM_freeN(stack);
432  }
433 
434  if (min_node) {
435  if (r_nearest) {
436  r_nearest->index = min_node->index;
437  r_nearest->dist = sqrtf(min_dist);
438  copy_vn_vn(r_nearest->co, min_node->co);
439  }
440 
441  return min_node->index;
442  }
443  else {
444  return -1;
445  }
446 }
447 
449  uint *nearest_len,
450  const uint nearest_len_capacity,
451  const int index,
452  const float dist,
453  const float co[KD_DIMS])
454 {
455  uint i;
456 
457  if (*nearest_len < nearest_len_capacity) {
458  (*nearest_len)++;
459  }
460 
461  for (i = *nearest_len - 1; i > 0; i--) {
462  if (dist >= nearest[i - 1].dist) {
463  break;
464  }
465  else {
466  nearest[i] = nearest[i - 1];
467  }
468  }
469 
470  nearest[i].index = index;
471  nearest[i].dist = dist;
472  copy_vn_vn(nearest[i].co, co);
473 }
474 
481  const KDTree *tree,
482  const float co[KD_DIMS],
483  KDTreeNearest r_nearest[],
484  const uint nearest_len_capacity,
485  float (*len_sq_fn)(const float co_search[KD_DIMS],
486  const float co_test[KD_DIMS],
487  const void *user_data),
488  const void *user_data)
489 {
490  const KDTreeNode *nodes = tree->nodes;
491  const KDTreeNode *root;
492  uint *stack, stack_default[KD_STACK_INIT];
493  float cur_dist;
494  uint stack_len_capacity, cur = 0;
495  uint i, nearest_len = 0;
496 
497 #ifdef DEBUG
498  BLI_assert(tree->is_balanced == true);
499 #endif
500 
501  if (UNLIKELY((tree->root == KD_NODE_UNSET) || nearest_len_capacity == 0)) {
502  return 0;
503  }
504 
505  if (len_sq_fn == NULL) {
506  len_sq_fn = len_squared_vnvn_cb;
508  }
509 
510  stack = stack_default;
511  stack_len_capacity = ARRAY_SIZE(stack_default);
512 
513  root = &nodes[tree->root];
514 
515  cur_dist = len_sq_fn(co, root->co, user_data);
517  r_nearest, &nearest_len, nearest_len_capacity, root->index, cur_dist, root->co);
518 
519  if (co[root->d] < root->co[root->d]) {
520  if (root->right != KD_NODE_UNSET) {
521  stack[cur++] = root->right;
522  }
523  if (root->left != KD_NODE_UNSET) {
524  stack[cur++] = root->left;
525  }
526  }
527  else {
528  if (root->left != KD_NODE_UNSET) {
529  stack[cur++] = root->left;
530  }
531  if (root->right != KD_NODE_UNSET) {
532  stack[cur++] = root->right;
533  }
534  }
535 
536  while (cur--) {
537  const KDTreeNode *node = &nodes[stack[cur]];
538 
539  cur_dist = node->co[node->d] - co[node->d];
540 
541  if (cur_dist < 0.0f) {
542  cur_dist = -cur_dist * cur_dist;
543 
544  if (nearest_len < nearest_len_capacity || -cur_dist < r_nearest[nearest_len - 1].dist) {
545  cur_dist = len_sq_fn(co, node->co, user_data);
546 
547  if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
549  r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
550  }
551 
552  if (node->left != KD_NODE_UNSET) {
553  stack[cur++] = node->left;
554  }
555  }
556  if (node->right != KD_NODE_UNSET) {
557  stack[cur++] = node->right;
558  }
559  }
560  else {
561  cur_dist = cur_dist * cur_dist;
562 
563  if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
564  cur_dist = len_sq_fn(co, node->co, user_data);
565  if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
567  r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
568  }
569 
570  if (node->right != KD_NODE_UNSET) {
571  stack[cur++] = node->right;
572  }
573  }
574  if (node->left != KD_NODE_UNSET) {
575  stack[cur++] = node->left;
576  }
577  }
578  if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
579  stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
580  }
581  }
582 
583  for (i = 0; i < nearest_len; i++) {
584  r_nearest[i].dist = sqrtf(r_nearest[i].dist);
585  }
586 
587  if (stack != stack_default) {
588  MEM_freeN(stack);
589  }
590 
591  return (int)nearest_len;
592 }
593 
595  const float co[KD_DIMS],
596  KDTreeNearest r_nearest[],
597  const uint nearest_len_capacity)
598 {
600  tree, co, r_nearest, nearest_len_capacity, NULL, NULL);
601 }
602 
603 static int nearest_cmp_dist(const void *a, const void *b)
604 {
605  const KDTreeNearest *kda = a;
606  const KDTreeNearest *kdb = b;
607 
608  if (kda->dist < kdb->dist) {
609  return -1;
610  }
611  else if (kda->dist > kdb->dist) {
612  return 1;
613  }
614  else {
615  return 0;
616  }
617 }
618 static void nearest_add_in_range(KDTreeNearest **r_nearest,
619  uint nearest_index,
620  uint *nearest_len_capacity,
621  const int index,
622  const float dist,
623  const float co[KD_DIMS])
624 {
625  KDTreeNearest *to;
626 
627  if (UNLIKELY(nearest_index >= *nearest_len_capacity)) {
628  *r_nearest = MEM_reallocN_id(
629  *r_nearest, (*nearest_len_capacity += KD_FOUND_ALLOC_INC) * sizeof(KDTreeNode), __func__);
630  }
631 
632  to = (*r_nearest) + nearest_index;
633 
634  to->index = index;
635  to->dist = sqrtf(dist);
636  copy_vn_vn(to->co, co);
637 }
638 
645  const KDTree *tree,
646  const float co[KD_DIMS],
647  KDTreeNearest **r_nearest,
648  const float range,
649  float (*len_sq_fn)(const float co_search[KD_DIMS],
650  const float co_test[KD_DIMS],
651  const void *user_data),
652  const void *user_data)
653 {
654  const KDTreeNode *nodes = tree->nodes;
655  uint *stack, stack_default[KD_STACK_INIT];
656  KDTreeNearest *nearest = NULL;
657  const float range_sq = range * range;
658  float dist_sq;
659  uint stack_len_capacity, cur = 0;
660  uint nearest_len = 0, nearest_len_capacity = 0;
661 
662 #ifdef DEBUG
663  BLI_assert(tree->is_balanced == true);
664 #endif
665 
666  if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
667  return 0;
668  }
669 
670  if (len_sq_fn == NULL) {
671  len_sq_fn = len_squared_vnvn_cb;
673  }
674 
675  stack = stack_default;
676  stack_len_capacity = ARRAY_SIZE(stack_default);
677 
678  stack[cur++] = tree->root;
679 
680  while (cur--) {
681  const KDTreeNode *node = &nodes[stack[cur]];
682 
683  if (co[node->d] + range < node->co[node->d]) {
684  if (node->left != KD_NODE_UNSET) {
685  stack[cur++] = node->left;
686  }
687  }
688  else if (co[node->d] - range > node->co[node->d]) {
689  if (node->right != KD_NODE_UNSET) {
690  stack[cur++] = node->right;
691  }
692  }
693  else {
694  dist_sq = len_sq_fn(co, node->co, user_data);
695  if (dist_sq <= range_sq) {
697  &nearest, nearest_len++, &nearest_len_capacity, node->index, dist_sq, node->co);
698  }
699 
700  if (node->left != KD_NODE_UNSET) {
701  stack[cur++] = node->left;
702  }
703  if (node->right != KD_NODE_UNSET) {
704  stack[cur++] = node->right;
705  }
706  }
707 
708  if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
709  stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
710  }
711  }
712 
713  if (stack != stack_default) {
714  MEM_freeN(stack);
715  }
716 
717  if (nearest_len) {
718  qsort(nearest, nearest_len, sizeof(KDTreeNearest), nearest_cmp_dist);
719  }
720 
721  *r_nearest = nearest;
722 
723  return (int)nearest_len;
724 }
725 
727  const float co[KD_DIMS],
728  KDTreeNearest **r_nearest,
729  const float range)
730 {
731  return BLI_kdtree_nd_(range_search_with_len_squared_cb)(tree, co, r_nearest, range, NULL, NULL);
732 }
733 
744  const KDTree *tree,
745  const float co[KD_DIMS],
746  float range,
747  bool (*search_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq),
748  void *user_data)
749 {
750  const KDTreeNode *nodes = tree->nodes;
751 
752  uint *stack, stack_default[KD_STACK_INIT];
753  float range_sq = range * range, dist_sq;
754  uint stack_len_capacity, cur = 0;
755 
756 #ifdef DEBUG
757  BLI_assert(tree->is_balanced == true);
758 #endif
759 
760  if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
761  return;
762  }
763 
764  stack = stack_default;
765  stack_len_capacity = ARRAY_SIZE(stack_default);
766 
767  stack[cur++] = tree->root;
768 
769  while (cur--) {
770  const KDTreeNode *node = &nodes[stack[cur]];
771 
772  if (co[node->d] + range < node->co[node->d]) {
773  if (node->left != KD_NODE_UNSET) {
774  stack[cur++] = node->left;
775  }
776  }
777  else if (co[node->d] - range > node->co[node->d]) {
778  if (node->right != KD_NODE_UNSET) {
779  stack[cur++] = node->right;
780  }
781  }
782  else {
783  dist_sq = len_squared_vnvn(node->co, co);
784  if (dist_sq <= range_sq) {
785  if (search_cb(user_data, node->index, node->co, dist_sq) == false) {
786  goto finally;
787  }
788  }
789 
790  if (node->left != KD_NODE_UNSET) {
791  stack[cur++] = node->left;
792  }
793  if (node->right != KD_NODE_UNSET) {
794  stack[cur++] = node->right;
795  }
796  }
797 
798  if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
799  stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
800  }
801  }
802 
803 finally:
804  if (stack != stack_default) {
805  MEM_freeN(stack);
806  }
807 }
808 
813 static uint *kdtree_order(const KDTree *tree)
814 {
815  const KDTreeNode *nodes = tree->nodes;
816  uint *order = MEM_mallocN(sizeof(uint) * tree->nodes_len, __func__);
817  for (uint i = 0; i < tree->nodes_len; i++) {
818  order[nodes[i].index] = i;
819  }
820  return order;
821 }
822 
823 /* -------------------------------------------------------------------- */
828  /* Static */
830  float range;
831  float range_sq;
834 
835  /* Per Search */
837  int search;
838 };
839 
840 static void deduplicate_recursive(const struct DeDuplicateParams *p, uint i)
841 {
842  const KDTreeNode *node = &p->nodes[i];
843  if (p->search_co[node->d] + p->range <= node->co[node->d]) {
844  if (node->left != KD_NODE_UNSET) {
845  deduplicate_recursive(p, node->left);
846  }
847  }
848  else if (p->search_co[node->d] - p->range >= node->co[node->d]) {
849  if (node->right != KD_NODE_UNSET) {
850  deduplicate_recursive(p, node->right);
851  }
852  }
853  else {
854  if ((p->search != node->index) && (p->duplicates[node->index] == -1)) {
855  if (len_squared_vnvn(node->co, p->search_co) <= p->range_sq) {
856  p->duplicates[node->index] = (int)p->search;
857  *p->duplicates_found += 1;
858  }
859  }
860  if (node->left != KD_NODE_UNSET) {
861  deduplicate_recursive(p, node->left);
862  }
863  if (node->right != KD_NODE_UNSET) {
864  deduplicate_recursive(p, node->right);
865  }
866  }
867 }
868 
888  const float range,
889  bool use_index_order,
890  int *duplicates)
891 {
892  int found = 0;
893  struct DeDuplicateParams p = {
894  .nodes = tree->nodes,
895  .range = range,
896  .range_sq = square_f(range),
897  .duplicates = duplicates,
898  .duplicates_found = &found,
899  };
900 
901  if (use_index_order) {
903  for (uint i = 0; i < tree->nodes_len; i++) {
904  const uint node_index = order[i];
905  const int index = (int)i;
906  if (ELEM(duplicates[index], -1, index)) {
907  p.search = index;
908  copy_vn_vn(p.search_co, tree->nodes[node_index].co);
909  int found_prev = found;
910  deduplicate_recursive(&p, tree->root);
911  if (found != found_prev) {
912  /* Prevent chains of doubles. */
913  duplicates[index] = index;
914  }
915  }
916  }
917  MEM_freeN(order);
918  }
919  else {
920  for (uint i = 0; i < tree->nodes_len; i++) {
921  const uint node_index = i;
922  const int index = p.nodes[node_index].index;
923  if (ELEM(duplicates[index], -1, index)) {
924  p.search = index;
925  copy_vn_vn(p.search_co, tree->nodes[node_index].co);
926  int found_prev = found;
927  deduplicate_recursive(&p, tree->root);
928  if (found != found_prev) {
929  /* Prevent chains of doubles. */
930  duplicates[index] = index;
931  }
932  }
933  }
934  }
935  return found;
936 }
937 
940 /* -------------------------------------------------------------------- */
944 static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
945 {
946  const KDTreeNode *n0 = n0_p;
947  const KDTreeNode *n1 = n1_p;
948  for (uint j = 0; j < KD_DIMS; j++) {
949  if (n0->co[j] < n1->co[j]) {
950  return -1;
951  }
952  else if (n0->co[j] > n1->co[j]) {
953  return 1;
954  }
955  }
956  /* Sort by pointer so the first added will be used.
957  * assignment below ignores const correctness,
958  * however the values aren't used for sorting and are to be discarded. */
959  if (n0 < n1) {
960  ((KDTreeNode *)n1)->d = KD_DIMS; /* tag invalid */
961  return -1;
962  }
963  else {
964  ((KDTreeNode *)n0)->d = KD_DIMS; /* tag invalid */
965  return 1;
966  }
967 }
968 
975 {
976 #ifdef DEBUG
977  tree->is_balanced = false;
978 #endif
979  qsort(tree->nodes, (size_t)tree->nodes_len, sizeof(*tree->nodes), kdtree_node_cmp_deduplicate);
980  uint j = 0;
981  for (uint i = 0; i < tree->nodes_len; i++) {
982  if (tree->nodes[i].d != KD_DIMS) {
983  if (i != j) {
984  tree->nodes[j] = tree->nodes[i];
985  }
986  j++;
987  }
988  }
989  tree->nodes_len = j;
990  return (int)tree->nodes_len;
991 }
992 
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define KD_DIMS
Definition: BLI_kdtree.h:62
A kd-tree for nearest neighbor search.
MINLINE float square_f(float a)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
unsigned int uint
Definition: BLI_sys_types.h:83
#define ARRAY_SIZE(arr)
#define SWAP(type, a, b)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
OperationNode * node
void * user_data
void * tree
static void deduplicate_recursive(const struct DeDuplicateParams *p, uint i)
Definition: kdtree_impl.h:840
int BLI_kdtree_nd_() calc_duplicates_fast(const KDTree *tree, const float range, bool use_index_order, int *duplicates)
Definition: kdtree_impl.h:887
int BLI_kdtree_nd_() find_nearest_n_with_len_squared_cb(const KDTree *tree, const float co[KD_DIMS], KDTreeNearest r_nearest[], const uint nearest_len_capacity, float(*len_sq_fn)(const float co_search[KD_DIMS], const float co_test[KD_DIMS], const void *user_data), const void *user_data)
Definition: kdtree_impl.h:480
#define KD_NEAR_ALLOC_INC
Definition: kdtree_impl.h:56
#define KD_NODE_ROOT_IS_INIT
Definition: kdtree_impl.h:65
void BLI_kdtree_nd_() range_search_cb(const KDTree *tree, const float co[KD_DIMS], float range, bool(*search_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq), void *user_data)
Definition: kdtree_impl.h:743
int BLI_kdtree_nd_() find_nearest(const KDTree *tree, const float co[KD_DIMS], KDTreeNearest *r_nearest)
Definition: kdtree_impl.h:236
void BLI_kdtree_nd_() balance(KDTree *tree)
Definition: kdtree_impl.h:204
static uint * kdtree_order(const KDTree *tree)
Definition: kdtree_impl.h:813
static uint kdtree_balance(KDTreeNode *nodes, uint nodes_len, uint axis, const uint ofs)
Definition: kdtree_impl.h:148
#define NODE_TEST_NEAREST(node)
static uint * realloc_nodes(uint *stack, uint *stack_len_capacity, const bool is_alloc)
Definition: kdtree_impl.h:220
int BLI_kdtree_nd_() deduplicate(KDTree *tree)
Definition: kdtree_impl.h:974
void BLI_kdtree_nd_() insert(KDTree *tree, int index, const float co[KD_DIMS])
Definition: kdtree_impl.h:127
static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
Definition: kdtree_impl.h:944
static void copy_vn_vn(float v0[KD_DIMS], const float v1[KD_DIMS])
Definition: kdtree_impl.h:71
struct KDTreeNode KDTreeNode
static void nearest_ordered_insert(KDTreeNearest *nearest, uint *nearest_len, const uint nearest_len_capacity, const int index, const float dist, const float co[KD_DIMS])
Definition: kdtree_impl.h:448
int BLI_kdtree_nd_() range_search(const KDTree *tree, const float co[KD_DIMS], KDTreeNearest **r_nearest, const float range)
Definition: kdtree_impl.h:726
struct KDTreeNode_head KDTreeNode_head
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:116
static float len_squared_vnvn_cb(const float co_kdtree[KD_DIMS], const float co_search[KD_DIMS], const void *UNUSED(user_data))
Definition: kdtree_impl.h:87
#define KD_NODE_UNSET
Definition: kdtree_impl.h:59
int BLI_kdtree_nd_() find_nearest_n(const KDTree *tree, const float co[KD_DIMS], KDTreeNearest r_nearest[], const uint nearest_len_capacity)
Definition: kdtree_impl.h:594
int BLI_kdtree_nd_() range_search_with_len_squared_cb(const KDTree *tree, const float co[KD_DIMS], KDTreeNearest **r_nearest, const float range, float(*len_sq_fn)(const float co_search[KD_DIMS], const float co_test[KD_DIMS], const void *user_data), const void *user_data)
Definition: kdtree_impl.h:644
static int nearest_cmp_dist(const void *a, const void *b)
Definition: kdtree_impl.h:603
#define KD_FOUND_ALLOC_INC
Definition: kdtree_impl.h:57
static void nearest_add_in_range(KDTreeNearest **r_nearest, uint nearest_index, uint *nearest_len_capacity, const int index, const float dist, const float co[KD_DIMS])
Definition: kdtree_impl.h:618
int BLI_kdtree_nd_() find_nearest_cb(const KDTree *tree, const float co[KD_DIMS], int(*filter_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq), void *user_data, KDTreeNearest *r_nearest)
Definition: kdtree_impl.h:342
#define KD_STACK_INIT
Definition: kdtree_impl.h:55
static float len_squared_vnvn(const float v0[KD_DIMS], const float v1[KD_DIMS])
Definition: kdtree_impl.h:78
#define BLI_kdtree_nd_(id)
Definition: kdtree_impl.h:30
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:43
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static int left
static unsigned a[3]
Definition: RandGen.cpp:92
const KDTreeNode * nodes
Definition: kdtree_impl.h:829
float search_co[KD_DIMS]
Definition: kdtree_impl.h:836
float co[KD_DIMS]
float co[KD_DIMS]
Definition: kdtree_impl.h:34
float co[KD_DIMS]
Definition: kdtree_impl.h:40
uint right
Definition: kdtree_impl.h:39
uint root
Definition: kdtree_impl.h:48
uint nodes_len
Definition: kdtree_impl.h:47
KDTreeNode * nodes
Definition: kdtree_impl.h:46