hashGrid.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
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 /* deep */ = 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 /* deep */ = 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         // iterate to the next existing box
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 /* deep */ = 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     //  private:
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     // ????? - not implemented
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     // count all items in the box
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 /* deep */ = 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   // this constructor creates a linear array of HashGridBox3 objects.
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 /* deep */)
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     // iterator over neighbour boxes
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           // iterate over all data items
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     // workaround for MSVC 7, dont change this !!!
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       // iterate over all the neighbouring boxes
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               // NOTE: getBox returns 0 if indices are invalid, so this automatically works
01928               box_[i].neighbours[current_neighbour++] = nbox;
01929             }
01930           }
01931         }
01932       }
01933     }
01934   }
01935 
01936 } // namespace BALL
01937 
01938 #endif // BALL_DATATYPE_HASHGRID_H