28 #ifndef pddgeom_OctTree_hpp
29 #define pddgeom_OctTree_hpp
33 #include <util/Basics.hpp>
34 #include <util/SimpleArrayOps.hpp>
44 ostream & operator << ( ostream & ,
const phdmesh::OctTreeKey & );
52 typedef unsigned value_type ;
53 enum { MaxDepth = 16 };
54 enum { MaskIndex = 0x0f };
55 enum { BitsPerIndex = 4 };
56 enum { BitsPerWord = std::numeric_limits<value_type>::digits };
57 enum { IndexPerWord = BitsPerWord / BitsPerIndex };
58 enum { NWord = MaxDepth / IndexPerWord };
59 enum { OKBits = StaticAssert< 0 == BitsPerWord % BitsPerIndex >::OK };
60 enum { OKWord = StaticAssert< 0 == MaxDepth % IndexPerWord >::OK };
62 value_type m_value[ NWord ];
66 { Copy<NWord>( m_value , 0u ); }
68 OctTreeKey(
const OctTreeKey & k )
69 { Copy<NWord>( m_value , k.m_value ); }
71 OctTreeKey & operator = (
const OctTreeKey & k )
72 { Copy<NWord>( m_value , k.m_value );
return *this ; }
74 bool operator == (
const OctTreeKey & k )
const
75 {
return Equal<NWord>( m_value , k.m_value ); }
77 bool operator != (
const OctTreeKey & k )
const
78 {
return Equal<NWord>( m_value , k.m_value ); }
80 bool operator < (
const OctTreeKey & k )
const
81 {
return Less<NWord>( m_value , k.m_value ); }
84 unsigned depth()
const ;
89 template<
unsigned Depth>
unsigned index()
const ;
92 unsigned index(
const unsigned Depth )
const ;
95 template<
unsigned D> OctTreeKey & clear_index() ;
98 OctTreeKey & clear_index(
const unsigned Depth );
101 template<
unsigned D> OctTreeKey & set_index(
const unsigned );
104 OctTreeKey & set_index(
const unsigned Depth ,
const unsigned );
107 OctTreeKey & clear();
110 OctTreeKey & set_maximum();
113 const value_type * value()
const {
return m_value ; }
116 OctTreeKey & set_value(
const value_type * );
119 bool intersect(
const OctTreeKey & k )
const ;
122 void throw_depth(
const unsigned )
const ;
123 void throw_index(
const unsigned ,
const unsigned )
const ;
130 OctTreeKey
hsfc3d(
const unsigned Depth ,
const unsigned *
const coord );
135 template<
unsigned Depth>
struct OctTreeSize ;
138 struct OctTreeSize<0>
139 {
enum { value = 1 }; };
141 template<
unsigned Depth>
144 enum { MaxDepth = 10 , N = Depth };
146 enum { OK = StaticAssert< N <= MaxDepth >::OK };
148 enum { value = 1 + 8 * OctTreeSize<Depth-1>::value };
151 unsigned oct_tree_size(
const unsigned Depth );
156 template<
unsigned Depth>
168 template<
unsigned Depth>
170 unsigned OctTreeKey::index()
const
172 enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
173 enum { which = ( Depth - 1 ) / IndexPerWord };
174 enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
176 return ( m_value[ which ] >> shift ) & MaskIndex ;
179 template<
unsigned Depth>
181 OctTreeKey & OctTreeKey::clear_index()
183 enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
184 enum { which = ( Depth - 1 ) / IndexPerWord };
185 enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
187 const value_type m = MaskIndex ;
189 m_value[ which ] &= ~( m << shift );
194 template<
unsigned Depth>
196 OctTreeKey & OctTreeKey::set_index(
const unsigned Index )
198 enum { OK = StaticAssert< 0 < Depth && Depth <= MaxDepth >::OK };
199 enum { which = ( Depth - 1 ) / IndexPerWord };
200 enum { shift = BitsPerWord - BitsPerIndex * ( Depth % IndexPerWord ) };
202 if ( 8 < Index ) { throw_index( Depth , Index ); }
204 const value_type m = MaskIndex ;
206 ( m_value[which] &= ~( m << shift ) ) |= Index << shift ;
OctTreeKey hsfc3d(const unsigned Depth, const unsigned *const coord)
unsigned oct_tree_offset(const unsigned Depth, const OctTreeKey &)