We demonstrate a bug (about stability) of CGAL::Mean_curvature_flow_skeletonization. We use Mean_curvature_flow_skeletonization to generate skeleton in our work and obtain different results in different runs, which is adverse to testing and optimizing our work. Therefore, we think it is necessary to fix the bug.
We notice that the issue #5726 has proposed a similar issue. A comment in issue #5726 is "It is a known issue that it is not deterministic, probably due to Polyhedron handles being hashes or put in a map". We find the cause of the uncertainty is the less operation, which uses a not deterministic key to compare two edges.
There are 4 key steps in Skeletonization: contract_geometry(), collapse_edges(), split_faces() and detect_degeneracies(). We find collapse_edges() is the only cause (by testing with parts of code).
The whole class CGAL::Mean_curvature_flow_skeletonization is in the file CGAL/Mean_curvature_flow_skeletonization.h:
In Mean_curvature_flow_skeletonization::collapse_short_edges(): it use std::set.
The elements are sorted by the less operation. I don't know the implement of the less operation (someone could help me). I print the order of elements and they are different in different runs. Therefore, it must be the cause.
Based on the observation, we fix the code by a simple way. We overrid the less operation of edge_descriptor and obtain deterministic results. The change of CGAL code is the following:
Issue Details
We demonstrate a bug (about stability) of CGAL::Mean_curvature_flow_skeletonization. We use Mean_curvature_flow_skeletonization to generate skeleton in our work and obtain different results in different runs, which is adverse to testing and optimizing our work. Therefore, we think it is necessary to fix the bug.
We notice that the issue #5726 has proposed a similar issue. A comment in issue #5726 is "It is a known issue that it is not deterministic, probably due to Polyhedron handles being hashes or put in a map". We find the cause of the uncertainty is the less operation, which uses a not deterministic key to compare two edges.
There are 4 key steps in Skeletonization: contract_geometry(), collapse_edges(), split_faces() and detect_degeneracies(). We find collapse_edges() is the only cause (by testing with parts of code).
The whole class CGAL::Mean_curvature_flow_skeletonization is in the file CGAL/Mean_curvature_flow_skeletonization.h: In Mean_curvature_flow_skeletonization::collapse_short_edges(): it use std::set.
The elements are sorted by the less operation. I don't know the implement of the less operation (someone could help me). I print the order of elements and they are different in different runs. Therefore, it must be the cause.
Based on the observation, we fix the code by a simple way. We overrid the less operation of edge_descriptor and obtain deterministic results. The change of CGAL code is the following:
Source Code (The input file and the output are in skeleton_debug.zip)
Command Line Output
running process number: 0 Number of vertices of the skeleton: 215 Number of edges of the skeleton: 214
running process number: 1 Number of vertices of the skeleton: 223 Number of edges of the skeleton: 222
running process number: 2 Number of vertices of the skeleton: 220 Number of edges of the skeleton: 219
Environment