00001
00002
00008 #if !defined(__BBoxTree_h__)
00009 #define __BBoxTree_h__
00010
00011
00012 #if defined(DEBUG_geom) && !defined(DEBUG_BBoxTree)
00013 #define DEBUG_BBoxTree
00014 #endif
00015
00016 #include "../kernel/BBox.h"
00017 #include "../kernel/distance.h"
00018
00019 #include "../../ads/functor/compose.h"
00020 #include "../../ads/functor/composite_compare.h"
00021 #include "../../ads/functor/Dereference.h"
00022
00023 #include "../../numerical/random/uniform/ContinuousUniformGenerator.h"
00024 #include "../../numerical/random/uniform/DiscreteUniformGeneratorMc32.h"
00025
00026 #include <vector>
00027
00028 BEGIN_NAMESPACE_GEOM
00029
00030
00031
00032
00033
00035
00039 template<int N, typename T>
00040 class BBoxTreeTypes {
00041
00042
00043
00044
00045 public:
00046
00048 typedef T Number;
00050 typedef ads::FixedArray<N,T> Point;
00052 typedef BBox<N,Number> BBox;
00054 typedef int SizeType;
00055
00057 typedef std::vector<int> IndexContainer;
00059 typedef typename IndexContainer::iterator IndexIterator;
00061 typedef typename IndexContainer::const_iterator IndexConstIterator;
00062 };
00063
00064
00065
00066
00067
00068
00069
00070 template<int N, typename T>
00071 class BBoxTreeLeaf;
00072
00074 template<int N, typename T>
00075 class BBoxTreeNode {
00076
00077
00078
00079
00080 private:
00081
00082 typedef BBoxTreeTypes<N,T> Types;
00083 typedef BBoxTreeLeaf<N,T> Leaf;
00084
00085
00086
00087
00088
00089
00090 public:
00091
00093 typedef typename Types::Number Number;
00095 typedef typename Types::Point Point;
00097 typedef typename Types::BBox BBox;
00099 typedef typename Types::SizeType SizeType;
00100
00101
00103
00104
00106 virtual
00107 ~BBoxTreeNode()
00108 {}
00109
00111
00113
00114
00116 virtual
00117 void
00118 computePointQuery(std::vector<const Leaf*>& leaves,
00119 const Point& x) const = 0;
00120
00122 virtual
00123 void
00124 computeWindowQuery(std::vector<const Leaf*>& leaves,
00125 const BBox& window) const = 0;
00126
00128 virtual
00129 void
00130 computeMinimumDistanceQuery(std::vector<const Leaf*>& leaves,
00131 const Point& x, Number* upperBound) const
00132 = 0;
00133
00135
00137
00138
00140 virtual
00141 const BBox&
00142 getDomain() const = 0;
00143
00145
00147
00148
00150 virtual
00151 void
00152 computeDomain(const std::vector<BBox>& boxes) = 0;
00153
00155
00157
00158
00160 virtual
00161 void
00162 printAscii(std::ostream& out) const = 0;
00163
00165
00167
00168
00170 virtual
00171 SizeType
00172 getMemoryUsage() const = 0;
00173
00175
00177
00178
00180 virtual
00181 void
00182 checkValidity(const std::vector<BBox>& boxes) const = 0;
00183
00185 };
00186
00187
00189
00190 template<int N, typename T>
00191 inline
00192 std::ostream&
00193 operator<<(std::ostream& out, const BBoxTreeNode<N,T>& node) {
00194 node.printAscii(out);
00195 return out;
00196 }
00197
00198
00199
00200
00201
00202
00203
00205 template<int N, typename T>
00206 class BBoxTreeLeaf :
00207 public BBoxTreeNode<N,T> {
00208
00209
00210
00211
00212 private:
00213
00214 typedef BBoxTreeTypes<N,T> Types;
00215 typedef BBoxTreeLeaf Leaf;
00217 typedef typename Types::IndexContainer IndexContainer;
00219 typedef typename Types::IndexIterator IndexIterator;
00220
00221
00222
00223
00224
00225 public:
00226
00228 typedef typename Types::Number Number;
00230 typedef typename Types::Point Point;
00232 typedef typename Types::BBox BBox;
00234 typedef typename Types::SizeType SizeType;
00235
00237 typedef typename Types::IndexConstIterator IndexConstIterator;
00238
00239
00240
00241
00242
00243 private:
00244
00246 BBox _domain;
00248 IndexContainer _indices;
00249
00250
00251
00252
00253
00254 private:
00255
00257 BBoxTreeLeaf(const BBoxTreeLeaf&);
00258
00260 BBoxTreeLeaf&
00261 operator=(const BBoxTreeLeaf&);
00262
00263
00264 public:
00265
00266
00268
00269
00271
00280 template<typename ObjectIter, typename ObjectIterIter>
00281 BBoxTreeLeaf(ObjectIter base, ObjectIterIter begin, ObjectIterIter end);
00282
00284 virtual
00285 ~BBoxTreeLeaf()
00286 {}
00287
00289
00291
00292
00294 const BBox&
00295 getDomain() const {
00296 return _domain;
00297 }
00298
00300 IndexConstIterator
00301 getIndicesBeginning() const {
00302 return _indices.begin();
00303 }
00304
00306 IndexConstIterator
00307 getIndicesEnd() const {
00308 return _indices.end();
00309 }
00310
00312
00314
00315
00317 void
00318 computeDomain(const std::vector<BBox>& boxes);
00319
00321
00323
00324
00326 void
00327 computePointQuery(std::vector<const Leaf*>& leaves, const Point& x) const {
00328 if (_domain.isIn(x)) {
00329 leaves.push_back(this);
00330 }
00331 }
00332
00334 void
00335 computeWindowQuery(std::vector<const Leaf*>& leaves,
00336 const BBox& window) const {
00337 if (doOverlap(window, _domain)) {
00338 leaves.push_back(this);
00339 }
00340 }
00341
00343 void
00344 computeMinimumDistanceQuery(std::vector<const Leaf*>& leaves,
00345 const Point& x, Number* upperBound) const;
00346
00348
00350
00351
00352
00353 void
00354 printAscii(std::ostream& out) const;
00355
00357
00359
00360
00362 SizeType
00363 getMemoryUsage() const {
00364 return int(sizeof(BBoxTreeLeaf) + _indices.size() * sizeof(int));
00365 }
00366
00368
00370
00371
00373
00377 void
00378 checkValidity(const std::vector<BBox>& boxes) const;
00379
00381 };
00382
00383
00384
00385
00386
00387
00388
00389
00391 template<int N, typename T>
00392 class BBoxTreeBranch :
00393 public BBoxTreeNode<N,T> {
00394
00395
00396
00397
00398 private:
00399
00400 typedef BBoxTreeTypes<N,T> Types;
00401 typedef BBoxTreeNode<N,T> Node;
00402 typedef BBoxTreeLeaf<N,T> Leaf;
00403
00404
00405
00406
00407
00408 public:
00409
00411 typedef typename Types::Number Number;
00413 typedef typename Types::Point Point;
00415 typedef typename Types::BBox BBox;
00417 typedef typename Types::SizeType SizeType;
00418
00419
00420
00421
00422
00423 private:
00424
00426 BBox _domain;
00428 Node* _left;
00430 Node* _right;
00431
00432
00433
00434
00435
00436 private:
00437
00438
00439 BBoxTreeBranch();
00440
00441
00442 BBoxTreeBranch(const BBoxTreeBranch&);
00443
00444
00445 BBoxTreeBranch&
00446 operator=(const BBoxTreeBranch&);
00447
00448 public:
00449
00450
00452
00453
00455 BBoxTreeBranch(const Point* base,
00456 const ads::FixedArray<N, std::vector<const Point*> >& sorted,
00457 SizeType leafSize);
00458
00460 virtual
00461 ~BBoxTreeBranch() {
00462 delete _left;
00463 delete _right;
00464 }
00465
00467
00469
00470
00472 const BBox&
00473 getDomain() const {
00474 return _domain;
00475 }
00476
00478
00480
00481
00483 void
00484 computeDomain(const std::vector<BBox>& boxes);
00485
00487
00489
00490
00492 void
00493 computePointQuery(std::vector<const Leaf*>& leaves, const Point& x) const;
00494
00496 void
00497 computeWindowQuery(std::vector<const Leaf*>& leaves,
00498 const BBox& window) const;
00499
00501 void
00502 computeMinimumDistanceQuery(std::vector<const Leaf*>& leaves,
00503 const Point& x, Number* upperBound) const;
00504
00506
00508
00509
00511 SizeType
00512 getMemoryUsage() const {
00513 return (sizeof(BBoxTreeBranch) + _left->getMemoryUsage()
00514 + _right->getMemoryUsage());
00515 }
00516
00518
00520
00521
00523 void
00524 checkValidity(const std::vector<BBox>& boxes) const;
00525
00527
00529
00530
00531
00532 void
00533 printAscii(std::ostream& out) const;
00534
00536 };
00537
00538
00539
00540
00541
00542
00543
00544
00546
00549 template<int N, typename T = double>
00550 class BBoxTree {
00551
00552
00553
00554
00555 private:
00556
00557 typedef BBoxTreeTypes<N,T> Types;
00558
00559
00560
00561
00562
00563 public:
00564
00566 typedef typename Types::Number Number;
00568 typedef typename Types::Point Point;
00570 typedef typename Types::BBox BBox;
00572 typedef typename Types::SizeType SizeType;
00573
00574
00575
00576
00577
00578
00579 private:
00580
00581 typedef BBoxTreeNode<N,T> Node;
00582 typedef BBoxTreeBranch<N,T> Branch;
00583 typedef BBoxTreeLeaf<N,T> Leaf;
00585 typedef typename Types::IndexConstIterator IndexConstIterator;
00586
00587
00588
00589
00590
00591 private:
00592
00594 Node* _root;
00595
00597 std::vector<BBox> _boxes;
00598
00600 mutable std::vector<const Leaf*> _leaves;
00601
00602 private:
00603
00604
00605
00606
00607
00608 private:
00609
00611 BBoxTree(const BBoxTree&);
00612
00614 BBoxTree&
00615 operator=(const BBoxTree&);
00616
00617 public:
00618
00619
00621
00622
00624 BBoxTree() :
00625 _root(0),
00626 _boxes(),
00627 _leaves()
00628 {}
00629
00631
00637 template<class BBoxInputIter>
00638 BBoxTree(BBoxInputIter begin, BBoxInputIter end,
00639 const SizeType leafSize = 8);
00640
00642
00648 template<class BBoxInputIter>
00649 void
00650 build(BBoxInputIter begin, BBoxInputIter end,
00651 const SizeType leafSize = 8);
00652
00654 ~BBoxTree() {
00655 if (_root) {
00656 delete _root;
00657 }
00658 }
00659
00661 void
00662 destroy();
00663
00664
00665
00667
00668
00670 SizeType
00671 getSize() const {
00672 return SizeType(_boxes.size());
00673 }
00674
00676 bool
00677 isEmpty() const {
00678 return _boxes.empty();
00679 }
00680
00681
00682
00684
00685
00687 template<typename IntegerOutputIter>
00688 void
00689 computePointQuery(IntegerOutputIter iter, const Point& x) const;
00690
00692 template<typename IntegerOutputIter>
00693 void
00694 computeWindowQuery(IntegerOutputIter iter, const BBox& window) const;
00695
00697 template<typename IntegerOutputIter>
00698 void
00699 computeMinimumDistanceQuery(IntegerOutputIter iter, const Point& x) const;
00700
00701
00702
00704
00705
00707 void
00708 printAscii(std::ostream& out) const;
00709
00710
00711
00713
00714
00716 SizeType
00717 getMemoryUsage() const {
00718 if (_root) {
00719 return (sizeof(BBoxTree) + _root->getMemoryUsage());
00720 }
00721 return sizeof(BBoxTree);
00722 }
00723
00724
00725
00727
00728
00730 void
00731 checkValidity() const {
00732 if (_root) {
00733 _root->checkValidity(_boxes);
00734 }
00735 }
00736
00737
00738
00739
00740
00741
00742
00743 private:
00744
00746 void
00747 build(SizeType leafSize);
00748 };
00749
00750
00752
00753 template<int N, typename T>
00754 inline
00755 std::ostream&
00756 operator<<(std::ostream& out, const BBoxTree<N,T>& x) {
00757 x.printAscii(out);
00758 return out;
00759 }
00760
00761
00762 END_NAMESPACE_GEOM
00763
00764 #define __geom_BBoxTree_ipp__
00765 #include "BBoxTree.ipp"
00766 #undef __geom_BBoxTree_ipp__
00767
00768 #endif