1 //:
2 // \file
3 #include <algorithm>
4 #include <cstring>
5 #include <iostream>
6 #include <list>
7 #include "boct_bit_tree.h"
8 #include "boct_tree_cell.h"
9 
10 //: copy constructor
boct_bit_tree(const boct_bit_tree & other)11 boct_bit_tree::boct_bit_tree(const boct_bit_tree &other)
12     : is_owning_(other.is_owning_), num_levels_(other.num_levels_) {
13   if (this->is_owning_) {
14     bits_ = new unsigned char[16];
15     std::memcpy(bits_, other.get_bits(), 16);
16   } else {
17     bits_ = other.bits_;
18   }
19 }
20 
21 //: constructor from an array of char bits
boct_bit_tree(const unsigned char * bits,int num_levels)22 boct_bit_tree::boct_bit_tree(const unsigned char *bits, int num_levels)
23     : is_owning_(true) {
24   bits_ = new unsigned char[16];
25 
26   // initialize num levels, bits
27   num_levels_ = std::min(4, num_levels);
28 
29   // copy 16 bytes
30   std::memcpy(bits_, bits, 16);
31 
32   ////zero out bits to start
33   // for (int i=0;i<16; i++)
34   // bits_[i] = bits[i];
35 }
36 
37 // Copy assignment operator
operator =(boct_bit_tree that)38 boct_bit_tree &boct_bit_tree::operator=(boct_bit_tree that) {
39   // swap members so 'that' can be safely destroyed
40   std::swap(this->bits_, that.bits_);
41   std::swap(this->is_owning_, that.is_owning_);
42   std::swap(this->num_levels_, that.num_levels_);
43 
44   // If is_owning, replace `that`s buffer with a copy
45   if (this->is_owning_) {
46     auto *new_bits = new unsigned char[16];
47     std::memcpy(new_bits, this->bits_, 16);
48     this->bits_ = new_bits;
49   }
50   // Don't destroy old buffer in case of "self assignment" (i.e assignment when
51   // both trees point to same buffer).
52   if (this->bits_ == that.bits_) {
53     that.is_owning_ = false;
54   }
55   return *this;
56 }
57 
traverse(const vgl_point_3d<double> p,int deepest,bool full)58 int boct_bit_tree::traverse(const vgl_point_3d<double> p, int deepest, bool full) {
59   // deepest level to traverse is either
60   deepest = std::max(deepest - 1, num_levels_ - 1);
61 
62   // force 1 register: curr = (bit, child_offset, depth, c_offset)
63   int curr_bit = (int)(bits_[0]);
64   int child_offset = 0;
65   int depth = 0;
66 
67   // bit index to be returned
68   int bit_index = 0;
69 
70   // clamp point
71   double pointx = p.x(); // clamp(p.x(), 0.0001f, 0.9999f);
72   double pointy = p.y(); // clamp(p.y(), 0.0001f, 0.9999f);
73   double pointz = p.z(); // clamp(p.z(), 0.0001f, 0.9999f);
74 
75   // while the curr node has children
76   while ((curr_bit || full) && (depth < deepest)) {
77     // determine child offset and bit index for given point
78     pointx += pointx; // point = point*2
79     pointy += pointy;
80     pointz += pointz;
81     int codex = ((int)std::floor(pointx)) & 1;
82     int codey = ((int)std::floor(pointy)) & 1;
83     int codez = ((int)std::floor(pointz)) & 1;
84 
85     int c_index = codex + (codey << 1) + (codez << 2); // c_index = binary(zyx)
86     bit_index = (8 * bit_index + 1) + c_index;         // i = 8i + 1 + c_index
87 
88     // update value of curr_bit and level
89     curr_bit = (1 << c_index) &
90                bits_[(depth + 1 +
91                       child_offset)]; // int curr_byte = (curr.z + 1) + curr.y;
92     child_offset = c_index;
93     depth++;
94   }
95   return bit_index;
96 }
97 
traverse_to_level(const vgl_point_3d<double> p,int deepest)98 int boct_bit_tree::traverse_to_level(const vgl_point_3d<double> p,
99                                      int deepest) {
100   // deepest level to traverse is either
101   deepest = std::min(deepest - 1, num_levels_ - 1);
102 
103   // force 1 register: curr = (bit, child_offset, depth, c_offset)
104   int curr_bit = (int)(bits_[0]);
105   int child_offset = 0;
106   int depth = 0;
107 
108   // bit index to be returned
109   int bit_index = 0;
110 
111   // clamp point
112   double pointx = p.x(); // clamp(p.x(), 0.0001f, 0.9999f);
113   double pointy = p.y(); // clamp(p.y(), 0.0001f, 0.9999f);
114   double pointz = p.z(); // clamp(p.z(), 0.0001f, 0.9999f);
115 
116   // while the curr node has children
117   while (curr_bit && depth < deepest) {
118     // determine child offset and bit index for given point
119     pointx += pointx; // point = point*2
120     pointy += pointy;
121     pointz += pointz;
122     int codex = ((int)std::floor(pointx)) & 1;
123     int codey = ((int)std::floor(pointy)) & 1;
124     int codez = ((int)std::floor(pointz)) & 1;
125 
126     int c_index = codex + (codey << 1) + (codez << 2); // c_index = binary(zyx)
127     bit_index = (8 * bit_index + 1) + c_index;         // i = 8i + 1 + c_index
128 
129     // update value of curr_bit and level
130     curr_bit = (1 << c_index) &
131                bits_[(depth + 1 +
132                       child_offset)]; // int curr_byte = (curr.z + 1) + curr.y;
133     child_offset = c_index;
134     depth++;
135   }
136   return bit_index;
137 }
cell_center(int bit_index)138 vgl_point_3d<double> boct_bit_tree::cell_center(int bit_index) {
139   // Indexes into precomputed cell_center matrix
140   return {
141       centerX[bit_index], centerY[bit_index], centerZ[bit_index]};
142 }
143 
144 //: Cell bounding box given bit_index, tree origin and tree len
145 vgl_box_3d<double>
cell_box(int bit_index,vgl_point_3d<double> orig,double len)146 boct_bit_tree::cell_box(int bit_index, vgl_point_3d<double> orig, double len) {
147   double half_len = cell_len(bit_index) / 2.0;
148   return {orig.x() + len * (centerX[bit_index] - half_len),
149                             orig.y() + len * (centerY[bit_index] - half_len),
150                             orig.z() + len * (centerZ[bit_index] - half_len),
151                             orig.x() + len * (centerX[bit_index] + half_len),
152                             orig.y() + len * (centerY[bit_index] + half_len),
153                             orig.z() + len * (centerZ[bit_index] + half_len)};
154 }
155 
cell_len(int bit_index) const156 double boct_bit_tree::cell_len(int bit_index) const {
157   if (bit_index == 0)
158     return 1.0;
159   else if (bit_index < 9)
160     return .5;
161   else if (bit_index < 73)
162     return .25;
163   else
164     return .125;
165 }
166 
valid_cell(int bit_index) const167 bool boct_bit_tree::valid_cell(int bit_index) const {
168   return (bit_index == 0) || this->bit_at((bit_index - 1) >> 3);
169 }
170 
is_leaf(int bit_index) const171 bool boct_bit_tree::is_leaf(int bit_index) const {
172   return this->valid_cell(bit_index) && (this->bit_at(bit_index) == 0);
173 }
174 
175 // returns bit indices of all tree nodes under rootBit
get_cell_bits(int rootBit) const176 std::vector<int> boct_bit_tree::get_cell_bits(int rootBit) const {
177   // use num cells to accelerate (cut off for loop)
178   std::vector<int> leafBits;
179 
180   // special root case
181   if (bits_[0] == 0 && rootBit == 0) {
182     leafBits.push_back(0);
183     return leafBits;
184   }
185 
186   // otherwise calc list of bit indices in the subtree of rootBIT, and then
187   // verify leaves
188   std::vector<int> subTree;
189   std::list<unsigned> toVisit;
190   toVisit.push_back(rootBit);
191   while (!toVisit.empty()) {
192     int currBitIndex = toVisit.front();
193     toVisit.pop_front();
194 
195     subTree.push_back(currBitIndex);
196 
197     if (!this->is_leaf(currBitIndex)) { // add children to the visit list
198       unsigned firstChild = 8 * currBitIndex + 1;
199       for (int ci = 0; ci < 8; ++ci)
200         toVisit.push_back(firstChild + ci);
201     }
202   }
203   return subTree;
204 }
205 
206 // returns bit indices of leaf nodes under rootBit
get_leaf_bits(int rootBit) const207 std::vector<int> boct_bit_tree::get_leaf_bits(int rootBit) const {
208   // use num cells to accelerate (cut off for loop)
209   std::vector<int> leafBits;
210 
211   // special root case
212   if (bits_[0] == 0 && rootBit == 0) {
213     leafBits.push_back(0);
214     return leafBits;
215   }
216 
217   // otherwise calc list of bit indices in the subtree of rootBIT, and then
218   // verify leaves
219   std::vector<int> subTree;
220   std::list<unsigned> toVisit;
221   toVisit.push_back(rootBit);
222   while (!toVisit.empty()) {
223     int currBitIndex = toVisit.front();
224     toVisit.pop_front();
225     if (this->is_leaf(currBitIndex)) {
226       subTree.push_back(currBitIndex);
227     } else { // add children to the visit list
228       unsigned firstChild = 8 * currBitIndex + 1;
229       for (int ci = 0; ci < 8; ++ci)
230         toVisit.push_back(firstChild + ci);
231     }
232   }
233   return subTree;
234 }
235 // returns bit indices of leaf nodes or nodes at the depth mentioned whichever
236 // comes first under rootBit
get_leaf_bits(int rootBit,int depth) const237 std::vector<int> boct_bit_tree::get_leaf_bits(int rootBit, int depth) const {
238   // use num cells to accelerate (cut off for loop)
239   std::vector<int> leafBits;
240   int curr_depth = 0;
241   // special root case
242   if (bits_[0] == 0 && rootBit == 0) {
243     leafBits.push_back(0);
244     return leafBits;
245   }
246 
247   // otherwise calc list of bit indices in the subtree of rootBIT, and then
248   // verify leaves
249   std::vector<int> subTree;
250   std::list<unsigned> toVisit;
251   toVisit.push_back(rootBit);
252   while (!toVisit.empty()) {
253     int currBitIndex = toVisit.front();
254     toVisit.pop_front();
255     if ((this->depth_at(currBitIndex) < depth && this->is_leaf(currBitIndex)) ||
256         this->depth_at(currBitIndex) == depth) {
257       subTree.push_back(currBitIndex);
258     } else { // add children to the visit list
259       curr_depth++;
260       unsigned firstChild = 8 * currBitIndex + 1;
261       for (int ci = 0; ci < 8; ++ci)
262         toVisit.push_back(firstChild + ci);
263     }
264   }
265 
266   return subTree;
267 }
268 //: Return cell with a particular locational code
get_data_index(int bit_index,bool is_random) const269 int boct_bit_tree::get_data_index(int bit_index, bool is_random) const {
270   ////Unpack data offset (offset to root data)
271   // tree[10] and [11] should form the short that refers to data offset
272   // root and first gen are special case, return just the root offset +
273   // bit_index
274 
275   int count_offset;
276   if (is_random)
277     count_offset = (int)bits_[10] * 256 + (int)bits_[11];
278   else
279     count_offset = (int)(bits_[13] << 24) | (bits_[12] << 16) |
280                    (bits_[11] << 8) | (bits_[10]);
281 
282   return count_offset + this->get_relative_index(bit_index);
283 }
284 
285 //: returns bit index assuming root data is located at 0
get_relative_index(int bit_index) const286 int boct_bit_tree::get_relative_index(int bit_index) const {
287   if (bit_index < 9)
288     return bit_index;
289 
290   // otherwise get parent index, parent byte index and relative bit index
291   unsigned char oneuplevel = (bit_index - 1) >> 3; // bit index of parent
292   unsigned char byte_index =
293       ((oneuplevel - 1) >> 3) + 1; // byte where parent is found
294 
295   // count pre parent bits
296   int count = 0;
297   for (int i = 0; i < byte_index; ++i)
298     count += bit_lookup[bits_[i]];
299 
300   // dont forget parent bits occurring the parent BYTE
301   unsigned char sub_bit_index = 8 - ((oneuplevel - 1) & (8 - 1));
302   unsigned char temp = bits_[byte_index] << sub_bit_index;
303 
304   count = count + bit_lookup[temp];
305   unsigned char finestleveloffset = (bit_index - 1) & (8 - 1);
306   count = 8 * count + 1 + finestleveloffset;
307 
308   return count;
309 }
310 
311 //: return number of cells in this tree (size of data chunk)
num_cells() const312 int boct_bit_tree::num_cells() const {
313   // count bits for each byte
314   int count = 0;
315   for (int i = 0; i < 10; i++) {
316     unsigned char n = bits_[i];
317     while (n) {
318       ++count;
319       n &= (n - 1);
320     }
321   }
322   return 8 * count + 1;
323 }
324 
325 // returns the number of leaf cells
num_leaves() const326 int boct_bit_tree::num_leaves() const { return get_leaf_bits(0).size(); }
327 
328 //----BIT MANIP Methods -----------------------------------------------
bit_at(int index) const329 unsigned char boct_bit_tree::bit_at(int index) const {
330   // make sure it's in bounds - all higher cells are leaves and thus 0
331   if (index > 72)
332     return 0;
333 
334   // root is special case
335   if (index == 0)
336     return bits_[0];
337 
338   // second generation is sort of a special case
339   if (index < 9)
340     return (1 << (index - 1) & bits_[1]) ? 1 : 0;
341 
342   int i = (index - 9) / 8 + 2; // byte index i
343   int bi = (index - 9) % 8;
344   return (1 << bi & bits_[i]) ? 1 : 0;
345 }
346 
set_bit_at(int index,bool val)347 void boct_bit_tree::set_bit_at(int index, bool val) {
348   if (index > 72) {
349     std::cerr << "No bit above 72, bad set call!\n";
350     return;
351   }
352 
353   // zero is a special case,
354   if (index == 0)
355     bits_[0] = (val) ? 1 : 0;
356 
357   int byte_index = (index - 1) / 8 + 1;
358   int child_offset = (index - 1) % 8;
359   unsigned char mask = 1 << child_offset;
360   unsigned char byte = bits_[byte_index];
361   bits_[byte_index] = (val) ? (byte | mask) : (byte & (mask ^ 0xFF));
362 }
363 
set_bit_and_parents_to_true(int index)364 void boct_bit_tree::set_bit_and_parents_to_true(int index) {
365   while (index > 0) {
366     this->set_bit_at(index, true);
367     index = parent_index(index);
368   }
369   this->set_bit_at(0, true);
370 }
371 
372 // A local implementation for floor(log(a)/log(8)) with integer argument a;
373 // this is a more straightforward (and not too inefficient) alternative for
374 //  std::floor(std::log(double a)/std::log(8.0)).
375 // Negative arguments make of course no sense; strictly speaking, also a=0
376 // makes no sense, but in that case a "very negative" value is returned.
int_log8(unsigned int a)377 inline static int int_log8(unsigned int a) {
378   if (a == 0)
379     return -0x7FFFFFFFL - 1L; // stands for minus infinity
380   int r = 0;
381   while (a >= 8)
382     ++r, a >>= 3; // divide by 8
383   return r;
384 }
385 
386 // A local (and recursive) implementation for a^b with a and b both integer;
387 // this is a more accurate alternative for std::pow(double a,double b),
388 // certainly in those cases where b is relatively small.
int_pow8(unsigned int b)389 inline static long int_pow8(unsigned int b) {
390   if (b == 0)
391     return 1;
392   return 1L << (3 * b);
393 }
394 
max_num_cells()395 int boct_bit_tree::max_num_cells() {
396   return int((int_pow8(num_levels_ + 1) - 1.0) / 7.0);
397 }
398 
max_num_inner_cells()399 int boct_bit_tree::max_num_inner_cells() {
400   return int((int_pow8(num_levels_) - 1.0) / 7.0);
401 }
402 
depth_at(int index) const403 int boct_bit_tree::depth_at(int index) const { return int_log8(7 * index + 1); }
404 
depth()405 int boct_bit_tree::depth() {
406 
407   int max_depth = 3;
408   int tree_depth = 0;
409   std::list<unsigned> toVisit; // maintain a queue of nodes and
410   std::list<int> visit_depth;  // node depth
411   toVisit.push_back(0);
412   visit_depth.push_back(0);
413   while (!toVisit.empty()) {
414     int currBitIndex = toVisit.front();
415     int currDepth = visit_depth.front();
416     if (currDepth > tree_depth) { // cut search if max depth is reached.
417       tree_depth = currDepth;
418       if (tree_depth == max_depth)
419         return tree_depth;
420     }
421     toVisit.pop_front();
422     visit_depth.pop_front();
423     if (!this->is_leaf(currBitIndex)) {
424       unsigned firstChild = 8 * currBitIndex + 1;
425       for (int ci = 0; ci < 8; ++ci) {
426         int cind = firstChild + ci;
427         toVisit.push_back(cind);
428         visit_depth.push_back(depth_at(cind));
429       }
430     }
431   }
432   return tree_depth;
433 }
434 #if 0
435 //: gets and sets buffer pointers (located at bytes 12 and 13
436 int boct_bit_tree::get_buffer_ptr()
437 {
438   unsigned char hi = this->bits_[12];
439   unsigned char lo = this->bits_[13];
440   unsigned short value = (unsigned short) ((hi << 8) | lo);
441   return int(value);
442 }
443 
444 int boct_bit_tree::set_buffer_ptr(int ptr)
445 {
446   unsigned char hi = (unsigned char)(ptr >> 8);
447   unsigned char lo = (unsigned char)(ptr & 255);
448   this->bits_[12] = hi;
449   this->bits_[13] = lo;
450   return  0;
451 }
452 #endif // 0
453 
get_data_ptr(bool is_random)454 int boct_bit_tree::get_data_ptr(bool is_random) {
455   if (is_random) {
456     unsigned char hi = this->bits_[10];
457     unsigned char lo = this->bits_[11];
458     auto value = (unsigned short)((hi << 8) | lo);
459     return int(value);
460   } else {
461     return int((bits_[13] << 24) | (bits_[12] << 16) | (bits_[11] << 8) |
462                (bits_[10]));
463   }
464 }
465 
set_data_ptr(int ptr,bool is_random)466 void boct_bit_tree::set_data_ptr(int ptr, bool is_random) {
467   if (is_random) {
468     auto hi = (unsigned char)(ptr >> 8);
469     auto lo = (unsigned char)(ptr & 255);
470     this->bits_[10] = hi;
471     this->bits_[11] = lo;
472   } else {
473     this->bits_[10] = (ptr)&0xff;
474     this->bits_[11] = (ptr >> 8) & 0xff;
475     this->bits_[12] = (ptr >> 16) & 0xff;
476     this->bits_[13] = (ptr >> 24) & 0xff;
477   }
478 }
479 
480 
wrap_const(const uchar16 & data,int num_levels)481 const boct_bit_tree boct_bit_tree::wrap_const(const uchar16 &data, int num_levels) {
482   // (uchar16 &bits, int num_levels = 4)
483   return boct_bit_tree(const_cast<uchar16 &>(data), num_levels);
484 }
485 
486 
487 unsigned char boct_bit_tree::bit_lookup[] = {
488     0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
489     2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
490     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
491     2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
492     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
493     4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
494     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
495     3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
496     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
497     4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
498     4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
499 
500 float boct_bit_tree::centerX[] = {
501     0.5,    0.25,   0.75,   0.25,   0.75,   0.25,   0.75,   0.25,   0.75,
502     0.125,  0.375,  0.125,  0.375,  0.125,  0.375,  0.125,  0.375,  0.625,
503     0.875,  0.625,  0.875,  0.625,  0.875,  0.625,  0.875,  0.125,  0.375,
504     0.125,  0.375,  0.125,  0.375,  0.125,  0.375,  0.625,  0.875,  0.625,
505     0.875,  0.625,  0.875,  0.625,  0.875,  0.125,  0.375,  0.125,  0.375,
506     0.125,  0.375,  0.125,  0.375,  0.625,  0.875,  0.625,  0.875,  0.625,
507     0.875,  0.625,  0.875,  0.125,  0.375,  0.125,  0.375,  0.125,  0.375,
508     0.125,  0.375,  0.625,  0.875,  0.625,  0.875,  0.625,  0.875,  0.625,
509     0.875,  0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
510     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625,
511     0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375,
512     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625,
513     0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375,
514     0.3125, 0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625,
515     0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375,
516     0.3125, 0.4375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
517     0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
518     0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125,
519     0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875,
520     0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125,
521     0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875,
522     0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125,
523     0.9375, 0.8125, 0.9375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
524     0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125,
525     0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
526     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625,
527     0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375,
528     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625,
529     0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375,
530     0.3125, 0.4375, 0.3125, 0.4375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
531     0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
532     0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
533     0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
534     0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125,
535     0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875,
536     0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125,
537     0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.0625, 0.1875, 0.0625, 0.1875,
538     0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125,
539     0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
540     0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125,
541     0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
542     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625,
543     0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375,
544     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.5625, 0.6875, 0.5625,
545     0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375,
546     0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
547     0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
548     0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
549     0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
550     0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125,
551     0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.0625, 0.1875,
552     0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125,
553     0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625, 0.1875,
554     0.0625, 0.1875, 0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125,
555     0.4375, 0.3125, 0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
556     0.0625, 0.1875, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125,
557     0.4375, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875, 0.0625, 0.1875,
558     0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.3125, 0.4375, 0.5625,
559     0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375,
560     0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875, 0.5625,
561     0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375,
562     0.8125, 0.9375, 0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
563     0.6875, 0.5625, 0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375,
564     0.8125, 0.9375, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625, 0.6875, 0.5625,
565     0.6875, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375, 0.8125, 0.9375};
566 
567 float boct_bit_tree::centerY[] = {
568     0.5,    0.25,   0.25,   0.75,   0.75,   0.25,   0.25,   0.75,   0.75,
569     0.125,  0.125,  0.375,  0.375,  0.125,  0.125,  0.375,  0.375,  0.125,
570     0.125,  0.375,  0.375,  0.125,  0.125,  0.375,  0.375,  0.625,  0.625,
571     0.875,  0.875,  0.625,  0.625,  0.875,  0.875,  0.625,  0.625,  0.875,
572     0.875,  0.625,  0.625,  0.875,  0.875,  0.125,  0.125,  0.375,  0.375,
573     0.125,  0.125,  0.375,  0.375,  0.125,  0.125,  0.375,  0.375,  0.125,
574     0.125,  0.375,  0.375,  0.625,  0.625,  0.875,  0.875,  0.625,  0.625,
575     0.875,  0.875,  0.625,  0.625,  0.875,  0.875,  0.625,  0.625,  0.875,
576     0.875,  0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
577     0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.3125,
578     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125,
579     0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.0625, 0.0625, 0.1875,
580     0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
581     0.0625, 0.0625, 0.1875, 0.1875, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125,
582     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125,
583     0.4375, 0.4375, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875,
584     0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
585     0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125,
586     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.0625, 0.0625,
587     0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875,
588     0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.3125, 0.3125, 0.4375, 0.4375,
589     0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125,
590     0.3125, 0.4375, 0.4375, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
591     0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875,
592     0.6875, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375,
593     0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.5625,
594     0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
595     0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.8125, 0.8125, 0.9375,
596     0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375,
597     0.8125, 0.8125, 0.9375, 0.9375, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625,
598     0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
599     0.6875, 0.6875, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375,
600     0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375,
601     0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625,
602     0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.8125, 0.8125,
603     0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375,
604     0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.0625, 0.0625, 0.1875, 0.1875,
605     0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625,
606     0.0625, 0.1875, 0.1875, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125,
607     0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375,
608     0.4375, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
609     0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.3125,
610     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125,
611     0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.0625, 0.0625, 0.1875,
612     0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
613     0.0625, 0.0625, 0.1875, 0.1875, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125,
614     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125,
615     0.4375, 0.4375, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875,
616     0.1875, 0.0625, 0.0625, 0.1875, 0.1875, 0.0625, 0.0625, 0.1875, 0.1875,
617     0.3125, 0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.3125,
618     0.3125, 0.4375, 0.4375, 0.3125, 0.3125, 0.4375, 0.4375, 0.5625, 0.5625,
619     0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875,
620     0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.8125, 0.8125, 0.9375, 0.9375,
621     0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125,
622     0.8125, 0.9375, 0.9375, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
623     0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875,
624     0.6875, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375,
625     0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.5625,
626     0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
627     0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.8125, 0.8125, 0.9375,
628     0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375,
629     0.8125, 0.8125, 0.9375, 0.9375, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625,
630     0.5625, 0.6875, 0.6875, 0.5625, 0.5625, 0.6875, 0.6875, 0.5625, 0.5625,
631     0.6875, 0.6875, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375,
632     0.9375, 0.8125, 0.8125, 0.9375, 0.9375, 0.8125, 0.8125, 0.9375, 0.9375};
633 
634 float boct_bit_tree::centerZ[] = {
635     0.5,    0.25,   0.25,   0.25,   0.25,   0.75,   0.75,   0.75,   0.75,
636     0.125,  0.125,  0.125,  0.125,  0.375,  0.375,  0.375,  0.375,  0.125,
637     0.125,  0.125,  0.125,  0.375,  0.375,  0.375,  0.375,  0.125,  0.125,
638     0.125,  0.125,  0.375,  0.375,  0.375,  0.375,  0.125,  0.125,  0.125,
639     0.125,  0.375,  0.375,  0.375,  0.375,  0.625,  0.625,  0.625,  0.625,
640     0.875,  0.875,  0.875,  0.875,  0.625,  0.625,  0.625,  0.625,  0.875,
641     0.875,  0.875,  0.875,  0.625,  0.625,  0.625,  0.625,  0.875,  0.875,
642     0.875,  0.875,  0.625,  0.625,  0.625,  0.625,  0.875,  0.875,  0.875,
643     0.875,  0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875,
644     0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.0625,
645     0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.0625, 0.0625,
646     0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.3125, 0.3125, 0.3125,
647     0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125,
648     0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125, 0.4375,
649     0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125, 0.4375, 0.4375,
650     0.4375, 0.4375, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875,
651     0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875,
652     0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.0625,
653     0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.3125, 0.3125,
654     0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125,
655     0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125,
656     0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125, 0.4375,
657     0.4375, 0.4375, 0.4375, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875,
658     0.1875, 0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875,
659     0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875,
660     0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875, 0.3125,
661     0.3125, 0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125,
662     0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125,
663     0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125, 0.3125,
664     0.4375, 0.4375, 0.4375, 0.4375, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875,
665     0.1875, 0.1875, 0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875,
666     0.1875, 0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875,
667     0.1875, 0.0625, 0.0625, 0.0625, 0.0625, 0.1875, 0.1875, 0.1875, 0.1875,
668     0.3125, 0.3125, 0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125,
669     0.3125, 0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125,
670     0.3125, 0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.3125, 0.3125, 0.3125,
671     0.3125, 0.4375, 0.4375, 0.4375, 0.4375, 0.5625, 0.5625, 0.5625, 0.5625,
672     0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875,
673     0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875, 0.6875,
674     0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875, 0.6875, 0.6875,
675     0.6875, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375,
676     0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.8125,
677     0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.8125, 0.8125,
678     0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.5625, 0.5625, 0.5625,
679     0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625,
680     0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875,
681     0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875, 0.6875,
682     0.6875, 0.6875, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375,
683     0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375,
684     0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.8125,
685     0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.5625, 0.5625,
686     0.5625, 0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625,
687     0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625,
688     0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625, 0.6875,
689     0.6875, 0.6875, 0.6875, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375,
690     0.9375, 0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375,
691     0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375,
692     0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375, 0.5625,
693     0.5625, 0.5625, 0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625,
694     0.5625, 0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625,
695     0.5625, 0.6875, 0.6875, 0.6875, 0.6875, 0.5625, 0.5625, 0.5625, 0.5625,
696     0.6875, 0.6875, 0.6875, 0.6875, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375,
697     0.9375, 0.9375, 0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375,
698     0.9375, 0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375,
699     0.9375, 0.8125, 0.8125, 0.8125, 0.8125, 0.9375, 0.9375, 0.9375, 0.9375};
700 
701 //------ I/O ----------------------------------------------------------
operator <<(std::ostream & s,const boct_bit_tree & t)702 std::ostream &operator<<(std::ostream &s, const boct_bit_tree &t) {
703   s << "boct_bit_tree:\n"
704     << "Tree bits:\n"
705     << "depth 0: " << (int)(t.bit_at(0)) << '\n';
706 
707   // one
708   s << "depth 1:";
709   for (int i = 1; i < 9; i++)
710     s << "  " << (int)t.bit_at(i);
711   s << '\n';
712 
713   // two
714   s << "depth 2:";
715   for (int i = 9; i < 73; i++)
716     s << "  " << (int)t.bit_at(i);
717   s << '\n';
718 
719   return s;
720 }
721