in octree/octree/octree_nn.cpp [6:108]
void NeighHelper::init_neigh_index() {
const vector<std::pair<string, int> > kernel_type{
{ "333", 0 }, { "111", 1 }, { "222", 2 },
{ "311", 3 }, { "131", 4 }, { "113", 5 },
{ "331", 6 }, { "313", 7 }, { "133", 8 } };
const vector<vector<int> > vec{ {} /* 333, 27 */, { 13 } /* 111, 1 */,
{ 13, 14, 16, 17, 22, 23, 25, 26 } /* 222, 8, 8 octants */,
{ 4, 13, 22 } /* 311, 3 */,
{ 10, 13, 16 } /* 131, 3 */,
{ 12, 13, 14 } /* 113, 3 */,
{ 1, 4, 7, 10, 13, 16, 19, 22, 25 } /* 331, 9 */,
{ 3, 4, 5, 12, 13, 14, 21, 22, 23 } /* 313, 9 */,
{ 9, 10, 11, 12, 13, 14, 15, 16, 17 } /* 133, 9 */ };
// init
ni_map_.insert(kernel_type.begin(), kernel_type.end());
ni_.resize(kernel_type.size());
// ni for kernel_size=333
ni_[0].assign(216, 0);
int* ni3 = ni_[0].data();
int id = 0;
for (int ijk = 0; ijk < 8; ++ijk) {
for (int xyz = 0; xyz < 27; ++xyz) {
int k = ijk % 2, p = ijk / 2;
int j = p % 2, i = p / 2;
int z = xyz % 3, q = xyz / 3;
int y = q % 3, x = q / 3;
ni3[id++] = ((x + i) << 4) | ((y + j) << 2) | (z + k);
}
}
// ni for other kernel_sizes
for (int k = 1; k < kernel_type.size(); ++k) {
int sz = vec[k].size();
ni_[k].assign(8 * sz, 0);
int* ni = ni_[k].data();
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < sz; ++j) {
ni[i * sz + j] = ni3[i * 27 + vec[k][j]];
}
}
}
// init the array parent & displacement
id = 0;
int tmp[64];
displacement_.assign(64, 0);
int* dis_ptr = displacement_.data();
for (int x = 1; x < 5; ++x) {
for (int y = 1; y < 5; ++y) {
for (int z = 1; z < 5; ++z) {
int x1 = x / 2;
int xb = x % 2;
int y1 = y / 2;
int yb = y % 2;
int z1 = z / 2;
int zb = z % 2;
tmp[id] = x1 * 9 + y1 * 3 + z1;
dis_ptr[id] = (xb << 2) | (yb << 1) | zb;
id++;
}
}
}
parent_.assign(512, 0);
int* parent_ptr = parent_.data();
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 64; ++j) {
parent_ptr[i * 64 + j] = ni3[i * 27 + tmp[j]];
}
}
// init the bilinear table
bilinear_.assign(512, -1);
const int mask[8][3] = { // bilinear weights:
{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, // 27, 9, 9, 9
{0, 1, 1}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}, // 3, 3, 3, 1
};
for (int i = 0; i < 8; ++i) {
// i -> xyz
int z0 = i % 2, t = i / 2;
int y0 = t % 2, x0 = t / 2;
for (int j = 0; j < 8; ++j) {
// j -> xyz
int z1 = j % 2, s = j / 2;
int y1 = s % 2, x1 = s / 2;
for (int k = 0; k < 8; ++k) {
int x2 = x0 + 1 + mask[k][0] * (2 * x1 - 1);
int y2 = y0 + 1 + mask[k][1] * (2 * y1 - 1);
int z2 = z0 + 1 + mask[k][2] * (2 * z1 - 1);
bilinear_[(i << 6) | (j << 3) | k] = (x2 << 4) | (y2 << 2) | z2;
}
}
}
}