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