使用CGAL进行网格布尔运算

时间:2017-10-17 13:42:51

标签: c++ mesh cgal

我正在尝试使用其中一个CGAL library examples来执行网格“差异”布尔运算。它适用于示例模型,但是当我尝试引入自己的简单网格时,会发生这种情况:

CGAL Error: assertion violation! s == LEFT_TURN triangulation_2.h

我正在努力解决造成这种情况的原因 - 我的模特肯定有问题,我猜?但是这些顶点和面孔对我来说都是理智的。

以下是我正在使用的模型:

cube.off

sphere.off

以下是代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/corefinement.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/boost/graph/selection.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3>             Mesh;
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
namespace PMP = CGAL::Polygon_mesh_processing;
namespace params = PMP::parameters;
struct Vector_pmap_wrapper {
    std::vector<bool>& vect;
    Vector_pmap_wrapper(std::vector<bool>& v) : vect(v) {}
    friend bool get(const Vector_pmap_wrapper& m, face_descriptor f)
    {
        return m.vect[f];
    }
    friend void put(const Vector_pmap_wrapper& m, face_descriptor f, bool b)
    {
        m.vect[f] = b;
    }
};
int main(int argc, char* argv[])
{
    const char* filename1 = (argc > 1) ? argv[1] : "data/cube.off";
    const char* filename2 = (argc > 2) ? argv[2] : "data/sphere.off";
    std::ifstream input(filename1);
    Mesh mesh1, mesh2;
    if (!input || !(input >> mesh1))
    {
        std::cerr << "First mesh is not a valid off file." << std::endl;
        return 1;
    }
    input.close();
    input.open(filename2);
    if (!input || !(input >> mesh2))
    {
        std::cerr << "Second mesh is not a valid off file." << std::endl;
        return 1;
    }
    //create a property on edges to indicate whether they are constrained
    Mesh::Property_map<edge_descriptor, bool> is_constrained_map =
        mesh1.add_property_map<edge_descriptor, bool>("e:is_constrained", false).first;
    // update mesh1 to contain the mesh bounding the difference
    // of the two input volumes.
    bool valid_difference =
        PMP::corefine_and_compute_difference(mesh1,
            mesh2,
            mesh1,
            params::all_default(), // default parameters for mesh1
            params::all_default(), // default parameters for mesh2
            params::edge_is_constrained_map(is_constrained_map));
    if (valid_difference)
    {
        std::cout << "Difference was successfully computed\n";
        std::ofstream output("difference.off");
        output << mesh1;
    }
    else {
        std::cout << "Difference could not be computed\n";
        return 1;
    }
    // collect faces incident to a constrained edge
    std::vector<face_descriptor> selected_faces;
    std::vector<bool> is_selected(num_faces(mesh1), false);
    BOOST_FOREACH(edge_descriptor e, edges(mesh1))
        if (is_constrained_map[e])
        {
            // insert all faces incident to the target vertex
            BOOST_FOREACH(halfedge_descriptor h,
                halfedges_around_target(halfedge(e, mesh1), mesh1))
            {
                if (!is_border(h, mesh1))
                {
                    face_descriptor f = face(h, mesh1);
                    if (!is_selected[f])
                    {
                        selected_faces.push_back(f);
                        is_selected[f] = true;
                    }
                }
            }
        }
    // increase the face selection
    CGAL::expand_face_selection(selected_faces, mesh1, 2,
        Vector_pmap_wrapper(is_selected), std::back_inserter(selected_faces));
    std::cout << selected_faces.size()
        << " faces were selected for the remeshing step\n";
    // remesh the region around the intersection polylines
    PMP::isotropic_remeshing(
        selected_faces,
        0.02,
        mesh1,
        params::edge_is_constrained_map(is_constrained_map));
    std::ofstream output("difference_remeshed.off");
    output << mesh1;
    return 0;
}

提前感谢任何可能提供帮助的人!

1 个答案:

答案 0 :(得分:1)

您的网格物体不是有效的输入网格物体(由于重复边缘而导致的自交叉)。如果您首先通过致电CGAL::Polygon_mesh_processing::stitch_borders()来修复它们,您将获得结果。