首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从多面体中连续减去多个多面体

从多面体中连续减去多个多面体
EN

Stack Overflow用户
提问于 2021-08-20 09:40:49
回答 1查看 102关注 1票数 0

我想得到从多面体中减去多个(可能是数百个)多面体的结果。我发现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。

代码如下:

代码语言:javascript
复制
#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

程序运行时发生的问题

  1. 在程序的第五次迭代(i==4)中,有时IDE将停止运行或崩溃,而不会抛出任何异常。为何会出现这个问题呢?是因为内存使用率太高吗?
  2. 在12个周期(i==11)之后,我希望将nef1转换为.off文件以保存当前结果。但是当程序到达"nef1.convert_to_polyhedron(res)"语句时,它会失败,因为nef1.is_simple()返回false。我查看了手册,我意识到这意味着nef1不再是一个2-流形。但是是什么导致nef1不再是2-流形的呢?CGAL中是否有一个函数可以修改nef1使其再次成为2-流形?
  3. 这不是一个错误,但计算速度太慢。还有别的办法可以更快地做到吗?

其他问题:实际上,我最初用MATLAB得到的是不带边界的多面体A和带边界的曲面B的点集。为了对A和B进行布尔运算,我用MATLAB编写了一些程序对A和B进行三角化,并将B转换成闭多面体。我知道该程序生成的三角剖分网格的质量不高,这可能是造成如此多错误的主要原因。这些是否完全可以用CGAL库完成?该怎么做呢?最重要的问题是CGAL库是否适合在三维几何上执行数百个连续的布尔运算?

非常感谢你阅读这个问题,如果你能帮我的话,我将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-30 09:56:30

在玩了一点你的输入,我可以说,最合理的原因,你所有的问题是,你的个人不是很干净。如果您设法从sv.off中删除退化的面孔,那么一切都应该运行良好。现在,有一种方法可以让一切变得更快:差异。如果我修改了您的代码来使用它,它看起来如下:

代码语言:javascript
复制
#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的前沿曲面重建(这里的例子)从你的点集中得到你的网格,它们应该足够干净。(我试过第一个,效果很好)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68860150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档