Documentation


fastoctreedeformableconstrained.h

Go to the documentation of this file.
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 // Interface of FastOctree<T,S,U>
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     //  FastOctree(const T& min,const FloatingPointType& size,const S& defaultData = S());
00195     //FastOctree(const T& min,const FloatingPointType& ,const FloatingPointType& ,const FloatingPointType&,
00196     //       const S& defaultData = S());
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     //protected:
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     //private:
00228     Cell* root_;
00229     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00230     // Interface of FastOctree<T,S,U>::Cell
00231     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00240     /*template<class T,class S,class U>
00241     class FastOctree<T,S,U>::Cell*/
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         //friend inline std::ostream& operator<<(std::ostream& s, const Cell &c);
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         // private:
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         //         /** added by FF for more flexibility than the FastOctree::dfs_iterator  (?)*/
00381         //         class dfs_iterator
00382         //         {
00383         //         public:
00384         //             dfs_iterator( Cell* c ):_cell(c){}
00385         //             virtual ~dfs_iterator(){}
00386         //
00387         //             dfs_iterator& operator++();
00388         //
00389         //             Cell& operator*(){ return *_cell; }
00390         //
00391         //         private:
00392         //             Cell* _cell;
00393         //             std::stack<Cell*> _stack;
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              * The lists of vertices ordered by depth,
00428              * There are only 2 different depths at the same time
00429              * So we have 2 lists and one ID to get the current top list
00430              */
00431             std::deque<Vertex*> _vLists[2];
00432             unsigned int _topListId;
00433 
00434             /*
00435              * Now, in order not to add only Vertices that are
00436              * not already in the list, keep a trace of the stored vertices
00437              */
00438             std::set
00439                 <Vertex*> _insertedList;
00440 
00441             Cell *_cell;
00442 
00443         };
00444 
00445 
00446         /*
00447          * Now, for each vertex of this cell,
00448          * Also get the vertices that are connected to it in the neighbourhood of the cell
00449          */
00450 
00451         class vertex_width_neighbours_iterator
00452         {
00453         public:
00454             vertex_width_neighbours_iterator( Cell *cell );
00455 
00456             /*
00457              * Only use this vertex at this depth to catch connected vertices
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     // Interface of FastOctree<T,S,U>::Face
00477     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00486     /*template<class T,class S,class U>
00487     class FastOctree<T,S,U>::Face*/
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         // What to do when entering a node
00525         virtual void enter(Cell*)
00526         {}
00527         ;
00528         // What to do when leaving a node
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         // What to do with a node
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 ;//class FastOctree
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 template<class T,class S,class U>
00575 std::ostream&
00576 FastOctree<T,S,U>::Cell::operator<<(std::ostream& s)
00577 {
00578     if( father() == NULL )
00579         s << "root->";
00580     else
00581     {
00582         s << *father() << fatherPos() << "->";
00583     }
00584     return s;
00585 }
00586 */
00587 /*
00588 template<class T,class S,class U>
00589 std::ostream& operator<<(std::ostream& s,typename const Cell& c)
00590 {
00591     if( c->father() == NULL )
00592         s << "root->";
00593     else
00594     {
00595         s << *(c->father()) << c->fatherPos() << "->";
00596     }
00597     return s;
00598 }
00599 */
00600 
00601 //************************************************************
00602 // Implementation of FastOctree<T,S,U>::Cell
00603 //************************************************************
00623 template<class T,class S,class U>
00624 void
00625 FastOctree<T,S,U>::Cell::subdivide(const S& defaultData)
00626 {
00627     // If it is already subdivided, exit!
00628     if (!isLeaf())
00629     {
00630         return;
00631     }
00632     // center_edge[e] = the index of vertex at the center of edge e.
00633     // Table is checked.
00634     static const unsigned short centerEdge[12] =
00635         {
00636             1,7,19,25,3,21,5,23,9,11,15,17
00637         };
00638 
00639     // center_face[f] = the index of point at the center of face f.
00640     // Table is checked.
00641     static const unsigned short centerFace[6] =
00642         {
00643             12,14,10,16,4,22
00644         };
00645 
00646     // face_edge[f] are the 4 edges who surround face f.
00647     // Table is checked.
00648     /*
00649     static const unsigned short faceEdge[6][4] =
00650     {
00651       { 5,10, 4, 8 },
00652       { 6,11, 7, 9 },
00653       { 0, 8, 2, 9 },
00654       { 3,11, 1,10 },
00655       { 0, 4, 1, 6 },
00656       { 3, 7, 2, 5 }  
00657     };
00658     */
00659     // alter_ego_edge_face[e][f] is the number of the edge equivalent to
00660     // edge \p e of a cell for cell sharing face \p f.
00661     // Table is checked.
00662     static const short alterEgoEdgeFace[12][6] =
00663         {
00664             {
00665                 -1,-1, 1,-1, 2,-1
00666             }
00667             ,             //{ 0,0,1,1,2,2 },
00668             { -1,-1,-1, 0, 3,-1 },       //{ 1,1,0,0,3,3 },
00669             { -1,-1, 3,-1,-1, 0 },       //{ 2,2,3,3,0,0 },
00670             { -1,-1,-1, 2,-1, 1 },       //{ 3,3,2,2,1,1 },
00671             {  6,-1,-1,-1, 5,-1 },       //{ 6,6,4,4,5,5 },
00672             {  7,-1,-1,-1,-1, 4 },       //{ 7,7,5,5,4,4 },
00673             { -1, 4,-1,-1, 7,-1 },       //{ 4,4,6,6,7,7 },
00674             { -1, 5,-1,-1,-1, 6 },       //{ 5,5,7,7,6,6 },
00675             {  9,-1,10,-1,-1,-1 },       //{ 9,9,10,10,8,8 },
00676             { -1, 8,11,-1,-1,-1 },       //{ 8,8,11,11,9,9 },
00677             { 11,-1,-1, 8,-1,-1 },       //{ 11,11,8,8,10,10 },
00678             { -1,10,-1, 9,-1,-1 }        //{ 10,10,9,9,11,11 }
00679         }
00680         ;
00681     // alter_ego_edge[e] is the index of the edge number \p e of a cell C
00682     // in the cell sharing this edge with cell C.
00683     // Table is checked.
00684     static const unsigned short alterEgoEdge[12] =
00685         {
00686             3,2,1,0,7,6,5,4,11,10,9,8
00687         };
00688 
00689     /* From Mathieu :
00690     * depending_points_edge_subdivided[e] gives you the 2 vertices
00691     * which are needed to create the new point at the middle of the edge \p e
00692     * They're part of the original points, we give them with new indices
00693     * Not checked
00694     */
00695     static const unsigned short depending_points_edge_subdivided[12][2] =
00696         {
00697             {
00698                 0,  2
00699             }
00700             , // vertex[1] is 1/2 ( vertex[0] + vertex[2] )
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      * vertexChildPos[v][0] gives our associated father's child position for the vertex v
00716      * vertexChildPos[v][1] gives the ID of the vertex in vertexChildPos[v][0] father's child
00717      */
00718     /*
00719     static const unsigned short vertexChildPos[27][2] =
00720     {
00721     {0,0}, {0,1}, {1,1}, {0,2}, {0,3}, {1,3}, {2,2}, {2,3}, {3,3},
00722     {0,4}, {0,5}, {1,5}, {0,6}, {0,7}, {1,7}, {2,6}, {2,7}, {3,7},
00723     {4,4}, {4,5}, {5,5}, {4,6}, {4,7}, {5,7}, {6,6}, {6,7}, {7,7}
00724     };
00725     */
00726 
00727     /* From Mathieu :
00728     * depending_points_face_subdivided[f] gives you the 4 vertices on which depends
00729     * the vertex at the "center" of face f.
00730     * We give the 4 vertices which are at the center of the 4 edges of the face
00731     * See later the "centerFace" table :
00732     * centerFace[f] = ( sum(i=0..3) depending_points_face_subdivided[f][i] ) / 4;
00733     */
00734     /*
00735     static const unsigned short depending_points_face_subdivided[6][4] =
00736     {
00737     {  3,  9, 21, 15 },     // For face 0 : vertex 12
00738     {  5, 11, 23, 17 },     // For face 1 : vertex 14
00739     {  1, 11, 19,  9 },     // For face 2 : vertex 10
00740     {  7, 15, 25, 17 },     // For face 3 : vertex 16
00741     {  1,  3,  5,  7 },     // For face 4 : vertex  4
00742     { 19, 23, 25, 21 },     // For face 5 : vertex 22
00743     };
00744     */
00745 
00746 
00747     //************************************************************
00748     // We create/get from neighbours the 27 vertices that
00749     // are necessary to subdivide the cell.
00750     //************************************************************
00751     VertexPtr vertices[27];
00752     std::fill(vertices,vertices+27,static_cast<VertexPtr>(NULL));
00753     // 8 are easily find: these are the vertices of the cell
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     // The center always has to be created
00764     // From Mathieu : Removed this, see this below, it's created from the centers of the faces
00765 
00766     // Search along the 6 faces and 12 edges the already existing vertices,
00767     // that is the vertex at center of faces and edges.
00768     // ATTENTION: this remark is to signal a subtil bug that was hard to
00769     // correct!! The subtle vertex is that calls to centerOfFace or
00770     // centerOfEdge silently returns NULL if vertex does not exist.  But some
00771     // vertices amongst the 27 we are trying to share can be "shared" in
00772     // different manner.  For example the middle vertex of an edge (e.g.
00773     // number 19) can be shared with 3 cells. It is eventually the same vertex
00774     // that is shared, but it can be "retrieved" from 3 neighbouring cells.
00775     // So once a retrieval has given a non NULL vertex, we must ensure that the
00776     // 2 other retrieval (which might return NULL) do not override the
00777     // result.  Actually, once we have find a way to share, we must skip other
00778     // retrievals (which speeds up by the way).
00779 
00780     /* From Mathieu :
00781     * We need to first deal the vertices at the center of edges
00782     * So we can use them to make the vertices at the center of faces
00783     * (We could also have used the "this" cell's 8 main vertices
00784     * But next, for constrained vertices, we would be able to parametrize
00785     * them directly from the 2 edges they depend on (given by the 2 pairs of points)
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         // First neighbour : on the edge
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         // Second neighbour : on the first face
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         // Third neighbour : on the second face
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             // There's a sharedPoint
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                     //                      std::cerr << "nNeighbours == 3 ->FREED\n";
00846                 }
00847                 else
00848                 {
00849                     //                      std::cerr << "Existe SharedPoint, 3 neighbours avec au moins 1 feuille : share it\n";
00850                 }
00851             }
00852             else if( nNeighbours == 2 )
00853             {
00854             std::cerr << "\tnNeighbours is 2\n";
00855                 //                  std::cerr << "nNeighbours == 2 : share it\n";
00856             }
00857             else if( nNeighbours == 1 )
00858             {
00859             std::cerr << "\tnNeighbours is 1\n";
00860         
00861         /*
00862                 if( neighbourEdge == NULL )
00863         //if( edgeOnRootFace(edge) || edgeOnRootEdge(edge) )
00864                 {
00865             
00866             std::cerr << "\t\tNeighbour == NULL\n";
00867             if( hasUncleSharingFace(faceAlongEdge[edge][0]) )
00868             {
00869                 std::cerr << "hasUncleSharingFace(faceAlongEdge[edge][0]" << faceAlongEdge[edge][0] << "\n";
00870             }
00871             if( hasUncleSharingFace(faceAlongEdge[edge][1]) )
00872             {
00873                 std::cerr << "hasUncleSharingFace(faceAlongEdge[edge][1]" << faceAlongEdge[edge][1] << "\n";
00874             }
00875             
00876             
00877             if( ! ((neighbourFace0 || hasUncleSharingFace(faceAlongEdge[edge][0])) && (neighbourFace1||hasUncleSharingFace(faceAlongEdge[edge][1])) ) )
00878             {
00879                 std::cerr << "\t\tfreeIt !\n";
00880                             (*edgeVertex)->freeIt();
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                     //                      std::cerr << "nNeighbours == 1 -> FREED\n";
00889                 else
00890                 {
00891                     //                      std::cerr << "nNeighbours == 1 : share it\n";
00892                 }
00893             }
00894             else // 0 neighbours
00895             {
00896                 //                  std::cerr << "Impossible : 0 neighbours et sharedPoint existe\n";
00897             }
00898 
00899         } // end sharedPoint != NULL
00900 
00901         else // sharedPoint == NULL
00902         {
00903             // Create it, warning, it could be freed just after
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                 //              std::cerr << "Creer : Free\n";
00911             }
00912             else
00913             {
00914                 *edgeVertex = createLinkedVertex(
00915                                   vertices[ depending_points_edge_subdivided[edge][0] ],
00916                                   vertices[ depending_points_edge_subdivided[edge][1] ] );
00917                 //              std::cerr << "Creer : Linked\n";
00918             }
00919         } // sharedPoint == NULL
00920 
00921     }
00922 
00923     //              std::cerr << "\n";
00924     for (unsigned short face=0;face<6;++face)
00925     {
00926         // With a cell sharing face, we can have 5 vertices in common:
00927         // - the center of the face
00928         // - the center of the 4 edges defining the shared face
00929 
00930         Cell* neighbour = cellSharingFace(face);
00931 
00932         if( neighbour != NULL )
00933         {
00934             // We have a neighbour, see if it already have this Vertex
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                 // this face is on the root's borders, it's free
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     /* From Mathieu :
00973     * Now create the "center" of the cell (it must always be created),
00974     * it's given by
00975     * (sum(f=0..5) vertices[ centerFace[f] ] ) / 6
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     // Create the children
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     // Update the neighbour informations
01000     for( unsigned short face=0 ; face<6 ; ++face )
01001     {
01002         Cell *neighbour = this->getNeighbour(face);
01003     
01004     // For each child cell containing this face
01005     if( !neighbour || neighbour->isLeaf() )
01006     {
01007         // It's on a root cell or
01008         // this neighbour is of size >= 
01009         // Simply tell them that it's their neighbour
01010         for( unsigned short i = 0 ; i<4 ; ++i )
01011         {
01012             unsigned int childId = childrenSharingFace[face][i] ;
01013             // The face's id correspond in our children
01014             this->child( childId )->_faceNeighbours[ face ] = neighbour;
01015         }
01016     }
01017     else
01018     {
01019         // Find the neighbour child corresponding
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             // The face's id correspond in our children
01025             this->child( childId )->_faceNeighbours[ face ] = neighbour->child( alterEgoChildId );
01026             
01027             // don't forget to tell this neighbour that we're its new neighbour along this face
01028             this->child( childId )->_faceNeighbours[ face ]->_faceNeighbours[ alterEgoFace[face] ] = this->child( childId );
01029         }
01030     }
01031     
01032     // Now make the information for brothers
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 // Implementation of FastOctree<T,S,U>::Cell
01049 //************************************************************
01060 // The simplification is not OK !!
01061 template<class T,class S,class U>
01062 void FastOctree<T,S,U>::Cell::simplify( )
01063 {
01064     //std::cerr << "simplify() of depth " << this->getData()._depth << " and cell is " << *this << "\n";
01065 
01066     if( !isLeaf() )
01067     {
01068         // Simplify the children
01069 
01070         for( unsigned short i=0 ; i<8 ; i++ )
01071         {
01072             //          std::cerr << "Simplify child " << i << "\n";
01073             children_[i]->simplify();
01074         }
01075 
01076         //std::cerr << "Now simplify us\n";
01077 
01078         //      std::cerr << "simplify() of depth " << this->getData()._depth << " and cell is " << *this << " end children\n";
01079 
01080         // This table associate to every vertex of the 27 vertices
01081         // one of the child that contains it and it's inner vertex id associated
01082         // Example :
01083         //   Vertex 25 is cell 6's 7th vertex (but also cell 7's 6th vertex)
01084         //   cellsChildrenVertices[25] = { 6, 7 };
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         // Get pointers to vertices
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             //std::cerr << "Vertex[" << v << "] = " << vertices[v] << "\n";
01103         }
01104 
01105 
01106         // Unregister the cells
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                 //std::cerr << "Child(" << c <<") -> Vertex[" << v << "] = " << child(c)->vertex(v) << "\n";
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                     //std::cerr << "\t" << *this->child(c)->vertex(v)->connectedCell(cellId) << "\n";
01125                 }
01126 
01127                 this->child(c)->vertex(v)->unregisterCell( this->child(c) );
01128             }
01129         }
01130 
01131         // Cells have been unregistered
01132         for( unsigned short v=0 ; v<27 ; v++ )
01133         {
01134             // Find if it's part of one of our children
01135             //std::cerr << "I'm vertex " << v << "\n";
01136 
01137             if( vertices[v]->nConnectedCells() == 0 )
01138             {
01139                 //std::cerr << "\tDeleting vertex\n";
01140                 // Ok to delete !
01141                 delete vertices[v];
01142                 vertices[v] = NULL;
01143             }
01144             else
01145             {
01146                 // See if we need to change the mainCell
01147                 unsigned int c;
01148                 for( c=0 ; c<8 ; ++c )
01149                 {
01150                     if( vertices[v]->getMainCell() == this->child(c) )
01151                     {
01152                         //std::cerr << "\tMaincell is child " << c << "\n";
01153                         // This means that I could have created it
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                             //std::cerr << "\t\tConencted to : " << *(vertices[v]->connectedCell(cellId)) << "\n";
01159                         }
01160 
01161                         // Find the first cell of same depth
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                         // Find it's position in the other cell
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                             //std::cerr << "\tConstrain it\n";
01185                             if( vertices[v]->getGeoLink()->getNGeoParents() == 4 )
01186                             {
01187                                 //std::cerr << "Hardlink for 4\n";
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                                 //std::cerr << "Hardlink for 2\n";
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                                 //std::cerr << "8 parents so free\n";
01198                             }
01199                         }
01200 
01201 
01202                         break;
01203                     }
01204                 }
01205 
01206                 if( c == 8 )
01207                 {
01208                     //std::cerr << "\tThis vertex' maincell is not one of our child\n";
01209                     // This vertex' maincell is not one of our child
01210                     if( (vertices[v]->isFree()) && (vertices[v]->getDepth() == this->getData()._depth+1) )
01211                     {
01212                         //std::cerr << "\tConstrain it\n";
01213                         if( vertices[v]->getGeoLink()->getNGeoParents() == 4 )
01214                         {
01215                             //std::cerr << "Hardlink for 4\n";
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                             //std::cerr << "Hardlink for 2\n";
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                             //std::cerr << "8 parents so free\n";
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     // Update the neighbour informations
01245     // Tell all the connected neighbours to one of our child that we're they're new neighbour
01246     // for the concerned face
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     // else nothing to do
01271     }
01272     /*
01273         // Update the neighbour informations
01274     for( unsigned short face=0 ; face<6 ; ++face )
01275     {
01276         Cell *neighbour = this->getNeighbour(face);
01277     
01278     // For each child cell containing this face
01279     if( !neighbour || neighbour->isLeaf() )
01280     {
01281         // It's on a root cell or
01282         // this neighbour is of size >= 
01283         // Simply tell them that it's their neighbour
01284         for( unsigned short i = 0 ; i<4 ; ++i )
01285         {
01286             unsigned int childId = childrenSharingFace[face][i] ;
01287             // The face's id correspond in our children
01288             this->child( childId )->_faceNeighbours[ face ] = neighbour;
01289         }
01290     }
01291     else
01292     {
01293         // Find the neighbour child corresponding
01294         for( unsigned short i = 0 ; i<4 ; ++i )
01295         {
01296             unsigned int childId = childrenSharingFace[face][i];
01297             unsigned int alterEgoChildId = childrenSharingFace[alterEgoFace[face]][i];
01298             // The face's id correspond in our children
01299             this->child( childId )->_faceNeighbours[ face ] = neighbour->child( alterEgoChildId );
01300             
01301             // don't forget to tell this neighbour that we're its new neighbour along this face
01302             this->child( childId )->_faceNeighbours[ face ]->_faceNeighbours[ alterEgoFace[face] ] = this->child( childId );
01303         }
01304     }
01305     
01306     // Now make the information for brothers
01307     for( unsigned int i=0 ; i<4 ; ++i )
01308     {
01309         unsigned int childId = childrenSharingFace[face][i];
01310         unsigned int alterEgoChildId = childrenSharingFace[alterEgoFace[face]][i];
01311         
01312         this->child( alterEgoChildId )->_faceNeighbours[ face ] = this->child( childId );
01313         this->child( childId )->_faceNeighbours[ alterEgoFace[face] ] = this->child( alterEgoChildId );
01314     }
01315     }
01316     */    
01317     //std::cerr << "simplify() : end  of depth " << this->getData()._depth << " and cel " << *this << "\n";
01318 
01319 }
01320 
01321 
01322 //************************************************************
01323 // Implementation of FastOctree<T,S,U>::Cell
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     //std::cerr << "createRootVertex\n";
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     //std::cerr << "createLinkedVertex3 : " << v1->getPosition() << " and " << v2->getPosition() << "\n";
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     //std::cerr << "createLinkedVertex2\n";
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     //std::cerr << "createFreeVertex with Vec " << v << "\n";
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     //std::cerr << "createFreeVertex2\n";
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     //  std::cerr << "createFreeVertex 2 parents : " << v1->getPosition() << " and " << v2->getPosition() << "\n";
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     //  std::cerr << "createFreeVertex 4 parents\n";
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     //  std::cerr << "createFreeVertex 8 parents\n";
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     // This stuff is done in the destrcutor of Vertex
01569     //vp->unregisterCell(this);
01570     //delete vp;
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     // Considering the face f of a cell, its center point is vertex
01586     // center_of_face[f][1] of its child center_of_face[f][0]. Four such pairs
01587     // exist, the table just gives one because since all 4 children of a cell
01588     // exist at the same time, they are equivalent.  The sum of first and
01589     // second elements of such pairs is a constant (indicated below in
01590     // comments).
01591     static const unsigned short centerOfFace[6][2] =
01592         {
01593             {
01594                 0, 6
01595             }
01596             , // or { 2,4 } or opposed (sum = 6)
01597             { 1, 7 }, // or { 3,5 } or opposed (sum = 8)
01598             { 0, 5 }, // or { 1,4 } or opposed (sum = 5)
01599             { 2, 7 }, // or { 3,6 } or opposed (sum = 9)
01600             { 0, 3 }, // or { 1,2 } or opposed (sum = 3)
01601             { 4, 7 }  // or { 5,6 } or opposed (sum = 11)
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     // Considering the edge e of a cell, its center point is vertex
01618     // center_of_edge[e][1] of its child center_of_edge[f][0]. Two such pairs
01619     // exist, the table just gives one because since all 4 children of a cell
01620     // exist at the same time, they are equivalent.  Such pairs are symmetric.
01621     // Table is checked.
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     // If the cell sharing FACE would be a brother (which we can say
01654     // from pos and FACE's index) then it always exist and we
01655     // query it from the father.
01656     // Else we consider the father's face that contains FACE (it
01657     // has the same index!) and ask the father to find a cell that would
01658     // share it. It would be an "uncle" of (*this).
01659     // We ask the uncle for the child who shares FACE. If exists, such a
01660     // child would be a cousin for (*this).
01661     if (father() == NULL)
01662     {
01663         //      std::cerr << "father is NULL for face " << face << "\n";
01664         return NULL;
01665     }
01666     if (hasBrotherAlongFace[pos_][face])
01667     {
01668         //      std::cerr << "Looking for my father's child for face " << face << " child (" <<alongFace[pos_][face]<< ")\n";
01669         return father()->child(alongFace[pos_][face]);
01670     }
01671     const Cell* uncle = father()->cellSharingFace(face);
01672     //  std::cerr << "Uncle is " << uncle << "\n";
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         //      std::cerr << "father is NULL\n";
01700         return false;
01701     //return true;
01702     }
01703     //  std::cerr << "Face0 : " << faceAlongEdge[edge][0] << " Face1 : " <<  faceAlongEdge[edge][1] << "\n";
01704     // For each edge, it has at maximum 1 face not shared by a brother for this edge
01705     if( !hasBrotherAlongFace[pos_][faceAlongEdge[edge][0]] )
01706     {
01707         //      std::cerr << "I don't have a brother on face0 " << faceAlongEdge[edge][0] << "\n";
01708         // Then if this face is on a root's face
01709         return father()->faceOnRootFace(faceAlongEdge[edge][0]);
01710     }
01711     if( !hasBrotherAlongFace[pos_][faceAlongEdge[edge][1]] )
01712     {
01713         //      std::cerr << "I don't have a brother on face1 " << faceAlongEdge[edge][1] << "\n";
01714         // Then if this face is on a root's face
01715         return father()->faceOnRootFace(faceAlongEdge[edge][1]);
01716     }
01717 
01718     //  std::cerr << "This is an inside edge\n";
01719     // This is an inside edge
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         // We're sharing an edge with our father
01733         return father()->edgeOnRootEdge(edge);
01734     else
01735         // This is an inside edge
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  * Get the brother (has the same father), cousin (at the same depth) or uncle (no children and deepest)
01761  * sharing face
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     /* First, go up and find our parent that is a brother of
01768      * our "uncle", if no such brother exists, return null
01769      */
01770     const Cell* parent = this;
01771     std::deque<unsigned int> posList;
01772 
01773     //std::cerr << "Face is " << face << "\n";
01774     //std::cerr << "Pos is " << parent->pos_ << "\n";
01775     while( (parent->father() != NULL) && !hasBrotherAlongFace[parent->pos_][face] )
01776     {
01777         //std::cerr << "First it\n";
01778         posList.push_front(parent->pos_);
01779         parent = parent->father();
01780         //std::cerr << "Have pushed " << posList.front() << "\n";
01781         // Memorize our position
01782     }
01783 
01784     if( parent->father() == NULL )
01785     {
01786         //std::cerr << "Parent is NULL\n";
01787         // No neighbour
01788         return NULL;
01789     }
01790 
01791     // Now descend back to find the touching cell
01792     //std::cerr << "parent pos is " << parent->pos_ << "\n";
01793     //std::cerr << "Uncle id on father : " << alongFace[parent->pos_][face] << "\n";
01794     Cell *uncle = parent->father()->child(alongFace[parent->pos_][face]);
01795 
01796     while( !uncle->isLeaf() && (uncle->data_._depth < this->data_._depth) )
01797     {
01798         //std::cerr << "Have poped " << posList.front() << "\n";
01799         uncle = uncle->child( alongFace[posList.front()][face] );
01800         //std::cerr << "\tchild ID is " << alongFace[posList.front()][face] << "\n";
01801         posList.pop_front();
01802     }
01803 
01804     //std::cerr << "Uncle pos is " << uncle->pos_ << "\n";
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         // We're not on an edge of our father, so we can't have an uncle ALONG this edge
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     // We search for the biggest cell who has a face that contains "face"
01895     // We remember all uncles crossed along the way
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     // We now search for cell sharing face if it exists and if so, we
01910     // add all its children touching the alter ego face
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     // If the cell sharing EDGE would be a brother (which we can say
01934     // from pos and EDGE's index) then it always exist and we
01935     // query it from the father.
01936 
01937     // Else we must request it to a brother of the father (that is an
01938     // uncle for (*this)). There can be 2 different cases: either the
01939     // edge lies inside a father's face and then we must query the cell
01940     // that shares this face. Or it lies on a father's edge and we must
01941     // query the cell that shares this supporting edge.
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     // For each face
01975     for( unsigned int f=0 ; f<6 ; ++f )
01976     {
01977         //std::cerr << "For face " << f << "\n";
01978         // For each possibility, it must at least be in one
01979         bool isGoodForFace = false;
01980         for( unsigned int p=0 ; p<4 ; ++p )
01981             //for( unsigned int p=0 ; p<1 ; ++p )
01982         {
01983             //std::cerr << "p : " << p << "next : " << (p+1)%4 << " prev : " << abs((p-1)%4) << "\n";
01984             //std::cerr << "point 0 : " << faceVertices[f][p] << ", 1 : " << faceVertices[f][(p+1)%4] <<
01985             //  ", 2 : " << faceVertices[f][abs((p-1)%4)] << "\n";
01986             //  getchar();
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             //std::cerr << "sp is " << sp << "\n";
01992             if( sp <= 0.000000001 )
01993             {
01994                 isGoodForFace = true;
01995                 break;
01996             }
01997         }
01998         if( !isGoodForFace )
01999             return false;
02000     }
02001 
02002     // Every face is containing it
02003     return true;
02004     /*
02005       const U O = *vertices_[0];
02006       const U  I = (*(vertices_[1])-O);
02007       const U  J = (*(vertices_[2])-O);
02008       const U  K = (*(vertices_[4])-O);
02009       const U  M = U(p[0],p[1],p[2])-O;
02010       FloatingPointType ps;
02011       ps = (M*I)/(I*I);
02012       if (ps < 0.0f || ps > 1.0f)
02013       {
02014         return false;
02015       }
02016       ps = (M*J)/(J*J);
02017       if (ps < 0.0f || ps > 1.0f)
02018       {
02019         return false;
02020       }
02021       ps = (M*K)/(K*K);
02022       if (ps < 0.0f || ps > 1.0f)
02023       {
02024         return false;
02025       }
02026       return true;
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     // Creates the eight vertex vertices
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     // Root cell has no neighbour
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     // Creates the eight vertex points
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     // Sets the 8 points from the father
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     // Do not register THIS vertex as it's already registerd by our father
02165     // It's equivalent to our father's position for our vertices
02166     //  const unsigned short vertexOnBorder = pos_;
02167 
02168     /*
02169      for( unsigned short v = 0 ; v<8 ; ++v )
02170         if( v != vertexOnBorder )
02171         {
02172             //std::cerr << "Adding one cell " << v << "\n";
02173     //          if( !vertices_[v]->isConnected(this) )
02174                 vertices_[v]->registerCell(this);
02175     //          else
02176     //              std::cerr <<"Constructor : Error register3\n";
02177     //          std::cerr << "Finished\n";
02178         }
02179         */
02180 
02181     for( unsigned short v = 0 ; v<8 ; ++v )
02182     {
02183         vertices_[v]->registerCell(this);
02184     }
02185 
02186     /*
02187         std::cerr << "Cell constructor : " << *this << "\n";
02188         std::cerr << "Registering vertices :\n";
02189       for( unsigned short v = 0 ; v<8 ; ++v )
02190         {
02191             vertices_[v]->registerCell(this);
02192             std::cerr << "Vertice[" <<v << "] is connected to :\n";
02193             for( unsigned short cellId=0 ; cellId<vertex(v)->nConnectedCells() ; ++cellId )
02194             {
02195                 std::cerr << "\t" << *vertex(v)->connectedCell(cellId) << "\n";
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     //std::cerr << "~Cell() of cell " << *this << "\n";
02216 
02217     Require( isLeaf() );
02218 
02219     /*
02220      * With simplify, every child is freed !
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     //std::cerr << "~Cell() end of cell " << *this << "\n";
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     // We do not count the memory size of toDelete_ deque because we
02257     // intend o supress it (in todo list) but we use it to find the
02258     // number of "owned" vertices.
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 // Implementation of Face
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 // Implementation of FastOctree<T,S,U>
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 template<class T, class S, class U>
02431 void FastOctree<T,S,U>::dfs_iterator::enter( Cell* cell )
02432 {
02433 }
02434 template<class T, class S, class U>
02435 void FastOctree<T,S,U>::dfs_iterator::leave( Cell* cell )
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     // First get the last item of the list
02460 
02461     dfs_iterator_data lastIt = _deque.front();
02462 
02463     if( !lastIt._entered )
02464     {
02465         // Mark it entered
02466         _deque.front()._entered = true;
02467 
02468         //
02469         // First push its children
02470         //
02471         if( !lastIt._cell->isLeaf() )
02472         {
02473             // Then push our children
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             // Call the enter function
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         // We have made all our children so call the leave function if needed
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 // template<class T, class S, class U>
02523 // class FastOctree<T,S,U>::dfs_leaf_iterator
02524 // {
02525 //  public:
02526 //      dfs_leaf_iterator( Cell*, void (*workF)(Cell*)=NULL );
02527 //      virtual ~dfs_leaf_iterator();
02528 //
02529 //      Cell* operator++();
02530 //      bool empty();
02531 //
02532 //      Cell* operator*();
02533 //
02534 //  protected:
02535 //      // What to do with a node
02536 //      virtual void work(Cell*){};
02537 //
02538 //
02539 //  private:
02540 //      void (*_workF)(Cell*);
02541 //
02542 //      std::deque<dfs_iterator_data> _deque;
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     // First get the last item of the list
02578 
02579     dfs_iterator_data lastIt = _deque.front();
02580 
02581     if( !lastIt._entered )
02582     {
02583         // Mark it entered
02584         _deque.front()._entered = true;
02585 
02586         //
02587         // First push its children
02588         //
02589         if( !lastIt._cell->isLeaf() )
02590         {
02591             // Then push our children
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             // Call the enter function
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     //cerr<<"FastOctree<T,S,U>::Cell::vertex_iterator::vertex_iterator, searching next vertex"<<endl;
02632     _nextVertex = next_vertex();
02633 /*    if( !_nextVertex )
02634         cerr<<"FastOctree<T,S,U>::Cell::vertex_iterator::vertex_iterator, no vertex"<<endl;*/
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         //cerr<<"FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() a"<<endl;
02657         while( _currentVertexNumber<8 && _currentCell->vertex(_currentVertexNumber)->getMainCell()!=_currentCell )
02658         {
02659             _currentVertexNumber++;
02660             //cerr<<"FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() b"<<endl;
02661         }
02662         if( _currentVertexNumber<8 ) // found a vertex
02663         {
02664             //cerr<<"FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() c"<<endl;
02665             found = _currentCell->vertex(_currentVertexNumber);
02666             //cerr<<"FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() found vertex number "<< _currentVertexNumber << endl;
02667             _currentVertexNumber++;
02668         }
02669         else // we must go to the next cell
02670         {
02671             _currentCell = dfs_iterator::operator ++();
02672             _currentCell = dfs_iterator::operator ++();
02673             _currentVertexNumber = 0;
02674             //cerr<<"FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() change cell ------- "<<endl;
02675         }
02676     }
02677     //cerr<<"------- FastOctree<T,S,U>::Vertex* FastOctree<T,S,U>::Cell::vertex_iterator::next_vertex() in cell "; _currentCell->printPos(cerr); cerr<<endl;
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             // Then add it to the other list and to the set
02712             _vLists[(_topListId+1)%2].push_back( res->child(i) );
02713             _insertedList.insert( res->child(i) );
02714         }
02715     }
02716 
02717     if( empty() )
02718     {
02719         // Switch to the (possibly empty) other list
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                 // Find the corresponding vertex in this new cell
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     for( unsigned short i=0 ; i < vertex->nConnectedCells() ; ++i )
02789     {
02790         Cell *connectedCell = vertex->connectedCell( i );
02791         if( connectedCell->getData()._depth == depth )
02792         {
02793             // Find the corresponding vertex in this new cell
02794             unsigned short child;
02795             for( child=0 ; child<8 ; ++child )
02796             {
02797                 if( connectedCell->vertex(child) == vertex )
02798                 {
02799                     _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][0] ) );
02800                     _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][1] ) );
02801                     _vLists[_topListId].push_back( connectedCell->vertex( Cell::connectedVertices[child][2] ) );
02802                     break;
02803                 }
02804             }
02805             Require( child != 8 );
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             // Then add it to the other list and to the set
02827             _vLists[(_topListId+1)%2].push_back( res->child(i) );
02828             _insertedList.insert( res->child(i) );
02829         }
02830     }
02831 
02832     if( empty() )
02833     {
02834         // Switch to the (possibly empty) other list
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 // Lookup tables
02883 //************************************************************
02884 /*
02885  * hasBrotherAlongFace[b][f] is true if child number \p b of a cell
02886  * has a brother along its face number \p f. Use along_face to find the
02887  * index of such brother.
02888  * Table is checked.
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  * hasBrotherAlongEdge[b][e] is true if child number \p b of a cell
02907  * has a brother along its edge number \p e.
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  * alongFace[b][f] returns the child number of the brother of child \p b
02926  * of a cell along face number \p f.  If such a brother would not exist
02927  * (indicated by hasBrotherAlongFace[b][f] being false), it has the value
02928  * of the brother along the face parallel to f for which a brother exists
02929  * (there is always one).
02930  * Table is checked.
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  * alongEdge[b][e] returns the child number of the brother of child \p b
02949  * of a cell along edge number \p e.  If such a brother would not exist
02950  * (indicated by hasBrotherAlongEdge[b][e] being false), it has the value
02951  * of the brother along the edge parallel to e for which a brother exists
02952  * (there is alwyas one).
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  * alterEgoFace[f] is the index of the face number \p f of a cell C in the
02971  * cell sharing this face with cell C.
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  * supportingFace[c][e] is the number of the cell's face (if any)
02981  * that contains edge \p e of child number \p c.
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  * hasOnFatherEdge[c][e] is true if child \p c of a cell shares
03000  * edge \p e with its father (actually half the one of its father).
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  * childrenSharingFace[f] are the indexes of the 4 children
03019  * that lies along face \p f.
03020  * Warning : each cell id corresponds with an alterego face, meaning :
03021  * childrenSharingFace[0][i] <=> childrenSharingFace[1][i] in the neighbouring cell !
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 }, // 0
03028         { 1,3,5,7 }, // 1
03029         { 0,1,4,5 }, // 2
03030         { 2,3,6,7 }, // 3
03031         { 0,1,2,3 }, // 4
03032         { 4,5,6,7 }  // 5
03033     };
03034 /*
03035  * faceVertices[f] are the 4 vertices that composes face \p f
03036  * (in such order as the normal points outward the cell.
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 /* From Mathieu :
03053  * faceAlongEdge[e] are the 2 faces which are sharing the
03054  * edge \p e.
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}, // 0
03061         {3,4}, // 1
03062         {2,5}, // 2
03063         {3,5}, // 3
03064         {0,4}, // 4
03065         {0,5}, // 5
03066         {1,4}, // 6
03067         {1,5}, // 7
03068         {0,2}, // 8
03069         {1,2}, // 9
03070         {0,3}, // 10
03071         {1,3}  // 11
03072     };
03073 
03074 /* From Mathieu :
03075  * For each vertex, give us the id of the vertices with whom we're sharing an edge
03076  * This list is ordered so that the first vertex is the one that don't depend on x, the second on y, third on z
03077  * X is given by P1-P0, Y by P2-P0 and Z by P4-P0 
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 /* From Mathieu :
03096  * For each vertex, give us the id of the faces connected
03097  * This list is ordered so that the first face is the one that don't depend on x, the second on y, third on z
03098  * X is given by P1-P0, Y by P2-P0 and Z by P4-P0
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

Generated on Thu Dec 23 13:52:25 2004 by doxygen 1.3.6