std::pair ComputeNormalizationParameters()

in src/Utils.cpp [109:168]


std::pair<Eigen::Vector3f, float> ComputeNormalizationParameters(
    pangolin::Geometry& geom,
    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 Eigen::Vector3f center((xMax + xMin) / 2.0f, (yMax + yMin) / 2.0f, (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;

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

  // add some buffer
  maxDistance *= buffer;

  return {-1 * center, (1.f / maxDistance)};
}