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>
9 #include <GfxTL/FlatCopyVector.h>
10 #include <GfxTL/LimitedHeap.h>
11 #include <GfxTL/MathHelper.h>
12 #include <GfxTL/NearestNeighbor.h>
13 #include <GfxTL/NullClass.h>
16 #include <GfxTL/VectorKernel.h>
17 #include <GfxTL/VectorXD.h>
18 #include <malloc.h>
19 
20 namespace 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 
49  ThisType&
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 
79  ScalarType&
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
192  CreateChild() const
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<
317  GlobalInfoType;
318  // traverse the tree and insert the point
319  typename BaseType::template TraversalInformation<
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
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<
345  GlobalInfoType;
346  GlobalInfoType gti;
347  typename BaseType::template TraversalInformation<
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 
379  const CellType* m_cell;
381  };
382 
383  template <class PointT>
384  struct PointsInBallAuxData : public FlatCopyVector<PointsInBallAuxInfo<PointT>>
385  {
388  };
389 
390  template <class PointT, class DistScalarT, class ContainerT>
391  void
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<
407  GlobalInfoType;
408  typedef typename BaseType::template TraversalInformation<
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 
440  {
441  }
442 
444  const TraversalInfoType& ti,
445  DistanceType sqrDist) :
446  m_cell(cell), m_ti(ti), m_sqrDist(sqrDist)
447  {
448  }
449 
450  const CellType* m_cell;
453  };
454 
455  template <class PointT>
456  struct NearestNeighborsAuxData : public FlatCopyVector<NearestNeighborsAuxInfo<PointT>>
457  {
460  };
461 
462  template <class PointT, class LimitedHeapT>
463  void
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<
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<
496  GlobalInfoType;
497  GlobalInfoType gti;
498  typename BaseType::template TraversalInformation<
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<
516  GlobalInfoType;
517  GlobalInfoType gti;
518  typename BaseType::template TraversalInformation<
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);
616  CellType *left, *right;
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;
718  TraversalInfoType ti;
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  {
744  TraversalInfoType rti;
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  {
755  TraversalInfoType lti;
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,
882  NearestNeighborsAuxData<PointT>* auxData,
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;
895  TraversalInfoType ti;
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  {
920  TraversalInfoType rti;
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  {
933  TraversalInfoType lti;
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
GfxTL::KdTree::PointsInBall
void PointsInBall(const PointT &p, DistScalarT sqrRadius, ContainerT *points) const
Definition: KdTree.h:334
NearestNeighbor.h
GfxTL::KdTreeCell::operator[]
ThisType & operator[](unsigned int i)
Definition: KdTree.h:50
GfxTL::KdTreeCell::operator()
bool operator()(const VectorT &v) const
Definition: KdTree.h:93
GfxTL::KdTree::PointsInBallAuxInfo::m_cell
const CellType * m_cell
Definition: KdTree.h:379
GfxTL::KdTree::BaseGlobalTraversalInformation::Point
void Point(const PointT &p)
Definition: KdTree.h:214
GfxTL::ScalarTypeDeferer
Definition: ScalarTypeDeferer.h:13
GfxTL::KdTree::PointsInBallAuxInfo::TraversalInfoType
BaseType::template TraversalInformation< BaseTraversalInformation< GlobalInfoType > > TraversalInfoType
Definition: KdTree.h:365
GfxTL::KdTree::NNTypeHelper::NNType
NN< typename BaseType::template DistanceType< typename ScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type, typename BaseType::DereferencedType > NNType
Definition: KdTree.h:482
GfxTL::KdTreeCell::SplitValue
const ScalarType SplitValue() const
Definition: KdTree.h:86
GfxTL::BaseKdTreeStrategy::StrategyBase::ShouldSubdivide
bool ShouldSubdivide(const CellType &cell, BuildInformationT &bi)
Definition: KdTree.h:132
GfxTL::DynVectorKernel
Definition: DynVectorKernel.h:7
GfxTL::KdTree::PointsInBallAuxInfo::DistanceType
BaseType::template DistanceType< typename ScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type DistanceType
Definition: KdTree.h:368
GfxTL::KdTree
Definition: KdTree.h:169
GfxTL::KdTree::PointsInBall
void PointsInBall(const PointT &p, DistScalarT sqrRadius, ContainerT *points, PointsInBallAuxData< PointT > *auxData) const
Definition: KdTree.h:392
GfxTL::KdTree::PointsInBallAuxInfo::GlobalInfoType
BaseType::template GlobalTraversalInformation< BaseGlobalTraversalInformation< PointT > > GlobalInfoType
Definition: KdTree.h:362
GfxTL::KdTree::BuildInformation::CreateChild
const unsigned int CreateChild() const
Definition: KdTree.h:192
GfxTL::KdTreeCell::Child
void Child(unsigned int i, ThisType *cell)
Definition: KdTree.h:62
GfxTL::KdTree::value_type
BaseType::value_type value_type
Definition: KdTree.h:178
GfxTL::KdTree::ScalarType
ScalarTypeDeferer< value_type >::ScalarType ScalarType
Definition: KdTree.h:180
GfxTL::ScalarTypeDeferer::ScalarType
PointT::value_type ScalarType
Definition: ScalarTypeDeferer.h:15
GfxTL::KdTree::NNTypeHelper
Definition: KdTree.h:476
GfxTL::KdTree::PointsInBallAuxInfo::m_ti
TraversalInfoType m_ti
Definition: KdTree.h:380
LimitedHeap.h
GfxTL::KdTree::BaseTraversalInformation::Global
void Global(const GlobalInfoT *globalInfo)
Definition: KdTree.h:230
GfxTL::KdTree::NearestNeighborsAuxInfo::m_sqrDist
DistanceType m_sqrDist
Definition: KdTree.h:452
GfxTL::KdTreeCell::value_type
BaseT::value_type value_type
Definition: KdTree.h:27
GfxTL::KdTreeCell::ThisType
KdTreeCell< BaseT > ThisType
Definition: KdTree.h:26
ScalarTypeConversion.h
VectorXD.h
GfxTL::KdTree::PointsInBallAuxData
Definition: KdTree.h:384
GfxTL::KdTreeCell::ScalarType
ScalarTypeDeferer< value_type >::ScalarType ScalarType
Definition: KdTree.h:28
GfxTL::NN
Definition: NearestNeighbor.h:8
GfxTL::FlatCopyVector
Definition: FlatCopyVector.h:11
GfxTL::KdTree::NearestNeighborsAuxInfo::m_cell
const CellType * m_cell
Definition: KdTree.h:450
GfxTL::KdTree::NearestNeighborsAuxInfo::NearestNeighborsAuxInfo
NearestNeighborsAuxInfo(const CellType *cell, const TraversalInfoType &ti, DistanceType sqrDist)
Definition: KdTree.h:443
GfxTL::BaseKdTreeStrategy::StrategyBase::EnterGlobalBuildInformation
void EnterGlobalBuildInformation(const CellType &cell, BuildInformationT *bi)
Definition: KdTree.h:139
GfxTL::KdTree::NearestNeighborsAuxData
Definition: KdTree.h:456
GfxTL::BaseKdTreeStrategy::StrategyBase::CellType
DataStrategyT::template StrategyBase< BaseT >::CellType CellType
Definition: KdTree.h:126
GfxTL::KdTreeCell
Definition: KdTree.h:23
GfxTL::KdTreeCell::KdTreeCell
KdTreeCell()
Definition: KdTree.h:35
GfxTL::KdTreeCell::SplitAxis
const unsigned int SplitAxis() const
Definition: KdTree.h:74
GfxTL::KdTree::NearestNeighborsAuxData::DistanceType
NearestNeighborsAuxInfo< PointT >::DistanceType DistanceType
Definition: KdTree.h:459
GfxTL::KdTree::BaseGlobalTraversalInformation::Point
const PointT & Point() const
Definition: KdTree.h:208
GfxTL::KdTree::BaseTraversalInformation
Definition: KdTree.h:224
GfxTL::KdTree::BaseType
StrategiesT::template StrategyBase< MetricT< VectorKernelT< BaseTree< KdTreeCell< typename StrategiesT::CellData > > > > > BaseType
Definition: KdTree.h:177
FlatCopyVector.h
GfxTL::KdTree::NearestNeighborsAuxInfo::TraversalInfoType
BaseType::template TraversalInformation< BaseTraversalInformation< GlobalInfoType > > TraversalInfoType
Definition: KdTree.h:434
GfxTL::KdTree::BaseGlobalTraversalInformation
Definition: KdTree.h:202
GfxTL::BaseKdTreeStrategy::StrategyBase::BaseType
DataStrategyT::template StrategyBase< BaseT > BaseType
Definition: KdTree.h:127
AABox.h
GfxTL::KdTree::NearestNeighborsAuxInfo
Definition: KdTree.h:427
BaseTree.h
GfxTL::KdTree::PointsInBallAuxInfo::PointsInBallAuxInfo
PointsInBallAuxInfo(const CellType *cell, const TraversalInfoType &ti)
Definition: KdTree.h:374
GfxTL::KdTree::Build
void Build()
Definition: KdTree.h:246
armarx::PointT
pcl::PointXYZRGBL PointT
Definition: Common.h:30
GfxTL::BaseKdTreeStrategy::StrategyBase::UpdateCellWithBack
void UpdateCellWithBack(const TraversalInformationT &, CellType *)
Definition: KdTree.h:151
GfxTL::KdTreeCell::NChildren
@ NChildren
Definition: KdTree.h:32
armarx::aron::similarity::FloatSimilarity::Type
Type
The Type enum.
Definition: FloatSimilarity.h:10
GfxTL::KdTree::BuildInformation
Definition: KdTree.h:182
GfxTL::KdTree::NearestNeighborsAuxInfo::NearestNeighborsAuxInfo
NearestNeighborsAuxInfo()
Definition: KdTree.h:439
GfxTL::KdTree::PointsInBallAuxInfo::PointsInBallAuxInfo
PointsInBallAuxInfo()
Definition: KdTree.h:370
GfxTL
Definition: AABox.h:9
GfxTL::KdTree::NearestNeighborsAuxData::TraversalInfoType
NearestNeighborsAuxInfo< PointT >::TraversalInfoType TraversalInfoType
Definition: KdTree.h:458
GfxTL::KdTreeCell::~KdTreeCell
~KdTreeCell()
Definition: KdTree.h:40
GfxTL::KdTree::ApproximateNearestNeighbors
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
GfxTL::KdTreeCell::SplitAxis
unsigned int & SplitAxis()
Definition: KdTree.h:68
GfxTL::KdTree::CellType
KdTreeCell< typename StrategiesT::CellData > CellType
Definition: KdTree.h:174
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
GfxTL::BaseKdTreeStrategy::StrategyBase::LeaveGlobalBuildInformation
void LeaveGlobalBuildInformation(const CellType &cell, const BuildInformationT &bi)
Definition: KdTree.h:145
GfxTL::KdTree::NearestNeighborsAuxInfo::m_ti
TraversalInfoType m_ti
Definition: KdTree.h:451
GfxTL::KdTree::DereferencedType
BaseType::DereferencedType DereferencedType
Definition: KdTree.h:179
GfxTL::BaseKdTreeStrategy::StrategyBase
Definition: KdTree.h:124
VectorKernel.h
GfxTL::BaseKdTreeStrategy
Definition: KdTree.h:115
GfxTL::KdTree::NearestNeighborsAuxInfo::DistanceType
BaseType::template DistanceType< typename ScalarTypeDeferer< PointT >::ScalarType, ScalarType >::Type DistanceType
Definition: KdTree.h:437
GfxTL::KdTree::BaseTraversalInformation::GlobalType
GlobalInfoT GlobalType
Definition: KdTree.h:227
NullClass.h
GfxTL::KdTree::BaseGlobalTraversalInformation::PointType
PointT PointType
Definition: KdTree.h:205
GfxTL::KdTreeCell::operator[]
const ThisType & operator[](unsigned int i) const
Definition: KdTree.h:56
GfxTL::LimitedHeap
Definition: LimitedHeap.h:15
GfxTL::KdTree::BaseTraversalInformation::Global
const GlobalInfoT & Global() const
Definition: KdTree.h:236
GfxTL::KdTree::PointsInBallAuxData::TraversalInfoType
PointsInBallAuxInfo< PointT >::TraversalInfoType TraversalInfoType
Definition: KdTree.h:386
GfxTL::KdTree::PointsInBallAuxInfo
Definition: KdTree.h:358
GfxTL::KdTree::InsertBack
void InsertBack()
Definition: KdTree.h:313
GfxTL::KdTree::NearestNeighborsAuxInfo::GlobalInfoType
BaseType::template GlobalTraversalInformation< BaseGlobalTraversalInformation< PointT > > GlobalInfoType
Definition: KdTree.h:431
GfxTL::BaseKdTreeStrategy::StrategyBase::DereferencedType
BaseType::DereferencedType DereferencedType
Definition: KdTree.h:128
GfxTL::KdTreeCell::SplitValue
ScalarType & SplitValue()
Definition: KdTree.h:80
MathHelper.h
GfxTL::BaseKdTreeStrategy::StrategyBase::TraversalInformationBase
Definition: KdTree.h:157
GfxTL::KdTree::BuildInformation::CreateChild
unsigned int & CreateChild()
Definition: KdTree.h:186
GfxTL::BaseKdTreeStrategy::CellData
Definition: KdTree.h:119
GfxTL::BaseKdTreeStrategy::value_type
DataStrategyT::value_type value_type
Definition: KdTree.h:117
ScalarTypeDeferer.h
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
GfxTL::KdTree::PointsInBallAuxData::DistanceType
PointsInBallAuxInfo< PointT >::DistanceType DistanceType
Definition: KdTree.h:387
GfxTL::KdTree::Contains
bool Contains(const PointT &p, DereferencedType *dref) const
Definition: KdTree.h:512
GfxTL::KdTree::NearestNeighbors
void NearestNeighbors(const PointT &p, unsigned int k, LimitedHeapT *neighbors, NearestNeighborsAuxData< PointT > *auxData) const
Definition: KdTree.h:464
GfxTL::KdTree::Remove
void Remove(DereferencedType s)
Definition: KdTree.h:327
GfxTL::KdTree::NearestNeighbors
void NearestNeighbors(const PointT &p, unsigned int k, LimitedHeapT *neighbors) const
Definition: KdTree.h:403