00001
00002
00003
00004
00005 #ifndef BALL_DATATYPE_HASHGRID_H
00006 #define BALL_DATATYPE_HASHGRID_H
00007
00008 #ifndef BALL_COMMON_H
00009 # include <BALL/common.h>
00010 #endif
00011
00012 #ifndef BALL_CONCEPT_FORWARDITERATOR_H
00013 # include <BALL/CONCEPT/forwardIterator.h>
00014 #endif
00015
00016 #ifndef BALL_CONCEPT_VISITOR_H
00017 # include <BALL/CONCEPT/visitor.h>
00018 #endif
00019
00020 #ifndef BALL_CONCEPT_PROCESSOR_H
00021 # include <BALL/CONCEPT/processor.h>
00022 #endif
00023
00024 #ifndef BALL_MATHS_VECTOR3_H
00025 # include <BALL/MATHS/vector3.h>
00026 #endif
00027
00028 #ifndef BALL_DATATYPE_LIST_H
00029 # include <BALL/DATATYPE/list.h>
00030 #endif
00031
00032 namespace BALL
00033 {
00038
00047 template <typename Item>
00048 class HashGridBox3
00049 {
00050 public:
00051
00055
00057 HashGridBox3();
00058
00060 HashGridBox3(const HashGridBox3& grid_box, bool deep = true);
00061
00063 ~HashGridBox3();
00064
00066 void clear();
00067
00071 void destroy();
00072
00074
00077
00079 void set(const HashGridBox3& box,bool = true)
00080 throw(Exception::NotImplemented);
00081
00083 const HashGridBox3& operator = (const HashGridBox3& box)
00084 throw(Exception::NotImplemented);
00085
00087
00090
00096 Item* find(const Item &item);
00097
00099 const Item* find(const Item& item) const;
00100
00104 Size getSize() const;
00105
00109 void insert(const Item& item);
00110
00116 bool remove(const Item& item);
00117
00123 bool removeAll(const Item& item);
00124
00126
00129
00131 void host(Visitor<HashGridBox3> &visitor);
00133
00136
00138 bool operator == (const HashGridBox3& box) const;
00139
00141 bool operator != (const HashGridBox3& box) const;
00142
00147 bool has(const Item& item) const;
00148
00152 bool isEmpty() const;
00153
00155
00158
00160 bool isValid() const;
00162 void dump(std::ostream& s = std::cout, Size depth = 0) const;
00163
00165
00168
00170 bool apply(UnaryProcessor<Item>& processor);
00171
00173 bool apply(UnaryProcessor< HashGridBox3<Item> >& processor);
00174
00176
00179
00181 class DataItem
00182 {
00183 public:
00184
00185 DataItem(const Item& item, DataItem* next)
00186 : item_(item),
00187 previous_(0),
00188 next_(next)
00189 {
00190 if (next_ != 0)
00191 {
00192 next_->previous_ = this;
00193 }
00194 }
00195
00196 Item item_;
00197 DataItem* previous_;
00198 DataItem* next_;
00199 };
00200
00201 typedef Position BoxIteratorPosition;
00202
00203 class BoxIteratorTraits
00204 {
00205 public:
00206
00207 BALL_CREATE_DEEP(BoxIteratorTraits)
00208
00209 virtual ~BoxIteratorTraits() throw () {}
00210
00211 BoxIteratorTraits()
00212 : bound_(0),
00213 position_(0)
00214 {
00215 }
00216
00217 BoxIteratorTraits(const HashGridBox3& box)
00218 : bound_((HashGridBox3 *)&box),
00219 position_(0)
00220 {
00221 }
00222
00223 BoxIteratorTraits(const BoxIteratorTraits& traits, bool = true)
00224 : bound_(traits.bound_),
00225 position_(traits.position_)
00226 {
00227 }
00228
00229 const BoxIteratorTraits& operator = (const BoxIteratorTraits& traits)
00230 {
00231 bound_ = traits.bound_;
00232 position_ = traits.position_;
00233 return *this;
00234 }
00235
00236 HashGridBox3* getContainer()
00237 {
00238 return bound_;
00239 }
00240
00241 const HashGridBox3* getContainer() const
00242 {
00243 return bound_;
00244 }
00245
00246 bool isSingular() const
00247 {
00248 return (bound_ == 0);
00249 }
00250
00251 BoxIteratorPosition& getPosition()
00252 {
00253 return position_;
00254 }
00255
00256 const BoxIteratorPosition& getPosition() const
00257 {
00258 return position_;
00259 }
00260
00261 bool operator == (const BoxIteratorTraits& traits) const
00262 {
00263 return (position_ == traits.position_);
00264 }
00265
00266 bool operator != (const BoxIteratorTraits& traits) const
00267 {
00268 return (position_ != traits.position_);
00269 }
00270
00271 bool isValid() const
00272 {
00273 return (bound_ != 0 && position_ < 27);
00274 }
00275
00276 void invalidate()
00277 {
00278 bound_ = 0;
00279 position_ = 100;
00280 }
00281
00282 void toBegin()
00283 {
00284 position_ = 0;
00285 }
00286
00287 bool isBegin() const
00288 {
00289 return (position_ == 0);
00290 }
00291
00292 void toEnd()
00293 {
00294 position_ = 27;
00295 }
00296
00297 bool isEnd() const
00298 {
00299 return (position_ == 27);
00300 }
00301
00302 HashGridBox3<Item>& getData()
00303 {
00304 return *bound_->neighbours[position_];
00305 }
00306
00307 const HashGridBox3<Item>& getData() const
00308 {
00309 return *bound_->neighbours[position_];
00310 }
00311
00312 void forward()
00313 {
00314 ++position_;
00315
00316 while (position_<27 && !(bound_->neighbours[position_]))
00317 {
00318 ++position_;
00319 }
00320 }
00321
00322 private:
00323
00324 HashGridBox3<Item> *bound_;
00325 BoxIteratorPosition position_;
00326 };
00327
00328 friend class BoxIteratorTraits;
00329
00334 typedef ForwardIterator
00335 <HashGridBox3<Item>, HashGridBox3<Item>,
00336 BoxIteratorPosition, BoxIteratorTraits>
00337 BoxIterator;
00338
00340 BoxIterator beginBox()
00341 {
00342 return BoxIterator::begin(*this);
00343 }
00344
00346 BoxIterator endBox()
00347 {
00348 return BoxIterator::end(*this);
00349 }
00350
00351
00353 typedef ConstForwardIterator
00354 <HashGridBox3<Item>, HashGridBox3<Item>,
00355 BoxIteratorPosition, BoxIteratorTraits>
00356 ConstBoxIterator;
00357
00359 ConstBoxIterator beginBox() const
00360 {
00361 return ConstBoxIterator::begin(*this);
00362 }
00363
00365 ConstBoxIterator endBox() const
00366 {
00367 return ConstBoxIterator::end(*this);
00368 }
00369
00370
00371 typedef DataItem* DataIteratorPosition;
00372
00373 class DataIteratorTraits
00374 {
00375 public:
00376
00377 BALL_CREATE_DEEP(DataIteratorTraits)
00378
00379 virtual ~DataIteratorTraits() {}
00380
00381 DataIteratorTraits()
00382 : bound_(0),
00383 position_(0)
00384 {
00385 }
00386
00387 DataIteratorTraits(const HashGridBox3& box)
00388 : bound_((HashGridBox3 *)&box),
00389 position_(0)
00390 {
00391 }
00392
00393 DataIteratorTraits(const DataIteratorTraits& traits, bool = true)
00394 : bound_(traits.bound_),
00395 position_(traits.position_)
00396 {
00397 }
00398
00399 const DataIteratorTraits& operator = (const DataIteratorTraits &traits)
00400 {
00401 bound_ = traits.bound_;
00402 position_ = traits.position_;
00403 return *this;
00404 }
00405
00406 HashGridBox3* getContainer()
00407 {
00408 return bound_;
00409 }
00410
00411 const HashGridBox3* getContainer() const
00412 {
00413 return bound_;
00414 }
00415
00416 bool isSingular() const
00417 {
00418 return (bound_ == 0);
00419 }
00420
00421 DataIteratorPosition& getPosition()
00422 {
00423 return position_;
00424 }
00425
00426 const DataIteratorPosition& getPosition() const
00427 {
00428 return position_;
00429 }
00430
00431 bool operator == (const DataIteratorTraits &traits) const
00432 {
00433 return (position_ == traits.position_);
00434 }
00435
00436 bool operator != (const DataIteratorTraits &traits) const
00437 {
00438 return (position_ != traits.position_);
00439 }
00440
00441 bool isValid() const
00442 {
00443 return (bound_ != 0 && position_ != 0);
00444 }
00445
00446 void invalidate()
00447 {
00448 bound_ = 0;
00449 position_ = 0;
00450 }
00451
00452 void toBegin()
00453 {
00454 position_ = bound_->first_item_;
00455 }
00456
00457 bool isBegin() const
00458 {
00459 return (position_ == bound_->first_item_);
00460 }
00461
00462 void toEnd()
00463 {
00464 position_ = 0;
00465 }
00466
00467 bool isEnd() const
00468 {
00469 return (position_ == 0);
00470 }
00471
00472 Item& getData()
00473 {
00474 return position_->item_;
00475 }
00476
00477 const Item& getData() const
00478 {
00479 return position_->item_;
00480 }
00481
00482 void forward()
00483 {
00484 position_ = position_->next_;
00485 }
00486
00487 private:
00488
00489 HashGridBox3<Item>* bound_;
00490 DataIteratorPosition position_;
00491 };
00492
00493 friend class DataIteratorTraits;
00494
00498 typedef ForwardIterator
00499 <HashGridBox3<Item>, Item,
00500 DataIteratorPosition, DataIteratorTraits>
00501 DataIterator;
00502
00504 DataIterator beginData()
00505 {
00506 return DataIterator::begin(*this);
00507 }
00508
00510 DataIterator endData()
00511 {
00512 return DataIterator::end(*this);
00513 }
00514
00515
00519 typedef ConstForwardIterator
00520 <HashGridBox3<Item>, Item,
00521 DataIteratorPosition, DataIteratorTraits>
00522 ConstDataIterator;
00523
00525 ConstDataIterator beginData() const
00526 {
00527 return ConstDataIterator::begin(*this);
00528 }
00529
00531 ConstDataIterator endData() const
00532 {
00533 return ConstDataIterator::end(*this);
00534 }
00535
00537
00539 HashGridBox3* neighbours[27];
00540
00541
00542 DataItem* first_item_;
00543 };
00544
00545 template<typename Item>
00546 HashGridBox3<Item>::HashGridBox3()
00547 : first_item_(0)
00548 {
00549 memset(neighbours, 0, 27*sizeof(HashGridBox3*));
00550 }
00551
00552 template<typename Item>
00553 HashGridBox3<Item>::HashGridBox3(const HashGridBox3<Item>& box, bool deep)
00554 : first_item_(0)
00555 {
00556 set(box, deep);
00557 }
00558
00559 template<typename Item>
00560 HashGridBox3<Item>::~HashGridBox3()
00561 {
00562 clear();
00563 }
00564
00565 template<typename Item>
00566 void HashGridBox3<Item>::clear()
00567 {
00568 for (DataItem* next_item = 0; first_item_ != 0; first_item_ = next_item)
00569 {
00570 next_item = first_item_->next_;
00571 delete first_item_;
00572 }
00573 }
00574
00575 template<typename Item>
00576 BALL_INLINE
00577 void HashGridBox3<Item>::destroy()
00578 {
00579 clear();
00580 }
00581
00582 template<typename Item>
00583 void HashGridBox3<Item>::set(const HashGridBox3<Item>& box, bool deep)
00584 throw(Exception::NotImplemented)
00585 {
00586
00587 throw Exception::NotImplemented(__FILE__, __LINE__);
00588 }
00589
00590 template<typename Item>
00591 BALL_INLINE
00592 const HashGridBox3<Item>& HashGridBox3<Item>::operator = (const HashGridBox3<Item>& box)
00593 throw(Exception::NotImplemented)
00594 {
00595 set(box);
00596
00597 return *this;
00598 }
00599
00600 template<typename Item>
00601 Item* HashGridBox3<Item>::find(const Item& item)
00602 {
00603 for (DataItem* item_ptr= first_item_; item_ptr != 0; item_ptr = item_ptr->next_)
00604 {
00605 if (item_ptr->item_ == item)
00606 {
00607 return &(item_ptr->item_);
00608 }
00609 }
00610
00611 return 0;
00612 }
00613
00614 template<typename Item>
00615 BALL_INLINE
00616 const Item* HashGridBox3<Item>::find(const Item& item) const
00617 {
00618 return const_cast<HashGridBox3*>(this)->find(item);
00619 }
00620
00621 template<typename Item>
00622 Size HashGridBox3<Item>::getSize() const
00623 {
00624 Size size = 0;
00625
00626
00627 for (const DataItem* item = first_item_; item != 0; item = item->next_, size++) {};
00628
00629 return size;
00630 }
00631
00632 template<typename Item>
00633 BALL_INLINE
00634 void HashGridBox3<Item>::insert(const Item& item)
00635 {
00636 first_item_ = new DataItem(item, first_item_);
00637 }
00638
00639 template<typename Item>
00640 bool HashGridBox3<Item>::remove(const Item& item)
00641 {
00642 for (DataItem* item_ptr = first_item_; item_ptr != 0; item_ptr = item_ptr->next_)
00643 {
00644 if (item_ptr->item_ == item)
00645 {
00646 if (item_ptr == first_item_)
00647 {
00648 first_item_ = first_item_->next_;
00649 }
00650
00651 if (item_ptr->next_ != 0)
00652 {
00653 item_ptr->next_->previous_ = item_ptr->previous_;
00654 }
00655
00656 if (item_ptr->previous_ != 0)
00657 {
00658 item_ptr->previous_->next_ = item_ptr->next_;
00659 }
00660
00661 delete item_ptr;
00662
00663 return true;
00664 }
00665 }
00666
00667 return false;
00668 }
00669
00670 template<typename Item>
00671 bool HashGridBox3<Item>::removeAll(const Item& item)
00672 {
00673 bool found = false;
00674 DataItem* next_item = 0;
00675 DataItem* item_ptr = first_item_;
00676
00677 while(item_ptr != 0)
00678 {
00679 next_item = item_ptr->next_;
00680
00681 if (item_ptr->item_ == item)
00682 {
00683 if (item_ptr == first_item_)
00684 {
00685 first_item_ = first_item_->next_;
00686 }
00687
00688 if (item_ptr->next_ != 0)
00689 {
00690 item_ptr->next_->previous_ = item_ptr->previous_;
00691 }
00692
00693 if (item_ptr->previous_ != 0)
00694 {
00695 item_ptr->previous_->next_ = item_ptr->next_;
00696 }
00697
00698 delete item_ptr;
00699
00700 found = true;
00701 }
00702
00703 item_ptr = next_item;
00704 }
00705
00706 return found;
00707 }
00708
00709 template <typename Item>
00710 BALL_INLINE
00711 void HashGridBox3<Item>::host(Visitor< HashGridBox3<Item> >& visitor)
00712 {
00713 visitor.visit(*this);
00714 }
00715
00716 template<typename Item>
00717 bool HashGridBox3<Item>::operator == (const HashGridBox3<Item>& box) const
00718 {
00719 const DataItem* a = first_item_;
00720 const DataItem* b = box.first_item_;
00721
00722 for (; a != 0 && b != 0; a = a->next_, b = b->next_)
00723 {
00724 if (a->item_ != b->item_)
00725 {
00726 return false;
00727 }
00728 }
00729
00730 return (a == b);
00731 }
00732
00733 template<typename Item>
00734 BALL_INLINE
00735 bool HashGridBox3<Item>::operator != (const HashGridBox3<Item>& box) const
00736 {
00737 return !(*this == box);
00738 }
00739
00740 template<typename Item>
00741 BALL_INLINE
00742 bool HashGridBox3<Item>::has(const Item& item) const
00743 {
00744 return (find(item) != 0);
00745 }
00746
00747 template<typename Item>
00748 BALL_INLINE
00749 bool HashGridBox3<Item>::isEmpty() const
00750 {
00751 return (first_item_ == 0);
00752 }
00753
00754 template<typename Item>
00755 bool HashGridBox3<Item>::isValid() const
00756 {
00757 Size size = 0;
00758 DataItem* item = 0;
00759
00760 for (item = first_item_; item != 0; item = item->next_)
00761 {
00762 ++size;
00763
00764 if (item->next_ == 0)
00765 {
00766 break;
00767 }
00768 }
00769
00770 for (; item != 0; item = item->previous_, --size) {};
00771
00772 return (size == 0);
00773 }
00774
00775 template<typename Item>
00776 void HashGridBox3<Item>::dump(std::ostream& s, Size depth) const
00777 {
00778 BALL_DUMP_STREAM_PREFIX(s);
00779
00780 BALL_DUMP_DEPTH(s, depth);
00781
00782 BALL_DUMP_DEPTH(s, depth);
00783 s << " size: " << getSize() << std::endl;
00784
00785 BALL_DUMP_DEPTH(s, depth);
00786 s << " data:" << std::endl;
00787 for (DataItem *item = first_item_; item != 0; item = item->next_)
00788 {
00789 BALL_DUMP_DEPTH(s, depth);
00790 s << " " << item->item_ << std::endl;
00791 }
00792
00793 BALL_DUMP_DEPTH(s, depth);
00794 s << " neighbor boxes:" << std::endl;
00795 for (Position i=0; i<27; ++i)
00796 {
00797 BALL_DUMP_DEPTH(s, depth);
00798 s << " " << neighbours[i] << std::endl;
00799 }
00800
00801 BALL_DUMP_STREAM_SUFFIX(s);
00802 }
00803
00804 template <typename Item>
00805 bool HashGridBox3<Item>::apply(UnaryProcessor<Item>& processor)
00806 {
00807 if (processor.start() == false)
00808 {
00809 return false;
00810 }
00811
00812 Processor::Result result;
00813
00814 for (DataItem *item = first_item_; item != 0; item = item->next_)
00815 {
00816 result = processor(item->item_);
00817
00818 if (result <= Processor::BREAK)
00819 {
00820 return (result == Processor::BREAK) ? true : false;
00821 }
00822 }
00823
00824 return processor.finish();
00825 }
00826
00827 template <typename Item>
00828 bool HashGridBox3<Item>::apply(UnaryProcessor< HashGridBox3<Item> >& processor)
00829 {
00830 if (processor.start() == false)
00831 {
00832 return false;
00833 }
00834
00835 Processor::Result result;
00836
00837 for (Position i=0; i<27; ++i)
00838 {
00839 result = processor(*neighbours[i]);
00840
00841 if (result <= Processor::BREAK)
00842 {
00843 return (result == Processor::BREAK) ? true : false;
00844 }
00845 }
00846
00847 return processor.finish();
00848 }
00849
00854 template <typename Item>
00855 class HashGrid3
00856 {
00857 public:
00858
00859 BALL_CREATE(HashGrid3)
00860
00861
00864
00866 HashGrid3();
00867
00878 HashGrid3(const Vector3& origin, Size dimension_x, Size dimension_y,
00879 Size dimension_z, float spacing_x, float spacing_y, float spacing_z);
00880
00884 HashGrid3(const Vector3& origin, Size dimension_x, Size dimension_y,
00885 Size dimension_z, float spacing);
00886
00896 HashGrid3(const Vector3& origin, const Vector3& size, float spacing);
00897
00899 HashGrid3(const HashGrid3& grid, bool deep = true);
00900
00902 virtual ~HashGrid3();
00903
00905 virtual void clear();
00906
00908 void clear(Position x, Position y, Position z);
00909
00911 void clear(const Vector3 &vector);
00912
00914 void destroy();
00915
00917 void destroy(Position x, Position y, Position z);
00918
00920 void destroy(const Vector3& vector);
00921
00923
00926
00928 void set(const Vector3& origin, const Vector3& unit,
00929 Size dimension_x, Size dimension_y, Size dimension_z);
00930
00932 void set(const Vector3& origin, float unit, Size size);
00933
00935 void set(const HashGrid3& grid, bool deep = true);
00936
00938 const HashGrid3& operator = (const HashGrid3& grid);
00939
00941 void get(Vector3& origin, Vector3& unit, Size& dimension_x, Size& dimension_y, Size& dimension_z) const;
00942
00944 void get(HashGrid3& grid, bool deep = true) const;
00945
00947
00950
00952 Size countNonEmptyBoxes() const;
00953
00955 Size getSize() const;
00956
00958 Vector3& getOrigin();
00959
00961 const Vector3& getOrigin() const;
00962
00964 Vector3& getUnit();
00965
00967 const Vector3& getUnit() const;
00968
00970 Size getSizeX() const;
00971
00973 Size getSizeY() const;
00974
00976 Size getSizeZ() const;
00977
00979 HashGridBox3<Item>* getBox(Position x, Position y, Position z);
00980
00982 const HashGridBox3<Item>* getBox(Position x, Position y, Position z) const;
00983
00985 HashGridBox3<Item>* getBox(const Vector3& vector);
00986
00988 const HashGridBox3<Item>* getBox(const Vector3 &vector) const;
00989
00991 bool getIndices(const HashGridBox3<Item>& box,
00992 Position& x, Position& y, Position& z) const;
00993
00995 void insert(Position x, Position y, Position z, const Item& item);
00996
00998 void insert(const Vector3& vector, const Item& item);
00999
01001 bool remove(Position x, Position y, Position z, const Item& item);
01002
01004 bool remove(const Vector3& vector, const Item& item);
01005
01007
01010
01012 void host(Visitor<HashGrid3>& visitor);
01013
01015
01018
01020 bool operator == (const HashGrid3& grid) const;
01021
01023 bool operator != (const HashGrid3& grid) const;
01024
01026 bool isEmpty() const;
01027
01029
01032
01034 virtual bool isValid() const;
01035
01037 virtual void dump(std::ostream& s = std::cout, Size depth = 0) const;
01038
01040
01044
01046 bool apply(UnaryProcessor<Item> &processor);
01047
01049 bool apply(UnaryProcessor< HashGridBox3<Item> > &processor);
01050
01054 const Item* getClosestItem(const Vector3& point, Size distance) const;
01055
01062 static float calculateMinSpacing(LongIndex memory, const Vector3& size);
01063
01065
01068
01069 typedef Position BoxIteratorPosition;
01070
01071 class BoxIteratorTraits
01072 {
01073 public:
01074
01075 BALL_CREATE_DEEP(BoxIteratorTraits)
01076
01077 virtual ~BoxIteratorTraits() {}
01078
01079 BoxIteratorTraits()
01080 : bound_(0),
01081 position_(0)
01082 {
01083 }
01084
01085 BoxIteratorTraits(const HashGrid3 &grid)
01086 : bound_((HashGrid3 *)&grid),
01087 position_(0)
01088 {
01089 }
01090
01091 BoxIteratorTraits(const BoxIteratorTraits& traits, bool = true)
01092 : bound_(traits.bound_),
01093 position_(traits.position_)
01094 {
01095 }
01096
01097 const BoxIteratorTraits& operator = (const BoxIteratorTraits& traits)
01098 {
01099 bound_ = traits.bound_;
01100 position_ = traits.position_;
01101 return *this;
01102 }
01103
01104 HashGrid3* getContainer()
01105 {
01106 return bound_;
01107 }
01108
01109 const HashGrid3* getContainer() const
01110 {
01111 return bound_;
01112 }
01113
01114 bool isSingular() const
01115 {
01116 return (bound_ == 0);
01117 }
01118
01119 BoxIteratorPosition& getPosition()
01120 {
01121 return position_;
01122 }
01123
01124 const BoxIteratorPosition& getPosition() const
01125 {
01126 return position_;
01127 }
01128
01129 bool operator == (const BoxIteratorTraits& traits) const
01130 {
01131 return (position_ == traits.position_);
01132 }
01133
01134 bool operator != (const BoxIteratorTraits& traits) const
01135 {
01136 return (position_ != traits.position_);
01137 }
01138
01139 bool isValid() const
01140 {
01141 return (bound_ != 0 && position_ < bound_->getSize());
01142 }
01143
01144 void invalidate()
01145 {
01146 bound_ = 0;
01147 position_ = bound_->getSize()+1;
01148 }
01149
01150 void toBegin()
01151 {
01152 position_ = 0;
01153 }
01154
01155 bool isBegin() const
01156 {
01157 return (position_ == 0);
01158 }
01159
01160 void toEnd()
01161 {
01162 position_ = bound_->getSize();
01163 }
01164
01165 bool isEnd() const
01166 {
01167 return (position_ == bound_->getSize());
01168 }
01169
01170 HashGridBox3<Item>& getData()
01171 {
01172 return bound_->box_[position_];
01173 }
01174
01175 const HashGridBox3<Item>& getData() const
01176 {
01177 return bound_->box_[position_];
01178 }
01179
01180 void forward()
01181 {
01182 ++position_;
01183 }
01184
01185 private:
01186
01187 HashGrid3<Item>* bound_;
01188 BoxIteratorPosition position_;
01189 };
01190
01191 friend class BoxIteratorTraits;
01192
01194 typedef ForwardIterator
01195 <HashGrid3<Item>, HashGridBox3<Item>,
01196 BoxIteratorPosition, BoxIteratorTraits>
01197 BoxIterator;
01198
01200 BoxIterator beginBox()
01201 {
01202 return BoxIterator::begin(*this);
01203 }
01204
01206 BoxIterator endBox()
01207 {
01208 return BoxIterator::end(*this);
01209 }
01210
01211
01213 typedef ConstForwardIterator
01214 <HashGrid3<Item>, HashGridBox3<Item>,
01215 BoxIteratorPosition, BoxIteratorTraits>
01216 ConstBoxIterator;
01217
01219 ConstBoxIterator beginBox() const
01220 {
01221 return ConstBoxIterator::begin(*this);
01222 }
01223
01225 ConstBoxIterator endBox() const
01226 {
01227 return ConstBoxIterator::end(*this);
01228 }
01229
01231
01232 private:
01233
01234
01235 Index getIndex_(const HashGridBox3<Item>& box) const;
01236
01238 void setNeighbours_();
01239
01240
01241 HashGridBox3<Item>* box_;
01242
01243 Vector3 origin_;
01244
01245 Vector3 unit_;
01246
01247 Size dimension_x_;
01248
01249 Size dimension_y_;
01250
01251 Size dimension_z_;
01252 };
01253
01254
01256
01257
01258 template <typename Item>
01259 HashGrid3<Item>::HashGrid3()
01260 : box_(0),
01261 origin_(0,0,0),
01262 unit_(0,0,0),
01263 dimension_x_(0),
01264 dimension_y_(0),
01265 dimension_z_(0)
01266 {
01267 }
01268
01269 template <typename Item>
01270 HashGrid3<Item>::HashGrid3
01271 (const Vector3 &originvector,
01272 Size dimension_x, Size dimension_y, Size dimension_z,
01273 float spacing_x, float spacing_y, float spacing_z)
01274 : box_(0),
01275 origin_(originvector),
01276 unit_(spacing_x, spacing_y, spacing_z),
01277 dimension_x_(dimension_x),
01278 dimension_y_(dimension_y),
01279 dimension_z_(dimension_z)
01280 {
01281 box_ = new HashGridBox3<Item>[dimension_x * dimension_y * dimension_z];
01282 setNeighbours_();
01283 }
01284
01285 template <typename Item>
01286 HashGrid3<Item>::HashGrid3
01287 (const Vector3& origin,
01288 Size dimension_x, Size dimension_y, Size dimension_z, float spacing)
01289 : box_(0),
01290 origin_(origin),
01291 unit_(spacing, spacing, spacing),
01292 dimension_x_(dimension_x),
01293 dimension_y_(dimension_y),
01294 dimension_z_(dimension_z)
01295 {
01296 box_ = new HashGridBox3<Item>[dimension_x * dimension_y * dimension_z];
01297 setNeighbours_();
01298 }
01299
01300
01301 template <typename Item>
01302 HashGrid3<Item>::HashGrid3(const Vector3& origin, const Vector3& size,
01303 float spacing)
01304 : box_(0),
01305 origin_(origin),
01306 unit_(spacing, spacing, spacing),
01307 dimension_x_((Size)(size.x / spacing + 1.0)),
01308 dimension_y_((Size)(size.y / spacing + 1.0)),
01309 dimension_z_((Size)(size.z / spacing + 1.0))
01310 {
01311 box_ = new HashGridBox3<Item>[dimension_x_ * dimension_y_ * dimension_z_];
01312 setNeighbours_();
01313 }
01314
01315 template <typename Item>
01316 HashGrid3<Item>::HashGrid3(const HashGrid3<Item>& grid, bool deep)
01317 : box_(0),
01318 origin_(),
01319 unit_()
01320 {
01321 set(grid, deep);
01322 }
01323
01324 template <typename Item>
01325 HashGrid3<Item>::~HashGrid3()
01326 {
01327 clear();
01328 delete [] box_;
01329 }
01330
01331 template <typename Item>
01332 void HashGrid3<Item>::clear()
01333 {
01334 if (box_ != 0)
01335 {
01336 Size size = dimension_x_ * dimension_y_ * dimension_z_;
01337
01338 for (Position index = 0; index < (Position)size; ++index)
01339 {
01340 box_[index].clear();
01341 }
01342 }
01343 }
01344
01345 template <typename Item>
01346 BALL_INLINE
01347 void HashGrid3<Item>::clear(Position x, Position y, Position z)
01348 {
01349 HashGridBox3<Item>* box = getBox(x, y, z);
01350
01351 if (box != 0)
01352 {
01353 box->clear();
01354 }
01355 }
01356
01357 template <typename Item>
01358 BALL_INLINE
01359 void HashGrid3<Item>::clear(const Vector3& vector)
01360 {
01361 HashGridBox3<Item>* box = getBox(vector);
01362
01363 if (box != 0)
01364 {
01365 box->clear();
01366 }
01367 }
01368
01369 template <typename Item>
01370 BALL_INLINE
01371 void HashGrid3<Item>::destroy()
01372 {
01373 clear();
01374 }
01375
01376 template <typename Item>
01377 BALL_INLINE
01378 void HashGrid3<Item>::destroy(Position x, Position y, Position z)
01379 {
01380 clear(x, y, z);
01381 }
01382
01383 template <typename Item>
01384 BALL_INLINE
01385 void HashGrid3<Item>::destroy(const Vector3 &vector)
01386 {
01387 clear(vector);
01388 }
01389
01390 template <typename Item>
01391 void HashGrid3<Item>::set
01392 (const Vector3& origin, const Vector3& unit,
01393 Size dimension_x, Size dimension_y, Size dimension_z)
01394 {
01395 clear();
01396 if (box_ != 0)
01397 {
01398 delete [] box_;
01399 }
01400 origin_.set(origin);
01401 unit_.set(unit);
01402 dimension_x_ = dimension_x;
01403 dimension_y_ = dimension_y;
01404 dimension_z_ = dimension_z;
01405 Size n = getSize();
01406 box_ = new HashGridBox3<Item> [n];
01407 setNeighbours_();
01408 }
01409
01410 template <typename Item>
01411 void HashGrid3<Item>::set(const Vector3& origin, float unit, Size size)
01412 {
01413 clear();
01414 if (box_ != 0)
01415 {
01416 delete [] box_;
01417 }
01418 origin_.set(origin);
01419 unit_.set(unit, unit, unit);
01420 dimension_x_ = size;
01421 dimension_y_ = size;
01422 dimension_z_ = size;
01423 box_ = new HashGridBox3<Item>[getSize()];
01424 setNeighbours_();
01425 }
01426
01427 template <typename Item>
01428 void HashGrid3<Item>::set(const HashGrid3<Item>& grid, bool )
01429 {
01430 set(grid.origin_, grid.unit_, grid.dimension_x_, grid.dimension_y_, grid.dimension_z_);
01431
01432 const HashGridBox3<Item>* sourcebox = grid.box_;
01433
01434 HashGridBox3<Item>* targetbox = box_;
01435
01436 const HashGridBox3<Item>* endbox = &grid.box_[grid.getSize()];
01437
01438 for (; sourcebox < endbox; ++sourcebox, ++targetbox)
01439 {
01440 if (sourcebox->isEmpty() == false)
01441 {
01442 for (typename HashGridBox3<Item>::DataItem* item = sourcebox->first_item_; item != 0; item = item->next_)
01443 {
01444 targetbox->insert(item->item_);
01445 }
01446 }
01447 }
01448 }
01449
01450 template <typename Item>
01451 BALL_INLINE
01452 const HashGrid3<Item>& HashGrid3<Item>::operator = (const HashGrid3<Item> &grid)
01453 {
01454 set(grid);
01455
01456 return *this;
01457 }
01458
01459 template <typename Item>
01460 BALL_INLINE
01461 void HashGrid3<Item>::get(Vector3 &origin, Vector3 &unit,
01462 Size& dimension_x, Size& dimension_y, Size& dimension_z) const
01463 {
01464 origin.set(origin_);
01465 unit.set(unit_);
01466 dimension_x = dimension_x_;
01467 dimension_y = dimension_y_;
01468 dimension_z = dimension_z_;
01469 }
01470
01471 template <typename Item>
01472 BALL_INLINE void
01473 HashGrid3<Item>::get(HashGrid3<Item> &grid, bool deep) const
01474 {
01475 grid.set(*this, deep);
01476 }
01477
01478 template <typename Item>
01479 Size
01480 HashGrid3<Item>::countNonEmptyBoxes() const
01481 {
01482 Size size = 0;
01483
01484 for (Position i=0; i<27; ++i)
01485 {
01486 if (!box_[i].isEmpty())
01487 ++size;
01488 }
01489
01490 return size;
01491 }
01492
01493 template <typename Item>
01494 BALL_INLINE
01495 Size HashGrid3<Item>::getSize() const
01496 {
01497 return (dimension_x_ * dimension_y_ * dimension_z_);
01498 }
01499
01500 template <typename Item>
01501 BALL_INLINE
01502 Vector3& HashGrid3<Item>::getOrigin()
01503 {
01504 return origin_;
01505 }
01506
01507 template <typename Item>
01508 BALL_INLINE
01509 const Vector3& HashGrid3<Item>::getOrigin() const
01510 {
01511 return origin_;
01512 }
01513
01514 template <typename Item>
01515 BALL_INLINE
01516 Vector3& HashGrid3<Item>::getUnit()
01517 {
01518 return unit_;
01519 }
01520
01521 template <typename Item>
01522 BALL_INLINE
01523 const Vector3& HashGrid3<Item>::getUnit() const
01524 {
01525 return unit_;
01526 }
01527
01528 template <typename Item>
01529 BALL_INLINE
01530 Size HashGrid3<Item>::getSizeX() const
01531 {
01532 return dimension_x_;
01533 }
01534
01535 template <typename Item>
01536 BALL_INLINE
01537 Size HashGrid3<Item>::getSizeY() const
01538 {
01539 return dimension_y_;
01540 }
01541
01542 template <typename Item>
01543 BALL_INLINE
01544 Size HashGrid3<Item>::getSizeZ() const
01545 {
01546 return dimension_z_;
01547 }
01548
01549 template <typename Item>
01550 const Item* HashGrid3<Item>::getClosestItem(const Vector3& point, Size dist) const
01551 {
01552 const HashGridBox3<Item>* box = getBox(point);
01553 if (!box) return 0;
01554
01555 Position x, y, z;
01556 getIndices(*box, x, y, z);
01557
01558 const Item* item = 0;
01559 float distance = FLT_MAX;
01560
01561
01562 for (Index xi = -(Index)dist; xi <= (Index)dist; xi++)
01563 {
01564 const Index xn = x + xi;
01565 for (Index yi = -(Index)dist; yi <= (Index)dist; yi++)
01566 {
01567 const Index yn = y + yi;
01568 for (Index zi = -(Index)dist; zi <= (Index)dist; zi++)
01569 {
01570
01571 const HashGridBox3<Item>* const box_ptr = getBox(xn, yn, z+zi);
01572 if (box_ptr != 0 && !box_ptr->isEmpty())
01573 {
01574 typename HashGridBox3<Item>::ConstDataIterator hit = box_ptr->beginData();
01575 for (;hit != box_ptr->endData(); hit++)
01576 {
01577 const float new_dist = ((*hit)->getPosition() - point).getSquareLength();
01578 if (new_dist < distance)
01579 {
01580 item = &*hit;
01581 distance = new_dist;
01582 }
01583 }
01584 }
01585 }
01586 }
01587 }
01588
01589 return item;
01590 }
01591
01592 template <typename Item>
01593 BALL_INLINE
01594 float HashGrid3<Item>::calculateMinSpacing(LongIndex memory, const Vector3& size)
01595 {
01596 LongSize memory_for_box = sizeof(HashGridBox3<Item>) + sizeof(HashGridBox3<Item>*);
01597 LongSize nr_boxes =(LongSize)floor((float)(memory / memory_for_box));
01598
01599 return pow((double)((size.x * size.y * size.z) / nr_boxes), (double)(1.0 / 3.0));
01600 }
01601
01602 template <typename Item>
01603 BALL_INLINE
01604 HashGridBox3<Item>* HashGrid3<Item>::getBox(Position x, Position y, Position z)
01605 {
01606 if (x >= (Position)dimension_x_ ||
01607 y >= (Position)dimension_y_ ||
01608 z >= (Position)dimension_z_)
01609 {
01610 return 0;
01611 }
01612 else
01613 {
01614 return &(box_[x * dimension_y_ * dimension_z_ + y * dimension_z_ + z]);
01615 }
01616 }
01617
01618 template <typename Item>
01619 BALL_INLINE
01620 const HashGridBox3<Item>* HashGrid3<Item>::getBox(Position x, Position y, Position z) const
01621 {
01622 return ((HashGrid3*)this)->getBox(x, y, z);
01623 }
01624
01625 template <typename Item>
01626 BALL_INLINE
01627 HashGridBox3<Item>* HashGrid3<Item>::getBox(const Vector3& vector)
01628 {
01629 float x = (vector.x - origin_.x) / unit_.x;
01630 float y = (vector.y - origin_.y) / unit_.y;
01631 float z = (vector.z - origin_.z) / unit_.z;
01632
01633
01634 Index x1 = (Index) Maths::floor(x);
01635 Index y1 = (Index) Maths::floor(y);
01636 Index z1 = (Index) Maths::floor(z);
01637
01638 return getBox(x1, y1, z1);
01639 }
01640
01641 template <typename Item>
01642 BALL_INLINE
01643 const HashGridBox3<Item>* HashGrid3<Item>::getBox(const Vector3& vector) const
01644 {
01645 return ((HashGrid3 *)this)->getBox(vector);
01646 }
01647
01648 template <typename Item>
01649 BALL_INLINE
01650 bool HashGrid3<Item>::getIndices
01651 (const HashGridBox3<Item>& box,
01652 Position& x, Position& y, Position& z) const
01653 {
01654 Index index = getIndex_(box);
01655
01656 if (index == INVALID_INDEX)
01657 {
01658 x = y = z = INVALID_POSITION;
01659
01660 return false;
01661 }
01662
01663 x = index / (dimension_y_ * dimension_z_);
01664 index -= x * dimension_y_ * dimension_z_;
01665 y = index / dimension_z_;
01666 z = index - y * dimension_z_;
01667
01668 return true;
01669 }
01670
01671 template <typename Item>
01672 BALL_INLINE
01673 void HashGrid3<Item>::insert
01674 (Position x, Position y, Position z, const Item& item)
01675 {
01676 HashGridBox3<Item>* box = getBox(x, y, z);
01677
01678 if (box != 0)
01679 {
01680 box->insert(item);
01681 }
01682 }
01683
01684 template <typename Item>
01685 BALL_INLINE
01686 void HashGrid3<Item>::insert(const Vector3& vector, const Item& item)
01687 {
01688 HashGridBox3<Item> *box = getBox(vector);
01689
01690 if (box != 0)
01691 {
01692 box->insert(item);
01693 }
01694 }
01695
01696 template <typename Item>
01697 BALL_INLINE
01698 bool HashGrid3<Item>::remove(Position x, Position y, Position z, const Item& item)
01699 {
01700 HashGridBox3<Item>* box = getBox(x, y, z);
01701
01702 if (box != 0)
01703 {
01704 return box->remove(item);
01705 }
01706
01707 return false;
01708 }
01709
01710 template <typename Item>
01711 BALL_INLINE
01712 bool HashGrid3<Item>::remove(const Vector3& vector, const Item& item)
01713 {
01714 HashGridBox3<Item>* box = getBox(vector);
01715
01716 if (box != 0)
01717 {
01718 return box->remove(item);
01719 }
01720
01721 return false;
01722 }
01723
01724 template <typename Item>
01725 BALL_INLINE
01726 void HashGrid3<Item>::host(Visitor< HashGrid3<Item> >& visitor)
01727 {
01728 visitor.visit(*this);
01729 }
01730
01731 template <typename Item>
01732 BALL_INLINE
01733 bool HashGrid3<Item>::operator == (const HashGrid3<Item>& grid) const
01734 {
01735 if (getSize() != grid.getSize()
01736 || origin_ != grid.origin_
01737 || unit_ != grid.unit_
01738 || dimension_x_ != grid.dimension_x_
01739 || dimension_y_ != grid.dimension_y_
01740 || dimension_z_ != grid.dimension_z_)
01741 {
01742 return false;
01743 }
01744
01745 const HashGridBox3<Item>* abox = box_;
01746
01747 const HashGridBox3<Item>* bbox = grid.box_;
01748
01749 const HashGridBox3<Item>* endbox = &box_[getSize()];
01750
01751 while (abox < endbox)
01752 {
01753 if (*abox++ != *bbox++)
01754 {
01755 return false;
01756 }
01757 }
01758
01759 return true;
01760 }
01761
01762 template <typename Item>
01763 BALL_INLINE
01764 bool HashGrid3<Item>::operator != (const HashGrid3<Item>& grid) const
01765 {
01766 return !(*this == grid);
01767 }
01768
01769 template <typename Item>
01770 BALL_INLINE
01771 bool HashGrid3<Item>::isEmpty() const
01772 {
01773 return (getSize() == 0);
01774 }
01775
01776 template <typename Item>
01777 bool HashGrid3<Item>::isValid() const
01778 {
01779 Size size = getSize();
01780
01781 for (Position index = 0; index < (Position)size; ++index)
01782 {
01783 if (box_[index].isValid() == false)
01784 {
01785 return false;
01786 }
01787 }
01788
01789 return true;
01790 }
01791
01792 template <typename Item>
01793 void HashGrid3<Item>::dump(std::ostream& s, Size depth) const
01794 {
01795 BALL_DUMP_STREAM_PREFIX(s);
01796
01797 BALL_DUMP_DEPTH(s, depth);
01798
01799 BALL_DUMP_DEPTH(s, depth);
01800 s << " origin: " << origin_ << std::endl;
01801
01802 BALL_DUMP_DEPTH(s, depth);
01803 s << " unit: " << unit_.z << std::endl;
01804
01805 BALL_DUMP_DEPTH(s, depth);
01806 s << " dimension: " << dimension_x_ << " "
01807 << dimension_y_ << " "
01808 << dimension_z_ << std::endl;
01809
01810 Size size = getSize();
01811 BALL_DUMP_DEPTH(s, depth);
01812 s << " size: " << size << std::endl;
01813
01814 BALL_DUMP_DEPTH(s, depth);
01815 s << " non empty boxes: " << countNonEmptyBoxes() << std::endl;
01816
01817 BALL_DUMP_DEPTH(s, depth);
01818 s << " boxes:" << std::endl;
01819 Position x, y, z;
01820 for (Position index = 0; index < (Position)size; ++index)
01821 {
01822 BALL_DUMP_DEPTH(s, depth);
01823 getIndices(box_[index], x, y, z);
01824 s << " " << index << ". box: ("
01825 << x << ',' << y << ',' << z << ')' << std::endl;
01826 box_[index].dump(s, 1);
01827 }
01828
01829 BALL_DUMP_DEPTH(s, depth);
01830 s << " non-empty boxes:" << std::endl;
01831
01832 for (Position i=0; i<27; ++i)
01833 {
01834 if (!box_[i].isEmpty())
01835 s << " " << getIndex_(box_[i]) << std::endl;
01836 }
01837 BALL_DUMP_STREAM_SUFFIX(s);
01838 }
01839
01840 template <typename Item>
01841 bool HashGrid3<Item>::apply(UnaryProcessor<Item>& processor)
01842 {
01843 if (processor.start() == false)
01844 {
01845 return false;
01846 }
01847 Processor::Result result;
01848
01849 for (Position i=0; i<27; ++i)
01850 {
01851 HashGridBox3<Item>* box = &box_[i];
01852 for (typename HashGridBox3<Item>::DataItem *item = box->first_item_; item != 0; item = item->next_)
01853 {
01854 result = processor(item->item_);
01855
01856 if (result <= Processor::BREAK)
01857 {
01858 return (result == Processor::BREAK) ? true : false;
01859 }
01860 }
01861 }
01862
01863 return processor->finish();
01864 }
01865
01866 template <typename Item>
01867 bool HashGrid3<Item>::apply(UnaryProcessor< HashGridBox3<Item> >& processor)
01868 {
01869 if (processor.start() == false)
01870 {
01871 return false;
01872 }
01873
01874 Processor::Result result;
01875
01876 for (Position i=0; i<27; ++i)
01877 {
01878 HashGridBox3<Item>* box = &box_[i];
01879 result = processor(*box);
01880
01881 if (result <= Processor::BREAK)
01882 {
01883 return (result == Processor::BREAK) ? true : false;
01884 }
01885 }
01886
01887 return processor->finish();
01888 }
01889
01890 template <typename Item>
01891 BALL_INLINE
01892 Index HashGrid3<Item>::getIndex_(const HashGridBox3<Item>& box) const
01893 {
01894 if (&box < box_ ||& box >= &box_[getSize()])
01895 {
01896 return INVALID_INDEX;
01897 }
01898 else
01899 {
01900 return (Index)(&box - box_);
01901 }
01902 }
01903
01904 template <typename Item>
01905 BALL_INLINE
01906 void HashGrid3<Item>::setNeighbours_()
01907 {
01908 for (Position i=0; i<getSize(); ++i)
01909 {
01910 Position x, y, z;
01911 getIndices(box_[i], x, y, z);
01912
01913 box_[i].neighbours[0] = &box_[i];
01914
01915 Position current_neighbour = 1;
01916
01917 for (int nx = x-1; (nx < (int)x+2); nx++)
01918 {
01919 for (int ny = y-1; (ny < (int)y+2); ny++)
01920 {
01921 for (int nz = z-1; (nz < (int)z+2); nz++)
01922 {
01923 HashGridBox3<Item>* nbox = getBox(nx, ny, nz);
01924
01925 if (nbox != &box_[i])
01926 {
01927
01928 box_[i].neighbours[current_neighbour++] = nbox;
01929 }
01930 }
01931 }
01932 }
01933 }
01934 }
01935
01936 }
01937
01938 #endif // BALL_DATATYPE_HASHGRID_H