31 #ifndef RTABMAP_FLANN_KDTREE_SINGLE_INDEX_H_
32 #define RTABMAP_FLANN_KDTREE_SINGLE_INDEX_H_
56 (*this)[
"leaf_max_size"] = leaf_max_size;
57 (*this)[
"reorder"] = reorder;
68 template <
typename Distance>
69 class KDTreeSingleIndex :
public NNIndex<Distance>
156 template<
typename Archive>
174 if (Archive::is_loading::value) {
180 if (Archive::is_loading::value) {
198 serialization::LoadArchive la(stream);
222 float epsError = 1+searchParams.eps;
224 std::vector<DistanceType> dists(
veclen_,0);
227 searchLevel<true>(result, vec,
root_node_, distsq, dists, epsError);
230 searchLevel<false>(result, vec,
root_node_, distsq, dists, epsError);
243 for (
size_t i = 0;
i <
size_;
i++) {
252 for (
size_t i=0;
i<
size_; ++
i) {
288 template<
typename Archive>
292 Index* obj =
static_cast<Index*
>(ar.getObject());
300 bool leaf_node =
false;
301 if (Archive::is_saving::value) {
307 if (Archive::is_loading::value) {
315 friend struct serialization::access;
325 template <
typename Archive>
370 for (
size_t k=1; k<
size_; ++k) {
403 for (
int k=left+1; k<right; ++k) {
416 node->divfeat = cutfeat;
419 left_bbox[cutfeat].high = cutval;
420 node->child1 =
divideTree(left, left+idx, left_bbox);
423 right_bbox[cutfeat].low = cutval;
424 node->child2 =
divideTree(left+idx, right, right_bbox);
426 node->divlow = left_bbox[cutfeat].high;
427 node->divhigh = right_bbox[cutfeat].low;
430 bbox[
i].low =
std::min(left_bbox[i].low, right_bbox[i].low);
431 bbox[
i].high =
std::max(left_bbox[i].high, right_bbox[i].high);
444 if (val<min_elem) min_elem = val;
445 if (val>max_elem) max_elem = val;
454 cutval = (bbox[0].high+bbox[0].low)/2;
460 cutval = (bbox[
i].high+bbox[
i].low)/2;
467 cutval = (min_elem+max_elem)/2;
468 max_span = max_elem - min_elem;
481 cutval = (min_elem+max_elem)/2;
486 planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
488 if (lim1>count/2) index = lim1;
489 else if (lim2<count/2) index = lim2;
490 else index =
count/2;
492 assert(index > 0 && index < count);
498 const float eps_val=0.00001f;
514 if (spread>max_spread) {
521 DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2;
525 if (split_val<min_elem) cutval = (
DistanceType)min_elem;
526 else if (split_val>max_elem) cutval = (
DistanceType)max_elem;
527 else cutval = split_val;
530 planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
532 if (lim1>count/2) index = lim1;
533 else if (lim2<count/2) index = lim2;
534 else index =
count/2;
536 assert(index > 0 && index < count);
554 while (left<=right &&
points_[ind[left]][cutfeat]<cutval) ++left;
555 while (left<=right &&
points_[ind[right]][cutfeat]>=cutval) --right;
556 if (left>right)
break;
557 std::swap(ind[left], ind[right]); ++left; --right;
563 while (left<=right &&
points_[ind[left]][cutfeat]<=cutval) ++left;
564 while (left<=right &&
points_[ind[right]][cutfeat]>cutval) --right;
565 if (left>right)
break;
566 std::swap(ind[left], ind[right]); ++left; --right;
592 template <
bool with_removed>
594 std::vector<DistanceType>& dists,
const float epsError)
const
597 if ((node->child1 == NULL)&&(node->child2 == NULL)) {
599 for (
int i=node->left; i<node->right; ++i) {
605 if (
dist<worst_dist) {
613 int idx = node->divfeat;
621 if ((diff1+diff2)<0) {
622 bestChild = node->child1;
623 otherChild = node->child2;
624 cut_dist =
distance_.accum_dist(val, node->divhigh, idx);
627 bestChild = node->child2;
628 otherChild = node->child1;
629 cut_dist =
distance_.accum_dist( val, node->divlow, idx);
633 searchLevel<with_removed>(result_set, vec, bestChild, mindistsq, dists, epsError);
636 mindistsq = mindistsq + cut_dist -
dst;
637 dists[idx] = cut_dist;
638 if (mindistsq*epsError<=result_set.worstDist()) {
639 searchLevel<with_removed>(result_set, vec, otherChild, mindistsq, dists, epsError);
669 std::vector<int>
vind_;
690 PooledAllocator
pool_;
698 #endif //FLANN_KDTREE_SINGLE_INDEX_H_