00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 # ifndef shape_octree_node_hpp
00014 # define shape_octree_node_hpp
00015
00016 # include <iostream>
00017 # include <list>
00018 # include <shape/bcell.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 } ;
00207 } ;
00208
00209 # undef Node
00210 # endif // NODE_H