11 #include "nanoflann.hpp"
15 namespace nanoflann_types
23 Point(T x, T y, T z) : x(x), y(y), z(z) {}
27 std::vector<Point> pts;
30 inline size_t kdtree_get_point_count()
const {
return pts.size(); }
33 inline T kdtree_distance(
const T *p1,
const size_t idx_p2,
size_t size)
const
35 const T d0=p1[0]-pts[idx_p2].x;
36 const T d1=p1[1]-pts[idx_p2].y;
37 const T d2=p1[2]-pts[idx_p2].z;
38 return d0*d0+d1*d1+d2*d2;
44 inline T kdtree_get_pt(
const size_t idx,
int dim)
const
46 if (dim==0)
return pts[idx].x;
47 else if (dim==1)
return pts[idx].y;
48 else return pts[idx].z;
55 bool kdtree_get_bbox(BBOX &bb)
const {
return false; }
59 using namespace nuklei_nanoflann;
60 typedef KDTreeSingleIndexAdaptor<
61 L2_Simple_Adaptor<double, PointCloud > ,
65 typedef std::pair<boost::shared_ptr<KDTreeIndex>, PointCloud> Tree;
71 #ifdef NUKLEI_USE_CGAL
72 using namespace cgal_neighbor_search_types;
74 boost::shared_ptr<Tree> tree(
new Tree);
77 Vector3 loc = i->getLoc();
78 tree->insert(Point_d(loc.X(), loc.Y(), loc.Z()));
80 if (deco_.has_key(NSTREE_KEY)) deco_.erase(NSTREE_KEY);
81 deco_.insert(NSTREE_KEY, tree);
84 NUKLEI_THROW(
"This function requires CGAL. See http://renaud-detry.net/nuklei/group__install.html");
93 using namespace nanoflann_types;
98 Vector3 loc = i->getLoc();
99 pc.pts.push_back(PointCloud::Point(loc.X(), loc.Y(), loc.Z()));
102 boost::shared_ptr<Tree> tree(
new Tree(boost::shared_ptr<KDTreeIndex>(), pc));
103 tree->first = boost::shared_ptr<KDTreeIndex>(
new KDTreeIndex(3 , tree->second, KDTreeSingleIndexAdaptorParams(10 ) ));
104 tree->first->buildIndex();
106 if (deco_.has_key(KDTREE_KEY)) deco_.erase(KDTREE_KEY);
107 deco_.insert(KDTREE_KEY, tree);
111 using namespace libkdtree_types;
113 boost::shared_ptr<Tree> tree(
new Tree);
116 Vector3 loc = i->getLoc();
118 std::distance(
as_const(*this).begin(), i)));
122 if (deco_.has_key(KDTREE_KEY)) deco_.erase(KDTREE_KEY);
123 deco_.insert(KDTREE_KEY, tree);
127 template<
class KernelType>
129 const EvaluationStrategy strategy)
const
131 NUKLEI_TRACE_BEGIN();
139 if (KDTREE_DENSITY_EVAL && size() > 1000)
141 #if NUKLEI_CHECK_KDTREE_COUNT
143 coord_t rng = maxLocCutPoint()*maxLocCutPoint();
145 const KernelType &evalPoint =
static_cast<const KernelType&
>(k);
146 for (const_iterator i = begin(); i != end(); i++)
148 const KernelType &densityPoint =
static_cast<const KernelType&
>(*i);
150 if ((densityPoint.loc_-evalPoint.loc_).SquaredLength() < rng)
156 if (KDTREE_NANOFLANN)
158 using namespace nanoflann_types;
159 if (!deco_.has_key(KDTREE_KEY))
160 NUKLEI_THROW(
"Undefined kd-tree. Call buildKdTree() first.");
162 const KernelType &evalPoint =
static_cast<const KernelType&
>(k);
164 boost::shared_ptr<Tree> tree(deco_.get< boost::shared_ptr<Tree> >(KDTREE_KEY));
167 coord_t range = maxLocCutPoint();
171 std::vector<std::pair<size_t,coord_t> > indices_dists;
172 RadiusResultSet<coord_t,size_t> resultSet(range,indices_dists);
174 as_const(*tree).first->findNeighbors(resultSet, evalPoint.loc_, nuklei_nanoflann::SearchParams());
176 for (std::vector<std::pair<size_t,coord_t> >::const_iterator i = indices_dists.begin(); i != indices_dists.end(); i++)
179 const KernelType &densityPoint =
static_cast<const KernelType&
>(at(i->first));
180 cvalue = densityPoint.eval(evalPoint);
181 if (strategy == MAX_EVAL) value = std::max(value, cvalue);
182 else if (strategy == SUM_EVAL) value += cvalue;
183 else if (strategy == WEIGHTED_SUM_EVAL) value += cvalue * densityPoint.getWeight();
189 using namespace libkdtree_types;
190 if (!deco_.has_key(KDTREE_KEY))
191 NUKLEI_THROW(
"Undefined kd-tree. Call buildKdTree() first.");
193 const KernelType &evalPoint =
static_cast<const KernelType&
>(k);
194 std::vector<FlexiblePoint> in_range;
197 boost::shared_ptr<Tree> tree(deco_.get< boost::shared_ptr<Tree> >(KDTREE_KEY));
198 FlexiblePoint s(evalPoint.loc_.X(), evalPoint.loc_.Y(), evalPoint.loc_.Z(), -1);
200 coord_t range = maxLocCutPoint();
202 as_const(*tree).find_within_range(s, range, std::back_inserter(in_range));
204 for (std::vector<FlexiblePoint>::const_iterator i = in_range.begin(); i != in_range.end(); i++)
207 const KernelType &densityPoint =
static_cast<const KernelType&
>(at(i->idx()));
208 cvalue = densityPoint.eval(evalPoint);
209 if (strategy == MAX_EVAL) value = std::max(value, cvalue);
210 else if (strategy == SUM_EVAL) value += cvalue;
211 else if (strategy == WEIGHTED_SUM_EVAL) value += cvalue * densityPoint.getWeight();
218 const KernelType &evalPoint =
static_cast<const KernelType&
>(k);
219 for (const_iterator i = begin(); i != end(); i++)
222 const KernelType &densityPoint =
static_cast<const KernelType&
>(*i);
223 cvalue = densityPoint.eval(evalPoint);
224 if (strategy == MAX_EVAL) value = std::max(value, cvalue);
225 else if (strategy == SUM_EVAL) value += cvalue;
226 else if (strategy == WEIGHTED_SUM_EVAL) value += cvalue * densityPoint.getWeight();
236 const EvaluationStrategy strategy)
const
238 NUKLEI_TRACE_BEGIN();
239 if (empty())
return 0;
243 switch (*kernelType_)
245 case kernel::base::R3:
247 value = staticEvaluationAt<kernel::r3>(k, strategy);
250 case kernel::base::R3XS2:
252 value = staticEvaluationAt<kernel::r3xs2>(k, strategy);
255 case kernel::base::R3XS2P:
257 value = staticEvaluationAt<kernel::r3xs2p>(k, strategy);
260 case kernel::base::SE3:
262 value = staticEvaluationAt<kernel::se3>(k, strategy);