1 #ifndef GfxTL__KDTREE_HEADER__
2 #define GfxTL__KDTREE_HEADER__
21 template<
class BaseT >
33 m_children[0] = m_children[1] = NULL;
47 return *m_children[i];
52 return *m_children[i];
80 template<
class VectorT >
83 return v[m_splitAxis] <= m_splitValue;
97 unsigned int m_splitAxis;
102 template<
class DataStrategyT >
108 :
public DataStrategyT::CellData
111 template<
class BaseT >
120 template<
class BuildInformationT >
126 template<
class BuildInformationT >
128 BuildInformationT* bi)
131 template<
class BuildInformationT >
133 const BuildInformationT& bi)
136 template<
class TraversalInformationT >
142 template<
class TraversalBaseT >
145 ::template TraversalInformation< TraversalBaseT >
150 template<
class StrategiesT,
template<
class >
class MetricT,
153 :
public StrategiesT::template StrategyBase
161 KdTreeCell< typename StrategiesT::CellData >
169 typedef typename StrategiesT::template StrategyBase
187 :
public BaseType::BuildInformation
192 return m_createChild;
196 return m_createChild;
200 unsigned int m_createChild;
203 template<
class Po
intT >
222 template<
class GlobalInfoT >
227 void Global(
const GlobalInfoT* globalInfo)
229 m_globalInfo = globalInfo;
233 return *m_globalInfo;
237 const GlobalInfoT* m_globalInfo;
242 typedef std::pair< CellType*, BuildInformation > Pair;
244 if (!BaseType::size())
249 std::deque< Pair > stack(1);
252 stack.back().first = BaseType::Root();
253 InitRootBuildInformation(&stack.back().second);
254 BaseType::InitRoot(stack.back().second, BaseType::Root());
257 Pair& p = stack.back();
260 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
264 if (BaseType::IsLeaf(*p.first))
266 if (!BaseType::ShouldSubdivide(*p.first, p.second))
271 Subdivide(p.second, p.first);
272 if (BaseType::IsLeaf(*p.first))
280 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
283 !this->ExistChild(*p.first, p.second.CreateChild()))
285 ++p.second.CreateChild();
292 BaseType::EnterGlobalBuildInformation(*p.first, &p.second);
293 stack.resize(stack.size() + 1);
294 stack.back().first = &(*p.first)[p.second.CreateChild()];
295 InitBuildInformation(*p.first, p.second,
296 p.second.CreateChild(), &stack.back().second);
297 InitCell(*p.first, p.second, p.second.CreateChild(),
298 stack.back().second, &(*p.first)[p.second.CreateChild()]);
299 ++p.second.CreateChild();
305 typedef typename BaseType::template GlobalTraversalInformation <
309 typename BaseType::template TraversalInformation <
311 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
320 template<
class Po
intT,
class DistScalarT,
class ContainerT >
326 DistScalarT sqrRadius,
327 ContainerT* points)
const
329 typedef typename BaseType::template GlobalTraversalInformation <
333 typename BaseType::template TraversalInformation <
338 InitRootTraversalInformation(*BaseType::Root(), &ti);
342 template<
class Po
intT >
345 typedef typename BaseType::template GlobalTraversalInformation <
347 typedef typename BaseType::template TraversalInformation <
362 template<
class Po
intT >
370 template<
class Po
intT,
class DistScalarT,
class ContainerT >
372 DistScalarT sqrRadius,
376 PrivatePointsInBall(p, sqrRadius, points, auxData);
379 template<
class Po
intT,
class LimitedHeapT >
381 LimitedHeapT* neighbors)
const
383 typedef typename BaseType::template GlobalTraversalInformation <
385 typedef typename BaseType::template TraversalInformation <
392 TraversalInformation ti;
397 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
398 PrivateNearestNeighbors(*BaseType::Root(), ti, neighbors);
399 neighbors->AssertHeap();
402 template<
class Po
intT >
405 typedef typename BaseType::template GlobalTraversalInformation <
407 typedef typename BaseType::template TraversalInformation <
424 template<
class Po
intT >
432 template<
class Po
intT,
class LimitedHeapT >
438 PrivateNearestNeighbors(p, auxData, neighbors);
439 neighbors->AssertHeap();
442 template<
class Po
intT >
446 typename BaseType::template DistanceType <
449 >
::Type,
typename BaseType::DereferencedType >
453 template<
class Po
intT,
class EpsilonT,
template<
class >
class ContainerT >
458 ContainerT >* neighbors)
const
460 typedef typename BaseType::template GlobalTraversalInformation <
463 typename BaseType::template TraversalInformation <
469 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
471 neighbors->AssertHeap();
474 template<
class Po
intT >
477 typedef typename BaseType::template GlobalTraversalInformation <
481 typename BaseType::template TraversalInformation <
485 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
486 return Contains(*BaseType::Root(), ti, dref);
490 void InitRootBuildInformation(BuildInformation* bi)
492 bi->CreateChild() = 0;
493 BaseType::InitRootBuildInformation(bi);
496 void InitBuildInformation(
const CellType& parent,
497 const BuildInformation& parentInfo,
unsigned int childIdx,
498 BuildInformation* bi)
500 bi->CreateChild() = 0;
501 BaseType::InitBuildInformation(parent, parentInfo, childIdx,
505 template<
class BuildInformationT >
506 void InitCell(
const CellType& parent,
507 const BuildInformationT& parentInfo,
unsigned int childIdx,
508 const BuildInformationT& bi,
CellType* cell)
510 BaseType::InitCell(parent, parentInfo, childIdx, bi, cell);
513 template<
class TraversalInformationT >
514 void InitTraversalInformation(
const CellType& parent,
515 const TraversalInformationT& pTi,
unsigned int childIdx,
516 TraversalInformationT* ti)
const
518 ti->Global(&pTi.Global());
519 BaseType::InitTraversalInformation(parent, pTi, childIdx, ti);
522 template<
class TraversalInformationT >
525 typename BaseType::CellRange range;
526 BaseType::GetCellRange(cell, ti, &range);
529 BaseType::InsertBack(range, &cell);
532 bool l = SplitAndInsert(cell, range, &(cell[0]), &(cell[1]));
533 TraversalInformationT cti;
536 UpdateCellWithBack(ti, &(cell[0]));
537 InitTraversalInformation(cell, ti, 0, &cti);
542 UpdateCellWithBack(ti, &(cell[1]));
543 InitTraversalInformation(cell, ti, 1, &cti);
552 BaseType::Remove(
s, &cell);
555 if (BaseType::Remove(cell,
s))
565 void Subdivide(BuildInformation& bi,
CellType* cell)
567 BaseType::ComputeSplit(bi, cell);
573 BaseType::SplitData(*cell, *cell, bi, left, right);
574 if (left->Size() == cell->Size())
579 else if (right->Size() == cell->Size())
601 cell->Child(0, left);
602 cell->Child(1, right);
603 if (BaseType::IsLeaf(*cell))
605 cell->Child(0, BaseType::InnerNodeMarker());
609 template<
class TraversalInformationT,
class DistScalarT,
612 const TraversalInformationT& ti, ContainerT* points)
const
614 if (BaseType::IsLeaf(cell))
617 typename BaseType::CellRange range;
618 BaseType::GetCellRange(cell, ti, &range);
619 for (
typename BaseType::HandleType h = range.first;
620 h != range.second; ++h)
622 DistScalarT d = BaseType::SqrDistance(ti.Global().Point(),
623 at(BaseType::Dereference(h)));
625 points->push_back(
typename ContainerT::value_type(
626 d, BaseType::Dereference(h)));
630 TraversalInformationT cti;
632 if (BaseType::ExistChild(cell, 0))
634 InitTraversalInformation(cell, ti, 0, &cti);
635 if (BaseType::CellSqrDistance(cell[0], cti) <= sqrRadius)
641 if (BaseType::ExistChild(cell, 1))
643 InitTraversalInformation(cell, ti, 1, &cti);
644 if (BaseType::CellSqrDistance(cell[1], cti) <= sqrRadius)
651 template<
class Po
intT,
class DistScalarT,
class ContainerT >
652 void PrivatePointsInBall(
const PointT& p, DistScalarT sqrRadius,
653 ContainerT* points, PointsInBallAuxData< PointT >* auxData)
const
655 typedef PointsInBallAuxData< PointT > AuxDataType;
656 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
657 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
658 typedef typename AuxDataType::value_type AuxDataValueType;
659 typedef typename AuxDataType::DistanceType DistanceType;
660 if (!BaseType::Root())
664 auxData->reserve(128);
666 TraversalInfoType ti;
669 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
670 const CellType* current = BaseType::Root();
673 if (BaseType::IsLeaf(*current))
675 typename BaseType::CellRange range;
676 BaseType::GetCellRange(*current, ti, &range);
677 typename BaseType::HandleType h = range.first;
679 for (; h != range.second; ++h)
681 typename ContainerT::value_type nn(
682 BaseType::SqrDistance(p, BaseType::at(BaseType::Dereference(h))),
683 BaseType::Dereference(h));
684 if (nn.sqrDist <= sqrRadius)
686 points->push_back(nn);
690 else if (!BaseType::ExistChild(*current, 0))
692 TraversalInfoType rti;
693 InitTraversalInformation(*current, ti, 1, &rti);
694 if (BaseType::CellSqrDistance(current[1], rti) <= sqrRadius)
696 current = &(*current)[1];
701 else if (!BaseType::ExistChild(*current, 1))
703 TraversalInfoType lti;
704 InitTraversalInformation(*current, ti, 0, <i);
705 if (BaseType::CellSqrDistance((*current)[0], lti) <= sqrRadius)
707 current = &(*current)[0];
714 TraversalInfoType lti, rti;
716 InitTraversalInformation(*current, ti, 0, <i);
717 InitTraversalInformation(*current, ti, 1, &rti);
719 dl = BaseType::CellSqrDistance((*current)[0], lti);
720 dr = BaseType::CellSqrDistance((*current)[1], rti);
725 auxData->push_back(AuxDataValueType(&(*current)[1], rti));
727 current = &(*current)[0];
731 else if (dr <= sqrRadius)
733 current = &(*current)[1];
739 if (!auxData->size())
743 current = auxData->back().m_cell;
744 ti = auxData->back().m_ti;
749 template<
class TraversalInformationT,
class LimitedHeapT >
750 void PrivateNearestNeighbors(
const CellType& cell,
751 const TraversalInformationT& ti,
752 LimitedHeapT* neighbors)
const
754 typedef typename LimitedHeapT::value_type NNType;
755 if (BaseType::IsLeaf(cell)
756 || (neighbors->size() + cell.Size() <= neighbors->Limit()))
758 typename BaseType::CellRange range;
759 BaseType::GetCellRange(cell, ti, &range);
760 typename BaseType::HandleType h = range.first;
762 for (; h != range.second; ++h)
764 NNType nn(BaseType::SqrDistance(ti.Global().Point(), BaseType::at(BaseType::Dereference(h))),
765 BaseType::Dereference(h));
766 neighbors->PushHeap(nn);
770 if (!BaseType::ExistChild(cell, 0))
772 TraversalInformationT rti;
773 typename NNType::ScalarType dr;
774 InitTraversalInformation(cell, ti, 1, &rti);
775 dr = BaseType::CellSqrDistance(cell[1], rti);
776 if ((neighbors->size() < neighbors->Limit()
777 || dr <= neighbors->front().sqrDist))
779 PrivateNearestNeighbors(cell[1], rti, neighbors);
783 else if (!BaseType::ExistChild(cell, 1))
785 TraversalInformationT lti;
786 typename NNType::ScalarType dl;
787 InitTraversalInformation(cell, ti, 0, <i);
788 dl = BaseType::CellSqrDistance(cell[0], lti);
789 if ((neighbors->size() < neighbors->Limit()
790 || dl <= neighbors->front().sqrDist))
792 PrivateNearestNeighbors(cell[0], lti, neighbors);
796 TraversalInformationT lti, rti;
798 typename NNType::ScalarType dl, dr;
799 InitTraversalInformation(cell, ti, 0, <i);
800 InitTraversalInformation(cell, ti, 1, &rti);
802 dl = BaseType::CellSqrDistance(cell[0], lti);
803 dr = BaseType::CellSqrDistance(cell[1], rti);
806 if ((neighbors->size() < neighbors->Limit()
807 || dl <= neighbors->front().sqrDist))
809 PrivateNearestNeighbors(cell[0], lti, neighbors);
811 if ((neighbors->size() < neighbors->Limit()
812 || dr <= neighbors->front().sqrDist))
814 PrivateNearestNeighbors(cell[1], rti, neighbors);
819 if ((neighbors->size() < neighbors->Limit()
820 || dr <= neighbors->front().sqrDist))
822 PrivateNearestNeighbors(cell[1], rti, neighbors);
824 if ((neighbors->size() < neighbors->Limit()
825 || dl <= neighbors->front().sqrDist))
827 PrivateNearestNeighbors(cell[0], lti, neighbors);
832 template<
class Po
intT,
class LimitedHeapT >
833 void PrivateNearestNeighbors(
const PointT& p,
834 NearestNeighborsAuxData< PointT >* auxData,
835 LimitedHeapT* neighbors)
const
837 typedef NearestNeighborsAuxData< PointT > AuxDataType;
838 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
839 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
840 typedef typename AuxDataType::value_type AuxDataValueType;
841 if (!BaseType::Root())
845 auxData->reserve(128);
847 TraversalInfoType ti;
850 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
851 const CellType* current = BaseType::Root();
854 typedef typename LimitedHeapT::value_type NNType;
855 if (BaseType::IsLeaf(*current)
856 || (neighbors->size() + current->Size() <= neighbors->Limit()))
858 typename BaseType::CellRange range;
859 BaseType::GetCellRange(*current, ti, &range);
860 typename BaseType::HandleType h = range.first;
862 for (; h != range.second; ++h)
864 NNType nn(BaseType::SqrDistance(ti.Global().Point(), BaseType::at(BaseType::Dereference(h))),
865 BaseType::Dereference(h));
866 neighbors->PushHeap(nn);
869 else if (!BaseType::ExistChild(*current, 0))
871 TraversalInfoType rti;
872 typename NNType::ScalarType dr;
873 InitTraversalInformation(*current, ti, 1, &rti);
874 dr = BaseType::CellSqrDistance(current[1], rti);
875 if (neighbors->size() < neighbors->Limit()
876 || dr <= neighbors->front().sqrDist)
878 current = &(*current)[1];
883 else if (!BaseType::ExistChild(*current, 1))
885 TraversalInfoType lti;
886 typename NNType::ScalarType dl;
887 InitTraversalInformation(*current, ti, 0, <i);
888 dl = BaseType::CellSqrDistance((*current)[0], lti);
889 if (neighbors->size() < neighbors->Limit()
890 || dl <= neighbors->front().sqrDist)
892 current = &(*current)[0];
899 TraversalInfoType lti, rti;
900 typename NNType::ScalarType dl, dr;
901 InitTraversalInformation(*current, ti, 0, <i);
902 InitTraversalInformation(*current, ti, 1, &rti);
904 dl = BaseType::CellSqrDistance((*current)[0], lti);
905 dr = BaseType::CellSqrDistance((*current)[1], rti);
908 if (neighbors->size() < neighbors->Limit()
909 || dl <= neighbors->front().sqrDist)
911 auxData->push_back(AuxDataValueType(&(*current)[1], rti, dr));
912 current = &(*current)[0];
916 if ((neighbors->size() < neighbors->Limit()
917 || dr <= neighbors->front().sqrDist))
919 current = &(*current)[1];
926 if (neighbors->size() < neighbors->Limit()
927 || dr <= neighbors->front().sqrDist)
929 auxData->push_back(AuxDataValueType(&(*current)[0], lti, dl));
930 current = &(*current)[1];
934 if ((neighbors->size() < neighbors->Limit()
935 || dl <= neighbors->front().sqrDist))
937 current = &(*current)[0];
946 if (!auxData->size())
950 if (neighbors->size() < neighbors->Limit()
951 || auxData->back().m_sqrDist <= neighbors->front().sqrDist)
953 current = auxData->back().m_cell;
954 ti = auxData->back().m_ti;
963 template<
class TraversalInformationT,
class NNT,
964 class EpsilonT,
template<
class >
class ContainerT >
966 const TraversalInformationT& ti, EpsilonT epsilon,
967 LimitedHeap< NNT, std::less<NNT>, ContainerT >* neighbors)
const
971 || (neighbors->size() + cell.Size() <= neighbors->Limit()))
973 typename BaseType::CellRange range;
974 GetCellRange(cell, ti, &range);
975 typename BaseType::HandleType h = range.first,
978 for (; h != hend; ++h)
980 neighbors->PushHeap(NNType(
981 SqrDistance(ti.Global().Point(), at(Dereference(h))),
986 TraversalInformationT lti, rti;
987 InitTraversalInformation(cell, ti, 0, <i);
988 InitTraversalInformation(cell, ti, 1, &rti);
990 typename LimitedHeap< NNT, std::less<NNT>, ContainerT >::value_type::ScalarType
992 dl = CellSqrDistance(cell[0], lti);
993 dr = CellSqrDistance(cell[1], rti);
996 if ((neighbors->size() < neighbors->Limit()
997 || epsilon * dl <= neighbors->front().sqrDist)
998 && BaseType::ExistChild(cell, 0))
1002 if ((neighbors->size() < neighbors->Limit()
1003 || epsilon * dr <= neighbors->front().sqrDist)
1004 && BaseType::ExistChild(cell, 1))
1011 if ((neighbors->size() < neighbors->Limit()
1012 || epsilon * dr <= neighbors->front().sqrDist)
1013 && BaseType::ExistChild(cell, 1))
1017 if ((neighbors->size() < neighbors->Limit()
1018 || epsilon * dl <= neighbors->front().sqrDist)
1019 && BaseType::ExistChild(cell, 0))
1026 template<
class TraversalInformationT >
1032 typename BaseType::CellRange range;
1033 GetCellRange(cell, ti, &range);
1034 typename BaseType::HandleType h = range.first,
1035 hend = range.second;
1036 for (; h != hend; ++h)
1037 if (at(Dereference(h)) == ti.Global().Point())
1039 *dref = Dereference(h);
1044 if (cell(ti.Global().Point()))
1046 if (!BaseType::ExistChild(cell, 0))
1050 TraversalInformationT lti;
1051 InitTraversalInformation(cell, ti, 0, <i);
1052 return Contains(cell[0], lti, dref);
1056 if (!BaseType::ExistChild(cell, 1))
1060 TraversalInformationT rti;
1061 InitTraversalInformation(cell, rti, 1, &rti);
1062 return Contains(cell[1], rti, dref);