00001
00009
00010
00011
00012 #pragma once
00013
00014
00015 #ifndef WIN32
00016 #pragma interface
00017 #endif // WIN32
00018
00019
00020 #include <stack>
00021 #include "mlist.h"
00022 #include "cube.h"
00023 #include "MarchingCubes.h"
00024 #include "mc_draw.h"
00025 #include "data_access.h"
00026
00027
00028
00029
00031 class PtrOctree
00032
00033 {
00034
00035 public:
00036 class geom_cell ;
00037 class cell_iterator ;
00038 class leaf_iterator ;
00039
00040
00041 protected:
00043 typedef struct cell
00044 {
00045 struct cell *brother ;
00046 struct cell *first_son ;
00047 real field ;
00048 } cell ;
00049
00051 cell _root ;
00052
00054 Level _max_level ;
00055
00057 real _max_field ;
00058
00060 MarchingCubes _mc ;
00061
00063 MC_Draw _mc_draw ;
00064
00066 uint _dual_temp_memory ;
00067
00068
00069
00070 public:
00072 PtrOctree() { init() ; }
00073
00075 ~PtrOctree() { clear() ; }
00076
00077
00079 void init() ;
00080
00082 void clear() { clear_octree() ; _mc.clean_all() ; }
00083
00085 void clear_branch( cell *b ) ;
00086
00088 void clear_octree() { clear_branch( &_root ) ; }
00089
00091 bool check () ;
00092
00094 void stats() ;
00095
00096
00098 Level max_level() const { return _max_level ; }
00099
00101 real max_field() const { return _max_field ; }
00102
00104 MarchingCubes &mc() { return _mc ; }
00105
00107 MC_Draw &mc_draw() { return _mc_draw ; }
00108
00110 bool set_impl( data_access *ref = NULL ) ;
00111
00113 bool refine( data_access *ref = NULL ) ;
00114
00116 bool adapt( data_access *ref = NULL ) ;
00117
00119 bool draw_wire() ;
00120
00122 bool draw_centers() ;
00123
00125 typedef bool ptr_dual_walker( PtrOctree &fo, geom_cell *cells ) ;
00126
00128 bool dual_cubes_walk( ptr_dual_walker &walker ) ;
00129
00131 bool build_isosurface( data_access *ref = NULL ) ;
00132
00134 bool direct_draw_isosurface( data_access *ref = NULL ) ;
00135
00137 bool draw_dual() ;
00138
00140 bool dual_timing() ;
00141
00142
00143
00144 public:
00146 inline cell_iterator cells_begin() { return cell_iterator( &_root ) ; }
00147
00149 inline leaf_iterator leaves_begin() { return leaf_iterator( &_root ) ; }
00150
00151
00152
00153 public:
00155 bool find_leaf( real x, real y, real z, geom_cell &cell ) ;
00156
00158 bool find_radius( real x, real y, real z, real r, List<geom_cell> &cells ) ;
00159
00161 bool adjacent( const geom_cell &cell, List<geom_cell> &cells ) ;
00162
00163
00164
00165
00166 public:
00167
00169 void draw_plane ( real nx, real ny, real nz, real d ) ;
00170
00172 void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ;
00173
00175 void draw_iso () { _mc.draw_surf() ; }
00176
00177
00178
00179 public :
00181 class geom_cell : public Cube
00182
00183 {
00184 friend class PtrOctree ;
00185
00186 protected:
00187 PtrOctree::cell *_cell ;
00188
00189
00190
00191 public:
00193 geom_cell( PtrOctree::cell *cell_ = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 )
00194 : Cube(cx_,cy_,cz_,lv_), _cell(cell_) {}
00195
00197 ~geom_cell() {}
00198
00199
00201 geom_cell( const geom_cell &i )
00202 : Cube(i), _cell(i._cell) {}
00203
00205 geom_cell &operator = ( const geom_cell &i )
00206 { Cube::operator=(i); _cell=i._cell; return *this; }
00207
00208
00209
00210 public :
00212 inline const PtrOctree::cell * cell() const { return _cell ; }
00214 inline PtrOctree::cell *&cell() { return _cell ; }
00215
00217 inline const PtrOctree::cell * first_son() const { return _cell->first_son ; }
00219 inline PtrOctree::cell *&first_son() { return _cell->first_son ; }
00220
00222 inline const PtrOctree::cell * brother() const { return _cell->brother ; }
00224 inline PtrOctree::cell *&brother() { return _cell->brother ; }
00225
00227 inline real operator*() const { return cell()->field ; }
00229 inline real &operator*() { return cell()->field ; }
00230
00231
00232
00233 public :
00235 inline bool operator ==( const geom_cell &i ) const { return cell() == i.cell() ; }
00236
00238 inline bool operator !=( const geom_cell &i ) const { return cell() != i.cell() ; }
00239
00241 inline bool is_leaf() const { return first_son() == NULL ; }
00242
00244 inline bool operator ()() const { return cell() != NULL ; }
00245
00246
00247
00248 public :
00250 inline bool sons( geom_cell *s )
00251 {
00252 if( !first_son() ) return false ;
00253
00254 int level_ = lv() + 1 ;
00255 real sz_ = sz() / 2.0 ;
00256 for( int i = 0 ; i < 8 ; ++i )
00257 {
00258 s[i].cell () = (i==0) ? first_son() : s[i-1].brother() ;
00259 s[i].lv () = level_ ;
00260 s[i].cx () = (i&1) ? cx() + sz_ : cx() - sz_ ;
00261 s[i].cy () = (i&2) ? cy() + sz_ : cy() - sz_ ;
00262 s[i].cz () = (i&4) ? cz() + sz_ : cz() - sz_ ;
00263 }
00264 return true ;
00265 }
00266
00268 inline bool son( int i , geom_cell &s )
00269 {
00270 if( is_leaf() ) return false ;
00271
00272 real sz_ = s.sz() / 2.0 ;
00273 ++s.lv() ;
00274 s.cx() = (i&1) ? cx() + sz_ : cx() - sz_ ;
00275 s.cy() = (i&2) ? cy() + sz_ : cy() - sz_ ;
00276 s.cz() = (i&4) ? cz() + sz_ : cz() - sz_ ;
00277
00278 s.cell() = first_son() ;
00279 while( --i > -1 ) s.cell() = s.brother() ;
00280
00281 return true ;
00282 }
00283 };
00284
00285
00286
00287
00288 public :
00290 class cell_iterator
00291
00292 {
00293 friend class PtrOctree ;
00294
00295 protected:
00297 std::stack<geom_cell> _s ;
00298
00299
00300
00301 public:
00303 cell_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 )
00304 { if( root ) _s.push( geom_cell( root, cx_, cy_, cz_, lv_ ) ) ; }
00305
00307 ~cell_iterator() {}
00308
00310 cell_iterator( const cell_iterator &i ) : _s(i._s) {}
00311
00313 cell_iterator &operator = ( const cell_iterator &i )
00314 { _s = i._s; return *this; }
00315
00316
00317
00318 public :
00320 inline bool operator ()() const { return !_s.empty() ; }
00321
00323 inline cell_iterator &operator ++()
00324 {
00325 if( _s.empty() ) return *this ;
00326 geom_cell n = _s.top() ; _s.pop() ;
00327 if( n.is_leaf() ) return *this ;
00328
00329
00330 geom_cell sons[8] ;
00331 n.sons( sons ) ;
00332 for( int i = 0 ; i < 8 ; ++i )
00333 _s.push( sons[i] ) ;
00334
00335 return *this ;
00336 }
00337
00338
00339
00340 public :
00342 inline geom_cell &top() { return _s.top() ; }
00343
00345 inline real &operator*() { return * _s.top() ; }
00346
00348 inline Level &lv() { return _s.top().lv() ; }
00349
00351 inline real &cx() { return _s.top().cx() ; }
00352
00354 inline real &cy() { return _s.top().cy() ; }
00355
00357 inline real &cz() { return _s.top().cz() ; }
00358
00360 inline real sz() { return _s.top().sz() ; }
00361
00363 inline bool is_leaf() const { return _s.top().is_leaf() ; }
00364
00366 inline bool contains( real x, real y, real z ) const { return _s.top().contains( x,y,z ) ; }
00367
00369 inline bool son( int i , geom_cell &s_ ) { return _s.top().son(i,s_) ; }
00370
00372 void draw_wire () const { _s.top().draw_wire () ; }
00373
00374 protected :
00376 inline std::stack< geom_cell > &s() { return _s ; }
00377 };
00378
00379
00381 class leaf_iterator : public cell_iterator
00382
00383 {
00384 public :
00385 leaf_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 ) : cell_iterator( root, cx_,cy_,cz_,lv_ )
00386 { if( root && !this->is_leaf() ) ++(*this) ; }
00387
00388
00390 inline leaf_iterator &operator ++()
00391 {
00392 cell_iterator &it = *this ;
00393 do ++it ; while ( it() && !it.is_leaf() ) ;
00394 return *this ;
00395 }
00396 } ;
00397 } ;
00398
00399
00400