CGAL / cgal

The public CGAL repository, see the README below
https://github.com/CGAL/cgal#readme
Other
5.01k stars 1.39k forks source link

Unauthorized intersections of constraints #8583

Open Codeboy-cn opened 3 weeks ago

Codeboy-cn commented 3 weeks ago

CGAL 5.6.2

I want to stretch or extrude the edges of an open mesh surface. Currently, I’m trying to find all edge points directly and stretch them to a new height, but the stretched model encounters errors with following clip or boolean_operation, indicating Unauthorized intersections of constraints error. And it cannot be repaired by remove_self_intersections.

My questions are:

  1. Is there a better way to stretch or extrude the edges?
  2. Is there a way to fix intersections to enable successful clip or boolean_operation?

test.stl

Image

after extrude Image

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/corefinement.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/clip.h>
#include <CGAL/Polygon_mesh_processing/border.h>
#include <CGAL/Surface_mesh.h>

using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point3 = Kernel::Point_3;
using Vector3 = Kernel::Vector_3;
using Mesh = CGAL::Surface_mesh<Point3>;
using Transformation = CGAL::Aff_transformation_3<Kernel>;

using vertex_descriptor = boost::graph_traits<Mesh>::vertex_descriptor;
using halfedge_descriptor = boost::graph_traits<Mesh>::halfedge_descriptor;

void createPlaneMesh(Mesh &mesh, double width, double height, Point3 origin)
{
    auto halfW = width * 0.5;
    auto halfH = height * 0.5;
    mesh.clear();
    auto v0 = mesh.add_vertex(Point3(origin.x() + -halfW, origin.y(), origin.z() + -halfH));
    auto v1 = mesh.add_vertex(Point3(origin.x() + halfW, origin.y(), origin.z() + -halfH));
    auto v2 = mesh.add_vertex(Point3(origin.x() + halfW, origin.y(), origin.z() + halfH));
    auto v3 = mesh.add_vertex(Point3(origin.x() + -halfW, origin.y(), origin.z() + halfH));
    mesh.add_face(v0, v1, v2);
    mesh.add_face(v0, v2, v3);
}

int main(int argc, char **argv)
{
    Mesh testMesh;
    CGAL::Polygon_mesh_processing::IO::read_polygon_mesh("./test.stl", testMesh);

    // Find all outer contour edges.
    std::vector<halfedge_descriptor> border_edges;
    CGAL::Polygon_mesh_processing::border_halfedges(faces(testMesh), testMesh, std::back_inserter(border_edges));

    // Stretch the outer contour edge to a fixed height.
    float target_y = -10;
    for (halfedge_descriptor hd : border_edges) {
        // vertex_descriptor source_vertex = source(hd, testMesh);
        vertex_descriptor target_vertex = target(hd, testMesh);

        auto target_point = testMesh.point(target_vertex);
        Point3 new_target(target_point.x(), target_y, target_point.z());
        testMesh.point(target_vertex) = new_target;
    }

    CGAL::IO::write_polygon_mesh("./outTest1.stl", testMesh);

    // Try fix self intersection.
    if (CGAL::Polygon_mesh_processing::does_self_intersect(testMesh))
    {
        std::cout << "Self-intersection detected" << std::endl;
        if (!CGAL::Polygon_mesh_processing::experimental::remove_self_intersections(testMesh))
        {
            std::cout << "remove_self_intersections faile" << std::endl;
        }
    }

    // Test.1: clip faile
    {
        Kernel::Plane_3 plane(0, -1, 0, 0);

        try
        {
            if (!CGAL::Polygon_mesh_processing::clip(testMesh, plane, CGAL::parameters::clip_volume(false)))
            {
                std::cerr << "Error: PlaneCut operation failed" << std::endl;
                return -1;
            }

            CGAL::IO::write_polygon_mesh("./outClipResult.stl", testMesh);

            return 0;
        }
        catch(const std::exception& e)
        {
            std::cerr << "PlaneCut Exception: " << e.what() << std::endl;
        }
    }

    // Test.2: intersection faile
    {
        Mesh planeMesh;
        createPlaneMesh(planeMesh, 100, 100, Point3(0, 0.01, 0));

        Mesh result;

        try
        {
            if (!CGAL::Polygon_mesh_processing::corefine_and_compute_intersection(testMesh, planeMesh, result))
            {
                std::cerr << "Error: intersection operation failed" << std::endl;
                return -1;
            }

            CGAL::IO::write_polygon_mesh("./outIntersectionResult.stl", result);
        }
        catch(const std::exception& e)
        {
            std::cerr << "Intersection exception: " << e.what() << std::endl;
        }
    }

    return 0;
}