- Add Google Test via CMake FetchContent (v1.14.0) - Add clausen.hpp: Clausen integral, Lobachevsky function, Im(Li2) - Add hyper_ideal_utility.hpp: generalized and ideal-vertex hyperbolic tetrahedron volume formulas using Eigen for the 4x4 Gram determinant - Port ClausenTest (5 tests) and HyperIdealUtilityTest (8 tests) from Java/JUnit — all 13 pass with same tolerances as the Java originals - Fix pre-existing VIEWER/viewer case mismatch in CMakeLists.txt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
2.9 KiB
C++
108 lines
2.9 KiB
C++
#include <CGAL/Simple_cartesian.h>
|
|
#include <CGAL/Surface_mesh.h>
|
|
#include <CGAL/IO/polygon_mesh_io.h>
|
|
|
|
|
|
#include "viewer_utils.h"
|
|
#include "mesh_utils.hpp"
|
|
|
|
|
|
#include <CLI11.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
|
|
#include <Eigen/Core>
|
|
|
|
|
|
using Kernel = CGAL::Simple_cartesian<double>;
|
|
using Point = Kernel::Point_3;
|
|
using Mesh = CGAL::Surface_mesh<Point>;
|
|
|
|
|
|
|
|
|
|
bool parse_arguments(int argc, char* argv[], std::string& input_file, std::string& output_file, bool& show, bool& verbose) {
|
|
CLI::App app{"demo of conformallab"};
|
|
app.add_option("-i,--input", input_file, "Input OFF file")->required();
|
|
app.add_option("-o,--output", output_file, "Output OFF file (optional)");
|
|
app.add_flag("-s,--show", show, "Show the input mesh in a viewer ");
|
|
app.add_flag("-v,--verbose",verbose, "Enable verbose output");
|
|
app.set_help_flag("-h,--help", "Show this help message and exit");
|
|
|
|
try {
|
|
CLI11_PARSE(app, argc, argv);
|
|
} catch (const CLI::ParseError &e) {
|
|
return false;
|
|
}
|
|
|
|
if (input_file.empty()) {
|
|
std::cerr << "Input file is required.\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (input_file.substr(input_file.find_last_of('.') + 1) != "off") {
|
|
std::cerr << "Unsupported file format. Please provide an OFF file.\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
std::cout << "Input file: " << input_file << "\n";
|
|
std::cout << "Output file: " << output_file << "\n";
|
|
std::cout << "Show mesh: " << (show ? "Yes" : "No") << "\n";
|
|
std::cout << "Verbose: " << (verbose ? "Yes" : "No") << "\n";
|
|
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
std::string input_file;
|
|
std::string output_file;
|
|
bool show = false;
|
|
bool verbose = false;
|
|
|
|
if(!parse_arguments(argc, argv, input_file, output_file, show, verbose)) {
|
|
std::cerr << "Failed to parse arguments.\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
Mesh surface_mesh;
|
|
if (!CGAL::IO::read_polygon_mesh(input_file, surface_mesh) || surface_mesh.is_empty()) {
|
|
std::cerr << "Invalid input file: " << input_file << "\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// #TODO: later: here we would call the unwrapping code, e.g.:
|
|
// UnwrapSettings settings;
|
|
// settings.target_geometry = TargetGeometry::Euclidean;
|
|
// UnwrapJob job(surface_mesh, settings);
|
|
// auto result = job.run();
|
|
// Mesh unwrapped = result.surface_unwrapped;
|
|
|
|
|
|
// CGAL -> libigl
|
|
if(show){
|
|
std::cout << "Visualizing input mesh...\n";
|
|
Eigen::MatrixXd V;
|
|
Eigen::MatrixXi F;
|
|
|
|
mesh_utils::cgal_to_eigen<Kernel>(surface_mesh, V, F);
|
|
viewer_utils::simple_visualize(V, F);
|
|
|
|
}
|
|
|
|
// for now, we just write the input mesh to the output file as a placeholder
|
|
if (!output_file.empty() && !CGAL::IO::write_polygon_mesh(output_file, surface_mesh)) {
|
|
std::cerr << "Failed to write output file: " << output_file << "\n";
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|