shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/octree_node.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a g i x
00003  *****************************************************************************
00004  * Node
00005  * 2008-03-21
00006  * Julien Wintz
00007  *****************************************************************************
00008  *               Copyright (C) 2006 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 
00013 # ifndef shape_octree_node_hpp
00014 # define shape_octree_node_hpp
00015 
00016 # include <iostream>
00017 # include <list>
00018 # include <shape/cell.hpp>
00019 # define Node octree_node<Object, CELL>
00020 //====================================================================
00021 namespace mmx {
00022 namespace shape {
00023 
00024 template <class Object, class CELL> class octree_node
00025 {
00026 public:
00027     enum FACE_TYPE { B, F, W, E, S, N } ;
00028     enum NODE_TYPE { B_SW, F_SW, B_SE, F_SE, B_NW, F_NW, B_NE, F_NE } ;
00029     enum EDGE_TYPE { B_E, B_W, B_S, B_N, F_E, F_W, F_S, F_N, S_E, N_E, S_W, N_W } ; 
00030 
00031 public:
00032     octree_node(void) ;
00033     octree_node(Object object, CELL cl) ;
00034     octree_node(NODE_TYPE nodeType, Node * parent, CELL & cl) ;
00035     octree_node(Node * left, Node * right, CELL cl) ;
00036 
00037 protected:
00038     octree_node(Node& node) ;
00039 
00040 public:    
00041     inline void setCell(const CELL & c) { m_cell = c ; }
00042     
00043     inline void setParent(Node * n) { m_parent = n ; }
00044     
00045     inline void setFNEchild(Node * n) { F_NEchild = n ; }
00046     inline void setFNWchild(Node * n) { F_NWchild = n ; }
00047     inline void setFSEchild(Node * n) { F_SEchild = n ; }
00048     inline void setFSWchild(Node * n) { F_SWchild = n ; } 
00049     
00050     inline void setBNEchild(Node * n) { B_NEchild = n ; } 
00051     inline void setBNWchild(Node * n) { B_NWchild = n ; } 
00052     inline void setBSEchild(Node * n) { B_SEchild = n ; } 
00053     inline void setBSWchild(Node * n) { B_SWchild = n ; } 
00054   
00055                 inline const CELL& get_cell(void) const { return m_cell; } 
00056     inline CELL & get_cell(void) { return m_cell ; }
00057 
00058 
00059     inline Object object(void) { return m_objects.front() ; }
00060 
00061     inline NODE_TYPE type(void) { return m_type ; }
00062     
00063     inline Node * FNEchild(void) { return F_NEchild ; }
00064     inline Node * FNWchild(void) { return F_NWchild ; }
00065     inline Node * FSEchild(void) { return F_SEchild ; }
00066     inline Node * FSWchild(void) { return F_SWchild ; } 
00067     
00068     inline Node * BNEchild(void) { return B_NEchild ; } 
00069     inline Node * BNWchild(void) { return B_NWchild ; } 
00070     inline Node * BSEchild(void) { return B_SEchild ; } 
00071     inline Node * BSWchild(void) { return B_SWchild ; }
00072 
00073     inline Node *  left(void) { return F_NWchild ; }
00074     inline Node * right(void) { return F_NEchild ; }
00075     
00076                 bool isLeaf(void) const;
00077                 size_t leafDistance() const;
00078 
00079 public:   
00080     CELL              m_cell ;
00081     std::list<Object> m_objects ;
00082     NODE_TYPE         m_type ;
00083     
00084     Node * m_parent  ;   
00085     Node * F_NEchild ; 
00086     Node * F_NWchild ;
00087     Node * F_SEchild ;
00088     Node * F_SWchild ;
00089     Node * B_NEchild ;
00090     Node * B_NWchild ; 
00091     Node * B_SEchild ; 
00092     Node * B_SWchild ; 
00093     
00094     int depth ;
00095     int index ;
00096 } ;
00097 
00098 //--------------------------------------------------------------------
00099 template<class Object, class CELL> Node::octree_node(void)
00100 { 
00101     m_type   = F_NE ;
00102     m_parent = NULL ;
00103     m_cell   = NULL ;
00104 
00105     F_NEchild = NULL ; F_NWchild = NULL ; F_SEchild = NULL ; F_SWchild = NULL ;
00106     B_NEchild = NULL ; B_NWchild = NULL ; B_SEchild = NULL ; B_SWchild = NULL ;
00107 
00108     depth = 0;
00109     index = 0;
00110 } 
00111 
00112 template<class Object, class CELL> Node::octree_node(Object object, CELL cl)
00113 { 
00114     this->m_type   = F_NE ;
00115     this->m_parent = NULL ;
00116     this->m_cell   = cl ;
00117     m_objects.push_back(object) ;
00118 
00119     F_NEchild = NULL ; F_NWchild = NULL ; F_SEchild = NULL ; F_SWchild = NULL;
00120     B_NEchild = NULL ; B_NWchild = NULL ; B_SEchild = NULL ; B_SWchild = NULL;
00121 
00122     depth = 0;
00123     index = 0;
00124 } 
00125 
00126 template <class Object, class CELL> Node::octree_node(Node * left, Node * right, CELL cl)
00127 {
00128     this->m_parent = NULL ;
00129     this->m_cell   = cl ;
00130 
00131     left->type  = F_NW ;  left->parent = this ; F_NWchild =  left ;
00132     right->type = F_NE ; right->parent = this ; F_NEchild = right ;
00133 
00134     F_NWchild = left  ; F_SWchild = NULL ;
00135     F_NEchild = right ; F_SEchild = NULL ;
00136     B_NEchild = NULL  ; B_NWchild = NULL ; 
00137     B_SEchild = NULL  ; B_SWchild = NULL ;
00138 
00139     depth = left->depth-1 ;
00140 }
00141 
00142 template <class Object, class CELL> Node::octree_node(NODE_TYPE type, Node * parent, CELL & cl)
00143 {  
00144     this->m_cell = cl ;
00145     this->m_type = type ; 
00146     this->m_parent = parent ;
00147 
00148     F_NEchild = NULL ; F_NWchild = NULL ; 
00149     F_SEchild = NULL ; F_SWchild = NULL ; 
00150     B_NEchild = NULL ; B_NWchild = NULL ; 
00151     B_SEchild = NULL ; B_SWchild = NULL ; 
00152 
00153     depth = parent->depth+1 ;
00154 
00155     switch(type) { 
00156     case F_NE: parent->setFNEchild(this) ; break ; 
00157     case F_NW: parent->setFNWchild(this) ; break ; 
00158     case F_SW: parent->setFSWchild(this) ; break ; 
00159     case F_SE: parent->setFSEchild(this) ; break ;
00160     case B_NE: parent->setBNEchild(this) ; break ;  
00161     case B_NW: parent->setBNWchild(this) ; break ;  
00162     case B_SW: parent->setBSWchild(this) ; break ;  
00163     case B_SE: parent->setBSEchild(this) ; break ; 
00164     default: std::cerr << "Error : the node's type isn't appropriate \n" ; break ;
00165     }
00166 }
00167 
00168 template<class Object, class CELL> bool Node::isLeaf(void) const
00169 {
00170     if((F_NEchild == NULL) && (F_NWchild == NULL) &&
00171        (F_SEchild == NULL) && (F_SWchild == NULL) && 
00172        (B_NEchild == NULL) && (B_NWchild == NULL) &&
00173        (B_SEchild == NULL) && (B_SWchild == NULL) )
00174         return true; 
00175     return false; 
00176 } 
00177 
00178 template<class Object, class CELL> size_t Node::leafDistance(void) const
00179 {
00180         if ( this->isLeaf() )
00181                 return 0;
00182 
00183         struct inner {
00184                 size_t operator()( const Node* node ) {
00185                         if ( node == 0 )
00186                                 return 0;
00187                         else
00188                                 return node->leafDistance();
00189                 }
00190         } I;
00191 
00192         size_t d = 0;
00193         d = std::min( d, I(B_NEchild) );
00194         d = std::min( d, I(B_NWchild) );
00195         d = std::min( d, I(B_SEchild) );
00196         d = std::min( d, I(B_SWchild) );
00197         d = std::min( d, I(F_NEchild) );
00198         d = std::min( d, I(F_NWchild) );
00199         d = std::min( d, I(F_SEchild) );
00200         d = std::min( d, I(F_SWchild) );
00201 
00202         return d+1;
00203 }
00204 
00205 
00206 } ; // namespace shape
00207 } ; // namespace mmx
00208 //====================================================================
00209 # undef Node
00210 # endif // NODE_H