void Contour::marching_cube()

in octree/octree/contour.cpp [5:74]


void Contour::marching_cube(vector<float>& V, vector<int>& F) {
  // subdivide
  const int depth = octree_->info().depth();
  vector<uintk> nodes_subdivided;
  for (int d = octree_->info().full_layer(); d < depth; ++d) {
    // Check subdividion of octree nodes
    int nnum = octree_->info().node_num(d);
    vector<uintk> nodes_need_subdivide;
    for (int i = 0; i < nnum; ++i) {
      // Only check the leaf nodes
      if (octree_->children_cpu(d)[i] < 0) {
        uintk keyi = octree_->key_cpu(d)[i];
        if (check_subdividion(keyi, d)) {
          nodes_need_subdivide.push_back(keyi);
        }
      }
    }

    // check the subdivided nodes in the last iteration
    for (int i = 0; i < nodes_subdivided.size(); ++i) {
      uintk keyi = nodes_subdivided[i];
      if (check_subdividion(keyi, d)) {
        nodes_need_subdivide.push_back(keyi);
      }
    }

    // subdivide
    size_t sz = nodes_need_subdivide.size();
    nodes_subdivided.resize(8 * sz);
    for (int i = 0; i < sz; ++i) {
      subdivide(nodes_subdivided.data() + 8 * i, nodes_need_subdivide[i]);
    }
  }

  // marching cube
  V.clear();
  F.clear();
  nodes_subdivided.insert(
      nodes_subdivided.end(), octree_->key_cpu(depth),
      octree_->key_cpu(depth) + octree_->info().node_num(depth));
  for (int i = 0; i < nodes_subdivided.size(); ++i) {
    uintk weight_case = 0;
    float corner_val[8], pt[3];
    octree_->key2xyz(pt, nodes_subdivided[i], depth);
    for (int j = 0; j < 8; ++j) {
      int x = pt[0] + MarchingCube::corner_[j][0];
      int y = pt[1] + MarchingCube::corner_[j][1];
      int z = pt[2] + MarchingCube::corner_[j][2];
      auto fvalue = fval(x, y, z);
      corner_val[j] = fvalue.first;
      if (fvalue.second != 0) weight_case |= (1 << j);
    }
    // only consider the voxel that in the support area of the implicit function
    if (weight_case != 255) continue;

    MarchingCube m_cube(corner_val, 0.0f, pt, V.size() / 3);
    m_cube.contouring(V, F);
  }

  // translate and scale points
  if (rescale_) {
    const float* bbmin = octree_->info().bbmin();
    const float scale = octree_->info().bbox_max_width() / float(1 << depth);
    for (int i = 0; i < V.size() / 3; ++i) {
      for (int c = 0; c < 3; ++c) {
        V[i * 3 + c] = V[i * 3 + c] * scale + bbmin[c];
      }
    }
  }
}