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;
}