我想得到从多面体中减去多个(可能是数百个)多面体的结果。我发现CGAL库的“Nef多面体上的三维布尔运算”包支持多面体之间的布尔运算。我想用这个包来解决我的问题,但我遇到了很多麻烦。虽然我知道CGAL库是一个强大的库,但我对它完全陌生,不知道如何最有效地使用它来解决我的问题。我的目标是使用CGAL库实现一个多面体减去多个多面体,我将详细介绍这个问题,以及我的方法和程序产生的错误。如果您能告诉我为什么程序会产生这些错误,以及我如何有效地使用CGAL库来实现一个多面体减去多个多面体,我将不胜感激。
我想用CGAL:来解决这个问题,我用MATLAB得到了一些多面体:A,B1,B2,...,Bi,..., Bn(n可能是几百)。我想知道A-B1-B2-...-Bn的结果。
我用CGAL库解决这个问题的方法:实际上只有A是一个2-流形,而Bi都是具有边界的三维曲面。为了使用CGAL库的“Nef多面体上的三维布尔运算”包,我将这些曲面转换为闭多面体。我将A保存为".off“格式文件,名为"blank.off”。Bi被转换成".off“格式,所有Bi都保存在一个名为"sv.off”的文件中。每个Bi由换行符分隔。我使用CGAL::OFF_to_nef_3()将文件"blank.off“读入Nef_polyhedron对象nef1。然后我编写了一个循环语句,在其中我使用CGAL::OFF_to_nef_3()将文件"sv.off“读入Nef_polyhedron对象nef2并执行nef2 1-=nef2 2。
代码如下:
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/draw_nef_3.h>
#include <CGAL/OFF_to_nef_3.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
#include<fstream>
#include<ctime>
int main() {
Polyhedron p1, p2, res;
int n = 0;
std::ifstream fin1("blank.off");
std::ifstream fin2("sv.off");
std::cout << "how many polyhedra in sv.off\n";
std::cin >> n;
//load nef2 and do bool operations
Nef_polyhedron nef1(p1);
Nef_polyhedron nef2(p2);
CGAL::OFF_to_nef_3(fin1, nef1);
fin1.close();
for (int i = 0; i < n;i++) {
nef2.clear();
CGAL::OFF_to_nef_3(fin2, nef2);
fin2.get();
nef1 -= nef2;
std::cout << "A-B" << i+1 << " have been calculated" << std::endl;
}
//convert nef2 to res.off
nef1.convert_to_polyhedron(res);
std::ofstream fout("res.off");
fout << res;
//draw
//CGAL::draw(nef1);
fin2.close();
return 0;
}您可以从Github下载blank.off和sv.off文件。下载链接:blank.off和sv.off
程序运行时发生的问题
"nef1.convert_to_polyhedron(res)"语句时,它会失败,因为nef1.is_simple()返回false。我查看了手册,我意识到这意味着nef1不再是一个2-流形。但是是什么导致nef1不再是2-流形的呢?CGAL中是否有一个函数可以修改nef1使其再次成为2-流形?其他问题:实际上,我最初用MATLAB得到的是不带边界的多面体A和带边界的曲面B的点集。为了对A和B进行布尔运算,我用MATLAB编写了一些程序对A和B进行三角化,并将B转换成闭多面体。我知道该程序生成的三角剖分网格的质量不高,这可能是造成如此多错误的主要原因。这些是否完全可以用CGAL库完成?该怎么做呢?最重要的问题是CGAL库是否适合在三维几何上执行数百个连续的布尔运算?
非常感谢你阅读这个问题,如果你能帮我的话,我将不胜感激。
发布于 2021-08-30 09:56:30
在玩了一点你的输入,我可以说,最合理的原因,你所有的问题是,你的个人不是很干净。如果您设法从sv.off中删除退化的面孔,那么一切都应该运行良好。现在,有一种方法可以让一切变得更快:差异。如果我修改了您的代码来使用它,它看起来如下:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Polygon_mesh_processing/corefinement.h>
#include <CGAL/draw_surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic;
typedef CGAL::Surface_mesh<Epic::Point_3> Surface_mesh;
int main() {
std::cout << "how many polyhedra in sv.off\n";
std::cin >> n;
std::ifstream fin1("data/blank.off");
std::ifstream fin2("data/sv.off");
//load nef2 and do bool operations
Surface_mesh s1, s2, out;
CGAL::IO::read_OFF(fin1, s1);
fin1.close();
for (int i = 0; i < n;i++) {
s2.clear();
CGAL::IO::read_OFF(fin2, s2);
fin2.get();
std::ofstream fout("s2.off");
fout << s2;
fout.close();
CGAL::Polygon_mesh_processing::corefine_and_compute_difference(s1, s2, s1);
std::cout << "A-B" << i+1 << " have been calculated" << std::endl;
}
//convert nef2 to res.off
std::ofstream fout("res.off");
fout << s1;
fout.close();
//draw
CGAL::draw(s1);
fin2.close();
return 0;
}但是,您必须确保您的sv网格是“干净的”,它们不能有退化的面孔,例如。从第一个sv网格的形状来看,我认为你可以使用CGAL的前沿曲面重建(这里的例子)从你的点集中得到你的网格,它们应该足够干净。(我试过第一个,效果很好)。
https://stackoverflow.com/questions/68860150
复制相似问题