KdTree.h
Go to the documentation of this file.
1#ifndef GfxTL__KDTREE_HEADER__
2#define GfxTL__KDTREE_HEADER__
3#include <algorithm>
4#include <deque>
5#include <memory>
6
7#include <GfxTL/AABox.h>
8#include <GfxTL/BaseTree.h>
10#include <GfxTL/LimitedHeap.h>
11#include <GfxTL/MathHelper.h>
13#include <GfxTL/NullClass.h>
16#include <GfxTL/VectorKernel.h>
17#include <GfxTL/VectorXD.h>
18#include <malloc.h>
19
20namespace GfxTL
21{
22 template <class BaseT>
23 class KdTreeCell : public BaseT
24 {
25 public:
27 typedef typename BaseT::value_type value_type;
29
30 enum
31 {
33 };
34
36 {
37 m_children[0] = m_children[1] = NULL;
38 }
39
41 {
42 if (m_children[0] != (KdTreeCell*)0x1)
43 {
44 delete m_children[0];
45 }
46 delete m_children[1];
47 }
48
50 operator[](unsigned int i)
51 {
52 return *m_children[i];
53 }
54
55 const ThisType&
56 operator[](unsigned int i) const
57 {
58 return *m_children[i];
59 }
60
61 void
62 Child(unsigned int i, ThisType* cell)
63 {
64 m_children[i] = cell;
65 }
66
67 unsigned int&
69 {
70 return m_splitAxis;
71 }
72
73 const unsigned int
74 SplitAxis() const
75 {
76 return m_splitAxis;
77 }
78
81 {
82 return m_splitValue;
83 }
84
85 const ScalarType
86 SplitValue() const
87 {
88 return m_splitValue;
89 }
90
91 template <class VectorT>
92 bool
93 operator()(const VectorT& v) const
94 {
95 return v[m_splitAxis] <= m_splitValue;
96 }
97
98 /*void *operator new(size_t size)
99 {
100 return _mm_malloc(size, 16);
101 }
102
103 void operator delete(void *ptr)
104 {
105 _mm_free(ptr);
106 }*/
107
108 private:
109 unsigned int m_splitAxis;
110 ScalarType m_splitValue;
111 ThisType* m_children[2];
112 };
113
114 template <class DataStrategyT>
116 {
117 typedef typename DataStrategyT::value_type value_type;
118
119 class CellData : public DataStrategyT::CellData
120 {
121 };
122
123 template <class BaseT>
124 struct StrategyBase : public DataStrategyT::template StrategyBase<BaseT>
125 {
126 typedef typename DataStrategyT::template StrategyBase<BaseT>::CellType CellType;
127 typedef typename DataStrategyT::template StrategyBase<BaseT> BaseType;
128 typedef typename BaseType::DereferencedType DereferencedType;
129
130 template <class BuildInformationT>
131 bool
132 ShouldSubdivide(const CellType& cell, BuildInformationT& bi)
133 {
134 return false;
135 }
136
137 template <class BuildInformationT>
138 void
139 EnterGlobalBuildInformation(const CellType& cell, BuildInformationT* bi)
140 {
141 }
142
143 template <class BuildInformationT>
144 void
145 LeaveGlobalBuildInformation(const CellType& cell, const BuildInformationT& bi)
146 {
147 }
148
149 template <class TraversalInformationT>
150 void
151 UpdateCellWithBack(const TraversalInformationT&, CellType*)
152 {
153 }
154
155 protected:
156 template <class TraversalBaseT>
158 public DataStrategyT::template StrategyBase<BaseT>::template TraversalInformation<
159 TraversalBaseT>
160 {
161 };
162 };
163 };
164
165 template <class StrategiesT,
166 template <class>
167 class MetricT,
168 template <class> class VectorKernelT = DynVectorKernel>
169 class KdTree :
170 public StrategiesT::template StrategyBase<
171 MetricT<VectorKernelT<BaseTree<KdTreeCell<typename StrategiesT::CellData>>>>>
172 {
173 public:
175 typedef typename StrategiesT::template StrategyBase<
176 MetricT<VectorKernelT<BaseTree<KdTreeCell<typename StrategiesT::CellData>>>>>
178 typedef typename BaseType::value_type value_type;
179 typedef typename BaseType::DereferencedType DereferencedType;
181
182 class BuildInformation : public BaseType::BuildInformation
183 {
184 public:
185 unsigned int&
187 {
188 return m_createChild;
189 }
190
191 const unsigned int
193 {
194 return m_createChild;
195 }
196
197 private:
198 unsigned int m_createChild;
199 };
200
201 template <class PointT>
203 {
204 public:
205 typedef PointT PointType;
206
207 const PointT&
208 Point() const
209 {
210 return m_point;
211 }
212
213 void
214 Point(const PointT& p)
215 {
216 m_point = p;
217 }
218
219 private:
220 PointT m_point;
221 };
222
223 template <class GlobalInfoT>
225 {
226 public:
227 typedef GlobalInfoT GlobalType;
228
229 void
230 Global(const GlobalInfoT* globalInfo)
231 {
232 m_globalInfo = globalInfo;
233 }
234
235 const GlobalInfoT&
236 Global() const
237 {
238 return *m_globalInfo;
239 }
240
241 private:
242 const GlobalInfoT* m_globalInfo;
243 };
244
245 void
247 {
248 typedef std::pair<CellType*, BuildInformation> Pair;
249 BaseType::Clear();
250 if (!BaseType::size())
251 {
252 return;
253 }
254 BaseType::Root() = new CellType;
255 std::deque<Pair> stack(1);
256 // init build information directly on stack to avoid
257 // copying.
258 stack.back().first = BaseType::Root();
259 InitRootBuildInformation(&stack.back().second);
260 BaseType::InitRoot(stack.back().second, BaseType::Root());
261 while (stack.size())
262 {
263 Pair& p = stack.back();
264 if (p.second.CreateChild() == CellType::NChildren)
265 {
266 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
267 stack.pop_back();
268 continue;
269 }
270 if (BaseType::IsLeaf(*p.first))
271 {
272 if (!BaseType::ShouldSubdivide(*p.first, p.second))
273 {
274 stack.pop_back();
275 continue;
276 }
277 Subdivide(p.second, p.first);
278 if (BaseType::IsLeaf(*p.first)) // couldn't subdivide?
279 {
280 stack.pop_back();
281 continue;
282 }
283 }
284 else
285 {
286 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
287 }
288 while (p.second.CreateChild() < CellType::NChildren &&
289 !this->ExistChild(*p.first, p.second.CreateChild()))
290 {
291 ++p.second.CreateChild();
292 }
293 if (p.second.CreateChild() == CellType::NChildren)
294 {
295 stack.pop_back();
296 continue;
297 }
298 BaseType::EnterGlobalBuildInformation(*p.first, &p.second);
299 stack.resize(stack.size() + 1); // create new entry
300 stack.back().first = &(*p.first)[p.second.CreateChild()];
301 InitBuildInformation(
302 *p.first, p.second, p.second.CreateChild(), &stack.back().second);
303 InitCell(*p.first,
304 p.second,
305 p.second.CreateChild(),
306 stack.back().second,
307 &(*p.first)[p.second.CreateChild()]);
308 ++p.second.CreateChild();
309 }
310 }
311
312 void
314 {
315 typedef typename BaseType::template GlobalTraversalInformation<
316 BaseGlobalTraversalInformation<value_type>>
317 GlobalInfoType;
318 // traverse the tree and insert the point
319 typename BaseType::template TraversalInformation<
320 BaseTraversalInformation<GlobalInfoType>>
321 ti;
322 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
323 InsertBack(*BaseType::Root(), ti);
324 }
325
326 void
328 {
329 Remove(*BaseType::Root(), s);
330 }
331
332 template <class PointT, class DistScalarT, class ContainerT>
333 void
334 PointsInBall(const PointT& p,
335 /*typename BaseType::template DistanceType
336 <
337 typename ScalarTypeDeferer< PointT >::ScalarType,
338 ScalarType
339 >::Type*/
340 DistScalarT sqrRadius,
341 ContainerT* points) const
342 {
343 typedef typename BaseType::template GlobalTraversalInformation<
344 BaseGlobalTraversalInformation<PointT>>
345 GlobalInfoType;
346 GlobalInfoType gti;
347 typename BaseType::template TraversalInformation<
348 BaseTraversalInformation<GlobalInfoType>>
349 ti;
350 points->clear();
351 gti.Point(p);
352 ti.Global(&gti);
353 InitRootTraversalInformation(*BaseType::Root(), &ti);
354 PointsInBall(sqrRadius, *BaseType::Root(), ti, points);
355 }
356
357 template <class PointT>
359 {
360 typedef typename BaseType::template GlobalTraversalInformation<
363 typedef typename BaseType::template TraversalInformation<
366 typedef typename BaseType::template DistanceType<
369
371 {
372 }
373
375 m_cell(cell), m_ti(ti)
376 {
377 }
378
381 };
382
383 template <class PointT>
389
390 template <class PointT, class DistScalarT, class ContainerT>
391 void
392 PointsInBall(const PointT& p,
393 DistScalarT sqrRadius,
394 ContainerT* points,
395 PointsInBallAuxData<PointT>* auxData) const
396 {
397 points->clear();
398 PrivatePointsInBall(p, sqrRadius, points, auxData);
399 }
400
401 template <class PointT, class LimitedHeapT>
402 void
403 NearestNeighbors(const PointT& p, unsigned int k, LimitedHeapT* neighbors) const
404 {
405 typedef typename BaseType::template GlobalTraversalInformation<
406 BaseGlobalTraversalInformation<PointT>>
407 GlobalInfoType;
408 typedef typename BaseType::template TraversalInformation<
409 BaseTraversalInformation<GlobalInfoType>>
410 TraversalInformation;
411 // typedef typename BaseType::template DistanceType <
412 // typename ScalarTypeDeferer< PointT >::ScalarType,
413 // ScalarType
414 // >::Type DistanceType;
415 GlobalInfoType gti;
416 TraversalInformation ti;
417 neighbors->clear();
418 neighbors->Limit(k);
419 gti.Point(p);
420 ti.Global(&gti);
421 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
422 PrivateNearestNeighbors(*BaseType::Root(), ti, neighbors);
423 neighbors->AssertHeap();
424 }
425
426 template <class PointT>
428 {
429 typedef typename BaseType::template GlobalTraversalInformation<
432 typedef typename BaseType::template TraversalInformation<
435 typedef typename BaseType::template DistanceType<
438
442
444 const TraversalInfoType& ti,
445 DistanceType sqrDist) :
446 m_cell(cell), m_ti(ti), m_sqrDist(sqrDist)
447 {
448 }
449
453 };
454
455 template <class PointT>
461
462 template <class PointT, class LimitedHeapT>
463 void
464 NearestNeighbors(const PointT& p,
465 unsigned int k,
466 LimitedHeapT* neighbors,
467 NearestNeighborsAuxData<PointT>* auxData) const
468 {
469 neighbors->clear();
470 neighbors->Limit(k);
471 PrivateNearestNeighbors(p, auxData, neighbors);
472 neighbors->AssertHeap();
473 }
474
475 template <class PointT>
477 {
478 typedef NN<typename BaseType::template DistanceType<
480 ScalarType>::Type,
481 typename BaseType::DereferencedType>
483 };
484
485 template <class PointT, class EpsilonT, template <class> class ContainerT>
486 void
488 unsigned int k,
489 EpsilonT epsilon,
491 std::less<typename NNTypeHelper<PointT>::NNType>,
492 ContainerT>* neighbors) const
493 {
494 typedef typename BaseType::template GlobalTraversalInformation<
495 BaseGlobalTraversalInformation<PointT>>
496 GlobalInfoType;
497 GlobalInfoType gti;
498 typename BaseType::template TraversalInformation<
499 BaseTraversalInformation<GlobalInfoType>>
500 ti;
501 neighbors->clear();
502 neighbors->Limit(k);
503 gti.Point(p);
504 ti.Global(&gti);
505 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
506 ApproximateNearestNeighbors(*BaseType::Root(), ti, 1 + epsilon, neighbors);
507 neighbors->AssertHeap();
508 }
509
510 template <class PointT>
511 bool
512 Contains(const PointT& p, DereferencedType* dref) const
513 {
514 typedef typename BaseType::template GlobalTraversalInformation<
515 BaseGlobalTraversalInformation<PointT>>
516 GlobalInfoType;
517 GlobalInfoType gti;
518 typename BaseType::template TraversalInformation<
519 BaseTraversalInformation<GlobalInfoType>>
520 ti;
521 gti.Point(p);
522 ti.Global(&gti);
523 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
524 return Contains(*BaseType::Root(), ti, dref);
525 }
526
527 private:
528 void
529 InitRootBuildInformation(BuildInformation* bi)
530 {
531 bi->CreateChild() = 0;
532 BaseType::InitRootBuildInformation(bi);
533 }
534
535 void
536 InitBuildInformation(const CellType& parent,
537 const BuildInformation& parentInfo,
538 unsigned int childIdx,
539 BuildInformation* bi)
540 {
541 bi->CreateChild() = 0;
542 BaseType::InitBuildInformation(parent, parentInfo, childIdx, bi);
543 }
544
545 template <class BuildInformationT>
546 void
547 InitCell(const CellType& parent,
548 const BuildInformationT& parentInfo,
549 unsigned int childIdx,
550 const BuildInformationT& bi,
551 CellType* cell)
552 {
553 BaseType::InitCell(parent, parentInfo, childIdx, bi, cell);
554 }
555
556 template <class TraversalInformationT>
557 void
558 InitTraversalInformation(const CellType& parent,
559 const TraversalInformationT& pTi,
560 unsigned int childIdx,
561 TraversalInformationT* ti) const
562 {
563 ti->Global(&pTi.Global());
564 BaseType::InitTraversalInformation(parent, pTi, childIdx, ti);
565 }
566
567 template <class TraversalInformationT>
568 void
569 InsertBack(CellType& cell, const TraversalInformationT& ti)
570 {
571 typename BaseType::CellRange range;
572 BaseType::GetCellRange(cell, ti, &range);
573 if (IsLeaf(cell))
574 {
575 BaseType::InsertBack(range, &cell);
576 return;
577 }
578 bool l = SplitAndInsert(cell, range, &(cell[0]), &(cell[1]));
579 TraversalInformationT cti;
580 if (l)
581 {
582 UpdateCellWithBack(ti, &(cell[0]));
583 InitTraversalInformation(cell, ti, 0, &cti);
584 InsertBack(cell[0], cti);
585 }
586 else
587 {
588 UpdateCellWithBack(ti, &(cell[1]));
589 InitTraversalInformation(cell, ti, 1, &cti);
590 InsertBack(cell[1], cti);
591 }
592 }
593
594 void
596 {
597 if (IsLeaf(cell))
598 {
599 BaseType::Remove(s, &cell);
600 return;
601 }
602 if (BaseType::Remove(cell, s))
603 {
604 Remove(cell[0], s);
605 }
606 else
607 {
608 Remove(cell[1], s);
609 }
610 }
611
612 void
613 Subdivide(BuildInformation& bi, CellType* cell)
614 {
615 BaseType::ComputeSplit(bi, cell);
617 left = new CellType;
618 right = new CellType;
619 // unsigned int splitIter = 1;
620 //splitAgain:
621 BaseType::SplitData(*cell, *cell, bi, left, right);
622 if (left->Size() == cell->Size())
623 {
624 delete right;
625 right = NULL;
626 }
627 else if (right->Size() == cell->Size())
628 {
629 delete left;
630 left = NULL;
631 }
632 //if(left->Size() == cell->Size() || right->Size() == cell->Size())
633 //{
634 // //if(splitIter < BaseType::m_dim)
635 // //{
636 // // ++splitIter;
637 // // if(BaseType::AlternateSplit(bi, cell))
638 // // goto splitAgain;
639 // //}
640 // for(unsigned int i = 0; i < 2; ++i)
641 // {
642 // left->Child(i, NULL);
643 // right->Child(i, NULL);
644 // }
645 // delete left;
646 // delete right;
647 // left = right = NULL;
648 //}
649 cell->Child(0, left);
650 cell->Child(1, right);
651 if (BaseType::IsLeaf(*cell))
652 {
653 cell->Child(0, BaseType::InnerNodeMarker());
654 }
655 }
656
657 template <class TraversalInformationT, class DistScalarT, class ContainerT>
658 void
659 PointsInBall(DistScalarT sqrRadius,
660 const CellType& cell,
661 const TraversalInformationT& ti,
662 ContainerT* points) const
663 {
664 if (BaseType::IsLeaf(cell))
665 {
666 // find all points within ball
667 typename BaseType::CellRange range;
668 BaseType::GetCellRange(cell, ti, &range);
669 for (typename BaseType::HandleType h = range.first; h != range.second; ++h)
670 {
671 DistScalarT d =
672 BaseType::SqrDistance(ti.Global().Point(), at(BaseType::Dereference(h)));
673 if (d <= sqrRadius)
674 points->push_back(
675 typename ContainerT::value_type(d, BaseType::Dereference(h)));
676 }
677 return;
678 }
679 TraversalInformationT cti;
680 // check distance to left box
681 if (BaseType::ExistChild(cell, 0))
682 {
683 InitTraversalInformation(cell, ti, 0, &cti);
684 if (BaseType::CellSqrDistance(cell[0], cti) <= sqrRadius)
685 {
686 PointsInBall(sqrRadius, cell[0], cti, points);
687 }
688 }
689 // check distance to right box
690 if (BaseType::ExistChild(cell, 1))
691 {
692 InitTraversalInformation(cell, ti, 1, &cti);
693 if (BaseType::CellSqrDistance(cell[1], cti) <= sqrRadius)
694 {
695 PointsInBall(sqrRadius, cell[1], cti, points);
696 }
697 }
698 }
699
700 template <class PointT, class DistScalarT, class ContainerT>
701 void
702 PrivatePointsInBall(const PointT& p,
703 DistScalarT sqrRadius,
704 ContainerT* points,
705 PointsInBallAuxData<PointT>* auxData) const
706 {
707 typedef PointsInBallAuxData<PointT> AuxDataType;
708 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
709 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
710 typedef typename AuxDataType::value_type AuxDataValueType;
711 typedef typename AuxDataType::DistanceType DistanceType;
712 if (!BaseType::Root())
713 {
714 return;
715 }
716 auxData->reserve(128);
717 GlobalInfoType gti;
719 gti.Point(p);
720 ti.Global(&gti);
721 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
722 const CellType* current = BaseType::Root();
723 while (1)
724 {
725 if (BaseType::IsLeaf(*current))
726 {
727 typename BaseType::CellRange range;
728 BaseType::GetCellRange(*current, ti, &range);
729 typename BaseType::HandleType h = range.first;
730 // let's find nearest neighbors from points within the cell
731 for (; h != range.second; ++h)
732 {
733 typename ContainerT::value_type nn(
734 BaseType::SqrDistance(p, BaseType::at(BaseType::Dereference(h))),
735 BaseType::Dereference(h));
736 if (nn.sqrDist <= sqrRadius)
737 {
738 points->push_back(nn);
739 }
740 }
741 }
742 else if (!BaseType::ExistChild(*current, 0))
743 {
745 InitTraversalInformation(*current, ti, 1, &rti);
746 if (BaseType::CellSqrDistance(current[1], rti) <= sqrRadius)
747 {
748 current = &(*current)[1];
749 ti = rti;
750 continue;
751 }
752 }
753 else if (!BaseType::ExistChild(*current, 1))
754 {
756 InitTraversalInformation(*current, ti, 0, &lti);
757 if (BaseType::CellSqrDistance((*current)[0], lti) <= sqrRadius)
758 {
759 current = &(*current)[0];
760 ti = lti;
761 continue;
762 }
763 }
764 else
765 {
766 TraversalInfoType lti, rti;
767 DistanceType dl, dr;
768 InitTraversalInformation(*current, ti, 0, &lti);
769 InitTraversalInformation(*current, ti, 1, &rti);
770 // descent into left child first
771 dl = BaseType::CellSqrDistance((*current)[0], lti);
772 dr = BaseType::CellSqrDistance((*current)[1], rti);
773 if (dl <= sqrRadius)
774 {
775 if (dr <= sqrRadius)
776 {
777 auxData->push_back(AuxDataValueType(&(*current)[1], rti));
778 }
779 current = &(*current)[0];
780 ti = lti;
781 continue;
782 }
783 else if (dr <= sqrRadius)
784 {
785 current = &(*current)[1];
786 ti = rti;
787 continue;
788 }
789 }
790 // pop stack
791 if (!auxData->size())
792 {
793 return;
794 }
795 current = auxData->back().m_cell;
796 ti = auxData->back().m_ti;
797 auxData->pop_back();
798 }
799 }
800
801 template <class TraversalInformationT, class LimitedHeapT>
802 void
803 PrivateNearestNeighbors(const CellType& cell,
804 const TraversalInformationT& ti,
805 LimitedHeapT* neighbors) const
806 {
807 typedef typename LimitedHeapT::value_type NNType;
808 if (BaseType::IsLeaf(cell) || (neighbors->size() + cell.Size() <= neighbors->Limit()))
809 {
810 typename BaseType::CellRange range;
811 BaseType::GetCellRange(cell, ti, &range);
812 typename BaseType::HandleType h = range.first;
813 // let's find nearest neighbors from points within the cell
814 for (; h != range.second; ++h)
815 {
816 NNType nn(BaseType::SqrDistance(ti.Global().Point(),
817 BaseType::at(BaseType::Dereference(h))),
818 BaseType::Dereference(h));
819 neighbors->PushHeap(nn);
820 }
821 return;
822 }
823 if (!BaseType::ExistChild(cell, 0))
824 {
825 TraversalInformationT rti;
826 typename NNType::ScalarType dr;
827 InitTraversalInformation(cell, ti, 1, &rti);
828 dr = BaseType::CellSqrDistance(cell[1], rti);
829 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
830 {
831 PrivateNearestNeighbors(cell[1], rti, neighbors);
832 }
833 return;
834 }
835 else if (!BaseType::ExistChild(cell, 1))
836 {
837 TraversalInformationT lti;
838 typename NNType::ScalarType dl;
839 InitTraversalInformation(cell, ti, 0, &lti);
840 dl = BaseType::CellSqrDistance(cell[0], lti);
841 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
842 {
843 PrivateNearestNeighbors(cell[0], lti, neighbors);
844 }
845 return;
846 }
847 TraversalInformationT lti, rti;
848
849 typename NNType::ScalarType dl, dr;
850 InitTraversalInformation(cell, ti, 0, &lti);
851 InitTraversalInformation(cell, ti, 1, &rti);
852 // descent into closer child first
853 dl = BaseType::CellSqrDistance(cell[0], lti);
854 dr = BaseType::CellSqrDistance(cell[1], rti);
855 if (dl <= dr)
856 {
857 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
858 {
859 PrivateNearestNeighbors(cell[0], lti, neighbors);
860 }
861 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
862 {
863 PrivateNearestNeighbors(cell[1], rti, neighbors);
864 }
865 }
866 else
867 {
868 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
869 {
870 PrivateNearestNeighbors(cell[1], rti, neighbors);
871 }
872 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
873 {
874 PrivateNearestNeighbors(cell[0], lti, neighbors);
875 }
876 }
877 }
878
879 template <class PointT, class LimitedHeapT>
880 void
881 PrivateNearestNeighbors(const PointT& p,
883 LimitedHeapT* neighbors) const
884 {
885 typedef NearestNeighborsAuxData<PointT> AuxDataType;
886 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
887 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
888 typedef typename AuxDataType::value_type AuxDataValueType;
889 if (!BaseType::Root())
890 {
891 return;
892 }
893 auxData->reserve(128);
894 GlobalInfoType gti;
896 gti.Point(p);
897 ti.Global(&gti);
898 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
899 const CellType* current = BaseType::Root();
900 while (1)
901 {
902 typedef typename LimitedHeapT::value_type NNType;
903 if (BaseType::IsLeaf(*current) ||
904 (neighbors->size() + current->Size() <= neighbors->Limit()))
905 {
906 typename BaseType::CellRange range;
907 BaseType::GetCellRange(*current, ti, &range);
908 typename BaseType::HandleType h = range.first;
909 // let's find nearest neighbors from points within the cell
910 for (; h != range.second; ++h)
911 {
912 NNType nn(BaseType::SqrDistance(ti.Global().Point(),
913 BaseType::at(BaseType::Dereference(h))),
914 BaseType::Dereference(h));
915 neighbors->PushHeap(nn);
916 }
917 }
918 else if (!BaseType::ExistChild(*current, 0))
919 {
921 typename NNType::ScalarType dr;
922 InitTraversalInformation(*current, ti, 1, &rti);
923 dr = BaseType::CellSqrDistance(current[1], rti);
924 if (neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist)
925 {
926 current = &(*current)[1];
927 ti = rti;
928 continue;
929 }
930 }
931 else if (!BaseType::ExistChild(*current, 1))
932 {
934 typename NNType::ScalarType dl;
935 InitTraversalInformation(*current, ti, 0, &lti);
936 dl = BaseType::CellSqrDistance((*current)[0], lti);
937 if (neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist)
938 {
939 current = &(*current)[0];
940 ti = lti;
941 continue;
942 }
943 }
944 else
945 {
946 TraversalInfoType lti, rti;
947 typename NNType::ScalarType dl, dr;
948 InitTraversalInformation(*current, ti, 0, &lti);
949 InitTraversalInformation(*current, ti, 1, &rti);
950 // descent into closer child first
951 dl = BaseType::CellSqrDistance((*current)[0], lti);
952 dr = BaseType::CellSqrDistance((*current)[1], rti);
953 if (dl <= dr)
954 {
955 if (neighbors->size() < neighbors->Limit() ||
956 dl <= neighbors->front().sqrDist)
957 {
958 auxData->push_back(AuxDataValueType(&(*current)[1], rti, dr));
959 current = &(*current)[0];
960 ti = lti;
961 continue;
962 }
963 if ((neighbors->size() < neighbors->Limit() ||
964 dr <= neighbors->front().sqrDist))
965 {
966 current = &(*current)[1];
967 ti = rti;
968 continue;
969 }
970 }
971 else
972 {
973 if (neighbors->size() < neighbors->Limit() ||
974 dr <= neighbors->front().sqrDist)
975 {
976 auxData->push_back(AuxDataValueType(&(*current)[0], lti, dl));
977 current = &(*current)[1];
978 ti = rti;
979 continue;
980 }
981 if ((neighbors->size() < neighbors->Limit() ||
982 dl <= neighbors->front().sqrDist))
983 {
984 current = &(*current)[0];
985 ti = lti;
986 continue;
987 }
988 }
989 }
990 // pop stack
991 while (1)
992 {
993 if (!auxData->size())
994 {
995 return;
996 }
997 if (neighbors->size() < neighbors->Limit() ||
998 auxData->back().m_sqrDist <= neighbors->front().sqrDist)
999 {
1000 current = auxData->back().m_cell;
1001 ti = auxData->back().m_ti;
1002 auxData->pop_back();
1003 break;
1004 }
1005 auxData->pop_back();
1006 }
1007 }
1008 }
1009
1010 template <class TraversalInformationT,
1011 class NNT,
1012 class EpsilonT,
1013 template <class>
1014 class ContainerT>
1015 void
1017 const TraversalInformationT& ti,
1018 EpsilonT epsilon,
1019 LimitedHeap<NNT, std::less<NNT>, ContainerT>* neighbors) const
1020 {
1021 typedef NNT NNType;
1022 if (IsLeaf(cell) || (neighbors->size() + cell.Size() <= neighbors->Limit()))
1023 {
1024 typename BaseType::CellRange range;
1025 GetCellRange(cell, ti, &range);
1026 typename BaseType::HandleType h = range.first, hend = range.second;
1027 // let's find nearest neighbors from points within the cell
1028 for (; h != hend; ++h)
1029 {
1030 neighbors->PushHeap(NNType(SqrDistance(ti.Global().Point(), at(Dereference(h))),
1031 Dereference(h)));
1032 }
1033 return;
1034 }
1035 TraversalInformationT lti, rti;
1036 InitTraversalInformation(cell, ti, 0, &lti);
1037 InitTraversalInformation(cell, ti, 1, &rti);
1038 // descent into closer child first
1039 typename LimitedHeap<NNT, std::less<NNT>, ContainerT>::value_type::ScalarType dl, dr;
1040 dl = CellSqrDistance(cell[0], lti);
1041 dr = CellSqrDistance(cell[1], rti);
1042 if (dl <= dr)
1043 {
1044 if ((neighbors->size() < neighbors->Limit() ||
1045 epsilon * dl <= neighbors->front().sqrDist) &&
1046 BaseType::ExistChild(cell, 0))
1047 {
1048 ApproximateNearestNeighbors(cell[0], lti, epsilon, neighbors);
1049 }
1050 if ((neighbors->size() < neighbors->Limit() ||
1051 epsilon * dr <= neighbors->front().sqrDist) &&
1052 BaseType::ExistChild(cell, 1))
1053 {
1054 ApproximateNearestNeighbors(cell[1], rti, epsilon, neighbors);
1055 }
1056 }
1057 else
1058 {
1059 if ((neighbors->size() < neighbors->Limit() ||
1060 epsilon * dr <= neighbors->front().sqrDist) &&
1061 BaseType::ExistChild(cell, 1))
1062 {
1063 ApproximateNearestNeighbors(cell[1], rti, epsilon, neighbors);
1064 }
1065 if ((neighbors->size() < neighbors->Limit() ||
1066 epsilon * dl <= neighbors->front().sqrDist) &&
1067 BaseType::ExistChild(cell, 0))
1068 {
1069 ApproximateNearestNeighbors(cell[0], lti, epsilon, neighbors);
1070 }
1071 }
1072 }
1073
1074 template <class TraversalInformationT>
1075 bool
1076 Contains(const CellType& cell,
1077 const TraversalInformationT& ti,
1078 DereferencedType* dref) const
1079 {
1080 if (IsLeaf(cell))
1081 {
1082 typename BaseType::CellRange range;
1083 GetCellRange(cell, ti, &range);
1084 typename BaseType::HandleType h = range.first, hend = range.second;
1085 for (; h != hend; ++h)
1086 if (at(Dereference(h)) == ti.Global().Point())
1087 {
1088 *dref = Dereference(h);
1089 return true;
1090 }
1091 return false;
1092 }
1093 if (cell(ti.Global().Point()))
1094 {
1095 if (!BaseType::ExistChild(cell, 0))
1096 {
1097 return false;
1098 }
1099 TraversalInformationT lti;
1100 InitTraversalInformation(cell, ti, 0, &lti);
1101 return Contains(cell[0], lti, dref);
1102 }
1103 else
1104 {
1105 if (!BaseType::ExistChild(cell, 1))
1106 {
1107 return false;
1108 }
1109 TraversalInformationT rti;
1110 InitTraversalInformation(cell, rti, 1, &rti);
1111 return Contains(cell[1], rti, dref);
1112 }
1113 }
1114 };
1115}; // namespace GfxTL
1116
1117#endif
ScalarTypeDeferer< value_type >::ScalarType ScalarType
Definition KdTree.h:28
ScalarType & SplitValue()
Definition KdTree.h:80
ThisType & operator[](unsigned int i)
Definition KdTree.h:50
const ScalarType SplitValue() const
Definition KdTree.h:86
unsigned int & SplitAxis()
Definition KdTree.h:68
const unsigned int SplitAxis() const
Definition KdTree.h:74
void Child(unsigned int i, ThisType *cell)
Definition KdTree.h:62
BaseT::value_type value_type
Definition KdTree.h:27
const ThisType & operator[](unsigned int i) const
Definition KdTree.h:56
bool operator()(const VectorT &v) const
Definition KdTree.h:93
KdTreeCell< BaseT > ThisType
Definition KdTree.h:26
void Global(const GlobalInfoT *globalInfo)
Definition KdTree.h:230
const GlobalInfoT & Global() const
Definition KdTree.h:236
const unsigned int CreateChild() const
Definition KdTree.h:192
unsigned int & CreateChild()
Definition KdTree.h:186
ScalarTypeDeferer< value_type >::ScalarType ScalarType
Definition KdTree.h:180
bool Contains(const PointT &p, DereferencedType *dref) const
Definition KdTree.h:512
BaseType::value_type value_type
Definition KdTree.h:178
KdTreeCell< typename StrategiesT::CellData > CellType
Definition KdTree.h:174
void PointsInBall(const PointT &p, DistScalarT sqrRadius, ContainerT *points) const
Definition KdTree.h:334
void Remove(DereferencedType s)
Definition KdTree.h:327
void ApproximateNearestNeighbors(const PointT &p, unsigned int k, EpsilonT epsilon, LimitedHeap< typename NNTypeHelper< PointT >::NNType, std::less< typename NNTypeHelper< PointT >::NNType >, ContainerT > *neighbors) const
Definition KdTree.h:487
void PointsInBall(const PointT &p, DistScalarT sqrRadius, ContainerT *points, PointsInBallAuxData< PointT > *auxData) const
Definition KdTree.h:392
void Build()
Definition KdTree.h:246
BaseType::DereferencedType DereferencedType
Definition KdTree.h:179
void NearestNeighbors(const PointT &p, unsigned int k, LimitedHeapT *neighbors) const
Definition KdTree.h:403
void NearestNeighbors(const PointT &p, unsigned int k, LimitedHeapT *neighbors, NearestNeighborsAuxData< PointT > *auxData) const
Definition KdTree.h:464
void InsertBack()
Definition KdTree.h:313
StrategiesT::template StrategyBase< MetricT< VectorKernelT< BaseTree< KdTreeCell< typename StrategiesT::CellData > > > > > BaseType
Definition KdTree.h:177
Definition AABox.h:10
DataStrategyT::template StrategyBase< BaseT >::CellType CellType
Definition KdTree.h:126
BaseType::DereferencedType DereferencedType
Definition KdTree.h:128
void EnterGlobalBuildInformation(const CellType &cell, BuildInformationT *bi)
Definition KdTree.h:139
bool ShouldSubdivide(const CellType &cell, BuildInformationT &bi)
Definition KdTree.h:132
DataStrategyT::template StrategyBase< BaseT > BaseType
Definition KdTree.h:127
void LeaveGlobalBuildInformation(const CellType &cell, const BuildInformationT &bi)
Definition KdTree.h:145
void UpdateCellWithBack(const TraversalInformationT &, CellType *)
Definition KdTree.h:151
DataStrategyT::value_type value_type
Definition KdTree.h:117
NN< typename BaseType::template DistanceType< typename ScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type, typename BaseType::DereferencedType > NNType
Definition KdTree.h:482
NearestNeighborsAuxInfo< PointT >::DistanceType DistanceType
Definition KdTree.h:459
NearestNeighborsAuxInfo< PointT >::TraversalInfoType TraversalInfoType
Definition KdTree.h:458
BaseType::template GlobalTraversalInformation< BaseGlobalTraversalInformation< PointT > > GlobalInfoType
Definition KdTree.h:431
BaseType::template DistanceType< typenameScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type DistanceType
Definition KdTree.h:437
NearestNeighborsAuxInfo(const CellType *cell, const TraversalInfoType &ti, DistanceType sqrDist)
Definition KdTree.h:443
BaseType::template TraversalInformation< BaseTraversalInformation< GlobalInfoType > > TraversalInfoType
Definition KdTree.h:434
PointsInBallAuxInfo< PointT >::DistanceType DistanceType
Definition KdTree.h:387
PointsInBallAuxInfo< PointT >::TraversalInfoType TraversalInfoType
Definition KdTree.h:386
BaseType::template GlobalTraversalInformation< BaseGlobalTraversalInformation< PointT > > GlobalInfoType
Definition KdTree.h:362
PointsInBallAuxInfo(const CellType *cell, const TraversalInfoType &ti)
Definition KdTree.h:374
BaseType::template DistanceType< typenameScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type DistanceType
Definition KdTree.h:368
BaseType::template TraversalInformation< BaseTraversalInformation< GlobalInfoType > > TraversalInfoType
Definition KdTree.h:365
PointT::value_type ScalarType