00001 #ifndef FASTOCTREE_H
00002 #define FASTOCTREE_H
00003
00004 #include <stack>
00005 #include <deque>
00006 #include <set>
00007 #include <vector>
00008 #include <algorithm>
00009 #include <stdexcept>
00010 #include <iostream>
00011
00012 #include "assertions.h"
00013 #include "global.h"
00014
00015 namespace animal
00016 {
00017 namespace octree
00018 {
00019
00020
00021
00022
00151 template<class T,class S,class U>
00152 class FastOctree
00153 {
00154 public:
00155 class Cell;
00156 class Face;
00167 typedef T Vertex;
00168 typedef Vertex* VertexPtr;
00169
00173 class dfs_iterator;
00174 class dfs_leaf_iterator;
00175 class dbs_iterator;
00176 typedef struct
00177 {
00178 bool _entered;
00179 Cell* _cell;
00180 }
00181 dfs_iterator_data;
00182
00183
00184
00185
00186
00187 public:
00191 typedef S Data;
00192
00193 FastOctree(Cell* root);
00194
00195
00196
00197 FastOctree(const U& min,const FloatingPointType& size,const S& defaultData = S());
00198 FastOctree(const U& min,const FloatingPointType& ,const FloatingPointType& ,const FloatingPointType&,
00199 const S& defaultData = S());
00200
00201 virtual ~FastOctree();
00202 inline Cell* root() const;
00203
00204 static inline unsigned short vertexIndex(unsigned short i,
00205 unsigned short j,
00206 unsigned short k);
00207 static inline unsigned short childIndex(unsigned short i,
00208 unsigned short j,
00209 unsigned short k);
00210 public:
00211
00212 static const bool hasBrotherAlongFace[8][6];
00213 static const bool hasBrotherAlongEdge[8][12];
00214 static const unsigned short alongFace[8][6];
00215 static const unsigned short alongEdge[8][12];
00216 static const unsigned short supportingFace[8][12];
00217 static const bool hasOnFatherEdge[8][12];
00218 static const unsigned short childrenSharingFace[6][4];
00219 static const unsigned short alterEgoFace[6];
00220 static const unsigned short faceVertices[6][4];
00221 static const unsigned short verticesConnectedFaces[8][3];
00222 static const unsigned short directionForVertexOnEdge[8][8];
00223 static const unsigned short directionForVertexOnFace[8][8];
00224
00225
00226 public:
00227
00228 Cell* root_;
00229
00230
00231
00240
00241
00242
00243 class Cell
00244 {
00245
00246 public:
00252 inline Data& operator*()
00253 {
00254 return data_;
00255 }
00256 inline Data* operator->()
00257 {
00258 return &data_;
00259 }
00260 inline const Data& operator*() const
00261 {
00262 return data_;
00263 }
00264 inline const Data* operator->() const
00265 {
00266 return &data_;
00267 }
00268
00269 inline void setData( const Data d )
00270 {
00271 data_ = d;
00272 }
00273 inline Data& getData( )
00274 {
00275 return data_;
00276 }
00277
00278 void subdivide(const S& defaultData = S());
00279 void simplify( );
00280
00281 Cell* locate(const U& p);
00282
00283 inline bool isLeaf() const;
00284 inline Vertex* vertex(unsigned short i) const;
00285 inline Cell* father() const;
00286 inline unsigned short fatherPos() const;
00287 inline Cell* child(unsigned short i) const;
00288
00289 inline Vertex center() const;
00290 inline Vertex diagonal() const;
00291 inline FloatingPointType size(unsigned short i) const;
00292
00293 inline Face face(unsigned short pos) const;
00294
00295 Cell* cellSharingFace(unsigned short i) const;
00296 template<class O>
00297 O copyChildrenTouchingFace(unsigned short face,O output) const;
00298 template<class O>
00299 O copyCellsTouchingFace(unsigned short face,O output) const;
00300 Cell* cellSharingEdge(unsigned short i) const;
00301
00302 bool hasUncleSharingFace( unsigned short i ) const;
00303 bool hasUncleSharingEdge( unsigned short edge ) const;
00304
00305 Cell* uncleSharingFace( unsigned short i ) const;
00306
00307 bool edgeOnRootFace( unsigned short edge ) const;
00308 bool edgeOnRootEdge( unsigned short edge ) const;
00309 bool faceOnRootFace( unsigned short face ) const;
00310
00311 bool contains(const U& p) const;
00312
00313 inline int memorySize() const;
00314
00315
00316 inline bool isRoot() const
00317 {
00318 return father_ == NULL;
00319 };
00320
00321
00325 inline Cell* getNeighbour( const unsigned int f ) const { Require(f<6); return _faceNeighbours[f]; };
00326
00327 class vertex_width_iterator;
00328 class vertex_width_neighbours_iterator;
00329 class vertex_connected_iterator;
00330
00331
00332
00333 protected:
00334 friend class FastOctree<T,S,U>;
00335
00339 Cell *_faceNeighbours[6];
00340
00341 Cell(Cell& f,unsigned short p,VertexPtr vertices[27],const S& defaultData);
00342 Cell( const U& min,const FloatingPointType& size,const S& defaultData = S());
00343 Cell( const U& min,const FloatingPointType& ,const FloatingPointType& ,const FloatingPointType&,
00344 const S& defaultData = S());
00345 ~Cell();
00346
00347 inline VertexPtr createRootVertex( const FloatingPointType x, const FloatingPointType y, const FloatingPointType z );
00348 inline VertexPtr createFreeVertex(const U& v);
00349 inline VertexPtr createFreeVertex(const FloatingPointType x,const FloatingPointType y,const FloatingPointType z);
00350 inline VertexPtr createFreeVertex( VertexPtr v1, VertexPtr v2 );
00351 inline VertexPtr createFreeVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4 );
00352 inline VertexPtr createFreeVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4, VertexPtr v5, VertexPtr v6, VertexPtr v7, VertexPtr v8 );
00353
00354 inline VertexPtr createLinkedVertex( VertexPtr v1, VertexPtr v2 );
00355 inline VertexPtr createLinkedVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4 );
00356
00357
00358 inline VertexPtr& vertexPtrAtCenterOfFace(unsigned short face);
00359 inline VertexPtr& vertexPtrAtCenterOfEdge(unsigned short edge);
00360
00361 inline void removeVertex( VertexPtr vp );
00362
00363 static const unsigned short faceAlongEdge[12][2];
00364
00365
00366 public:
00367
00368 Data data_;
00369 Cell* children_[8];
00370 Cell* father_;
00371 unsigned short pos_;
00372 VertexPtr vertices_[8];
00373 std::deque<VertexPtr> toDelete_;
00374
00375 void printPos( std::ostream& out ) const;
00376 static const unsigned short connectedVertices[8][3];
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00399 class vertex_iterator: public dfs_iterator
00400 {
00401 public:
00402 vertex_iterator( Cell *cell );
00403 ~vertex_iterator();
00404
00405 Vertex* operator++();
00406 bool empty();
00407
00408 private:
00409 Vertex* next_vertex();
00410 Cell *_currentCell;
00411 int _currentVertexNumber;
00412 Vertex* _nextVertex;
00413
00414 };
00415
00416 class vertex_width_iterator
00417 {
00418 public:
00419 vertex_width_iterator( Cell *cell );
00420 ~vertex_width_iterator();
00421
00422 Vertex* operator++();
00423 bool empty();
00424
00425 private:
00426
00427
00428
00429
00430
00431 std::deque<Vertex*> _vLists[2];
00432 unsigned int _topListId;
00433
00434
00435
00436
00437
00438 std::set
00439 <Vertex*> _insertedList;
00440
00441 Cell *_cell;
00442
00443 };
00444
00445
00446
00447
00448
00449
00450
00451 class vertex_width_neighbours_iterator
00452 {
00453 public:
00454 vertex_width_neighbours_iterator( Cell *cell );
00455
00456
00457
00458
00459 vertex_width_neighbours_iterator( Vertex* vertex, Cell *cell, unsigned int vPos );
00460 ~vertex_width_neighbours_iterator();
00461
00462 Vertex* operator++();
00463 bool empty();
00464
00465 private:
00466 std::deque<Vertex*> _vLists[2];
00467 unsigned int _topListId;
00468 std::set
00469 <Vertex*> _insertedList;
00470
00471 Cell *_cell;
00472
00473 };
00474 };
00475
00476
00477
00486
00487
00488 class Face
00489 {
00490 public:
00491 inline Vertex* vertex(unsigned short i) const;
00492 inline unsigned short pos() const;
00493 inline Vertex* vertexAtCenter() const;
00494 inline const FloatingPointType* normal() const;
00495 protected:
00496 friend class Cell;
00497 Face(const Cell* cell,unsigned short pos);
00498 private:
00499 const Cell* cell_;
00500 unsigned short pos_;
00501 };
00502
00503
00504 class dfs_iterator
00505 {
00506 public:
00507 dfs_iterator( Cell*, bool (*selectF)(Cell*) = NULL, void (*enterF)(Cell*)=NULL, void (*leaveF)(Cell*)=NULL );
00508 virtual ~dfs_iterator();
00509
00510 Cell* operator++();
00511 bool empty();
00512
00513 Cell* operator*();
00514
00515 protected:
00520 virtual bool select(Cell*)
00521 {
00522 return true;
00523 };
00524
00525 virtual void enter(Cell*)
00526 {}
00527 ;
00528
00529 virtual void leave(Cell*)
00530 {}
00531 ;
00532
00533
00534 private:
00535 bool (*_selectF)(Cell*);
00536 void (*_enterF)(Cell*);
00537 void (*_leaveF)(Cell*);
00538
00539 std::deque<dfs_iterator_data> _deque;
00540 };
00541
00542
00543 class dfs_leaf_iterator
00544 {
00545 public:
00546 dfs_leaf_iterator( Cell*, void (*workF)(Cell*)=NULL );
00547 virtual ~dfs_leaf_iterator();
00548
00549 Cell* operator++();
00550 bool empty();
00551
00552 Cell* operator*();
00553
00554 protected:
00555
00556 virtual void work(Cell*)
00557 {}
00558 ;
00559
00560
00561 private:
00562 void (*_workF)(Cell*);
00563
00564 std::deque<dfs_iterator_data> _deque;
00565 };
00566
00567 }
00568 ;
00569
00570 template<class T,class S,class U>
00571 void
00572 FastOctree<T,S,U>::Cell::printPos( std::ostream& out ) const { if( father_ ) father_->printPos(out); else out<<'r'; out<<pos_; }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00623 template<class T,class S,class U>
00624 void
00625 FastOctree<T,S,U>::Cell::subdivide(const S& defaultData)
00626 {
00627
00628 if (!isLeaf())
00629 {
00630 return;
00631 }
00632
00633
00634 static const unsigned short centerEdge[12] =
00635 {
00636 1,7,19,25,3,21,5,23,9,11,15,17
00637 };
00638
00639
00640
00641 static const unsigned short centerFace[6] =
00642 {
00643 12,14,10,16,4,22
00644 };
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 static const short alterEgoEdgeFace[12][6] =
00663 {
00664 {
00665 -1,-1, 1,-1, 2,-1
00666 }
00667 ,
00668 { -1,-1,-1, 0, 3,-1 },
00669 { -1,-1, 3,-1,-1, 0 },
00670 { -1,-1,-1, 2,-1, 1 },
00671 { 6,-1,-1,-1, 5,-1 },
00672 { 7,-1,-1,-1,-1, 4 },
00673 { -1, 4,-1,-1, 7,-1 },
00674 { -1, 5,-1,-1,-1, 6 },
00675 { 9,-1,10,-1,-1,-1 },
00676 { -1, 8,11,-1,-1,-1 },
00677 { 11,-1,-1, 8,-1,-1 },
00678 { -1,10,-1, 9,-1,-1 }
00679 }
00680 ;
00681
00682
00683
00684 static const unsigned short alterEgoEdge[12] =
00685 {
00686 3,2,1,0,7,6,5,4,11,10,9,8
00687 };
00688
00689
00690
00691
00692
00693
00694
00695 static const unsigned short depending_points_edge_subdivided[12][2] =
00696 {
00697 {
00698 0, 2
00699 }
00700 ,
00701 { 6, 8 },
00702 { 18, 20 },
00703 { 24, 26 },
00704 { 0, 6 },
00705 { 18, 24 },
00706 { 2, 8 },
00707 { 20, 26 },
00708 { 0, 18 },
00709 { 2, 20 },
00710 { 6, 24 },
00711 { 8, 26 }
00712 };
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 VertexPtr vertices[27];
00752 std::fill(vertices,vertices+27,static_cast<VertexPtr>(NULL));
00753
00754 vertices[ 0] = vertices_[0];
00755 vertices[ 2] = vertices_[1];
00756 vertices[ 6] = vertices_[2];
00757 vertices[ 8] = vertices_[3];
00758 vertices[18] = vertices_[4];
00759 vertices[20] = vertices_[5];
00760 vertices[24] = vertices_[6];
00761 vertices[26] = vertices_[7];
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 for (unsigned short edge=0;edge<12;++edge)
00788 {
00789 Vertex** edgeVertex = vertices + centerEdge[edge];
00790
00791 std::cerr << "Making edge " << edge << " : vertex " << centerEdge[edge] << "\n";
00797 VertexPtr sharedPoint = NULL;
00798 unsigned short nNeighbours = 0;
00799
00800 Cell *neighbourEdge, *neighbourFace0, *neighbourFace1;
00801
00802 neighbourEdge = cellSharingEdge( edge );
00803 if( neighbourEdge != NULL )
00804 {
00805 nNeighbours++;
00806 if( !neighbourEdge->isLeaf() )
00807 {
00808 sharedPoint = neighbourEdge->vertexPtrAtCenterOfEdge(alterEgoEdge[edge]);
00809 }
00810 }
00811
00812
00813 neighbourFace0 = cellSharingFace( faceAlongEdge[edge][0] );
00814 if( neighbourFace0 != NULL )
00815 {
00816 nNeighbours++;
00817 if( (sharedPoint==NULL) && (!neighbourFace0->isLeaf()) )
00818 {
00819 sharedPoint = neighbourFace0->vertexPtrAtCenterOfEdge(alterEgoEdgeFace[edge][faceAlongEdge[edge][0]]);
00820 }
00821 }
00822
00823
00824 neighbourFace1 = cellSharingFace( faceAlongEdge[edge][1] );
00825 if( neighbourFace1 != NULL )
00826 {
00827 nNeighbours++;
00828 if( (sharedPoint==NULL) && (!neighbourFace1->isLeaf()) )
00829 sharedPoint = neighbourFace1->vertexPtrAtCenterOfEdge(alterEgoEdgeFace[edge][faceAlongEdge[edge][1]]);
00830 }
00831
00832
00833 if( sharedPoint != NULL )
00834 {
00835 std::cerr << "sharePoint != NULL\n";
00836
00837 *edgeVertex = sharedPoint;
00838
00839 if( nNeighbours == 3 )
00840 {
00841 std::cerr << "\tnNeighbours is 3\n";
00842 if( !neighbourEdge->isLeaf() && !neighbourFace0->isLeaf() && !neighbourFace1->isLeaf() )
00843 {
00844 (*edgeVertex)->freeIt();
00845
00846 }
00847 else
00848 {
00849
00850 }
00851 }
00852 else if( nNeighbours == 2 )
00853 {
00854 std::cerr << "\tnNeighbours is 2\n";
00855
00856 }
00857 else if( nNeighbours == 1 )
00858 {
00859 std::cerr << "\tnNeighbours is 1\n";
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 if( !( this->getNeighbour( faceAlongEdge[edge][0] ) && this->getNeighbour( faceAlongEdge[edge][1] ) ) )
00884 {
00885 std::cerr << "\t\tfreeIt !\n";
00886 (*edgeVertex)->freeIt();
00887 }
00888
00889 else
00890 {
00891
00892 }
00893 }
00894 else
00895 {
00896
00897 }
00898
00899 }
00900
00901 else
00902 {
00903
00904
00905 if(edgeOnRootEdge(edge) )
00906 {
00907 *edgeVertex = createFreeVertex(
00908 vertices[ depending_points_edge_subdivided[edge][0] ],
00909 vertices[ depending_points_edge_subdivided[edge][1] ] );
00910
00911 }
00912 else
00913 {
00914 *edgeVertex = createLinkedVertex(
00915 vertices[ depending_points_edge_subdivided[edge][0] ],
00916 vertices[ depending_points_edge_subdivided[edge][1] ] );
00917
00918 }
00919 }
00920
00921 }
00922
00923
00924 for (unsigned short face=0;face<6;++face)
00925 {
00926
00927
00928
00929
00930 Cell* neighbour = cellSharingFace(face);
00931
00932 if( neighbour != NULL )
00933 {
00934
00935 if( !neighbour->isLeaf() )
00936 {
00937 vertices[centerFace[face]] =
00938 neighbour->vertexPtrAtCenterOfFace(alterEgoFace[face]);
00939 vertices[centerFace[face]]->freeIt();
00940 }
00941 else
00942 {
00943 vertices[centerFace[face]] = createLinkedVertex(
00944 vertices_[faceVertices[face][0]],
00945 vertices_[faceVertices[face][1]],
00946 vertices_[faceVertices[face][2]],
00947 vertices_[faceVertices[face][3]] );
00948 }
00949 }
00950 else
00951 {
00952 if( faceOnRootFace(face) )
00953 {
00954
00955 vertices[centerFace[face]] = createFreeVertex(
00956 vertices_[faceVertices[face][0]],
00957 vertices_[faceVertices[face][1]],
00958 vertices_[faceVertices[face][2]],
00959 vertices_[faceVertices[face][3]] );
00960 }
00961 else
00962 {
00963 vertices[centerFace[face]] = createLinkedVertex(
00964 vertices_[faceVertices[face][0]],
00965 vertices_[faceVertices[face][1]],
00966 vertices_[faceVertices[face][2]],
00967 vertices_[faceVertices[face][3]] );
00968 }
00969 }
00970 }
00971
00972
00973
00974
00975
00976
00977 vertices[13] = createFreeVertex(
00978 vertices_[ 0 ],
00979 vertices_[ 1 ],
00980 vertices_[ 2 ],
00981 vertices_[ 3 ],
00982 vertices_[ 4 ],
00983 vertices_[ 5 ],
00984 vertices_[ 6 ],
00985 vertices_[ 7 ]
00986 );
00987
00988
00989 Cell** c = children_;
00990 *c++ = new Cell(*this,0,vertices,defaultData);
00991 *c++ = new Cell(*this,1,vertices,defaultData);
00992 *c++ = new Cell(*this,2,vertices,defaultData);
00993 *c++ = new Cell(*this,3,vertices,defaultData);
00994 *c++ = new Cell(*this,4,vertices,defaultData);
00995 *c++ = new Cell(*this,5,vertices,defaultData);
00996 *c++ = new Cell(*this,6,vertices,defaultData);
00997 *c++ = new Cell(*this,7,vertices,defaultData);
00998
00999
01000 for( unsigned short face=0 ; face<6 ; ++face )
01001 {
01002 Cell *neighbour = this->getNeighbour(face);
01003
01004
01005 if( !neighbour || neighbour->isLeaf() )
01006 {
01007
01008
01009
01010 for( unsigned short i = 0 ; i<4 ; ++i )
01011 {
01012 unsigned int childId = childrenSharingFace[face][i] ;
01013
01014 this->child( childId )->_faceNeighbours[ face ] = neighbour;
01015 }
01016 }
01017 else
01018 {
01019
01020 for( unsigned short i = 0 ; i<4 ; ++i )
01021 {
01022 unsigned int childId = childrenSharingFace[face][i];
01023 unsigned int alterEgoChildId = childrenSharingFace[alterEgoFace[face]][i];
01024
01025 this->child( childId )->_faceNeighbours[ face ] = neighbour->child( alterEgoChildId );
01026
01027
01028 this->child( childId )->_faceNeighbours[ face ]->_faceNeighbours[ alterEgoFace[face] ] = this->child( childId );
01029 }
01030 }
01031
01032
01033 for( unsigned int i=0 ; i<4 ; ++i )
01034 {
01035 unsigned int childId = childrenSharingFace[face][i];
01036 unsigned int alterEgoChildId = childrenSharingFace[alterEgoFace[face]][i];
01037
01038 this->child( alterEgoChildId )->_faceNeighbours[ face ] = this->child( childId );
01039 this->child( childId )->_faceNeighbours[ alterEgoFace[face] ] = this->child( alterEgoChildId );
01040 }
01041 }
01042
01043 }
01044
01045
01046
01047
01048
01049
01060
01061 template<class T,class S,class U>
01062 void FastOctree<T,S,U>::Cell::simplify( )
01063 {
01064
01065
01066 if( !isLeaf() )
01067 {
01068
01069
01070 for( unsigned short i=0 ; i<8 ; i++ )
01071 {
01072
01073 children_[i]->simplify();
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 static const unsigned short cellsChildrenVertices[27][2] =
01087 {
01088 {
01089 0,0
01090 }
01091 , {0,1}, {1,1}, {0,2}, {0,3}, {1,3}, {2,2}, {2,3}, {3,3},
01092 {0,4}, {0,5}, {1,5}, {0,6}, {0,7}, {1,7}, {2,6}, {2,7}, {3,7},
01093 {4,4}, {4,5}, {5,5}, {4,6}, {4,7}, {5,7}, {6,6}, {6,7}, {7,7}
01094 };
01095
01096
01097
01098 VertexPtr vertices[27];
01099 for( unsigned short v=0 ; v<27 ; v++ )
01100 {
01101 vertices[v] = this->child( cellsChildrenVertices[v][0] )->vertex( cellsChildrenVertices[v][1] );
01102
01103 }
01104
01105
01106
01107 for( unsigned short c=0 ; c<8 ; ++c )
01108 {
01109 for( unsigned short v=0 ; v<8 ; ++v )
01110 {
01111 Require( this->child(c)->vertex(v)->isConnected( this->child(c) ) );
01112
01113
01114 for( unsigned short cellId=0 ; cellId<this->child(c)->vertex(v)->nConnectedCells() ; ++cellId )
01115 {
01116 unsigned int i;
01117 for( i=0 ; i<8 ; ++i )
01118 {
01119 if( this->child(c)->vertex(v)->connectedCell(cellId)->vertex(i) == this->child(c)->vertex(v) )
01120 break;
01121 }
01122
01123 Require( i != 8);
01124
01125 }
01126
01127 this->child(c)->vertex(v)->unregisterCell( this->child(c) );
01128 }
01129 }
01130
01131
01132 for( unsigned short v=0 ; v<27 ; v++ )
01133 {
01134
01135
01136
01137 if( vertices[v]->nConnectedCells() == 0 )
01138 {
01139
01140
01141 delete vertices[v];
01142 vertices[v] = NULL;
01143 }
01144 else
01145 {
01146
01147 unsigned int c;
01148 for( c=0 ; c<8 ; ++c )
01149 {
01150 if( vertices[v]->getMainCell() == this->child(c) )
01151 {
01152
01153
01154 Cell *otherCell = NULL;
01155 for( unsigned short cellId=0 ; cellId<vertices[v]->nConnectedCells() ; ++cellId )
01156 {
01157 Require( vertices[v]->connectedCell(cellId)->getData()._depth >= this->child(c)->getData()._depth );
01158
01159 }
01160
01161
01162 for( unsigned short cellId=0 ; cellId<vertices[v]->nConnectedCells() ; ++cellId )
01163 {
01164 if( vertices[v]->connectedCell(cellId)->getData()._depth == vertices[v]->getDepth() )
01165 otherCell = vertices[v]->connectedCell(cellId);
01166 }
01167
01168
01169 unsigned short vPos = 8;
01170 for( unsigned int j=0 ; j<8 ; ++j )
01171 {
01172 if( otherCell->vertex(j) == vertices[v] )
01173 {
01174 vPos = j;
01175 break;
01176 }
01177 }
01178 Require( vPos != 8 );
01179
01180 vertices[v]->setMainCell( otherCell, vPos );
01181
01182 if( vertices[v]->isFree() )
01183 {
01184
01185 if( vertices[v]->getGeoLink()->getNGeoParents() == 4 )
01186 {
01187
01188 vertices[v]->hardLinkIt( vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(0)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(1)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(2)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(3)) );
01189 }
01190 else if( vertices[v]->getGeoLink()->getNGeoParents() == 2 )
01191 {
01192
01193 vertices[v]->hardLinkIt( vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(0)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(1)) );
01194 }
01195 else
01196 {
01197
01198 }
01199 }
01200
01201
01202 break;
01203 }
01204 }
01205
01206 if( c == 8 )
01207 {
01208
01209
01210 if( (vertices[v]->isFree()) && (vertices[v]->getDepth() == this->getData()._depth+1) )
01211 {
01212
01213 if( vertices[v]->getGeoLink()->getNGeoParents() == 4 )
01214 {
01215
01216 vertices[v]->hardLinkIt( vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(0)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(1)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(2)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(3)) );
01217 }
01218 else if( vertices[v]->getGeoLink()->getNGeoParents() == 2 )
01219 {
01220
01221 vertices[v]->hardLinkIt( vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(0)), vertices[v]->getGeoLink()->getGeoParent(vertices[v]->getGeoLink()->getGeoParentId(1)) );
01222 }
01223 else
01224 {
01225
01226 }
01227 }
01228
01229 }
01230 }
01231
01232 }
01233
01234
01235
01236 for(unsigned short i=0 ; i<8 ; ++i )
01237 {
01238 delete children_[i];
01239 children_[i] = NULL;
01240 }
01241
01242 }
01243
01244
01245
01246
01247 for( unsigned short face=0 ; face<6 ; ++face )
01248 {
01249 if( this->getNeighbour(face) )
01250 {
01251 unsigned short aeFace = alterEgoFace[ face ];
01252
01253 std::deque<Cell*> connectedCells;
01254 connectedCells.push_back( this->getNeighbour(face) );
01255
01256 while( !connectedCells.empty() )
01257 {
01258 Cell *cell = connectedCells.front();
01259 connectedCells.pop_front();
01260 cell->_faceNeighbours[ aeFace ] = this;
01261 if( !cell->isLeaf() )
01262 {
01263 for( unsigned short i=0 ; i<4 ; ++i )
01264 {
01265 connectedCells.push_back( cell->child( childrenSharingFace[aeFace][i] ) );
01266 }
01267 }
01268 }
01269 }
01270
01271 }
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319 }
01320
01321
01322
01323
01324
01331 template<class T,class S,class U>
01332 typename FastOctree<T,S,U>::Cell*
01333 FastOctree<T,S,U>::Cell::locate(const U& p)
01334 {
01335 const Vertex& O = *vertices_[0];
01336 const Vertex I = (*(vertices_[1])-O);
01337 const Vertex J = (*(vertices_[2])-O);
01338 const Vertex K = (*(vertices_[4])-O);
01339 const Vertex M = Vertex(p[0],p[1],p[2])-O;
01340 FloatingPointType ps;
01341 ps = (M*I)/(I*I);
01342 if (ps < 0.0f || ps > 1.0f)
01343 {
01344 return NULL;
01345 }
01346 const unsigned short x = ps<0.5f?0:1;
01347 ps = (M*J)/(J*J);
01348 if (ps < 0.0f || ps > 1.0f)
01349 {
01350 return NULL;
01351 }
01352 const unsigned short y = ps<0.5f?0:1;
01353 ps = (M*K)/(K*K);
01354 if (ps < 0.0f || ps > 1.0f)
01355 {
01356 return NULL;
01357 }
01358 const unsigned short z = ps<0.5f?0:1;
01359
01360 Cell* c = child(x + 2*y + 4*z);
01361 return c != NULL ? c : this;
01362 }
01368 template<class T,class S,class U>
01369 inline bool
01370 FastOctree<T,S,U>::Cell::isLeaf() const
01371 {
01372 return child(0) == NULL;
01373 }
01382 template<class T,class S,class U>
01383 inline typename FastOctree<T,S,U>::Vertex*
01384 FastOctree<T,S,U>::Cell::vertex(unsigned short i) const
01385 {
01386 return static_cast<Vertex*>(vertices_[i]);
01387 }
01391 template<class T,class S,class U>
01392 inline typename FastOctree<T,S,U>::Cell*
01393 FastOctree<T,S,U>::Cell::father() const
01394 {
01395 return father_;
01396 }
01401 template<class T,class S,class U>
01402 inline unsigned short
01403 FastOctree<T,S,U>::Cell::fatherPos() const
01404 {
01405 return pos_;
01406 }
01415 template<class T,class S,class U>
01416 inline typename FastOctree<T,S,U>::Cell*
01417 FastOctree<T,S,U>::Cell::child(unsigned short i) const
01418 {
01419 return children_[i];
01420 }
01427 template<class T,class S,class U>
01428 inline typename FastOctree<T,S,U>::Vertex
01429 FastOctree<T,S,U>::Cell::center() const
01430 {
01431 const Vertex& A = *vertices_[7];
01432 const Vertex& B = *vertices_[0];
01433 return Vertex(0.5f*(A[0]+B[0]),0.5f*(A[1]+B[1]),0.5f*(A[2]+B[2]));
01434 }
01438 template<class T,class S,class U>
01439 inline typename FastOctree<T,S,U>::Vertex
01440 FastOctree<T,S,U>::Cell::diagonal() const
01441 {
01442 const Vertex& A = *vertices_[7];
01443 const Vertex& B = *vertices_[0];
01444 return Vertex(A[0]-B[0],A[1]-B[1],A[2]-B[2]);
01445 }
01449 template<class T,class S,class U>
01450 inline FloatingPointType
01451 FastOctree<T,S,U>::Cell::size(unsigned short i) const
01452 {
01453 return (*vertices_[7])[i]-(*vertices_[0])[i];
01454 }
01459 template<class T,class S,class U>
01460 inline typename FastOctree<T,S,U>::Face
01461 FastOctree<T,S,U>::Cell::face(unsigned short pos) const
01462 {
01463 return Face(this,pos);
01464 }
01465
01466
01469 template<class T,class S,class U>
01470 inline typename FastOctree<T,S,U>::VertexPtr
01471 FastOctree<T,S,U>::Cell::createRootVertex( const FloatingPointType x, const FloatingPointType y, const FloatingPointType z )
01472 {
01473
01474 VertexPtr u = new Vertex( x,y,z, NULL );
01475 Ensure( u->isFree() );
01476 return u;
01477 }
01481 template<class T,class S,class U>
01482 inline typename FastOctree<T,S,U>::VertexPtr
01483 FastOctree<T,S,U>::Cell::createLinkedVertex( VertexPtr v1, VertexPtr v2 )
01484 {
01485
01486 VertexPtr u = createFreeVertex( v1, v2 );
01487 u->hardLinkIt( v1, v2 );
01488 Ensure( !u->isFree() );
01489 return u;
01490 }
01495 template<class T,class S,class U>
01496 inline typename FastOctree<T,S,U>::VertexPtr
01497 FastOctree<T,S,U>::Cell::createLinkedVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4 )
01498 {
01499
01500 VertexPtr u = createFreeVertex( v1, v2, v3, v4 );
01501 u->hardLinkIt(v1,v2,v3,v4);
01502 Ensure( !u->isFree() );
01503 return u;
01504 }
01505
01506
01507
01510 template<class T,class S,class U>
01511 inline typename FastOctree<T,S,U>::VertexPtr
01512 FastOctree<T,S,U>::Cell::createFreeVertex(const U& v)
01513 {
01514
01515 VertexPtr u;
01516 u = new Vertex( v,
01517 vertices_[0], vertices_[1], vertices_[2], vertices_[3],
01518 vertices_[4], vertices_[5], vertices_[6], vertices_[7], this );
01519 Ensure( u->isFree() );
01520 return u;
01521 }
01522 template<class T,class S,class U>
01523 inline typename FastOctree<T,S,U>::VertexPtr
01524 FastOctree<T,S,U>::Cell::createFreeVertex(const FloatingPointType x,
01525 const FloatingPointType y,
01526 const FloatingPointType z)
01527 {
01528
01529 return createFreeVertex(U(x,y,z));
01530 }
01531 template<class T,class S,class U>
01532 inline typename FastOctree<T,S,U>::VertexPtr
01533 FastOctree<T,S,U>::Cell::createFreeVertex( VertexPtr v1, VertexPtr v2 )
01534 {
01535
01536 VertexPtr u = createFreeVertex( (v1->getPosition() + v2->getPosition() )/2.0 );
01537 u->softLinkIt(v1,v2);
01538 return u;
01539 }
01540 template<class T,class S,class U>
01541 inline typename FastOctree<T,S,U>::VertexPtr
01542 FastOctree<T,S,U>::Cell::createFreeVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4 )
01543 {
01544
01545 VertexPtr u = createFreeVertex( (v1->getPosition()+v2->getPosition()+v3->getPosition()+v4->getPosition())/4.0 );
01546 u->softLinkIt(v1,v2,v3,v4);
01547 return u;
01548 }
01549 template<class T,class S,class U>
01550 inline typename FastOctree<T,S,U>::VertexPtr
01551 FastOctree<T,S,U>::Cell::createFreeVertex( VertexPtr v1, VertexPtr v2, VertexPtr v3, VertexPtr v4, VertexPtr v5, VertexPtr v6, VertexPtr v7, VertexPtr v8 )
01552 {
01553
01554 VertexPtr u = createFreeVertex( (v1->getPosition()+v2->getPosition()+v3->getPosition()+v4->getPosition()+v5->getPosition()+v6->getPosition()+v7->getPosition()+v8->getPosition())/8.0 );
01555 u->softLinkIt(v1,v2,v3,v4,v5,v6,v7,v8);
01556 return u;
01557 }
01558
01559
01565 template<class T,class S,class U>
01566 inline void FastOctree<T,S,U>::Cell::removeVertex( typename FastOctree<T,S,U>::VertexPtr vp )
01567 {
01568
01569
01570
01571 toDelete_.push_back(vp);
01572 }
01573
01581 template<class T,class S,class U>
01582 inline typename FastOctree<T,S,U>::VertexPtr&
01583 FastOctree<T,S,U>::Cell::vertexPtrAtCenterOfFace(unsigned short face)
01584 {
01585
01586
01587
01588
01589
01590
01591 static const unsigned short centerOfFace[6][2] =
01592 {
01593 {
01594 0, 6
01595 }
01596 ,
01597 { 1, 7 },
01598 { 0, 5 },
01599 { 2, 7 },
01600 { 0, 3 },
01601 { 4, 7 }
01602 };
01603 const unsigned short* i = centerOfFace[face];
01604 return child(i[0])->vertices_[i[1]];
01605 }
01613 template<class T,class S,class U>
01614 inline typename FastOctree<T,S,U>::VertexPtr&
01615 FastOctree<T,S,U>::Cell::vertexPtrAtCenterOfEdge(unsigned short edge)
01616 {
01617
01618
01619
01620
01621
01622 static const unsigned short centerOfEdge[12][2] =
01623 {
01624 {
01625 0, 1
01626 },
01627 { 2, 3 },
01628 { 4, 5 },
01629 { 6, 7 },
01630 { 0, 2 },
01631 { 4, 6 },
01632 { 1, 3 },
01633 { 5, 7 },
01634 { 0, 4 },
01635 { 1, 5 },
01636 { 2, 6 },
01637 { 3, 7 }
01638 };
01639 const unsigned short* i = centerOfEdge[edge];
01640 return child(i[0])->vertices_[i[1]];
01641 }
01649 template<class T,class S,class U>
01650 typename FastOctree<T,S,U>::Cell*
01651 FastOctree<T,S,U>::Cell::cellSharingFace(unsigned short face) const
01652 {
01653
01654
01655
01656
01657
01658
01659
01660
01661 if (father() == NULL)
01662 {
01663
01664 return NULL;
01665 }
01666 if (hasBrotherAlongFace[pos_][face])
01667 {
01668
01669 return father()->child(alongFace[pos_][face]);
01670 }
01671 const Cell* uncle = father()->cellSharingFace(face);
01672
01673 return uncle == NULL ? NULL : uncle->child(alongFace[pos_][face]);
01674 }
01675
01679 template<class T,class S,class U>
01680 bool FastOctree<T,S,U>::Cell::faceOnRootFace( unsigned short face ) const
01681 {
01682 if( father() == NULL )
01683 return true;
01684 else if( hasBrotherAlongFace[pos_][face] )
01685 return false;
01686 else
01687 return father()->faceOnRootFace(face);
01688 }
01694 template<class T,class S,class U>
01695 bool FastOctree<T,S,U>::Cell::edgeOnRootFace( unsigned short edge ) const
01696 {
01697 if( father() == NULL )
01698 {
01699
01700 return false;
01701
01702 }
01703
01704
01705 if( !hasBrotherAlongFace[pos_][faceAlongEdge[edge][0]] )
01706 {
01707
01708
01709 return father()->faceOnRootFace(faceAlongEdge[edge][0]);
01710 }
01711 if( !hasBrotherAlongFace[pos_][faceAlongEdge[edge][1]] )
01712 {
01713
01714
01715 return father()->faceOnRootFace(faceAlongEdge[edge][1]);
01716 }
01717
01718
01719
01720 return false;
01721 }
01722
01726 template<class T,class S,class U>
01727 bool FastOctree<T,S,U>::Cell::edgeOnRootEdge( unsigned short edge ) const
01728 {
01729 if( father() == NULL )
01730 return true;
01731 if( hasOnFatherEdge[pos_][edge] )
01732
01733 return father()->edgeOnRootEdge(edge);
01734 else
01735
01736 return false;
01737 }
01738
01744 template<class T,class S,class U>
01745 bool FastOctree<T,S,U>::Cell::hasUncleSharingFace(unsigned short face) const
01746 {
01747 if (father() == NULL)
01748 {
01749 return false;
01750 }
01751 if( hasBrotherAlongFace[pos_][face] )
01752 return false;
01753 if( father()->cellSharingFace(face) == NULL )
01754 return false;
01755 else
01756 return true;
01757 }
01758
01759
01760
01761
01762
01763 template<class T,class S,class U>
01764 typename FastOctree<T,S,U>::Cell*
01765 FastOctree<T,S,U>::Cell::uncleSharingFace(unsigned short face) const
01766 {
01767
01768
01769
01770 const Cell* parent = this;
01771 std::deque<unsigned int> posList;
01772
01773
01774
01775 while( (parent->father() != NULL) && !hasBrotherAlongFace[parent->pos_][face] )
01776 {
01777
01778 posList.push_front(parent->pos_);
01779 parent = parent->father();
01780
01781
01782 }
01783
01784 if( parent->father() == NULL )
01785 {
01786
01787
01788 return NULL;
01789 }
01790
01791
01792
01793
01794 Cell *uncle = parent->father()->child(alongFace[parent->pos_][face]);
01795
01796 while( !uncle->isLeaf() && (uncle->data_._depth < this->data_._depth) )
01797 {
01798
01799 uncle = uncle->child( alongFace[posList.front()][face] );
01800
01801 posList.pop_front();
01802 }
01803
01804
01805 return uncle;
01806 }
01807
01814 template<class T,class S,class U>
01815 bool FastOctree<T,S,U>::Cell::hasUncleSharingEdge(unsigned short edge) const
01816 {
01817 if (father() == NULL)
01818 {
01819 return false;
01820 }
01821 if ( !hasOnFatherEdge[pos_][edge] )
01822 {
01823
01824 return false;
01825 }
01826 if( father()->cellSharingEdge(edge) != NULL )
01827 return true;
01828 else
01829 return false;
01830 }
01848 template<class T,class S,class U>
01849 template<class O>
01850 O
01851 FastOctree<T,S,U>::Cell::copyChildrenTouchingFace(unsigned short face,
01852 O output) const
01853 {
01854 for (unsigned short i=0;i<4;++i)
01855 {
01856 Cell* c = child(childrenSharingFace[face][i]);
01857 if (c != NULL)
01858 {
01859 *output++ = c;
01860 output = c->copyChildrenTouchingFace(face,output);
01861 }
01862 }
01863 return output;
01864 }
01888 template<class T,class S,class U>
01889 template<class O>
01890 O
01891 FastOctree<T,S,U>::Cell::copyCellsTouchingFace(unsigned short face,
01892 O output) const
01893 {
01894
01895
01896 std::deque<Cell*> uncles;
01897 const Cell* C = this;
01898 while (C != NULL && C->father() != NULL &&
01899 !hasBrotherAlongFace[C->fatherPos()][face])
01900 {
01901 Cell* uncle = C->father()->cellSharingFace(face);
01902 if (uncle != NULL)
01903 {
01904 uncles.push_front(uncle);
01905 }
01906 C = C->father();
01907 }
01908 output = std::copy(uncles.begin(),uncles.end(),output);
01909
01910
01911 Cell* D = cellSharingFace(face);
01912 if (D != NULL)
01913 {
01914 *output++ = D;
01915 output = D->copyChildrenTouchingFace(alterEgoFace[face],output);
01916 }
01917 return output;
01918 }
01929 template<class T,class S,class U>
01930 typename FastOctree<T,S,U>::Cell*
01931 FastOctree<T,S,U>::Cell::cellSharingEdge(unsigned short edge) const
01932 {
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942 if (father() == NULL)
01943 {
01944 return NULL;
01945 }
01946 if (hasBrotherAlongEdge[pos_][edge])
01947 {
01948 return father()->child(alongEdge[pos_][edge]);
01949 }
01950 const Cell* uncle;
01951 if (hasOnFatherEdge[pos_][edge])
01952 {
01953 uncle = father()->cellSharingEdge(edge);
01954 }
01955 else
01956 {
01957 uncle = father()->cellSharingFace(supportingFace[pos_][edge]);
01958 }
01959 return uncle == NULL ? NULL : uncle->child(alongEdge[pos_][edge]);
01960 }
01964 template<class T,class S,class U>
01965 bool
01966 FastOctree<T,S,U>::Cell::contains(const U& p) const
01967 {
01968
01969 U pos = p;
01970 U vPos[8];
01971 for( unsigned int v = 0 ; v<8 ; ++v )
01972 vPos[v] = vertex(v)->getPosition();
01973
01974
01975 for( unsigned int f=0 ; f<6 ; ++f )
01976 {
01977
01978
01979 bool isGoodForFace = false;
01980 for( unsigned int p=0 ; p<4 ; ++p )
01981
01982 {
01983
01984
01985
01986
01987 U v1 = vPos[faceVertices[f][(p+1)%4]] - vPos[faceVertices[f][p]];
01988 U v2 = vPos[faceVertices[f][abs((p-1)%4)]] - vPos[faceVertices[f][p]];
01989 U v3 = v1 ^ v2;
01990 FloatingPointType sp = (pos-vPos[faceVertices[f][p]]) * v3;
01991
01992 if( sp <= 0.000000001 )
01993 {
01994 isGoodForFace = true;
01995 break;
01996 }
01997 }
01998 if( !isGoodForFace )
01999 return false;
02000 }
02001
02002
02003 return true;
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 }
02029 template<class T,class S,class U>
02030 FastOctree<T,S,U>::Cell::Cell( const U& minP,const FloatingPointType& size,
02031 const S& defaultData)
02032 : data_(defaultData),father_(NULL),pos_(0)
02033 {
02034 Cell** c = children_;
02035 *c++ = NULL;
02036 *c++ = NULL;
02037 *c++ = NULL;
02038 *c++ = NULL;
02039 *c++ = NULL;
02040 *c++ = NULL;
02041 *c++ = NULL;
02042 *c++ = NULL;
02043
02044 VertexPtr* p = vertices_;
02045
02046 FloatingPointType *minPValues = minP.get_FloatingPointTypePointerCopy();
02047 (*p++) = createRootVertex(minPValues[0]+0.0f,minPValues[1]+0.0f,minPValues[2]+0.0f);
02048 (*p++) = createRootVertex(minPValues[0]+size,minPValues[1]+0.0f,minPValues[2]+0.0f);
02049 (*p++) = createRootVertex(minPValues[0]+0.0f,minPValues[1]+size,minPValues[2]+0.0f);
02050 (*p++) = createRootVertex(minPValues[0]+size,minPValues[1]+size,minPValues[2]+0.0f);
02051 (*p++) = createRootVertex(minPValues[0]+0.0f,minPValues[1]+0.0f,minPValues[2]+size);
02052 (*p++) = createRootVertex(minPValues[0]+size,minPValues[1]+0.0f,minPValues[2]+size);
02053 (*p++) = createRootVertex(minPValues[0]+0.0f,minPValues[1]+size,minPValues[2]+size);
02054 (*p++) = createRootVertex(minPValues[0]+size,minPValues[1]+size,minPValues[2]+size);
02055 free( minPValues );
02056
02057 p = vertices_;
02058 (p++)->registerCell( this );
02059 (p++)->registerCell( this );
02060 (p++)->registerCell( this );
02061 (p++)->registerCell( this );
02062 (p++)->registerCell( this );
02063 (p++)->registerCell( this );
02064 (p++)->registerCell( this );
02065 (p++)->registerCell( this );
02066
02067 for( unsigned short v=0 ; v<8 ; ++v )
02068 {
02069 Require( !vertices_[v]->hasMainCell() );
02070 vertices_[v]->setMainCell( this, v );
02071 }
02072
02073
02074 for( unsigned short i=0 ; i<6 ; ++i )
02075 {
02076 _faceNeighbours[i] = NULL;
02077 }
02078
02079 }
02080 template<class T,class S,class U>
02081 FastOctree<T,S,U>::Cell::Cell( const U& minP,
02082 const FloatingPointType& xsize,
02083 const FloatingPointType& ysize,
02084 const FloatingPointType& zsize,
02085 const S& defaultData)
02086 : data_(defaultData),father_(NULL),pos_(0)
02087 {
02088 Cell** c = children_;
02089 *c++ = NULL;
02090 *c++ = NULL;
02091 *c++ = NULL;
02092 *c++ = NULL;
02093 *c++ = NULL;
02094 *c++ = NULL;
02095 *c++ = NULL;
02096 *c++ = NULL;
02097
02098
02099 VertexPtr* p = vertices_;
02100 const FloatingPointType *minPValues = minP;
02101 (*p++) = createRootVertex(minPValues[0]+ 0.0f,minPValues[1]+ 0.0f,minPValues[2]+ 0.0f);
02102 (*p++) = createRootVertex(minPValues[0]+xsize,minPValues[1]+ 0.0f,minPValues[2]+ 0.0f);
02103 (*p++) = createRootVertex(minPValues[0]+ 0.0f,minPValues[1]+ysize,minPValues[2]+ 0.0f);
02104 (*p++) = createRootVertex(minPValues[0]+xsize,minPValues[1]+ysize,minPValues[2]+ 0.0f);
02105 (*p++) = createRootVertex(minPValues[0]+ 0.0f,minPValues[1]+ 0.0f,minPValues[2]+zsize);
02106 (*p++) = createRootVertex(minPValues[0]+xsize,minPValues[1]+ 0.0f,minPValues[2]+zsize);
02107 (*p++) = createRootVertex(minPValues[0]+ 0.0f,minPValues[1]+ysize,minPValues[2]+zsize);
02108 (*p++) = createRootVertex(minPValues[0]+xsize,minPValues[1]+ysize,minPValues[2]+zsize);
02109
02110 p = vertices_;
02111 (*p++)->registerCell( this );
02112 (*p++)->registerCell( this );
02113 (*p++)->registerCell( this );
02114 (*p++)->registerCell( this );
02115 (*p++)->registerCell( this );
02116 (*p++)->registerCell( this );
02117 (*p++)->registerCell( this );
02118 (*p++)->registerCell( this );
02119
02120 for( unsigned short v=0 ; v<8 ; ++v )
02121 {
02122 Require( !vertices_[v]->hasMainCell() );
02123 vertices_[v]->setMainCell( this, v );
02124 }
02125
02126 for( unsigned short i=0 ; i<6 ; ++i )
02127 {
02128 _faceNeighbours[i] = NULL;
02129 }
02130
02131 }
02132 template<class T,class S,class U>
02133 FastOctree<T,S,U>::Cell::Cell(Cell& f,unsigned short pos,
02134 FastOctree<T,S,U>::VertexPtr vertices[27],
02135 const S& defaultData)
02136 : data_(defaultData),father_(&f),pos_(pos)
02137 {
02138 Cell** c = children_;
02139 *c++ = NULL;
02140 *c++ = NULL;
02141 *c++ = NULL;
02142 *c++ = NULL;
02143 *c++ = NULL;
02144 *c++ = NULL;
02145 *c++ = NULL;
02146 *c++ = NULL;
02147
02148 const unsigned short I = pos_&0x1;
02149 const unsigned short J = (pos_>>1)&0x1;
02150 const unsigned short K = (pos_>>2)&0x1;
02151 const unsigned short I0 = I,I1 = 1+I;
02152 const unsigned short J0 = 3*J,J1 = 3*(1+J);
02153 const unsigned short K0 = 9*K,K1 = 9*(1+K);
02154 VertexPtr* p = vertices_;
02155 *p++ = vertices[I0+J0+K0];
02156 *p++ = vertices[I1+J0+K0];
02157 *p++ = vertices[I0+J1+K0];
02158 *p++ = vertices[I1+J1+K0];
02159 *p++ = vertices[I0+J0+K1];
02160 *p++ = vertices[I1+J0+K1];
02161 *p++ = vertices[I0+J1+K1];
02162 *p++ = vertices[I1+J1+K1];
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 for( unsigned short v = 0 ; v<8 ; ++v )
02182 {
02183 vertices_[v]->registerCell(this);
02184 }
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200 for( unsigned short v=0 ; v<8 ; ++v )
02201 {
02202 if( !vertices_[v]->hasMainCell() )
02203 vertices_[v]->setMainCell( this, v );
02204 }
02205
02206 for( unsigned short i=0 ; i<6 ; ++i )
02207 {
02208 _faceNeighbours[i] = NULL;
02209 }
02210
02211 }
02212 template<class T,class S,class U>
02213 FastOctree<T,S,U>::Cell::~Cell()
02214 {
02215
02216
02217 Require( isLeaf() );
02218
02219
02220
02221
02222 if( !isLeaf() )
02223 simplify();
02224
02225 if( father() == NULL )
02226 {
02227 for( unsigned short v=0 ; v<8 ; ++v )
02228 {
02229 vertices_[v]->unregisterCell(this);
02230 delete vertices_[v];
02231 vertices_[v] = NULL;
02232 }
02233 }
02234
02235
02236
02237 }
02238
02239
02240
02241
02252 template<class T,class S,class U>
02253 inline int
02254 FastOctree<T,S,U>::Cell::memorySize() const
02255 {
02256
02257
02258
02259 return
02260 sizeof(S)+
02261 sizeof(Cell*)*8+
02262 sizeof(Cell*)+
02263 sizeof(unsigned short)+
02264 sizeof(VertexPtr)*8+
02265 sizeof(Vertex)*toDelete_.size();
02266 }
02267
02268
02269
02273 template<class T,class S,class U>
02274 inline typename FastOctree<T,S,U>::Vertex*
02275 FastOctree<T,S,U>::Face::vertex(unsigned short i) const
02276 {
02277 return cell_->vertex(FastOctree<T,S,U>::faceVertices[pos_][i]);
02278 }
02282 template<class T,class S,class U>
02283 inline unsigned short
02284 FastOctree<T,S,U>::Face::pos() const
02285 {
02286 return pos_;
02287 }
02293 template<class T,class S,class U>
02294 inline typename FastOctree<T,S,U>::Vertex*
02295 FastOctree<T,S,U>::Face::vertexAtCenter() const
02296 {
02297 return cell_->vertexPtrAtCenterOfFace(i);
02298 }
02304 template<class T,class S,class U>
02305 inline const FloatingPointType*
02306 FastOctree<T,S,U>::Face::normal() const
02307 {
02308 static const FloatingPointType normals[6][3] =
02309 {
02310 {
02311 -1.0f, 0.0f, 0.0f
02312 },
02313 { 1.0f, 0.0f, 0.0f },
02314 { 0.0f,-1.0f, 0.0f },
02315 { 0.0f, 1.0f, 0.0f },
02316 { 0.0f, 0.0f,-1.0f },
02317 { 0.0f, 0.0f, 1.0 }
02318 };
02319 return normals[pos_];
02320 }
02321 template<class T,class S,class U>
02322 inline FastOctree<T,S,U>::Face::Face(const FastOctree<T,S,U>::Cell* cell,
02323 unsigned short pos)
02324 : cell_(cell),pos_(pos)
02325 {}
02326
02327
02328
02333 template<class T,class S,class U>
02334 FastOctree<T,S,U>::FastOctree(FastOctree<T,S,U>::Cell* root)
02335 : root_(root)
02336 {}
02345 template<class T,class S,class U>
02346 FastOctree<T,S,U>::FastOctree(const U& min,
02347 const FloatingPointType& size,const S& defaultData)
02348 {
02349 root_ = new Cell(min,size,defaultData);
02350 }
02359 template<class T,class S,class U>
02360 FastOctree<T,S,U>::FastOctree(const U& min,
02361 const FloatingPointType& sx,const FloatingPointType& sy,const FloatingPointType& sz,
02362 const S& defaultData)
02363 {
02364 root_ = new Cell(min,sx,sy,sz,defaultData);
02365 }
02372 template<class T,class S,class U>
02373 FastOctree<T,S,U>::~FastOctree()
02374 {
02375 delete root_;
02376 }
02380 template<class T,class S,class U>
02381 inline typename FastOctree<T,S,U>::Cell*
02382 FastOctree<T,S,U>::root() const
02383 {
02384 return root_;
02385 }
02390 template<class T,class S,class U>
02391 inline unsigned short
02392 FastOctree<T,S,U>::vertexIndex(unsigned short i,unsigned short j,unsigned short k)
02393 {
02394 return i+2*j+4*k;
02395 }
02400 template<class T,class S,class U>
02401 inline unsigned short
02402 FastOctree<T,S,U>::childIndex(unsigned short i,unsigned short j,unsigned short k)
02403 {
02404 return i+2*j+4*k;
02405 }
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 template<class T, class S, class U>
02417 FastOctree<T,S,U>::dfs_iterator::dfs_iterator( Cell* cStart, bool (*selectF)(Cell*), void (*enterF)(Cell*), void (*leaveF)(Cell*) ) :
02418 _selectF(selectF), _enterF(enterF), _leaveF(leaveF)
02419 {
02420 dfs_iterator_data data = {false,cStart};
02421 _deque.push_front(data);
02422 }
02423
02424 template<class T, class S, class U>
02425 FastOctree<T,S,U>::dfs_iterator::~dfs_iterator()
02426 {}
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 template<class T, class S, class U>
02441 bool FastOctree<T,S,U>::dfs_iterator::empty( )
02442 {
02443 return _deque.empty();
02444 }
02445
02446 template<class T, class S, class U>
02447 typename FastOctree<T,S,U>::Cell*
02448 FastOctree<T,S,U>::dfs_iterator::operator*()
02449 {
02450 Require( !empty() );
02451 return _deque.front()._cell;
02452 }
02453
02454 template<class T, class S, class U>
02455 typename FastOctree<T,S,U>::Cell*
02456 FastOctree<T,S,U>::dfs_iterator::operator++()
02457 {
02458 Require( !empty() );
02459
02460
02461 dfs_iterator_data lastIt = _deque.front();
02462
02463 if( !lastIt._entered )
02464 {
02465
02466 _deque.front()._entered = true;
02467
02468
02469
02470
02471 if( !lastIt._cell->isLeaf() )
02472 {
02473
02474 for( short c=7 ; c>=0 ; --c )
02475 {
02476 dfs_iterator_data data = {false,lastIt._cell->child(c)};
02477 _deque.push_front( data );
02478 }
02479 }
02480
02481
02482 if( (_selectF != NULL && _selectF(lastIt._cell)) || (_selectF == NULL && select(lastIt._cell)) )
02483 {
02484
02485 if( _enterF != NULL )
02486 {
02487 _enterF(lastIt._cell);
02488 }
02489 else
02490 {
02491 enter( lastIt._cell );
02492 }
02493 }
02494
02495 }
02496 else
02497 {
02498
02499 if( (_selectF != NULL && _selectF(lastIt._cell)) || (_selectF == NULL && select(lastIt._cell)) )
02500 {
02501 if( _leaveF != NULL )
02502 {
02503 _leaveF( lastIt._cell );
02504 }
02505 else
02506 {
02507 leave( lastIt._cell );
02508 }
02509 }
02510
02511 _deque.pop_front();
02512 }
02513
02514 return lastIt._cell;
02515 }
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545 template<class T, class S, class U>
02546 FastOctree<T,S,U>::dfs_leaf_iterator::dfs_leaf_iterator( Cell* cStart, void (*workF)(Cell*) ) :
02547 _workF(workF)
02548 {
02549 dfs_iterator_data data = {false,cStart};
02550 _deque.push_front(data);
02551 }
02552
02553 template<class T, class S, class U>
02554 FastOctree<T,S,U>::dfs_leaf_iterator::~dfs_leaf_iterator()
02555 {}
02556
02557
02558 template<class T, class S, class U>
02559 bool FastOctree<T,S,U>::dfs_leaf_iterator::empty( )
02560 {
02561 return _deque.empty();
02562 }
02563
02564 template<class T, class S, class U>
02565 typename FastOctree<T,S,U>::Cell*
02566 FastOctree<T,S,U>::dfs_leaf_iterator::operator*()
02567 {
02568 Require( !empty() );
02569 return _deque.front()._cell;
02570 }
02571
02572 template<class T, class S, class U>
02573 typename FastOctree<T,S,U>::Cell*
02574 FastOctree<T,S,U>::dfs_leaf_iterator::operator++()
02575 {
02576 Require( !empty() );
02577
02578
02579 dfs_iterator_data lastIt = _deque.front();
02580
02581 if( !lastIt._entered )
02582 {
02583
02584 _deque.front()._entered = true;
02585
02586
02587
02588
02589 if( !lastIt._cell->isLeaf() )
02590 {
02591
02592 for( short c=7 ; c>=0 ; --c )
02593 {
02594 dfs_iterator_data data = {false,lastIt._cell->child(c)};
02595 _deque.push_front( data );
02596 }
02597 }
02598 else
02599 {
02600
02601 if( _workF != NULL )
02602 {
02603 _workF(lastIt._cell);
02604 }
02605 else
02606 {
02607 work( lastIt._cell );
02608 }
02609 }
02610
02611 }
02612 else
02613 {
02614 _deque.pop_front();
02615 }
02616
02617 return lastIt._cell;
02618 }
02619
02620
02621
02622
02623
02624
02625 template<class T,class S,class U>
02626 FastOctree<T,S,U>::Cell::vertex_iterator::vertex_iterator( FastOctree<T,S,U>::Cell *cell )
02627 : dfs_iterator(cell)
02628 , _currentCell(cell)
02629 , _currentVertexNumber(0)
02630 {
02631
02632 _nextVertex = next_vertex();
02633
02634
02635 }
02636
02637 template<class T,class S,class U>
02638 FastOctree<T,S,U>::Cell::vertex_iterator::~vertex_iterator()
02639 {
02640 }
02641
02642 template<class T,class S,class U>
02643 typename FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::operator++()
02644 {
02645 FastOctree<T,S,U>::Vertex* result = _nextVertex;
02646 _nextVertex = next_vertex();
02647 return result;
02648 }
02649
02650 template<class T,class S,class U>
02651 typename FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex()
02652 {
02653 FastOctree<T,S,U>::Vertex* found = 0;
02654 while( !found && !dfs_iterator::empty() )
02655 {
02656
02657 while( _currentVertexNumber<8 && _currentCell->vertex(_currentVertexNumber)->getMainCell()!=_currentCell )
02658 {
02659 _currentVertexNumber++;
02660
02661 }
02662 if( _currentVertexNumber<8 )
02663 {
02664
02665 found = _currentCell->vertex(_currentVertexNumber);
02666
02667 _currentVertexNumber++;
02668 }
02669 else
02670 {
02671 _currentCell = dfs_iterator::operator ++();
02672 _currentCell = dfs_iterator::operator ++();
02673 _currentVertexNumber = 0;
02674
02675 }
02676 }
02677
02678 return found;
02679 }
02680
02681 template<class T,class S,class U>
02682 bool FastOctree<T,S,U>::Cell::vertex_iterator::empty()
02683 {
02684 return _nextVertex == 0;
02685 }
02686
02687
02688 template<class T,class S,class U>
02689 FastOctree<T,S,U>::Cell::vertex_width_iterator::vertex_width_iterator( FastOctree<T,S,U>::Cell *cell ) :
02690 _topListId(0), _cell(cell)
02691 {
02692 for( unsigned short v=0 ; v<8 ; ++v )
02693 _vLists[_topListId].push_back( _cell->vertex(v) );
02694
02695 }
02696 template<class T,class S,class U>
02697 FastOctree<T,S,U>::Cell::vertex_width_iterator::~vertex_width_iterator()
02698 {}
02699 template<class T,class S,class U>
02700 typename FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_width_iterator::operator++()
02701 {
02702 Require( !empty() );
02703
02704 Vertex* res = _vLists[_topListId].front();
02705 _vLists[_topListId].pop_front();
02706
02707 for( unsigned int i=0 ; i<res->nChildren() ; ++i )
02708 {
02709 if( _insertedList.find(res->child(i)) == _insertedList.end() )
02710 {
02711
02712 _vLists[(_topListId+1)%2].push_back( res->child(i) );
02713 _insertedList.insert( res->child(i) );
02714 }
02715 }
02716
02717 if( empty() )
02718 {
02719
02720 _topListId = (_topListId+1)%2;
02721 }
02722
02723 return res;
02724 }
02725 template<class T,class S,class U>
02726 bool FastOctree<T,S,U>::Cell::vertex_width_iterator::empty()
02727 {
02728 return _vLists[_topListId].empty();
02729 }
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740 template<class T,class S,class U>
02741 FastOctree<T,S,U>::Cell::vertex_width_neighbours_iterator::vertex_width_neighbours_iterator( FastOctree<T,S,U>::Cell *cell ) :
02742 _topListId(0), _cell(cell)
02743 {
02744 for( unsigned short v=0 ; v<8 ; ++v )
02745 {
02746 _vLists[_topListId].push_back( _cell->vertex(v) );
02747 }
02748
02749 for( unsigned short v=0 ; v<8 ; ++v )
02750 {
02751 ConstrainedVertex *vertex = _vLists[_topListId][v];
02752 for( unsigned short i=0 ; i < vertex->nConnectedCells() ; ++i )
02753 {
02754 Cell *connectedCell = vertex->connectedCell( i );
02755 if( connectedCell->getData()._depth == cell->getData()._depth )
02756 {
02757
02758 unsigned short child;
02759 for( child=0 ; child<8 ; ++child )
02760 {
02761 if( connectedCell->vertex(child) == _vLists[_topListId][v] )
02762 {
02763 _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][0] ) );
02764 _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][1] ) );
02765 _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][2] ) );
02766 break;
02767 }
02768 }
02769 Require( child != 8 );
02770 }
02771 }
02772 }
02773 }
02774
02775 template<class T,class S,class U>
02776 FastOctree<T,S,U>::Cell::vertex_width_neighbours_iterator::vertex_width_neighbours_iterator( typename FastOctree<T,S,U>::Vertex* vertex, FastOctree<T,S,U>::Cell *cell, unsigned int vPos ) :
02777 _topListId(0), _cell(NULL)
02778 {
02779 _vLists[_topListId].push_back( vertex );
02780
02781 Cell::vertex_connected_iterator it( vertex, cell, vPos );
02782 while( !it.empty() )
02783 {
02784 _vLists[_topListId].push_back( ++it );
02785 }
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809 }
02810
02811 template<class T,class S,class U>
02812 FastOctree<T,S,U>::Cell::vertex_width_neighbours_iterator::~vertex_width_neighbours_iterator()
02813 {}
02814 template<class T,class S,class U>
02815 typename FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_width_neighbours_iterator::operator++()
02816 {
02817 Require( !empty() );
02818
02819 Vertex* res = _vLists[_topListId].front();
02820 _vLists[_topListId].pop_front();
02821
02822 for( unsigned int i=0 ; i<res->nChildren() ; ++i )
02823 {
02824 if( _insertedList.find(res->child(i)) == _insertedList.end() )
02825 {
02826
02827 _vLists[(_topListId+1)%2].push_back( res->child(i) );
02828 _insertedList.insert( res->child(i) );
02829 }
02830 }
02831
02832 if( empty() )
02833 {
02834
02835 _topListId = (_topListId+1)%2;
02836 }
02837
02838 return res;
02839 }
02840 template<class T,class S,class U>
02841 bool FastOctree<T,S,U>::Cell::vertex_width_neighbours_iterator::empty()
02842 {
02843 return _vLists[_topListId].empty();
02844 }
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890 template<class T,class S,class U>
02891 const bool
02892 FastOctree<T,S,U>::hasBrotherAlongFace[8][6] =
02893 {
02894 {
02895 false,true ,false,true ,false,true
02896 },
02897 { true ,false,false,true ,false,true },
02898 { false,true ,true ,false,false,true },
02899 { true ,false,true ,false,false,true },
02900 { false,true ,false,true ,true ,false },
02901 { true ,false,false,true ,true ,false },
02902 { false,true ,true ,false,true ,false },
02903 { true ,false,true ,false,true ,false }
02904 };
02905
02906
02907
02908
02909 template<class T,class S,class U>
02910 const bool
02911 FastOctree<T,S,U>::hasBrotherAlongEdge[8][12] =
02912 {
02913 {
02914 false,false,false,true ,false,false,false,true ,false,false,false,true
02915 },
02916 { false,false,false,true ,false,true ,false,false,false,false,true ,false },
02917 { false,false,true ,false,false,false,false,true ,false,true ,false,false },
02918 { false,false,true ,false,false,true ,false,false,true ,false,false,false },
02919 { false,true ,false,false,false,false,true ,false,false,false,false,true },
02920 { false,true ,false,false,true ,false,false,false,false,false,true ,false },
02921 { true ,false,false,false,false,false,true ,false,false,true ,false,false },
02922 { true ,false,false,false,true ,false,false,false,true ,false,false,false }
02923 };
02924
02925
02926
02927
02928
02929
02930
02931
02932 template<class T,class S,class U>
02933 const unsigned short
02934 FastOctree<T,S,U>::alongFace[8][6] =
02935 {
02936 {
02937 1,1,2,2,4,4
02938 },
02939 { 0,0,3,3,5,5 },
02940 { 3,3,0,0,6,6 },
02941 { 2,2,1,1,7,7 },
02942 { 5,5,6,6,0,0 },
02943 { 4,4,7,7,1,1 },
02944 { 7,7,4,4,2,2 },
02945 { 6,6,5,5,3,3 }
02946 };
02947
02948
02949
02950
02951
02952
02953
02954 template<class T,class S,class U>
02955 const unsigned short
02956 FastOctree<T,S,U>::alongEdge[8][12] =
02957 {
02958 {
02959 6,6,6,6,5,5,5,5,3,3,3,3
02960 },
02961 { 7,7,7,7,4,4,4,4,2,2,2,2 },
02962 { 4,4,4,4,7,7,7,7,1,1,1,1 },
02963 { 5,5,5,5,6,6,6,6,0,0,0,0 },
02964 { 2,2,2,2,1,1,1,1,7,7,7,7 },
02965 { 3,3,3,3,0,0,0,0,6,6,6,6 },
02966 { 0,0,0,0,3,3,3,3,5,5,5,5 },
02967 { 1,1,1,1,2,2,2,2,4,4,4,4 }
02968 };
02969
02970
02971
02972
02973 template<class T,class S,class U>
02974 const unsigned short
02975 FastOctree<T,S,U>::alterEgoFace[6] =
02976 {
02977 1,0,3,2,5,4
02978 };
02979
02980
02981
02982
02983 template<class T,class S,class U>
02984 const unsigned short
02985 FastOctree<T,S,U>::supportingFace[8][12] =
02986 {
02987 {
02988 6,4,2,1,4,0,4,1,2,2,0,1
02989 },
02990 { 6,4,2,1,4,1,4,1,2,2,1,1 },
02991 { 4,6,1,3,4,0,4,1,0,1,2,3 },
02992 { 4,6,1,3,4,1,4,1,1,1,3,3 },
02993 { 2,1,6,5,0,4,1,5,2,2,0,1 },
02994 { 2,1,6,5,1,5,1,5,2,2,1,1 },
02995 { 1,3,5,7,0,4,1,5,0,1,2,3 },
02996 { 1,3,5,7,1,5,1,5,1,1,3,3 }
02997 };
02998
02999
03000
03001
03002 template<class T,class S,class U>
03003 const bool
03004 FastOctree<T,S,U>::hasOnFatherEdge[8][12] =
03005 {
03006 {
03007 true ,false,false,false,true ,false,false,false,true ,false,false,false
03008 },
03009 { true ,false,false,false,false,false,true ,false,false,true ,false,false },
03010 { false,true ,false,false,true ,false,false,false,false,false,true ,false },
03011 { false,true ,false,false,false,false,true ,false,false,false,false,true },
03012 { false,false,true ,false,false,true ,false,false,true ,false,false,false },
03013 { false,false,true ,false,false,false,false,true ,false,true ,false,false },
03014 { false,false,false,true ,false,true ,false,false,false,false,true ,false },
03015 { false,false,false,true ,false,false,false,true ,false,false,false,true }
03016 };
03017
03018
03019
03020
03021
03022
03023 template<class T,class S,class U>
03024 const unsigned short
03025 FastOctree<T,S,U>::childrenSharingFace[6][4] =
03026 {
03027 { 0,2,4,6 },
03028 { 1,3,5,7 },
03029 { 0,1,4,5 },
03030 { 2,3,6,7 },
03031 { 0,1,2,3 },
03032 { 4,5,6,7 }
03033 };
03034
03035
03036
03037
03038 template<class T,class S,class U>
03039 const unsigned short
03040 FastOctree<T,S,U>::faceVertices[6][4] =
03041 {
03042 {
03043 0,4,6,2
03044 },
03045 { 5,1,3,7 },
03046 { 0,1,5,4 },
03047 { 3,2,6,7 },
03048 { 0,2,3,1 },
03049 { 6,4,5,7 }
03050 };
03051
03052
03053
03054
03055
03056 template<class T,class S,class U>
03057 const unsigned short
03058 FastOctree<T,S,U>::Cell::faceAlongEdge[12][2] =
03059 {
03060 {2,4},
03061 {3,4},
03062 {2,5},
03063 {3,5},
03064 {0,4},
03065 {0,5},
03066 {1,4},
03067 {1,5},
03068 {0,2},
03069 {1,2},
03070 {0,3},
03071 {1,3}
03072 };
03073
03074
03075
03076
03077
03078
03079 template<class T,class S,class U>
03080 const unsigned short
03081 FastOctree<T,S,U>::Cell::connectedVertices[8][3] =
03082 {
03083 {
03084 1,2,4
03085 },
03086 {0,3,5},
03087 {3,0,6},
03088 {2,1,7},
03089 {5,6,0},
03090 {4,7,1},
03091 {7,4,2},
03092 {6,5,3}
03093 };
03094
03095
03096
03097
03098
03099
03100 template<class T,class S,class U>
03101 const unsigned short
03102 FastOctree<T,S,U>::verticesConnectedFaces[8][3] =
03103 {
03104 {
03105 0,2,4
03106 },
03107 {1,2,4},
03108 {0,3,4},
03109 {1,3,4},
03110 {0,2,5},
03111 {1,2,5},
03112 {0,3,5},
03113 {1,3,5}
03114 };
03115
03123 template<class T,class S,class U>
03124 const unsigned short
03125 FastOctree<T,S,U>::directionForVertexOnEdge[8][8] =
03126 {
03127 {
03128 -1,0,1,-1, 2,-1,-1,-1
03129 },
03130 {0,-1,-1,1, -1,2,-1,-1},
03131 {1,-1,-1,0, -1,-1,2,-1},
03132 {-1,1,0,-1, -1,-1,-1,2},
03133 {2,-1,-1,-1, -1,0,1,-1},
03134 {-1,2,-1,-1, 0,-1,-1,1},
03135 {-1,-1,2,-1, 1,-1,-1,0},
03136 {-1,-1,-1,2, -1,1,0,-1}
03137 };
03138
03139
03140 template<class T,class S,class U>
03141 const unsigned short
03142 FastOctree<T,S,U>::directionForVertexOnFace[8][8] =
03143 {
03144 {
03145 -1,-1,-1,2, -1,1,0,-1
03146 },
03147 {-1,-1,2,-1, 1,-1,-1,0},
03148 {-1,2,-1,-1, 0,-1,-1,1},
03149 {2,-1,-1,-1, -1,0,1,-1},
03150
03151 {-1,1,0,-1, -1,-1,-1,2},
03152 {1,-1,-1,0, -1,-1,2,-1},
03153 {0,-1,-1,1, -1,2,-1,-1},
03154 {-1,0,1,-1, 2,-1,-1,-1}
03155 };
03156
03157 }
03158 }
03159
03160 #endif // FASTOCTREE_H