00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef RTABMAP_FLANN_ALL_INDICES_H_
00031 #define RTABMAP_FLANN_ALL_INDICES_H_
00032
00033 #include "rtflann/general.h"
00034
00035 #include "rtflann/algorithms/nn_index.h"
00036 #include "rtflann/algorithms/kdtree_index.h"
00037 #include "rtflann/algorithms/kdtree_single_index.h"
00038 #include "rtflann/algorithms/kmeans_index.h"
00039 #include "rtflann/algorithms/composite_index.h"
00040 #include "rtflann/algorithms/linear_index.h"
00041 #include "rtflann/algorithms/hierarchical_clustering_index.h"
00042 #include "rtflann/algorithms/lsh_index.h"
00043 #include "rtflann/algorithms/autotuned_index.h"
00044 #ifdef FLANN_USE_CUDA
00045 #include "rtflann/algorithms/kdtree_cuda_3d_index.h"
00046 #endif
00047
00048
00049 namespace rtflann
00050 {
00051
00055 template<bool, typename T = void> struct enable_if{};
00056 template<typename T> struct enable_if<true,T> { typedef T type; };
00057
00061 template<bool, typename T> struct disable_if{ typedef T type; };
00062 template<typename T> struct disable_if<true,T> { };
00063
00067 template <typename T, typename U>
00068 struct same_type
00069 {
00070 enum {value = false};
00071 };
00072
00073 template<typename T>
00074 struct same_type<T,T>
00075 {
00076 enum {value = true};
00077 };
00078
00079 #define HAS_MEMBER(member) \
00080 template<typename T> \
00081 struct member { \
00082 typedef char No; \
00083 typedef long Yes; \
00084 template<typename C> static Yes test( typename C::member* ); \
00085 template<typename C> static No test( ... ); \
00086 enum { value = sizeof (test<T>(0))==sizeof(Yes) }; \
00087 };
00088
00089 HAS_MEMBER(needs_kdtree_distance)
00090 HAS_MEMBER(needs_vector_space_distance)
00091 HAS_MEMBER(is_kdtree_distance)
00092 HAS_MEMBER(is_vector_space_distance)
00093
00094 struct DummyDistance
00095 {
00096 typedef float ElementType;
00097 typedef float ResultType;
00098
00099 template <typename Iterator1, typename Iterator2>
00100 ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const
00101 {
00102 return ResultType(0);
00103 }
00104
00105 template <typename U, typename V>
00106 inline ResultType accum_dist(const U& a, const V& b, int) const
00107 {
00108 return ResultType(0);
00109 }
00110 };
00111
00115 template<template <typename> class Index, typename Distance, typename ElemType>
00116 struct valid_combination
00117 {
00118 static const bool value = same_type<ElemType,typename Distance::ElementType>::value &&
00119 (!needs_kdtree_distance<Index<DummyDistance> >::value || is_kdtree_distance<Distance>::value) &&
00120 (!needs_vector_space_distance<Index<DummyDistance> >::value || is_kdtree_distance<Distance>::value || is_vector_space_distance<Distance>::value);
00121
00122 };
00123
00124
00125
00126
00127
00128 template <template<typename> class Index, typename Distance, typename T>
00129 inline NNIndex<Distance>* create_index_(rtflann::Matrix<T> data, const rtflann::IndexParams& params, const Distance& distance,
00130 typename enable_if<valid_combination<Index,Distance,T>::value,void>::type* = 0)
00131 {
00132 return new Index<Distance>(data, params, distance);
00133 }
00134
00135 template <template<typename> class Index, typename Distance, typename T>
00136 inline NNIndex<Distance>* create_index_(rtflann::Matrix<T> data, const rtflann::IndexParams& params, const Distance& distance,
00137 typename disable_if<valid_combination<Index,Distance,T>::value,void>::type* = 0)
00138 {
00139 return NULL;
00140 }
00141
00142 template<typename Distance>
00143 inline NNIndex<Distance>*
00144 create_index_by_type(const flann_algorithm_t index_type,
00145 const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
00146 {
00147 typedef typename Distance::ElementType ElementType;
00148
00149 NNIndex<Distance>* nnIndex;
00150
00151 switch (index_type) {
00152
00153 case FLANN_INDEX_LINEAR:
00154 nnIndex = create_index_<LinearIndex,Distance,ElementType>(dataset, params, distance);
00155 break;
00156 case FLANN_INDEX_KDTREE_SINGLE:
00157 nnIndex = create_index_<KDTreeSingleIndex,Distance,ElementType>(dataset, params, distance);
00158 break;
00159 case FLANN_INDEX_KDTREE:
00160 nnIndex = create_index_<KDTreeIndex,Distance,ElementType>(dataset, params, distance);
00161 break;
00164 #ifdef FLANN_USE_CUDA
00165 case FLANN_INDEX_KDTREE_CUDA:
00166 nnIndex = create_index_<KDTreeCuda3dIndex,Distance,ElementType>(dataset, params, distance);
00167 break;
00168 #endif
00169
00170 case FLANN_INDEX_KMEANS:
00171 nnIndex = create_index_<KMeansIndex,Distance,ElementType>(dataset, params, distance);
00172 break;
00173 case FLANN_INDEX_COMPOSITE:
00174 nnIndex = create_index_<CompositeIndex,Distance,ElementType>(dataset, params, distance);
00175 break;
00176 case FLANN_INDEX_AUTOTUNED:
00177 nnIndex = create_index_<AutotunedIndex,Distance,ElementType>(dataset, params, distance);
00178 break;
00179 case FLANN_INDEX_HIERARCHICAL:
00180 nnIndex = create_index_<HierarchicalClusteringIndex,Distance,ElementType>(dataset, params, distance);
00181 break;
00182 case FLANN_INDEX_LSH:
00183 nnIndex = create_index_<LshIndex,Distance,ElementType>(dataset, params, distance);
00184 break;
00185 default:
00186 throw FLANNException("Unknown index type");
00187 }
00188
00189 if (nnIndex==NULL) {
00190 throw FLANNException("Unsupported index/distance combination");
00191 }
00192 return nnIndex;
00193 }
00194
00195 }
00196
00197 #endif