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