
About
I want to read STL files in C++, but there seem to be several options.
Name | License | Commercial Use |
Assimp | BSD 3-Clause | Possible |
VCG Library | GPL or LGPL | Restricted |
libigl | MPL 2.0 or GPL | Possible |
Open3D | MIT License | Possible |
CGAL | GPL or Commercial | Paid |
Assimp, Open3D, and libigl might be good choices.
However, Assimp took an incredibly long time to build, and I lost all motivation to proceed further. Open3D was quite troublesome to build with CMake, encountering various errors related to Python bindings and the GUI. Among them, the Python binding errors seem to stem from standard libraries no longer used after Python 3.8. Libraries with many dependencies are indeed a hassle to manage.
I tried libigl a little, and it worked smoothly. It simply reads the vertices and face information of an STL file, but it worked seamlessly with Eigen. This might be thanks to the stable performance of libraries like Eigen.
Anyway, here’s a snippet for reference
Main.cpp
Some of the part is not so cool in the code because it uses ‘fopen’ and ‘FILE’.
#include <CLI/CLI.hpp>
#include <iostream>
#include <igl/readSTL.h>
#include <Eigen/Core>
#include <iostream>
int main(int argc, char** argv){
CLI::App app("Example CLI");
std::string stl_path = "./test.stl";
app.add_option("-s,--stl", stl_path, "Set Path for stl file");
CLI11_PARSE(app, argc, argv);
std::cout << "stl_path" << stl_path << std::endl;
FILE* stl_file = fopen(stl_path.c_str(), "rb");
if (!stl_file) {
std::cerr << "Failed to open STL file: " << stl_path << std::endl;
return 1;
}
Eigen::MatrixXd V; // Coordinates of Vertices
Eigen::MatrixXi F; // Indeces of Faces
Eigen::MatrixXd N; // NOrmal
if (!igl::readSTL(stl_file, V, F, N)) {
std::cerr << "Failed to load STL file: " << stl_path << std::endl;
#fclose(stl_file);
return 1;
}
#fclose(stl_file);
std::cout << "Successfully loaded: " << stl_path << std::endl;
std::cout << "Vertices: " << V.rows() << std::endl;
std::cout << "Triangles: " << F.rows() << std::endl;
std::cout << "Normals: " << N.rows() << std::endl;
return 0;
}
cmake_minimum_required(VERSION 3.14)
project(my_project)
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
FetchContent_Declare(
CLI11
GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
GIT_TAG v2.3.2
)
FetchContent_MakeAvailable(CLI11)
FetchContent_Declare(
Eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.0
)
FetchContent_MakeAvailable(Eigen)
FetchContent_Declare(
Libigl
GIT_REPOSITORY https://github.com/libigl/libigl.git
GIT_TAG v2.4.0
)
FetchContent_MakeAvailable(Libigl)
add_executable(my_project src/main.cpp)
target_link_libraries(my_project PRIVATE CLI11 igl::core Eigen3::Eigen)
target_include_directories(my_project PRIVATE
${Eigen_SOURCE_DIR}
${Libigl_SOURCE_DIR}/include
)