@@ -143,6 +143,9 @@ class KDTreeIndex : public NNIndex<Distance>
143
143
*/
144
144
void buildIndex ()
145
145
{
146
+ freeIndex ();
147
+ cleanRemovedPoints ();
148
+
146
149
// Create a permutable array of indices to the input vectors.
147
150
std::vector<int > ind (size_);
148
151
for (size_t i = 0 ; i < size_; ++i) {
@@ -256,10 +259,20 @@ class KDTreeIndex : public NNIndex<Distance>
256
259
float epsError = 1 +searchParams.eps ;
257
260
258
261
if (maxChecks==FLANN_CHECKS_UNLIMITED) {
259
- getExactNeighbors (result, vec, epsError);
262
+ if (removed_) {
263
+ getExactNeighbors<true >(result, vec, epsError);
264
+ }
265
+ else {
266
+ getExactNeighbors<false >(result, vec, epsError);
267
+ }
260
268
}
261
269
else {
262
- getNeighbors (result, vec, maxChecks, epsError);
270
+ if (removed_) {
271
+ getNeighbors<true >(result, vec, maxChecks, epsError);
272
+ }
273
+ else {
274
+ getNeighbors<false >(result, vec, maxChecks, epsError);
275
+ }
263
276
}
264
277
}
265
278
@@ -510,16 +523,16 @@ class KDTreeIndex : public NNIndex<Distance>
510
523
* Performs an exact nearest neighbor search. The exact search performs a full
511
524
* traversal of the tree.
512
525
*/
513
- template <typename ResultSet >
514
- void getExactNeighbors (ResultSet& result, const ElementType* vec, float epsError)
526
+ template <bool with_removed >
527
+ void getExactNeighbors (ResultSet<DistanceType> & result, const ElementType* vec, float epsError)
515
528
{
516
529
// checkID -= 1; /* Set a different unique ID for each search. */
517
530
518
531
if (trees_ > 1 ) {
519
532
fprintf (stderr," It doesn't make any sense to use more than one tree for exact search" );
520
533
}
521
534
if (trees_>0 ) {
522
- searchLevelExact (result, vec, tree_roots_[0 ], 0.0 , epsError);
535
+ searchLevelExact<with_removed> (result, vec, tree_roots_[0 ], 0.0 , epsError);
523
536
}
524
537
}
525
538
@@ -528,6 +541,7 @@ class KDTreeIndex : public NNIndex<Distance>
528
541
* because the tree traversal is abandoned after a given number of descends in
529
542
* the tree.
530
543
*/
544
+ template <bool with_removed>
531
545
void getNeighbors (ResultSet<DistanceType>& result, const ElementType* vec, int maxCheck, float epsError)
532
546
{
533
547
int i;
@@ -539,12 +553,12 @@ class KDTreeIndex : public NNIndex<Distance>
539
553
540
554
/* Search once through each tree down to root. */
541
555
for (i = 0 ; i < trees_; ++i) {
542
- searchLevel (result, vec, tree_roots_[i], 0 , checkCount, maxCheck, epsError, heap, checked);
556
+ searchLevel<with_removed> (result, vec, tree_roots_[i], 0 , checkCount, maxCheck, epsError, heap, checked);
543
557
}
544
558
545
559
/* Keep searching other branches from heap until finished. */
546
560
while ( heap->popMin (branch) && (checkCount < maxCheck || !result.full () )) {
547
- searchLevel (result, vec, branch.node , branch.mindist , checkCount, maxCheck, epsError, heap, checked);
561
+ searchLevel<with_removed> (result, vec, branch.node , branch.mindist , checkCount, maxCheck, epsError, heap, checked);
548
562
}
549
563
550
564
delete heap;
@@ -556,6 +570,7 @@ class KDTreeIndex : public NNIndex<Distance>
556
570
* higher levels, all exemplars below this level must have a distance of
557
571
* at least "mindistsq".
558
572
*/
573
+ template <bool with_removed>
559
574
void searchLevel (ResultSet<DistanceType>& result_set, const ElementType* vec, NodePtr node, DistanceType mindist, int & checkCount, int maxCheck,
560
575
float epsError, Heap<BranchSt>* heap, DynamicBitset& checked)
561
576
{
@@ -567,8 +582,11 @@ class KDTreeIndex : public NNIndex<Distance>
567
582
/* If this is a leaf node, then do check and return. */
568
583
if ((node->child1 == NULL )&&(node->child2 == NULL )) {
569
584
int index = node->divfeat ;
585
+ if (with_removed) {
586
+ if (removed_points_.test (index)) return ;
587
+ }
570
588
/* Do not check same node more than once when searching multiple trees. */
571
- if ( checked.test (index) || removed_points_. test (index) || ((checkCount>=maxCheck)&& result_set.full ()) ) return ;
589
+ if ( checked.test (index) || ((checkCount>=maxCheck)&& result_set.full ()) ) return ;
572
590
checked.set (index);
573
591
checkCount++;
574
592
@@ -598,19 +616,21 @@ class KDTreeIndex : public NNIndex<Distance>
598
616
}
599
617
600
618
/* Call recursively to search next level down. */
601
- searchLevel (result_set, vec, bestChild, mindist, checkCount, maxCheck, epsError, heap, checked);
619
+ searchLevel<with_removed> (result_set, vec, bestChild, mindist, checkCount, maxCheck, epsError, heap, checked);
602
620
}
603
621
604
622
/* *
605
623
* Performs an exact search in the tree starting from a node.
606
624
*/
607
- template <typename ResultSet >
608
- void searchLevelExact (ResultSet& result_set, const ElementType* vec, const NodePtr node, DistanceType mindist, const float epsError)
625
+ template <bool with_removed >
626
+ void searchLevelExact (ResultSet<DistanceType> & result_set, const ElementType* vec, const NodePtr node, DistanceType mindist, const float epsError)
609
627
{
610
628
/* If this is a leaf node, then do check and return. */
611
629
if ((node->child1 == NULL )&&(node->child2 == NULL )) {
612
630
int index = node->divfeat ;
613
- if (removed_points_.test (index)) return ; // ignore removed points
631
+ if (with_removed) {
632
+ if (removed_points_.test (index)) return ; // ignore removed points
633
+ }
614
634
DistanceType dist = distance_ (node->point , vec, veclen_);
615
635
result_set.addPoint (dist,index);
616
636
@@ -634,10 +654,10 @@ class KDTreeIndex : public NNIndex<Distance>
634
654
DistanceType new_distsq = mindist + distance_.accum_dist (val, node->divval , node->divfeat );
635
655
636
656
/* Call recursively to search next level down. */
637
- searchLevelExact (result_set, vec, bestChild, mindist, epsError);
657
+ searchLevelExact<with_removed> (result_set, vec, bestChild, mindist, epsError);
638
658
639
659
if (mindist*epsError<=result_set.worstDist ()) {
640
- searchLevelExact (result_set, vec, otherChild, new_distsq, epsError);
660
+ searchLevelExact<with_removed> (result_set, vec, otherChild, new_distsq, epsError);
641
661
}
642
662
}
643
663
0 commit comments