根据 libigl 教程:
Libigl 在内部使用精确算术来稳健地构造中间布尔结果。如果将该结果“四舍五入”为浮点数(甚至是双精度),如果重新注入到进一步的布尔运算中会导致问题。为了方便 CSG 树操作并鼓励调用者不要显式多次调用 igl::copyleft::cgal::mesh_boolean,libigl 实现了一个类 igl::copyleft::cgal::CSGTree。
简而言之 - 您可以使用该函数构造CSGmesh_boolean
网格,但在这种情况下,您必须明确注意中间计算的稳健性。该类CSGTree
会自动为您执行此操作,因为它对所有带有坐标的中间计算使用CGAL精确算术。该类的另一个好处CSGTree
- 您可以在一行代码中构建多级 CSG 树。下面的示例显示了如何从两个网格构建最简单的 CSG 树并将其可视化:
#include <Eigen/Dense>
#include <igl/copyleft/cgal/CSGTree.h>
#include <igl/opengl/glfw/Viewer.h>
#include <igl/read_triangle_mesh.h>
int main()
{
// ------ load mesh #1
Eigen::MatrixXd V1;
Eigen::MatrixXi F1;
igl::read_triangle_mesh("data/sphere.obj", V1, F1);
// ------ load mesh #2
Eigen::MatrixXd V2;
Eigen::MatrixXi F2;
igl::read_triangle_mesh("data/xcylinder.obj", V2, F2);
// ------ combine meshes #1 and #2
const igl::copyleft::cgal::CSGTree t{{V1, F1}, {V2, F2}, "union"};
// ------ plot the combined mesh
const auto V = t.cast_V<Eigen::MatrixXd>();
const auto F = t.F();
igl::opengl::glfw::Viewer viewer;
viewer.data().set_mesh(V, F);
viewer.launch();
}
这样的单行构造是可能的,因为它CSGTree
具有以下构造函数(其中包括):
CSGTree(const CSGTree & A, const CSGTree & B, const MeshBooleanType & type)
正如您在上面看到的 - 如果有必要,可以通过模板函数将生成的坐标数组转换为双精度数组cast_V
- 例如,用于可视化。这个可视化的结果如下: