BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
hashGrid.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_DATATYPE_HASHGRID_H
6 #define BALL_DATATYPE_HASHGRID_H
7 
8 #ifndef BALL_COMMON_H
9 # include <BALL/common.h>
10 #endif
11 
12 #ifndef BALL_CONCEPT_FORWARDITERATOR_H
14 #endif
15 
16 #ifndef BALL_CONCEPT_VISITOR_H
17 # include <BALL/CONCEPT/visitor.h>
18 #endif
19 
20 #ifndef BALL_CONCEPT_PROCESSOR_H
21 # include <BALL/CONCEPT/processor.h>
22 #endif
23 
24 #ifndef BALL_MATHS_VECTOR3_H
25 # include <BALL/MATHS/vector3.h>
26 #endif
27 
28 #ifdef BALL_HAS_GNU_SLIST
29 #include <ext/slist>
30 #else
31 #include <list>
32 #endif
33 
34 #include <algorithm>
35 
36 namespace BALL
37 {
38  namespace __private
39  {
40  extern const char BALL_EXPORT neighbour_table_[27][3];
41  }
42 
43  template <typename Item> class HashGrid3;
44 
49 
58  template <typename Item>
60  {
61  public:
62 
66 
69 
71  void clear();
72 
76  void destroy();
77 
79 
82 
84 
87 
88  void setParent(HashGrid3<Item>* p);
89 
93  void getIndices(Position& x, Position& y, Position& z);
94 
100  Item* find(const Item &item);
101 
103  const Item* find(const Item& item) const;
104 
108  Size getSize() const;
109 
113  void insert(const Item& item);
114 
120  bool remove(const Item& item);
121 
127  bool removeAll(const Item& item);
128 
130 
133 
135  void host(Visitor<HashGridBox3> &visitor);
137 
140 
142  bool operator == (const HashGridBox3& box) const;
143 
145  bool operator != (const HashGridBox3& box) const;
146 
151  bool has(const Item& item) const;
152 
156  bool isEmpty() const;
157 
159 
162 
164  bool isValid() const;
166  void dump(std::ostream& s = std::cout, Size depth = 0) const;
167 
169 
172 
174  bool apply(UnaryProcessor<Item>& processor);
175 
177  bool apply(UnaryProcessor< HashGridBox3<Item> >& processor);
178 
180 
184 
186  {
187  public:
188 
190 
191  virtual ~BoxIteratorTraits() {}
192 
194  : bound_(0),
195  position_(0),
196  x_(0), y_(0), z_(0)
197  {
198  }
199 
201  : bound_((HashGridBox3 *)&box),
202  position_(0)
203  {
204  bound_->getIndices(x_, y_, z_);
205  }
206 
207  BoxIteratorTraits(const BoxIteratorTraits& traits, bool /* deep */ = true)
208  : bound_(traits.bound_),
209  position_(traits.position_)
210  {
211  }
212 
214  {
215  return bound_;
216  }
217 
218  const HashGridBox3* getContainer() const
219  {
220  return bound_;
221  }
222 
223  bool isSingular() const
224  {
225  return (bound_ == 0);
226  }
227 
229  {
230  return position_;
231  }
232 
234  {
235  return position_;
236  }
237 
238  bool operator == (const BoxIteratorTraits& traits) const
239  {
240  return (position_ == traits.position_);
241  }
242 
243  bool operator != (const BoxIteratorTraits& traits) const
244  {
245  return (position_ != traits.position_);
246  }
247 
248  bool isValid() const
249  {
250  return (bound_ != 0 && position_ < 27);
251  }
252 
253  void invalidate()
254  {
255  bound_ = 0;
256  position_ = 100;
257  }
258 
259  void toBegin()
260  {
261  position_ = 0;
262  cur_box_ = bound_;
263  }
264 
265  bool isBegin() const
266  {
267  return (position_ == 0);
268  }
269 
270  void toEnd()
271  {
272  position_ = 27;
273  cur_box_ = 0;
274  }
275 
276  bool isEnd() const
277  {
278  return (position_ == 27);
279  }
280 
282  {
283  return *cur_box_;
284  }
285 
287  {
288  return *cur_box_;
289  }
290 
291  void forward()
292  {
293  ++position_;
294  // iterate to the next existing box
295  while ( position_ < 27
296  && !(cur_box_ = bound_->parent->getBox(x_ + __private::neighbour_table_[position_][0],
297  y_ + __private::neighbour_table_[position_][1],
298  z_ + __private::neighbour_table_[position_][2])))
299  {
300  ++position_;
301  }
302  }
303 
304  private:
305 
310  };
311 
312  friend class BoxIteratorTraits;
313 
318  typedef ForwardIterator
322 
325  {
326  return BoxIterator::begin(*this);
327  }
328 
331  {
332  return BoxIterator::end(*this);
333  }
334 
335 
337  typedef ConstForwardIterator
341 
344  {
345  return ConstBoxIterator::begin(*this);
346  }
347 
350  {
351  return ConstBoxIterator::end(*this);
352  }
353 
354 #ifdef BALL_HAS_GNU_SLIST
355  typedef typename __gnu_cxx::slist<Item> DataContainer;
356 #else
357  typedef typename std::list<Item> DataContainer;
358 #endif
359 
360  typedef typename DataContainer::iterator DataIteratorPosition;
361 
363  {
364  public:
365 
367 
368  virtual ~DataIteratorTraits() {}
369 
371  : bound_(0),
372  position_()
373  {
374  }
375 
377  : bound_((HashGridBox3 *)&box),
378  position_(bound_->data.begin())
379  {
380  }
381 
382  DataIteratorTraits(const DataIteratorTraits& traits, bool /* deep */ = true)
383  : bound_(traits.bound_),
384  position_(traits.position_)
385  {
386  }
387 
389  {
390  bound_ = traits.bound_;
391  position_ = traits.position_;
392  return *this;
393  }
394 
396  {
397  return bound_;
398  }
399 
400  const HashGridBox3* getContainer() const
401  {
402  return bound_;
403  }
404 
405  bool isSingular() const
406  {
407  return (bound_ == 0);
408  }
409 
411  {
412  return position_;
413  }
414 
416  {
417  return position_;
418  }
419 
420  bool operator == (const DataIteratorTraits &traits) const
421  {
422  return (position_ == traits.position_);
423  }
424 
425  bool operator != (const DataIteratorTraits &traits) const
426  {
427  return (position_ != traits.position_);
428  }
429 
430  bool isValid() const
431  {
432  return (bound_ != 0 && position_ != bound_->data.end());
433  }
434 
435  void invalidate()
436  {
437  bound_ = 0;
438  position_ = bound_->data.end();
439  }
440 
441  void toBegin()
442  {
443  position_ = bound_->data.begin();
444  }
445 
446  bool isBegin() const
447  {
448  return (position_ == bound_->data.begin());
449  }
450 
451  void toEnd()
452  {
453  position_ = bound_->data.end();
454  }
455 
456  bool isEnd() const
457  {
458  return (position_ == bound_->data.end());
459  }
460 
461  Item& getData()
462  {
463  return *position_;
464  }
465 
466  const Item& getData() const
467  {
468  return *position_;
469  }
470 
471  void forward()
472  {
473  ++position_;
474  }
475 
476  private:
477 
480  };
481 
482  friend class DataIteratorTraits;
483 
487  typedef ForwardIterator
488  <HashGridBox3<Item>, Item,
491 
494  {
495  return DataIterator::begin(*this);
496  }
497 
500  {
501  return DataIterator::end(*this);
502  }
503 
504 
508  typedef ConstForwardIterator
509  <HashGridBox3<Item>, Item,
512 
515  {
516  return ConstDataIterator::begin(*this);
517  }
518 
521  {
522  return ConstDataIterator::end(*this);
523  }
524 
526 
528 
530  };
531 
532  template<typename Item>
534  : parent(p)
535  {
536  }
537 
538  template<typename Item>
540  {
541  data.clear();
542  }
543 
544  template<typename Item>
545  BALL_INLINE
547  {
548  clear();
549  }
550 
551  template<typename Item>
553  {
554  parent = p;
555  }
556 
557  template<typename Item>
560  {
561  parent->getIndices(*this, x, y, z);
562  }
563 
564  template<typename Item>
565  Item* HashGridBox3<Item>::find(const Item& item)
566  {
567  typename DataContainer::iterator found = std::find(data.begin(), data.end(), item);
568 
569  if (found != data.end())
570  {
571  return &(*found);
572  }
573 
574  return 0;
575  }
576 
577  template<typename Item>
578  BALL_INLINE
579  const Item* HashGridBox3<Item>::find(const Item& item) const
580  {
581  return const_cast<HashGridBox3*>(this)->find(item);
582  }
583 
584  template<typename Item>
586  {
587  return data.size();
588  }
589 
590  template<typename Item>
591  BALL_INLINE
592  void HashGridBox3<Item>::insert(const Item& item)
593  {
594  data.push_front(item);
595  }
596 
597  template<typename Item>
598  bool HashGridBox3<Item>::remove(const Item& item)
599  {
600 #ifdef BALL_HAS_GNU_SLIST
601  if(data.empty())
602  {
603  return false;
604  }
605 
606  if(*data.begin() == item)
607  {
608  data.pop_front();
609  return true;
610  }
611 
612  DataIteratorPosition prev = data.begin();
613  DataIteratorPosition pos = prev;
614  for(++pos; pos != data.end(); ++pos)
615  {
616  if(*pos == item)
617  {
618  data.erase_after(prev);
619  return true;
620  }
621 
622  prev = pos;
623  }
624  return false;
625 #else
626  DataIteratorPosition pos = std::find(data.begin(), data.end(), item);
627 
628  if (pos != data.end())
629  {
630  data.erase(pos);
631 
632  return true;
633  }
634 
635  return false;
636 #endif
637  }
638 
639  template<typename Item>
640  bool HashGridBox3<Item>::removeAll(const Item& item)
641  {
642  data.remove(item);
643 
644  return true;
645  }
646 
647  template <typename Item>
648  BALL_INLINE
650  {
651  visitor.visit(*this);
652  }
653 
654  template<typename Item>
656  {
657  return (data == box.data);
658  }
659 
660  template<typename Item>
661  BALL_INLINE
663  {
664  return !(*this == box);
665  }
666 
667  template<typename Item>
668  BALL_INLINE
669  bool HashGridBox3<Item>::has(const Item& item) const
670  {
671  return (std::find(data.begin(), data.end(), item) != data.end());
672  }
673 
674  template<typename Item>
675  BALL_INLINE
677  {
678  return data.empty();
679  }
680 
681  template<typename Item>
683  {
684  // this is no longer required...
685  return true;
686  }
687 
688  template<typename Item>
689  void HashGridBox3<Item>::dump(std::ostream& s, Size depth) const
690  {
692 
693  BALL_DUMP_DEPTH(s, depth);
694 
695  BALL_DUMP_DEPTH(s, depth);
696  s << " size: " << getSize() << std::endl;
697 
698  BALL_DUMP_DEPTH(s, depth);
699  s << " data:" << std::endl;
700  for (typename DataContainer::const_iterator d_it = data.begin(); d_it != data.end(); ++d_it)
701  {
702  BALL_DUMP_DEPTH(s, depth);
703  s << " " << *d_it << std::endl;
704  }
705 
707  }
708 
709  template <typename Item>
711  {
712  if (processor.start() == false)
713  {
714  return false;
715  }
716 
717  Processor::Result result;
718 
719  for (typename DataContainer::iterator d_it = data.begin(); d_it != data.end(); ++d_it)
720  {
721  result = processor(*d_it);
722 
723  if (result <= Processor::BREAK)
724  {
725  return (result == Processor::BREAK) ? true : false;
726  }
727  }
728 
729  return processor.finish();
730  }
731 
732  template <typename Item>
734  {
735  if (processor.start() == false)
736  {
737  return false;
738  }
739 
740  Processor::Result result;
741 
742  for (BoxIterator it = beginBox(); +it; ++it)
743  {
744  result = processor(*it);
745 
746  if (result <= Processor::BREAK)
747  {
748  return (result == Processor::BREAK) ? true : false;
749  }
750  }
751 
752  return processor.finish();
753  }
754 
759  template <typename Item>
760  class HashGrid3
761  {
762  public:
763 
765 
766 
769 
771  HashGrid3();
772 
783  HashGrid3(const Vector3& origin, Size dimension_x, Size dimension_y,
784  Size dimension_z, float spacing_x, float spacing_y, float spacing_z);
785 
789  HashGrid3(const Vector3& origin, Size dimension_x, Size dimension_y,
790  Size dimension_z, float spacing);
791 
801  HashGrid3(const Vector3& origin, const Vector3& size, float spacing);
802 
804  HashGrid3(const HashGrid3& grid, bool deep = true);
805 
807  virtual ~HashGrid3();
808 
810  virtual void clear();
811 
813  void clear(Position x, Position y, Position z);
814 
816  void clear(const Vector3 &vector);
817 
819  void destroy();
820 
822  void destroy(Position x, Position y, Position z);
823 
825  void destroy(const Vector3& vector);
826 
828 
831 
833  void set(const Vector3& origin, const Vector3& unit,
834  Size dimension_x, Size dimension_y, Size dimension_z);
835 
837  void set(const Vector3& origin, float unit, Size size);
838 
840  void set(const HashGrid3& grid, bool deep = true);
841 
843  const HashGrid3& operator = (const HashGrid3& grid);
844 
846  void get(Vector3& origin, Vector3& unit, Size& dimension_x, Size& dimension_y, Size& dimension_z) const;
847 
849  void get(HashGrid3& grid, bool deep = true) const;
850 
852 
855 
857  Size countNonEmptyBoxes() const;
858 
860  Size getSize() const;
861 
863  Vector3& getOrigin();
864 
866  const Vector3& getOrigin() const;
867 
869  Vector3& getUnit();
870 
872  const Vector3& getUnit() const;
873 
875  Size getSizeX() const;
876 
878  Size getSizeY() const;
879 
881  Size getSizeZ() const;
882 
884  HashGridBox3<Item>* getBox(Position x, Position y, Position z);
885 
887  const HashGridBox3<Item>* getBox(Position x, Position y, Position z) const;
888 
890  HashGridBox3<Item>* getBox(const Vector3& vector);
891 
893  const HashGridBox3<Item>* getBox(const Vector3 &vector) const;
894 
896  bool getIndices(const HashGridBox3<Item>& box,
897  Position& x, Position& y, Position& z) const;
898 
900  void insert(Position x, Position y, Position z, const Item& item);
901 
903  void insert(const Vector3& vector, const Item& item);
904 
906  bool remove(Position x, Position y, Position z, const Item& item);
907 
909  bool remove(const Vector3& vector, const Item& item);
910 
912 
915 
917  void host(Visitor<HashGrid3>& visitor);
918 
920 
923 
925  bool operator == (const HashGrid3& grid) const;
926 
928  bool operator != (const HashGrid3& grid) const;
929 
931  bool isEmpty() const;
932 
934 
937 
939  virtual bool isValid() const;
940 
942  virtual void dump(std::ostream& s = std::cout, Size depth = 0) const;
943 
945 
949 
951  bool apply(UnaryProcessor<Item> &processor);
952 
954  bool apply(UnaryProcessor< HashGridBox3<Item> > &processor);
955 
959  const Item* getClosestItem(const Vector3& point, Size distance) const;
960 
967  static float calculateMinSpacing(LongIndex memory, const Vector3& size);
968 
970 
973 
975 
977  {
978  public:
979 
980  BALL_CREATE_DEEP(BoxIteratorTraits)
981 
982  virtual ~BoxIteratorTraits() {}
983 
985  : bound_(0),
986  position_(0)
987  {
988  }
989 
991  : bound_((HashGrid3 *)&grid),
992  position_(0)
993  {
994  }
995 
996  BoxIteratorTraits(const BoxIteratorTraits& traits, bool /* deep */ = true)
997  : bound_(traits.bound_),
998  position_(traits.position_)
999  {
1000  }
1001 
1003  {
1004  bound_ = traits.bound_;
1005  position_ = traits.position_;
1006  return *this;
1007  }
1008 
1009  HashGrid3* getContainer()
1010  {
1011  return bound_;
1012  }
1013 
1014  const HashGrid3* getContainer() const
1015  {
1016  return bound_;
1017  }
1018 
1019  bool isSingular() const
1020  {
1021  return (bound_ == 0);
1022  }
1023 
1024  BoxIteratorPosition& getPosition()
1025  {
1026  return position_;
1027  }
1028 
1029  const BoxIteratorPosition& getPosition() const
1030  {
1031  return position_;
1032  }
1033 
1034  bool operator == (const BoxIteratorTraits& traits) const
1035  {
1036  return (position_ == traits.position_);
1037  }
1038 
1039  bool operator != (const BoxIteratorTraits& traits) const
1040  {
1041  return (position_ != traits.position_);
1042  }
1043 
1044  bool isValid() const
1045  {
1046  return (bound_ != 0 && position_ < bound_->getSize());
1047  }
1048 
1049  void invalidate()
1050  {
1051  bound_ = 0;
1052  position_ = bound_->getSize()+1;
1053  }
1054 
1055  void toBegin()
1056  {
1057  position_ = 0;
1058  }
1059 
1060  bool isBegin() const
1061  {
1062  return (position_ == 0);
1063  }
1064 
1065  void toEnd()
1066  {
1067  position_ = bound_->getSize();
1068  }
1069 
1070  bool isEnd() const
1071  {
1072  return (position_ == bound_->getSize());
1073  }
1074 
1076  {
1077  return bound_->box_[position_];
1078  }
1079 
1080  const HashGridBox3<Item>& getData() const
1081  {
1082  return bound_->box_[position_];
1083  }
1084 
1085  void forward()
1086  {
1087  ++position_;
1088  }
1089 
1090  private:
1091 
1094  };
1095 
1096  friend class BoxIteratorTraits;
1097 
1099  typedef ForwardIterator
1103 
1106  {
1107  return BoxIterator::begin(*this);
1108  }
1109 
1112  {
1113  return BoxIterator::end(*this);
1114  }
1115 
1116 
1118  typedef ConstForwardIterator
1122 
1125  {
1126  return ConstBoxIterator::begin(*this);
1127  }
1128 
1131  {
1132  return ConstBoxIterator::end(*this);
1133  }
1134 
1136 
1137  private:
1138 
1139  //_
1140  Index getIndex_(const HashGridBox3<Item>& box) const;
1141 
1142  //_
1144  //_
1146  //_
1148  //_
1150  //_
1152  //_
1153  vector<HashGridBox3<Item> > box_;
1154  };
1155 
1156 
1158 
1159 
1160  template <typename Item>
1162  : origin_(0,0,0),
1163  unit_(0,0,0),
1164  dimension_x_(0),
1165  dimension_y_(0),
1166  dimension_z_(0)
1167  {
1168  }
1169 
1170  template <typename Item>
1172  (const Vector3 &originvector,
1173  Size dimension_x, Size dimension_y, Size dimension_z,
1174  float spacing_x, float spacing_y, float spacing_z)
1175  : origin_(originvector),
1176  unit_(spacing_x, spacing_y, spacing_z),
1177  dimension_x_(dimension_x),
1178  dimension_y_(dimension_y),
1179  dimension_z_(dimension_z),
1180  box_(dimension_x * dimension_y * dimension_z, HashGridBox3<Item>(this))
1181  {
1182  }
1183 
1184  template <typename Item>
1186  (const Vector3& origin,
1187  Size dimension_x, Size dimension_y, Size dimension_z, float spacing)
1188  : origin_(origin),
1189  unit_(spacing, spacing, spacing),
1190  dimension_x_(dimension_x),
1191  dimension_y_(dimension_y),
1192  dimension_z_(dimension_z),
1193  box_(dimension_x * dimension_y * dimension_z, HashGridBox3<Item>(this))
1194  {
1195  }
1196 
1197  // this constructor creates a linear array of HashGridBox3 objects.
1198  template <typename Item>
1199  HashGrid3<Item>::HashGrid3(const Vector3& origin, const Vector3& size,
1200  float spacing)
1201  : origin_(origin),
1202  unit_(spacing, spacing, spacing),
1203  dimension_x_((Size)(size.x / spacing + 1.0)),
1204  dimension_y_((Size)(size.y / spacing + 1.0)),
1205  dimension_z_((Size)(size.z / spacing + 1.0)),
1206  box_(dimension_x_ * dimension_y_ * dimension_z_, HashGridBox3<Item>(this))
1207  {
1208  }
1209 
1210  template <typename Item>
1212  {
1213  set(grid, deep);
1214  }
1215 
1216  template <typename Item>
1218  {
1219  }
1220 
1221  template <typename Item>
1223  {
1224  Size size = dimension_x_ * dimension_y_ * dimension_z_;
1225 
1226  for (Position index = 0; index < (Position)size; ++index)
1227  {
1228  box_[index].clear();
1229  }
1230  }
1231 
1232  template <typename Item>
1233  BALL_INLINE
1235  {
1236  HashGridBox3<Item>* box = getBox(x, y, z);
1237 
1238  if (box != 0)
1239  {
1240  box->clear();
1241  }
1242  }
1243 
1244  template <typename Item>
1245  BALL_INLINE
1246  void HashGrid3<Item>::clear(const Vector3& vector)
1247  {
1248  HashGridBox3<Item>* box = getBox(vector);
1249 
1250  if (box != 0)
1251  {
1252  box->clear();
1253  }
1254  }
1255 
1256  template <typename Item>
1257  BALL_INLINE
1259  {
1260  clear();
1261  }
1262 
1263  template <typename Item>
1264  BALL_INLINE
1266  {
1267  clear(x, y, z);
1268  }
1269 
1270  template <typename Item>
1271  BALL_INLINE
1272  void HashGrid3<Item>::destroy(const Vector3 &vector)
1273  {
1274  clear(vector);
1275  }
1276 
1277  template <typename Item>
1279  (const Vector3& origin, const Vector3& unit,
1280  Size dimension_x, Size dimension_y, Size dimension_z)
1281  {
1282  origin_.set(origin);
1283  unit_.set(unit);
1284  dimension_x_ = dimension_x;
1285  dimension_y_ = dimension_y;
1286  dimension_z_ = dimension_z;
1287  box_.assign(getSize(), HashGridBox3<Item>(this));
1288  }
1289 
1290  template <typename Item>
1291  void HashGrid3<Item>::set(const Vector3& origin, float unit, Size size)
1292  {
1293  origin_.set(origin);
1294  unit_.set(unit, unit, unit);
1295  dimension_x_ = size;
1296  dimension_y_ = size;
1297  dimension_z_ = size;
1298  box_.assign(getSize(), HashGridBox3<Item>(this));
1299  }
1300 
1301  template <typename Item>
1302  void HashGrid3<Item>::set(const HashGrid3<Item>& grid, bool /* deep */)
1303  {
1304  origin_.set(grid.origin_);
1305  unit_.set(grid.unit_);
1306  dimension_x_ = grid.dimension_x_;
1307  dimension_y_ = grid.dimension_y_;
1308  dimension_z_ = grid.dimension_z_;
1309  box_ = grid.box_;
1310 
1311  for(Position i = 0; i < box_.size(); ++i)
1312  {
1313  box_[i].setParent(this);
1314  }
1315  }
1316 
1317  template <typename Item>
1318  BALL_INLINE
1320  {
1321  set(grid);
1322 
1323  return *this;
1324  }
1325 
1326  template <typename Item>
1327  BALL_INLINE
1328  void HashGrid3<Item>::get(Vector3 &origin, Vector3 &unit,
1329  Size& dimension_x, Size& dimension_y, Size& dimension_z) const
1330  {
1331  origin.set(origin_);
1332  unit.set(unit_);
1333  dimension_x = dimension_x_;
1334  dimension_y = dimension_y_;
1335  dimension_z = dimension_z_;
1336  }
1337 
1338  template <typename Item>
1339  BALL_INLINE void
1340  HashGrid3<Item>::get(HashGrid3<Item> &grid, bool deep) const
1341  {
1342  grid.set(*this, deep);
1343  }
1344 
1345  template <typename Item>
1346  Size
1348  {
1349  Size size = 0;
1350 
1351  for (Position i=0; i<27; ++i)
1352  {
1353  if (!box_[i].isEmpty())
1354  ++size;
1355  }
1356 
1357  return size;
1358  }
1359 
1360  template <typename Item>
1361  BALL_INLINE
1363  {
1364  return (dimension_x_ * dimension_y_ * dimension_z_);
1365  }
1366 
1367  template <typename Item>
1368  BALL_INLINE
1370  {
1371  return origin_;
1372  }
1373 
1374  template <typename Item>
1375  BALL_INLINE
1377  {
1378  return origin_;
1379  }
1380 
1381  template <typename Item>
1382  BALL_INLINE
1384  {
1385  return unit_;
1386  }
1387 
1388  template <typename Item>
1389  BALL_INLINE
1391  {
1392  return unit_;
1393  }
1394 
1395  template <typename Item>
1396  BALL_INLINE
1398  {
1399  return dimension_x_;
1400  }
1401 
1402  template <typename Item>
1403  BALL_INLINE
1405  {
1406  return dimension_y_;
1407  }
1408 
1409  template <typename Item>
1410  BALL_INLINE
1412  {
1413  return dimension_z_;
1414  }
1415 
1416  template <typename Item>
1417  const Item* HashGrid3<Item>::getClosestItem(const Vector3& point, Size dist) const
1418  {
1419  const HashGridBox3<Item>* box = getBox(point);
1420  if (!box) return 0;
1421 
1422  Position x, y, z;
1423  getIndices(*box, x, y, z);
1424 
1425  const Item* item = 0;
1426  float distance = FLT_MAX;
1427 
1428  // iterator over neighbour boxes
1429  for (Index xi = -(Index)dist; xi <= (Index)dist; xi++)
1430  {
1431  const Index xn = x + xi;
1432  for (Index yi = -(Index)dist; yi <= (Index)dist; yi++)
1433  {
1434  const Index yn = y + yi;
1435  for (Index zi = -(Index)dist; zi <= (Index)dist; zi++)
1436  {
1437  // iterate over all data items
1438  const HashGridBox3<Item>* const box_ptr = getBox(xn, yn, z+zi);
1439  if (box_ptr != 0 && !box_ptr->isEmpty())
1440  {
1441  typename HashGridBox3<Item>::ConstDataIterator hit = box_ptr->beginData();
1442  for (;hit != box_ptr->endData(); hit++)
1443  {
1444  const float new_dist = ((*hit)->getPosition() - point).getSquareLength();
1445  if (new_dist < distance)
1446  {
1447  item = &*hit;
1448  distance = new_dist;
1449  }
1450  }
1451  }
1452  }
1453  }
1454  }
1455 
1456  return item;
1457  }
1458 
1459  template <typename Item>
1460  BALL_INLINE
1462  {
1463  LongSize memory_for_box = sizeof(HashGridBox3<Item>) + sizeof(HashGridBox3<Item>*);
1464  LongSize nr_boxes =(LongSize)floor((float)(memory / memory_for_box));
1465 
1466  return pow((double)((size.x * size.y * size.z) / nr_boxes), (double)(1.0 / 3.0));
1467  }
1468 
1469  template <typename Item>
1470  BALL_INLINE
1472  {
1473  if (x >= (Position)dimension_x_ ||
1474  y >= (Position)dimension_y_ ||
1475  z >= (Position)dimension_z_)
1476  {
1477  return 0;
1478  }
1479  else
1480  {
1481  return &(box_[x * dimension_y_ * dimension_z_ + y * dimension_z_ + z]);
1482  }
1483  }
1484 
1485  template <typename Item>
1486  BALL_INLINE
1488  {
1489  return ((HashGrid3*)this)->getBox(x, y, z);
1490  }
1491 
1492  template <typename Item>
1493  BALL_INLINE
1495  {
1496  float x = (vector.x - origin_.x) / unit_.x;
1497  float y = (vector.y - origin_.y) / unit_.y;
1498  float z = (vector.z - origin_.z) / unit_.z;
1499 
1500  // workaround for MSVC 7, dont change this !!!
1501  Index x1 = (Index) Maths::floor(x);
1502  Index y1 = (Index) Maths::floor(y);
1503  Index z1 = (Index) Maths::floor(z);
1504 
1505  return getBox(x1, y1, z1);
1506  }
1507 
1508  template <typename Item>
1509  BALL_INLINE
1511  {
1512  return ((HashGrid3 *)this)->getBox(vector);
1513  }
1514 
1515  template <typename Item>
1516  BALL_INLINE
1518  (const HashGridBox3<Item>& box,
1519  Position& x, Position& y, Position& z) const
1520  {
1521  Index index = getIndex_(box);
1522 
1523  if (index == INVALID_INDEX)
1524  {
1525  x = y = z = INVALID_POSITION;
1526 
1527  return false;
1528  }
1529 
1530  x = index / (dimension_y_ * dimension_z_);
1531  index -= x * dimension_y_ * dimension_z_;
1532  y = index / dimension_z_;
1533  z = index - y * dimension_z_;
1534 
1535  return true;
1536  }
1537 
1538  template <typename Item>
1539  BALL_INLINE
1541  (Position x, Position y, Position z, const Item& item)
1542  {
1543  HashGridBox3<Item>* box = getBox(x, y, z);
1544 
1545  if (box != 0)
1546  {
1547  box->insert(item);
1548  }
1549  }
1550 
1551  template <typename Item>
1552  BALL_INLINE
1553  void HashGrid3<Item>::insert(const Vector3& vector, const Item& item)
1554  {
1555  HashGridBox3<Item> *box = getBox(vector);
1556 
1557  if (box != 0)
1558  {
1559  box->insert(item);
1560  }
1561  }
1562 
1563  template <typename Item>
1564  BALL_INLINE
1565  bool HashGrid3<Item>::remove(Position x, Position y, Position z, const Item& item)
1566  {
1567  HashGridBox3<Item>* box = getBox(x, y, z);
1568 
1569  if (box != 0)
1570  {
1571  return box->remove(item);
1572  }
1573 
1574  return false;
1575  }
1576 
1577  template <typename Item>
1578  BALL_INLINE
1579  bool HashGrid3<Item>::remove(const Vector3& vector, const Item& item)
1580  {
1581  HashGridBox3<Item>* box = getBox(vector);
1582 
1583  if (box != 0)
1584  {
1585  return box->remove(item);
1586  }
1587 
1588  return false;
1589  }
1590 
1591  template <typename Item>
1592  BALL_INLINE
1594  {
1595  visitor.visit(*this);
1596  }
1597 
1598  template <typename Item>
1599  BALL_INLINE
1601  {
1602  if (getSize() != grid.getSize()
1603  || origin_ != grid.origin_
1604  || unit_ != grid.unit_
1605  || dimension_x_ != grid.dimension_x_
1606  || dimension_y_ != grid.dimension_y_
1607  || dimension_z_ != grid.dimension_z_)
1608  {
1609  return false;
1610  }
1611 
1612  return box_ == grid.box_;
1613  }
1614 
1615  template <typename Item>
1616  BALL_INLINE
1618  {
1619  return !(*this == grid);
1620  }
1621 
1622  template <typename Item>
1623  BALL_INLINE
1625  {
1626  return (getSize() == 0);
1627  }
1628 
1629  template <typename Item>
1631  {
1632  Size size = getSize();
1633 
1634  for (Position index = 0; index < (Position)size; ++index)
1635  {
1636  if (box_[index].isValid() == false)
1637  {
1638  return false;
1639  }
1640  }
1641 
1642  return true;
1643  }
1644 
1645  template <typename Item>
1646  void HashGrid3<Item>::dump(std::ostream& s, Size depth) const
1647  {
1649 
1650  BALL_DUMP_DEPTH(s, depth);
1651 
1652  BALL_DUMP_DEPTH(s, depth);
1653  s << " origin: " << origin_ << std::endl;
1654 
1655  BALL_DUMP_DEPTH(s, depth);
1656  s << " unit: " << unit_.z << std::endl;
1657 
1658  BALL_DUMP_DEPTH(s, depth);
1659  s << " dimension: " << dimension_x_ << " "
1660  << dimension_y_ << " "
1661  << dimension_z_ << std::endl;
1662 
1663  Size size = getSize();
1664  BALL_DUMP_DEPTH(s, depth);
1665  s << " size: " << size << std::endl;
1666 
1667  BALL_DUMP_DEPTH(s, depth);
1668  s << " non empty boxes: " << countNonEmptyBoxes() << std::endl;
1669 
1670  BALL_DUMP_DEPTH(s, depth);
1671  s << " boxes:" << std::endl;
1672  Position x, y, z;
1673  for (Position index = 0; index < (Position)size; ++index)
1674  {
1675  BALL_DUMP_DEPTH(s, depth);
1676  getIndices(box_[index], x, y, z);
1677  s << " " << index << ". box: ("
1678  << x << ',' << y << ',' << z << ')' << std::endl;
1679  box_[index].dump(s, 1);
1680  }
1681 
1682  BALL_DUMP_DEPTH(s, depth);
1683  s << " non-empty boxes:" << std::endl;
1684 
1685  for (Position i=0; i<27; ++i)
1686  {
1687  if (!box_[i].isEmpty())
1688  s << " " << getIndex_(box_[i]) << std::endl;
1689  }
1691  }
1692 
1693  template <typename Item>
1695  {
1696  if (processor.start() == false)
1697  {
1698  return false;
1699  }
1700  Processor::Result result;
1701 
1702  for (Position i=0; i<27; ++i)
1703  {
1704  HashGridBox3<Item>* box = &box_[i];
1705  for (typename HashGridBox3<Item>::DataIterator *item = box->beginData(); +item; ++item)
1706  {
1707  result = processor(*item);
1708 
1709  if (result <= Processor::BREAK)
1710  {
1711  return (result == Processor::BREAK) ? true : false;
1712  }
1713  }
1714  }
1715 
1716  return processor->finish();
1717  }
1718 
1719  template <typename Item>
1721  {
1722  if (processor.start() == false)
1723  {
1724  return false;
1725  }
1726 
1727  Processor::Result result;
1728 
1729  for (Position i=0; i<27; ++i)
1730  {
1731  HashGridBox3<Item>* box = &box_[i];
1732  result = processor(*box);
1733 
1734  if (result <= Processor::BREAK)
1735  {
1736  return (result == Processor::BREAK) ? true : false;
1737  }
1738  }
1739 
1740  return processor->finish();
1741  }
1742 
1743  template <typename Item>
1744  BALL_INLINE
1746  {
1747  if ((&box < &box_[0]) || (&box - &box_[0] >= getSize()))
1748  {
1749  return INVALID_INDEX;
1750  }
1751  else
1752  {
1753  return (Index)(&box - &box_[0]);
1754  }
1755  }
1756 } // namespace BALL
1757 
1758 #endif // BALL_DATATYPE_HASHGRID_H