BrunoLevy / geogram

a programming library with geometric algorithms
Other
1.87k stars 128 forks source link

A way to avoid stack overflow in CVT #90

Closed daichi-ishida closed 1 year ago

daichi-ishida commented 1 year ago

Hi Bruno, this library is very practical and I've been using this a lot!

I am currently facing an issue with a stack overflow exception when setting up a large-scale point cloud with around 650,000 points in CVT. Further investigation suggests that the NearestNeighbors and KdTree used in the Delaunay_NearestNeighbors class are consuming the stack excessively. Are there any options available to address this problem and prevent the stack overflow exception?

This is how I set now (almost same as vorpalite)

    GEO::CentroidalVoronoiTesselation CVT(&M_domain, GEO::coord_index_t(3));
    CVT.set_volumetric(true);
    CVT.delaunay()->set_vertices(points.size()/3, points.data());
    CVT.RVD()->set_exact_predicates(true);

    GEO::BuildRVDMesh callback(M_result);
    callback.set_simplify_voronoi_facets(true);

    double angle_threshold = GEO::CmdLine::get_arg_double("poly:normal_angle_threshold");
    if (angle_threshold != 0.0) callback.set_simplify_boundary_facets(true, angle_threshold);

    callback.set_tessellate_non_convex_facets(GEO::CmdLine::get_arg_bool("poly:tessellate_non_convex_facets"));
    callback.set_shrink(GEO::CmdLine::get_arg_double("poly:cells_shrink"));
    callback.set_generate_ids(true);
    CVT.RVD()->for_each_polyhedron(callback);

Many thanks

BrunoLevy commented 1 year ago

Hi,

daichi-ishida commented 1 year ago

The platform is Windows, but as for the RVD build, running it on Linux does not finish the process as well. Could it be related to the point cloud being too dense? (As for point cloud, there no duplicated points)

Here is my dataset and example program: https://github.com/daichi-ishida/geogram_example

The data directory contains success case and failure case (that causes stack overflow). You can switch them on lines 175 and 176 in geogram_example/src/point_check/main.cpp

Thanks in advance

BrunoLevy commented 1 year ago

Fantastic ! Thank you very much for this detailed issue report (the best one I have ever received !).

BrunoLevy commented 1 year ago

I was able to get it and compile it. I will come back to you shortly, as soon as I make progress.

BrunoLevy commented 1 year ago

Got it ! Pretty nice example :-) image image

To obtain it, I changed two things: 1) insert this line right right after all the other GEO::CmdLine(...) calls:

GEO::CmdLine::set_arg("algo:delaunay","PDEL");

2) replace the call to preprocess(M_domain) with:

M_domain.facets.triangulate();

Explanations:

BrunoLevy commented 1 year ago

Just filed a pull request to https://github.com/daichi-ishida/geogram_example with the fix.

daichi-ishida commented 1 year ago

Thank you for your quick response and for resolving the issue! I have also tested and confirmed that it works on my end as well, so I have merged the Pull Request.