int main()

in source/rig/RigAnalyzer.cpp [477:612]


int main(int argc, char* argv[]) {
  system_util::initDep(argc, argv, kUsageMessage);

  CHECK_NE(FLAGS_rig, "");

  // Read the cameras
  Camera::Rig rig = Camera::loadRig(FLAGS_rig);

  // Modify rig
  if (!FLAGS_rearrange.empty()) { // clone rig[0] into named configuration
    rig = makeNamedArrangement(FLAGS_rearrange, rig[0], FLAGS_custom);
  } else if (!FLAGS_eulers.empty()) { // clone first camera according to eulers
    rig = makeRigFromEulers(rig[0], readVectorFile(FLAGS_eulers), false);
  } else if (!FLAGS_revolve.empty()) {
    rig = revolveRig(rig, readVectorFile(FLAGS_revolve));
  } else if (FLAGS_perturb_cameras) {
    std::srand(FLAGS_perturb_seed);
    Camera::perturbCameras(
        rig,
        FLAGS_perturb_positions,
        FLAGS_perturb_rotations,
        FLAGS_perturb_principals,
        FLAGS_perturb_focals);
  }

  if (!FLAGS_rotate_cam_z.empty()) {
    const Camera& zCam = Camera::findCameraById(FLAGS_rotate_cam_z, rig);
    const Camera::Vector3 z = Eigen::Vector3d::UnitZ();
    Camera::Real angle = acos(zCam.position.dot(z));
    Camera::Vector3 axis = zCam.position.cross(z);
    axis.normalize();
    Eigen::AngleAxis<Camera::Real> alignCamToZ(angle, axis);
    Camera::Matrix3 rot = alignCamToZ.toRotationMatrix();
    for (Camera& camera : rig) {
      LOG(INFO) << camera.forward();
      LOG(INFO) << rot * camera.forward();
      camera.position = rot * camera.position;
      camera.setRotation(rot * camera.forward(), rot * camera.up(), rot * camera.right());
    }
  }

  if (FLAGS_z_is_up || FLAGS_z_is_down || !FLAGS_rotate.empty()) {
    Camera::Matrix3 m;
    if (FLAGS_z_is_up) {
      m << 1, 0, 0, 0, 0, -1, 0, 1, 0;
    } else if (FLAGS_z_is_down) {
      m << 1, 0, 0, 0, 0, 1, 0, -1, 0;
    } else {
      Camera::Vector3 euler;
      std::istringstream s(FLAGS_rotate);
      s >> euler.x() >> euler.y() >> euler.z();
      CHECK(s.eof() && !s.fail()) << "bad --rotate vector " << FLAGS_rotate;
      m = rotationMatrixFromEulers(euler);
    }
    for (Camera& camera : rig) {
      camera.position = m * camera.position;
      camera.setRotation(m * camera.forward(), m * camera.up(), m * camera.right());
    }
  }

  if (FLAGS_scale_rig != 1) {
    LOG(INFO) << "scaling rig by " << FLAGS_scale_rig;
    for (Camera& camera : rig) {
      camera.position *= FLAGS_scale_rig;
    }
  }

  if (FLAGS_radius > 0) {
    for (Camera& camera : rig) {
      camera.position = FLAGS_radius * camera.position.normalized();
    }
  }

  if (FLAGS_scale_resolution != 1) {
    for (Camera& camera : rig) {
      camera = camera.rescale(FLAGS_scale_resolution * camera.resolution);
    }
  }

  // Generate the directions that we want to test
  std::vector<Camera::Vector3> samples = getFibonacciUnits(FLAGS_sample_count);
  samples = discardPoles(samples, FLAGS_discard_poles * M_PI / 180);

  // Go through N distances from min_distance to kNearInfinity
  const int kN = 20;
  for (int i = 0; i < kN; ++i) {
    Camera::Real frac = i / Camera::Real(kN);
    Camera::Real distance = FLAGS_min_distance / (1 - frac);

    // Compute coverage for each sample
    Eigen::VectorXd coverages(samples.size());
    for (int i = 0; i < int(samples.size()); ++i) {
      int coverage = 0;
      for (const Camera& camera : rig) {
        if (camera.sees(distance * samples[i])) {
          ++coverage;
        }
      }
      coverages[i] = coverage;
    }

    // Report results
    const int minC = coverages.minCoeff();
    double quality = minC + (coverages.array() >= minC + 1).count() / double(coverages.size());
    std::cout << folly::format(
                     "distance: {:.2f} quality: {:.2f} samples: {} {}",
                     distance,
                     quality,
                     ssize(coverages),
                     getHistogram(coverages))
              << std::endl;
  }

  // Write the cameras
  if (FLAGS_output_rig != "") {
    Camera::saveRig(FLAGS_output_rig, rig, {"command line:", gflags::GetArgv()});
  }

  if (FLAGS_output_obj != "") {
    saveRigObj(FLAGS_output_obj, rig);
  }

  if (FLAGS_output_equirect != "") {
    saveEquirect(FLAGS_output_equirect, rig);
  }

  if (FLAGS_output_camera != "" && FLAGS_output_camera_id != "") {
    saveCamera(FLAGS_output_camera, FLAGS_output_camera_id, rig);
  }

  if (FLAGS_output_cross_section != "") {
    saveCrossSection(FLAGS_output_cross_section, rig);
  }

  return 0;
}