in octree/octree/merge_octrees.cpp [114:198]
void MergeOctrees::merge_octree() {
typedef typename KeyTrait<uintk>::uints uints;
// omp_set_num_threads(8);
//#pragma omp parallel for
for (int i = 0; i < batch_size_; ++i) {
// copy key
// the channel and location of key is 1 and -1
for (int d = 0; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kKey)) break;
int p = i * (depth_ + 1) + d;
uintk* des = octbatch_parser_.mutable_key_cpu(d) + nnum_cum_layer_[p];
const uintk* src = octree_parsers_[i].key_cpu(d);
for (int j = 0; j < nnum_[p]; ++j) {
des[j] = src[j];
uints* ptr = reinterpret_cast<uints*>(des + j);
ptr[3] = i;
}
}
// copy children
// by default, the channel and location of children is 1 and -1,
for (int d = 0; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kChild)) break;
int p = i * (depth_ + 1) + d;
int* des = octbatch_parser_.mutable_children_cpu(d) + nnum_cum_layer_[p];
const int* src = octree_parsers_[i].children_cpu(d);
for (int j = 0; j < nnum_[p]; ++j) {
des[j] = -1 == src[j] ? src[j] : src[j] + nnum_cum_nempty_layer_[p];
}
}
// copy data: !NOTE! the type of signal is float!!!
int feature_channel = info_batch_.channel(OctreeInfo::kFeature);
int feature_location = info_batch_.locations(OctreeInfo::kFeature);
int depth_start = feature_location == depth_ ? depth_ : 0;
for (int d = depth_start; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kFeature)) break;
int p = i * (depth_ + 1) + d;
for (int c = 0; c < feature_channel; c++) {
float* des = octbatch_parser_.mutable_feature_cpu(d) +
c * nnum_batch_[d] + nnum_cum_layer_[p];
const float* src = octree_parsers_[i].feature_cpu(d) + c * nnum_[p];
for (int j = 0; j < nnum_[p]; ++j) { des[j] = src[j]; }
}
}
// copy label: !NOTE! the type of label is float!!!
int label_location = info_batch_.locations(OctreeInfo::kLabel);
depth_start = label_location == depth_ ? depth_ : 0;
for (int d = depth_start; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kLabel)) break;
int p = i * (depth_ + 1) + d;
float* des = octbatch_parser_.mutable_label_cpu(d) + nnum_cum_layer_[p];
const float* src = octree_parsers_[i].label_cpu(d);
for (int j = 0; j < nnum_[p]; ++j) { des[j] = src[j]; }
}
// copy split label: !NOTE! the type of label is float!!!
int split_location = info_batch_.locations(OctreeInfo::kSplit);
depth_start = split_location == depth_ ? depth_ : 0;
for (int d = depth_start; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kSplit)) break;
int p = i * (depth_ + 1) + d;
float* des = octbatch_parser_.mutable_split_cpu(d) + nnum_cum_layer_[p];
const float* src = octree_parsers_[i].split_cpu(d);
for (int j = 0; j < nnum_[p]; ++j) des[j] = src[j];
}
}
// calc and set neighbor info
for (int d = 1; d < depth_ + 1; ++d) {
if (!info_batch_.has_property(OctreeInfo::kNeigh)) break;
CHECK(info_batch_.has_property(OctreeInfo::kChild));
if (d <= full_layer_) {
calc_neigh_cpu(octbatch_parser_.mutable_neighbor_cpu(d), d, batch_size_);
} else {
calc_neigh_cpu(octbatch_parser_.mutable_neighbor_cpu(d),
octbatch_parser_.neighbor_cpu(d - 1),
octbatch_parser_.children_cpu(d - 1),
octbatch_parser_.info().node_num(d - 1));
}
}
}