00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef GRID_TREE_3D_HH
00025 #define GRID_TREE_3D_HH
00026
00027 #include "inline-macro.hh"
00028 #include "grid-3d.hh"
00029
00035
00036
00037 class CGridTree3dNode
00038 {
00039 public:
00040
00041 virtual ~CGridTree3dNode() {};
00042
00043 private:
00044 };
00045
00046
00047
00048 template <class T>
00049 class CGridTree3dLeaf : public CGridTree3dNode
00050 {
00051 public:
00052
00053 CGridTree3dLeaf() {}
00054 CGridTree3dLeaf(const T & AData) : FData(AData) {}
00055 virtual ~CGridTree3dLeaf() {}
00056
00057 void setData(const T & AData) { FData = AData; }
00058 const T & getData() const { return FData; }
00059
00060 private:
00061
00062 T FData;
00063 };
00064
00065
00066
00067 template <class T> class CGridTree3dIterator;
00068
00069 template <class T>
00070 class CGridTree3d : public CGridTree3dNode
00071 {
00072 public:
00073
00078
00087 CGridTree3d(int ASizeI, int ASizeJ, int ASizeK,
00088 const CBoundingBox & ABB);
00089
00095 virtual ~CGridTree3d();
00096
00098
00103
00104 int getSizeI() const;
00105 int getSizeJ() const;
00106 int getSizeK() const;
00107
00108 CGrid3d<CGridTree3dNode*> & getGrid();
00109
00110 const T & getCell(const CGridTree3dIterator<T> & AIter) const;
00111
00112 CBoundingBox getCellBoundingBox(const CGridTree3dIterator<T> & AIter) const;
00113
00114 void setCell(const CGridTree3dIterator<T> & AIter, const T & AObj);
00115
00116 CGridTree3d<T> * splitCellInGrid(const CGridTree3dIterator<T> & AIter,
00117 int ASizeI, int ASizeJ, int ASizeK);
00118
00120
00121 private:
00122
00127
00129
00130 private:
00131
00136
00137 CGrid3d<CGridTree3dNode*> FGrid;
00138
00140 };
00141
00142
00143
00144 template <class T>
00145 class CGridTree3dIterator
00146 {
00147 public:
00148 CGridTree3dIterator(CGridTree3d<T> & AGrid);
00149 CGridTree3dIterator(CGridTree3d<T> & AGrid, const CBoundingBox & ABB);
00150 CGridTree3dIterator(const CGridTree3dIterator<T> & AI);
00151 virtual ~CGridTree3dIterator();
00152
00153 virtual void reinit();
00154 virtual bool cont() const;
00155 virtual void next();
00156
00157 int getI() const { return FIter.getI(); }
00158 int getJ() const { return FIter.getJ(); }
00159 int getK() const { return FIter.getK(); }
00160
00161 const CGrid3dIterator<CGridTree3dNode*> & getIter() const { return FIter; }
00162
00163 CGridTree3d<T> & getGridTree() const { return FGrid; }
00164 const CGridTree3dIterator<T> & getGoodIter() const
00165 {
00166 if (FSubIter != NULL)
00167 return FSubIter->getGoodIter();
00168 else
00169 return *this;
00170 }
00171
00172 const T & getCurrent() const { return FGrid.getCell(*this); }
00173 const T & operator*() const { return getCurrent(); }
00174 const T * operator->() const { return &(getCurrent()); }
00175
00176 CGridTree3dIterator<T> & operator++()
00177 {
00178 next();
00179 return *this;
00180 }
00181
00182 CGridTree3dIterator<T> operator++(int)
00183 {
00184 CGridTree3dIterator<T> tmp = *this;
00185 next();
00186 return tmp;
00187 }
00188
00189 friend std::ostream & operator<<(std::ostream & AO,
00190 const CGridTree3dIterator<T> & AI)
00191 {
00192 AO << AI.FIter;
00193
00194 if (AI.FSubIter != NULL)
00195 AO << " --> " << *AI.FSubIter;
00196
00197 return AO;
00198 }
00199
00200 protected:
00201 virtual void createSubIter();
00202 virtual void deleteSubIter();
00203
00204 protected:
00205 CGridTree3d<T> & FGrid;
00206 CGrid3dIterator<CGridTree3dNode*> FIter;
00207 CGridTree3dIterator<T> * FSubIter;
00208 CBoundingBox FBB;
00209 };
00210
00211
00212
00213
00214
00215 template <class T>
00216 CGridTree3d<T>::CGridTree3d(int ASizeI, int ASizeJ, int ASizeK,
00217 const CBoundingBox & ABB)
00218 : FGrid(ASizeI, ASizeJ, ASizeK, ABB)
00219 {
00220
00221
00222
00223 for (CGrid3dIterator<CGridTree3dNode*> gi(FGrid); gi.cont(); ++gi)
00224 FGrid.setCell(gi, new CGridTree3dLeaf<T>);
00225 }
00226
00227
00228
00229 template <class T>
00230 CGridTree3d<T>::~CGridTree3d()
00231 {
00232 for (CGrid3dIterator<CGridTree3dNode*> gi(FGrid); gi.cont(); ++gi)
00233 delete *gi;
00234 }
00235
00236
00237
00238 template <class T> inline
00239 int CGridTree3d<T>::getSizeI() const
00240 {
00241 return FGrid.getSizeI();
00242 }
00243
00244
00245
00246 template <class T> inline
00247 int CGridTree3d<T>::getSizeJ() const
00248 {
00249 return FGrid.getSizeJ();
00250 }
00251
00252
00253
00254 template <class T> inline
00255 int CGridTree3d<T>::getSizeK() const
00256 {
00257 return FGrid.getSizeK();
00258 }
00259
00260
00261
00262 template <class T> inline
00263 CGrid3d<CGridTree3dNode*> & CGridTree3d<T>::getGrid()
00264 {
00265 return FGrid;
00266 }
00267
00268
00269
00270 template <class T> inline
00271 const T & CGridTree3d<T>::getCell(const CGridTree3dIterator<T> & AIter) const
00272 {
00273 const CGridTree3dIterator<T> & it = AIter.getGoodIter();
00274
00275 CGridTree3dNode * node = *it.getIter();
00276 CGridTree3dLeaf<T> * leaf = dynamic_cast<CGridTree3dLeaf<T>*>(node);
00277
00278 assert(leaf != NULL);
00279
00280 return leaf->getData();
00281 }
00282
00283
00284
00285 template <class T> inline
00286 CBoundingBox
00287 CGridTree3d<T>::getCellBoundingBox(const CGridTree3dIterator<T> & AIter) const
00288 {
00289 const CGridTree3dIterator<T> & it = AIter.getGoodIter();
00290 return it.getGridTree().getGrid().getCellBoundingBox(it.getIter());
00291 }
00292
00293
00294
00295 template <class T> inline
00296 void CGridTree3d<T>::setCell(const CGridTree3dIterator<T> & AIter,
00297 const T & AObj)
00298 {
00299 const CGridTree3dIterator<T> & it = AIter.getGoodIter();
00300 CGridTree3dNode * node = *it.getIter();
00301 CGridTree3dLeaf<T> * leaf = dynamic_cast<CGridTree3dLeaf<T>*>(node);
00302
00303 assert(leaf != NULL);
00304
00305 leaf->setData(AObj);
00306 }
00307
00308
00309
00310 template <class T> inline
00311 CGridTree3d<T> *
00312 CGridTree3d<T>::splitCellInGrid(const CGridTree3dIterator<T> & AIter,
00313 int ASizeI, int ASizeJ, int ASizeK)
00314 {
00315 const CGridTree3dIterator<T> & it = AIter.getGoodIter();
00316 CGrid3d<CGridTree3dNode*> & grid = it.getGridTree().getGrid();
00317 CGridTree3dNode * node = *it.getIter();
00318 CBoundingBox bb = grid.getCellBoundingBox(it.getIter());
00319
00320 delete node;
00321
00322 CGridTree3d<T> * new_grid = new CGridTree3d<T>(ASizeI,
00323 ASizeJ,
00324 ASizeK,
00325 bb);
00326 grid.setCell(it.getIter(), new_grid);
00327
00328 return new_grid;
00329 }
00330
00331
00332
00333
00334
00335 template <class T> inline
00336 CGridTree3dIterator<T>::CGridTree3dIterator(CGridTree3d<T> & AGrid)
00337 : FGrid(AGrid), FIter(AGrid.getGrid()), FSubIter(NULL), FBB()
00338 {
00339 reinit();
00340 }
00341
00342
00343
00344 template <class T> inline
00345 CGridTree3dIterator<T>::CGridTree3dIterator(CGridTree3d<T> & AGrid,
00346 const CBoundingBox & ABB)
00347 : FGrid(AGrid), FIter(AGrid.getGrid(), ABB), FSubIter(NULL), FBB(ABB)
00348 {
00349 reinit();
00350 }
00351
00352
00353
00354 template <class T> inline
00355 CGridTree3dIterator<T>::CGridTree3dIterator(const CGridTree3dIterator<T> & AI)
00356 : FGrid(AI.FGrid), FIter(AI.FIter), FBB(AI.FBB)
00357 {
00358 if (AI.FSubIter == NULL)
00359 FSubIter = NULL;
00360 else
00361 FSubIter = new CGridTree3dIterator<T>(*AI.FSubIter);
00362 }
00363
00364
00365
00366 template <class T> inline
00367 CGridTree3dIterator<T>::~CGridTree3dIterator()
00368 {
00369 deleteSubIter();
00370 }
00371
00372
00373
00374 template <class T> inline
00375 void CGridTree3dIterator<T>::reinit()
00376 {
00377 FIter.reinit();
00378
00379 deleteSubIter();
00380
00381 if (cont())
00382 createSubIter();
00383 }
00384
00385
00386
00387 template <class T> inline
00388 bool CGridTree3dIterator<T>::cont() const
00389 {
00390 return FIter.cont();
00391 }
00392
00393
00394
00395 template <class T> inline
00396 void CGridTree3dIterator<T>::next()
00397 {
00398 if (FSubIter != NULL) {
00399 if (FSubIter->cont())
00400 FSubIter->next();
00401
00402 if (!FSubIter->cont()) {
00403 delete FSubIter;
00404 FSubIter = NULL;
00405 }
00406 }
00407
00408 if (FSubIter == NULL) {
00409 FIter.next();
00410
00411 if (cont())
00412 createSubIter();
00413 }
00414 }
00415
00416
00417
00418 template <class T> inline
00419 void CGridTree3dIterator<T>::createSubIter()
00420 {
00421 CGridTree3d<T> * grid = dynamic_cast<CGridTree3d<T>*>(*FIter);
00422
00423 if (grid != NULL) {
00424 if (FBB.isEmpty())
00425 FSubIter = new CGridTree3dIterator<T>(*grid);
00426 else
00427 FSubIter = new CGridTree3dIterator<T>(*grid, FBB);
00428
00429 assert(FSubIter->cont());
00430 }
00431 }
00432
00433
00434
00435 template <class T> inline
00436 void CGridTree3dIterator<T>::deleteSubIter()
00437 {
00438 if (FSubIter != NULL) {
00439 delete FSubIter;
00440 FSubIter = NULL;
00441 }
00442 }
00443
00444
00445
00446 #endif