corefine_and_compute_difference CGAL error: precondition violation

corefine_and_compute_difference CGAL error: precondition violation

问题描述

我从文件“blank.off”中读取网格并将其加载到 surface_mesh 变量 blank 中。一个名为“hepoints49.txt”的文件存储点云。我使用函数CGAL::advancing_front_surface_reconstruction()将这个点云转换为surface_meshsv,然后使用函数corefine_and_compute_difference(blank,sv,res)之间进行布尔减法]blanksv。但程序抛出异常并终止。终端显示如下:

Using context  4 . 3 GL
load sv...
Using context  4 . 3 GL
start difference...
CGAL error: precondition violation!
Expression : CGAL::is_valid_polygon_mesh(tm)
File       : D:\dev\vcpkg\installed\x64-windows\include\CGAL/Polygon_mesh_processing/orientation.h
Line       : 190

你能帮我解决这个问题吗?

代码

#include<iostream>
#include<io.h>
#include<fstream>
#include<algorithm>
#include<array>
#include<CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include<CGAL/Advancing_front_surface_reconstruction.h>
#include<CGAL/Surface_mesh.h>
#include<CGAL/disable_warnings.h>
#include<CGAL/draw_surface_mesh.h>
#include<ctime>
#include<string>
#include<CGAL/polygon_mesh_processing/corefinement.h>
#include<CGAL/polygon_mesh_processing/remesh.h>
#include<CGAL/boost/graph/selection.h>
#include<CGAL/polygon_mesh_processing/repair_self_intersections.h>

using std::cin;
using std::cout;
using std::endl;
using std::string;

namespace PMP = CGAL::Polygon_mesh_processing;

typedef std::array<std::size_t, 3> Facet;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Mesh;

struct Construct {
    Mesh& mesh;

    template <typename PointIterator>
    Construct(Mesh& mesh, PointIterator b, PointIterator e):mesh(mesh) {
        for (; b != e; ++b) {
            boost::graph_traits<Mesh>::vertex_descriptor v;
            v = add_vertex(mesh);
            mesh.point(v) = *b;
        }
    }

    Construct& operator=(const Facet f) {
        typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
        typedef boost::graph_traits<Mesh>::vertices_size_type size_type;
        mesh.add_face(vertex_descriptor(static_cast<size_type>(f[0])),
            vertex_descriptor(static_cast<size_type>(f[1])),
            vertex_descriptor(static_cast<size_type>(f[2])));
        return *this;
    }
    
    Construct& operator*() { return *this; }
    Construct& operator++() { return *this; }
    Construct& operator++(int) { return *this; }
};

int main() {
    
    //load blank
    Mesh blank, sv,res;
    std::ifstream fin("blank.off");
    fin>>blank;
    fin.close();

    CGAL::draw(blank);

    //load sv
    string filename = "hepoints49.txt" ;
    std::cout << "load sv..."<< std::endl;
    fin.open(filename);
    std::vector<Point_3> points;
    std::vector<Facet> facets;
    std::copy(std::istream_iterator<Point_3>(fin),
        std::istream_iterator<Point_3>(),
        std::back_inserter(points));//load points
    fin.close();
    Construct construct(sv, points.begin(), points.end());
    CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), construct);//convert sv to surface_mesh
    CGAL::draw(sv);

    std::cout << "start difference..." << std::endl;
    bool valid_difference = PMP::corefine_and_compute_difference(blank,sv,res);

    if (valid_difference) {
        std::cout << "difference was successfully computed. " << std::endl;
        CGAL::draw(res);
    }
    else {
        std::cout << "difference could not be completed. Skip. " << endl << endl;
    }
    
    //CGAL::draw(res);
    return 0;
}

运行时环境

CGAL 版本:5.3

IDE:VS2017

解决方案配置:调试 x64

我试过运行这个程序在Release模式下,当然没有抛出异常。但是我得到的结果却和我想要的相反

文件

代码中出现的文件如下:

https://github.com/wenzaifou/for-stack-overflow-question3.git

Github link因为文件比较大所以提供

通过推进前输出构建网格的方式没有过滤掉孤立的顶点,这导致引发异常。添加对 CGAL::Polygon_mesh_processing::remove_isolated_vertices(sv) 的调用将解决问题。

那么您可能会遇到您的网格不是面向外的问题(意味着代表 space 的无限部分)。添加以下调用将解决问题:

if (!CGAL::Polygon_mesh_processing::is_outward_oriented(blank))
  CGAL::Polygon_mesh_processing::reverse_face_orientations(blank);
if (!CGAL::Polygon_mesh_processing::is_outward_oriented(sv))
  CGAL::Polygon_mesh_processing::reverse_face_orientations(sv);

文档参考 here and there.