fixing named parameter

removing approximate convex decomposition from PMP
This commit is contained in:
Sven Oesau 2025-11-20 13:08:36 +01:00
parent 9475ccb9b6
commit aa05cbaeda
9 changed files with 26 additions and 1697 deletions

View File

@ -130,12 +130,12 @@ The method employs a top-down splitting phase followed by a bottom-up merging to
The volume calculation, convex hull computation and the concavity search is accelerated by a voxel grid. The grid is prepared before the splitting phase and is labelled into outside, inside or surface. The convex hulls are calculated from voxel corners. Thus, a mesh with a high resolution is less penalized by its number of vertices. The volume calculation, convex hull computation and the concavity search is accelerated by a voxel grid. The grid is prepared before the splitting phase and is labelled into outside, inside or surface. The convex hulls are calculated from voxel corners. Thus, a mesh with a high resolution is less penalized by its number of vertices.
The splitting phase typically results in a number of convex volumes larger than targeted. The second phase employs a bottom-up merging that reduces the number of convex volumes to the targeted number while aiming at maintaining a low volume difference between convex volumes and the input mesh. The greedy merging maintains a priority queue to incrementally merge the pair of convex volumes with the smallest increase of volume difference. The splitting phase typically results in a number of convex volumes larger than targeted. The second phase employs a bottom-up merging that reduces the number of convex volumes to the targeted number while aiming at maintaining a low volume difference between convex volumes and the input mesh. The greedy merging maintains a priority queue to incrementally merge the pair of convex volumes with the smallest increase of volume difference.
The splitting phase is not limited by the chosen `maximum_number_of_convex_hulls`, because a splitting into a larger number of more convex parts with a subsequent merging leads to better results. The splitting phase is not limited by the chosen `maximum_number_of_convex_volumes`, because a splitting into a larger number of more convex parts with a subsequent merging leads to better results.
\subsection Convex_decomposition_3ACD_Parameters Parameters \subsection Convex_decomposition_3ACD_Parameters Parameters
Several parameters of the algorithm impact the quality of the result as well as the running time. Several parameters of the algorithm impact the quality of the result as well as the running time.
- `maximum_number_of_convex_hulls`: The maximum number of convex volumes output by the method. The actual number may be lower for mostly convex input meshes, e.g., a sphere. The impact on the running time is rather low. The default is 16. - `maximum_number_of_convex_volumes`: The maximum number of convex volumes output by the method. The actual number may be lower for mostly convex input meshes, e.g., a sphere. The impact on the running time is rather low. The default is 16.
- `maximum_depth`: The maximum depth for the hierarchical splitting phase. For complex meshes, a higher maximum depth is required to split small concavities into convex parts. The choice of `maximum_depth` has a larger impact on the running time. The default is 10. - `maximum_depth`: The maximum depth for the hierarchical splitting phase. For complex meshes, a higher maximum depth is required to split small concavities into convex parts. The choice of `maximum_depth` has a larger impact on the running time. The default is 10.
- `maximum_number_of_voxels`: This parameter controls the resolution of the voxel grid used for speed-up. Larger numbers result in a higher memory footprint and a higher running time. A small number also limits the `maximum_depth`. The voxel grid is isotropic and the longest axis of the bounding box will be split into a number of voxels equal to the cubic root of `maximum_number_of_voxels`. The default value is 1.000.000. - `maximum_number_of_voxels`: This parameter controls the resolution of the voxel grid used for speed-up. Larger numbers result in a higher memory footprint and a higher running time. A small number also limits the `maximum_depth`. The voxel grid is isotropic and the longest axis of the bounding box will be split into a number of voxels equal to the cubic root of `maximum_number_of_voxels`. The default value is 1.000.000.
- `volume_error`: The splitting of a convex volume into smaller parts is controlled by the `volume_error` which provides the tolerance for difference in volume. The difference is calculated by \f$ (|C_i| - |P_i|) / |P_i|\f$. The default value is 0.01. Thus, if a convex volume has 1 percent more volume that the part of the input mesh it approximates, it will be further divided. - `volume_error`: The splitting of a convex volume into smaller parts is controlled by the `volume_error` which provides the tolerance for difference in volume. The difference is calculated by \f$ (|C_i| - |P_i|) / |P_i|\f$. The default value is 0.01. Thus, if a convex volume has 1 percent more volume that the part of the input mesh it approximates, it will be further divided.

View File

@ -111,13 +111,13 @@ approximate_convex_decomposition()
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
std::vector<Convex_hull> convex_hulls; std::vector<Convex_hull> convex_volumes;
convex_hulls.reserve(9); convex_volumes.reserve(9);
CGAL::Polygon_mesh_processing::approximate_convex_decomposition(*(sm_item->face_graph()), std::back_inserter(convex_hulls), CGAL::Polygon_mesh_processing::approximate_convex_decomposition(*(sm_item->face_graph()), std::back_inserter(convex_volumes),
CGAL::parameters::maximum_depth(maximumDepth) CGAL::parameters::maximum_depth(maximumDepth)
.volume_error(volumeError) .volume_error(volumeError)
.maximum_number_of_convex_hulls(maximumConvexHulls) .maximum_number_of_convex_volumes(maximumConvexHulls)
.split_at_concavity(splitConcavity) .split_at_concavity(splitConcavity)
.maximum_number_of_voxels(numVoxels) .maximum_number_of_voxels(numVoxels)
.concurrency_tag(CGAL::Parallel_if_available_tag())); .concurrency_tag(CGAL::Parallel_if_available_tag()));
@ -126,10 +126,10 @@ approximate_convex_decomposition()
std::vector<QColor> distinct_colors; std::vector<QColor> distinct_colors;
// the first color is either the background or the unique domain // the first color is either the background or the unique domain
compute_deterministic_color_map(QColor(80, 250, 80), convex_hulls.size(), std::back_inserter(distinct_colors)); compute_deterministic_color_map(QColor(80, 250, 80), convex_volumes.size(), std::back_inserter(distinct_colors));
for (std::size_t i = 0; i < convex_hulls.size(); i++) { for (std::size_t i = 0; i < convex_volumes.size(); i++) {
const Convex_hull& ch = convex_hulls[i]; const Convex_hull& ch = convex_volumes[i];
SMesh sm; SMesh sm;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(ch.first, ch.second, sm); CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(ch.first, ch.second, sm);

View File

@ -59,7 +59,6 @@ create_single_source_cgal_program("isotropic_remeshing_with_allow_move.cpp")
create_single_source_cgal_program("triangle_mesh_autorefinement.cpp") create_single_source_cgal_program("triangle_mesh_autorefinement.cpp")
create_single_source_cgal_program("soup_autorefinement.cpp") create_single_source_cgal_program("soup_autorefinement.cpp")
create_single_source_cgal_program("snap_polygon_soup.cpp") create_single_source_cgal_program("snap_polygon_soup.cpp")
create_single_source_cgal_program("approximate_convex_decomposition.cpp")
find_package(Eigen3 QUIET) find_package(Eigen3 QUIET)
include(CGAL_Eigen3_support) include(CGAL_Eigen3_support)
@ -144,7 +143,6 @@ if(TARGET CGAL::TBB_support)
target_link_libraries(hausdorff_bounded_error_distance_example PRIVATE CGAL::TBB_support) target_link_libraries(hausdorff_bounded_error_distance_example PRIVATE CGAL::TBB_support)
target_link_libraries(soup_autorefinement PRIVATE CGAL::TBB_support) target_link_libraries(soup_autorefinement PRIVATE CGAL::TBB_support)
target_link_libraries(snap_polygon_soup PRIVATE CGAL::TBB_support) target_link_libraries(snap_polygon_soup PRIVATE CGAL::TBB_support)
target_link_libraries(approximate_convex_decomposition PRIVATE CGAL::TBB_support)
create_single_source_cgal_program("corefinement_parallel_union_meshes.cpp") create_single_source_cgal_program("corefinement_parallel_union_meshes.cpp")
target_link_libraries(corefinement_parallel_union_meshes PRIVATE CGAL::TBB_support) target_link_libraries(corefinement_parallel_union_meshes PRIVATE CGAL::TBB_support)

View File

@ -1,47 +0,0 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/approximate_convex_decomposition.h>
#include <iostream>
#include <string>
#include <vector>
using K = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point = K::Point_3;
using Convex_hull = std::pair<std::vector<Point>, std::vector<std::array<unsigned int, 3> > >;
using Mesh = CGAL::Surface_mesh<Point>;
namespace PMP = CGAL::Polygon_mesh_processing;
int main(int argc, char* argv[])
{
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/knot2.off");
std::cout << filename << std::endl;
Mesh mesh;
if(!PMP::IO::read_polygon_mesh(filename, mesh)) {
std::cerr << "Invalid input." << std::endl;
return 1;
}
std::vector<Convex_hull> convex_hulls;
convex_hulls.reserve(9);
PMP::approximate_convex_decomposition(mesh, std::back_inserter(convex_hulls),
CGAL::parameters::maximum_depth(10)
.volume_error(0.1)
.maximum_number_of_convex_hulls(9)
.split_at_concavity(true)
.maximum_number_of_voxels(1000000)
.concurrency_tag(CGAL::Parallel_if_available_tag()));
for (std::size_t i = 0;i<convex_hulls.size();i++) {
const Convex_hull& ch = convex_hulls[i];
CGAL::IO::write_polygon_soup(std::to_string(i) + ".off", ch.first, ch.second);
}
return 0;
}

View File

@ -182,7 +182,7 @@ CGAL_add_named_parameter(snap_grid_size_t, snap_grid_size, snap_grid_size)
CGAL_add_named_parameter(maximum_number_of_voxels_t, maximum_number_of_voxels, maximum_number_of_voxels) CGAL_add_named_parameter(maximum_number_of_voxels_t, maximum_number_of_voxels, maximum_number_of_voxels)
CGAL_add_named_parameter(maximum_depth_t, maximum_depth, maximum_depth) CGAL_add_named_parameter(maximum_depth_t, maximum_depth, maximum_depth)
CGAL_add_named_parameter(volume_error_t, volume_error, volume_error) CGAL_add_named_parameter(volume_error_t, volume_error, volume_error)
CGAL_add_named_parameter(maximum_number_of_convex_hulls_t, maximum_number_of_convex_hulls, maximum_number_of_convex_hulls) CGAL_add_named_parameter(maximum_number_of_convex_volumes_t, maximum_number_of_convex_volumes, maximum_number_of_convex_volumes)
CGAL_add_named_parameter(split_at_concavity_t, split_at_concavity, split_at_concavity) CGAL_add_named_parameter(split_at_concavity_t, split_at_concavity, split_at_concavity)

View File

@ -27,19 +27,19 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
std::vector<Convex_hull> convex_hulls; std::vector<Convex_hull> convex_volumes;
convex_hulls.reserve(9); convex_volumes.reserve(9);
CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_hulls), CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_volumes),
CGAL::parameters::maximum_depth(10) CGAL::parameters::maximum_depth(10)
.volume_error(0.1) .volume_error(0.1)
.maximum_number_of_convex_hulls(9) .maximum_number_of_convex_volumes(9)
.split_at_concavity(true) .split_at_concavity(true)
.maximum_number_of_voxels(1000000) .maximum_number_of_voxels(1000000)
.concurrency_tag(CGAL::Parallel_if_available_tag())); .concurrency_tag(CGAL::Parallel_if_available_tag()));
for (std::size_t i = 0;i<convex_hulls.size();i++) { for (std::size_t i = 0;i<convex_volumes.size();i++) {
const Convex_hull& ch = convex_hulls[i]; const Convex_hull& ch = convex_volumes[i];
CGAL::IO::write_polygon_soup(std::to_string(i) + ".off", ch.first, ch.second); CGAL::IO::write_polygon_soup(std::to_string(i) + ".off", ch.first, ch.second);
} }

View File

@ -1607,7 +1607,7 @@ void merge(std::vector<Convex_hull_candidate<GeomTraits>>& candidates, const typ
* *
* \cgalNamedParamsEnd * \cgalNamedParamsEnd
* *
* \return the number of convex hulls. Note that this value may be lower than the `maximum_number_of_convex_hulls`, for example if the specified `volume_error` is quickly met. * \return the number of convex hulls. Note that this value may be lower than the `maximum_number_of_convex_volumes`, for example if the specified `volume_error` is quickly met.
* *
* \sa `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()` * \sa `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()`
*/ */
@ -1626,7 +1626,7 @@ std::size_t approximate_convex_decomposition(const FaceGraph& tmesh, OutputItera
} }
#endif #endif
const unsigned int max_convex_hulls = parameters::choose_parameter(parameters::get_parameter(np, internal_np::maximum_number_of_convex_hulls), 16); const unsigned int max_convex_hulls = parameters::choose_parameter(parameters::get_parameter(np, internal_np::maximum_number_of_convex_volumes), 16);
assert(max_convex_hulls > 0); assert(max_convex_hulls > 0);
if (max_convex_hulls == 1) { if (max_convex_hulls == 1) {

View File

@ -23,27 +23,27 @@ int main(int argc, char* argv[])
Mesh mesh; Mesh mesh;
std::vector<Convex_hull> convex_hulls; std::vector<Convex_hull> convex_volumes;
// Try with empty mesh // Try with empty mesh
CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_hulls), CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_volumes),
CGAL::parameters::maximum_depth(10) CGAL::parameters::maximum_depth(10)
.volume_error(0.1) .volume_error(0.1)
.maximum_number_of_convex_hulls(9) .maximum_number_of_convex_volumes(9)
.split_at_concavity(true) .split_at_concavity(true)
.maximum_number_of_voxels(1000000) .maximum_number_of_voxels(1000000)
.concurrency_tag(CGAL::Parallel_if_available_tag())); .concurrency_tag(CGAL::Parallel_if_available_tag()));
assert(convex_hulls.size() == 0); assert(convex_volumes.size() == 0);
if (!PMP::IO::read_polygon_mesh(filename, mesh)) { if (!PMP::IO::read_polygon_mesh(filename, mesh)) {
std::cerr << "Invalid input." << std::endl; std::cerr << "Invalid input." << std::endl;
return 1; return 1;
} }
convex_hulls.reserve(9); convex_volumes.reserve(9);
CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_hulls), CGAL::approximate_convex_decomposition(mesh, std::back_inserter(convex_volumes),
CGAL::parameters::maximum_depth(10) CGAL::parameters::maximum_depth(10)
.volume_error(0.1) .volume_error(0.1)
.maximum_number_of_convex_hulls(9) .maximum_number_of_convex_hulls(9)
@ -51,8 +51,8 @@ int main(int argc, char* argv[])
.maximum_number_of_voxels(1000000) .maximum_number_of_voxels(1000000)
.concurrency_tag(CGAL::Parallel_if_available_tag())); .concurrency_tag(CGAL::Parallel_if_available_tag()));
assert(convex_hulls.size() > 0); assert(convex_volumes.size() > 0);
assert(convex_hulls.size() <= 9); assert(convex_volumes.size() <= 9);
return 0; return 0;
} }