float BoundingCubeNormalization()

in src/Utils.cpp [170:244]


float BoundingCubeNormalization(
    pangolin::Geometry& geom,
    bool fitToUnitSphere,
    const float buffer) {
  float xMin = 1000000, xMax = -1000000, yMin = 1000000, yMax = -1000000, zMin = 1000000,
        zMax = -1000000;

  pangolin::Image<float> vertices =
      pangolin::get<pangolin::Image<float>>(geom.buffers["geometry"].attributes["vertex"]);

  const std::size_t numVertices = vertices.h;

  ///////// Only consider vertices that were used in some face
  std::vector<unsigned char> verticesUsed(numVertices, 0);
  // turn to true if the vertex is used
  for (const auto& object : geom.objects) {
    auto itVertIndices = object.second.attributes.find("vertex_indices");
    if (itVertIndices != object.second.attributes.end()) {
      pangolin::Image<uint32_t> ibo =
          pangolin::get<pangolin::Image<uint32_t>>(itVertIndices->second);

      for (uint i = 0; i < ibo.h; ++i) {
        for (uint j = 0; j < 3; ++j) {
          verticesUsed[ibo(j, i)] = 1;
        }
      }
    }
  }
  /////////

  // compute min max in each dimension
  for (size_t i = 0; i < numVertices; i++) {
    // pass when it's not used.
    if (verticesUsed[i] == 0)
      continue;
    xMin = fmin(xMin, vertices(0, i));
    yMin = fmin(yMin, vertices(1, i));
    zMin = fmin(zMin, vertices(2, i));
    xMax = fmax(xMax, vertices(0, i));
    yMax = fmax(yMax, vertices(1, i));
    zMax = fmax(zMax, vertices(2, i));
  }

  const float xCenter = (xMax + xMin) / 2.0f;
  const float yCenter = (yMax + yMin) / 2.0f;
  const float zCenter = (zMax + zMin) / 2.0f;

  // make the mean zero
  float maxDistance = -1.0f;
  for (size_t i = 0; i < numVertices; i++) {
    // pass when it's not used.
    if (verticesUsed[i] == false)
      continue;
    vertices(0, i) -= xCenter;
    vertices(1, i) -= yCenter;
    vertices(2, i) -= zCenter;

    const float dist = Eigen::Map<Eigen::Vector3f>(vertices.RowPtr(i)).norm();
    maxDistance = std::max(maxDistance, dist);
  }

  // add some buffer
  maxDistance *= buffer;

  if (fitToUnitSphere) {
    for (size_t i = 0; i < numVertices; i++) {
      vertices(0, i) /= maxDistance;
      vertices(1, i) /= maxDistance;
      vertices(2, i) /= maxDistance;
    }
    maxDistance = 1;
  }

  return maxDistance;
}