mirror of https://github.com/CGAL/cgal
made snap polygon soup an option of autorefine_triangle_soup
This commit is contained in:
parent
8079f69f8b
commit
d4e66753ad
|
|
@ -1,10 +1,11 @@
|
|||
#define PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||
#define CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Polygon_mesh_processing/snap_polygon_soup.h>
|
||||
#include <CGAL/Polygon_mesh_processing/repair_polygon_soup.h>
|
||||
#include <CGAL/Polygon_mesh_processing/autorefinement.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
||||
#include <CGAL/IO/polygon_soup_io.h>
|
||||
|
|
@ -14,6 +15,8 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/internal/snap_polygon_soup.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef CGAL::Cartesian<double> Cartesian;
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
|
@ -26,7 +29,7 @@ int main(int argc, char** argv)
|
|||
: std::string(argv[1]);
|
||||
|
||||
const int grid_size = argc == 2 ? 23
|
||||
: std::stoi(std::string(argv[2]));
|
||||
: std::stoi(std::string(argv[2]));
|
||||
|
||||
std::vector<Point> input_points;
|
||||
std::vector<boost::container::small_vector<std::size_t, 3>> input_triangles;
|
||||
|
|
@ -40,15 +43,16 @@ int main(int argc, char** argv)
|
|||
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
PMP::snap_polygon_soup(input_points, input_triangles, CGAL::parameters::erase_all_duplicates(true).concurrency_tag(CGAL::Parallel_if_available_tag()).snap_grid_size(grid_size));
|
||||
PMP::autorefine_triangle_soup(input_points, input_triangles, CGAL::parameters::do_snap(true).erase_all_duplicates(true).concurrency_tag(CGAL::Parallel_if_available_tag()).snap_grid_size(grid_size));
|
||||
t.stop();
|
||||
std::cout << "#points = " << input_points.size() << " and #triangles = " << input_triangles.size() << " in " << t.time() << " sec." << std::endl;
|
||||
|
||||
std::vector<Cartesian::Point_3> output_points;
|
||||
std::cout << "Does self-intersect: " << PMP::does_triangle_soup_self_intersect(input_points, input_triangles) << std::endl;
|
||||
for(auto &p: input_points)
|
||||
output_points.emplace_back(CGAL::to_double(p.x()),CGAL::to_double(p.y()),CGAL::to_double(p.z()));
|
||||
|
||||
CGAL::IO::write_polygon_soup("rounded_soup.off", output_points, input_triangles, CGAL::parameters::stream_precision(17));
|
||||
// CGAL::IO::write_polygon_soup("rounded_soup.off", input_points, input_triangles, CGAL::parameters::stream_precision(17));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
|
||||
|
||||
|
||||
#ifdef CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE
|
||||
#define CGAL_PMP_AUTOREFINE_VERBOSE(X) std::cout << X << "\n";
|
||||
#endif
|
||||
|
|
@ -975,6 +974,15 @@ void generate_subtriangles(std::size_t ti,
|
|||
} // end of autorefine_impl
|
||||
#endif
|
||||
|
||||
namespace internal{
|
||||
// Forward declaration
|
||||
template <typename PointRange, typename PolygonRange, class NamedParameters = parameters::Default_named_parameters>
|
||||
bool snap_polygon_soup(PointRange &points,
|
||||
PolygonRange &triangles,
|
||||
const NamedParameters& np = parameters::default_values());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup PMP_corefinement_grp
|
||||
*
|
||||
|
|
@ -986,6 +994,10 @@ void generate_subtriangles(std::size_t ti,
|
|||
* `soup_triangles` will be updated to contain both the input triangles and the new subdivided triangles. Degenerate triangles will be removed.
|
||||
* Also triangles in `soup_triangles` will be triangles without intersection first, followed by triangles coming from a subdivision induced
|
||||
* by an intersection. The named parameter `visitor()` can be used to track
|
||||
* If the do_snap parameter is set to true, the coordinates of the vertices are rounded to fit within the precision of a double-precision floating point,
|
||||
* while preserving the model free of intersections. Note that this option does not guarantee an intersection-free output; however,
|
||||
* the returned boolean will be true if the output is free of self-intersections. The snap_grid_size parameter limits the drift of the snapped vertices.
|
||||
* A smaller value is more likely to output an intersection free output and perform more vertex collapses, but it may increase the Hausdorff distance from the input.
|
||||
*
|
||||
* @tparam PointRange a model of the concept `RandomAccessContainer`
|
||||
* whose value type is the point type
|
||||
|
|
@ -1021,13 +1033,32 @@ void generate_subtriangles(std::size_t ti,
|
|||
* \cgalParamDefault{`Autorefinement::Default_visitor`}
|
||||
* \cgalParamExtra{The visitor will be copied.}
|
||||
* \cgalParamNEnd
|
||||
* \cgalParamNBegin{do_snap}
|
||||
* \cgalParamDescription{Enable the rounding of the coordinates so that they fit in doubles.}
|
||||
* \cgalParamType{boolean}
|
||||
* \cgalParamDefault{false}
|
||||
* \cgalParamNEnd
|
||||
* \cgalParamNBegin{snap_grid_size}
|
||||
* \cgalParamDescription{Scale the points to [-2^gs, 2^gs] where gs is the snap_grid_size before to round them on integer. Use only if do_snap is true.}
|
||||
* \cgalParamType{unsigned int}
|
||||
* \cgalParamDefault{23}
|
||||
* \cgalParamExtra{Must be lower than 52.}
|
||||
* \cgalParamNEnd
|
||||
* \cgalParamNBegin{numbers_of_iteration}
|
||||
* \cgalParamDescription{Maximum number of iteration performed by the snap algorithm. Use only if do_snap is true.}
|
||||
* \cgalParamType{unsigned int}
|
||||
* \cgalParamDefault{15}
|
||||
* \cgalParamNEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*
|
||||
* \return `true` if the modified triangle soup is free from self-intersection, and `false` if the algorithm was not
|
||||
* able to provide such a triangle soup within the number of iterations.
|
||||
*/
|
||||
template <class PointRange, class TriangleRange, class NamedParameters = parameters::Default_named_parameters>
|
||||
void autorefine_triangle_soup(PointRange& soup_points,
|
||||
bool autorefine_triangle_soup(PointRange& soup_points,
|
||||
TriangleRange& soup_triangles,
|
||||
const NamedParameters& np = parameters::default_values())
|
||||
|
||||
{
|
||||
using parameters::choose_parameter;
|
||||
using parameters::get_parameter;
|
||||
|
|
@ -1050,6 +1081,17 @@ void autorefine_triangle_soup(PointRange& soup_points,
|
|||
> ::type Visitor;
|
||||
Visitor visitor(choose_parameter<Visitor>(get_parameter(np, internal_np::visitor)));
|
||||
|
||||
//TODO just modify do_snap instead of getting np one by one
|
||||
const bool do_snap = choose_parameter(get_parameter(np, internal_np::do_snap), false);
|
||||
const int grid_size = choose_parameter(get_parameter(np, internal_np::snap_grid_size), 23);
|
||||
const unsigned int nb_of_iteration = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 15);
|
||||
const bool ead = choose_parameter(get_parameter(np, internal_np::erase_all_duplicates), false);
|
||||
|
||||
if(do_snap)
|
||||
{
|
||||
CGAL_PMP_AUTOREFINE_VERBOSE("Snap polygon soup");
|
||||
return internal::snap_polygon_soup(soup_points, soup_triangles, parameters::point_map(pm).snap_grid_size(grid_size).number_of_iterations(nb_of_iteration).erase_all_duplicates(ead).concurrency_tag(Concurrency_tag()));
|
||||
}
|
||||
|
||||
constexpr bool parallel_execution = std::is_same_v<Parallel_tag, Concurrency_tag>;
|
||||
|
||||
|
|
@ -1077,7 +1119,7 @@ void autorefine_triangle_soup(PointRange& soup_points,
|
|||
for(std::size_t i=0; i<soup_triangles.size(); ++i)
|
||||
visitor.verbatim_triangle_copy(i, i);
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// mark degenerate faces so that we can ignore them
|
||||
|
|
@ -1642,6 +1684,7 @@ void autorefine_triangle_soup(PointRange& soup_points,
|
|||
swap(soup_triangles, soup_triangles_out);
|
||||
|
||||
CGAL_PMP_AUTOREFINE_VERBOSE("done");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@
|
|||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Léo Valque
|
||||
// Author(s) : Léo Valque, Sylvain Lazard
|
||||
|
||||
#ifndef CGAL_POLYGON_MESH_PROCESSING_POLYGON_SOUP_ROUNDING_H
|
||||
#define CGAL_POLYGON_MESH_PROCESSING_POLYGON_SOUP_ROUNDING_H
|
||||
#ifndef CGAL_POLYGON_MESH_PROCESSING_SNAP_POLYGON_SOUP_H
|
||||
#define CGAL_POLYGON_MESH_PROCESSING_SNAP_POLYGON_SOUP_H
|
||||
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Algebraic_structure_traits.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/license/Polygon_mesh_processing/geometric_repair.h>
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/autorefinement.h>
|
||||
// #include <CGAL/Polygon_mesh_processing/autorefinement.h>
|
||||
#include <CGAL/Polygon_mesh_processing/repair_polygon_soup.h>
|
||||
|
||||
#include <CGAL/Fraction_traits.h>
|
||||
|
|
@ -30,7 +30,6 @@ namespace CGAL
|
|||
namespace Polygon_mesh_processing
|
||||
{
|
||||
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
|
|
@ -69,7 +68,6 @@ double ceil(NT x){
|
|||
return std::ceil(to_double(x));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -116,17 +114,21 @@ double ceil(NT x){
|
|||
* \cgalParamNBegin{numbers_of_iteration}
|
||||
* \cgalParamDescription{Maximum number of iteration performed by the algorithm.}
|
||||
* \cgalParamType{unsigned int}
|
||||
* \cgalParamDefault{20}
|
||||
* \cgalParamDefault{15}
|
||||
* \cgalParamNEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*
|
||||
* \return `true` if the modified triangle soup is free from self-intersection, and `false` if the algorithm was not
|
||||
* able to provide such a triangle soup within the number of iterations.
|
||||
*/
|
||||
template <typename PointRange, typename PolygonRange, class NamedParameters = parameters::Default_named_parameters>
|
||||
template <typename PointRange, typename PolygonRange, class NamedParameters>
|
||||
bool snap_polygon_soup(PointRange &points,
|
||||
PolygonRange &triangles,
|
||||
const NamedParameters& np = parameters::default_values())
|
||||
const NamedParameters& np)
|
||||
// template <typename PointRange, typename PolygonRange, class NamedParameters = parameters::Default_named_parameters>
|
||||
// bool snap_polygon_soup(PointRange &points,
|
||||
// PolygonRange &triangles,
|
||||
// const NamedParameters& np = parameters::default_values())
|
||||
{
|
||||
using parameters::choose_parameter;
|
||||
using parameters::get_parameter;
|
||||
|
|
@ -141,8 +143,8 @@ bool snap_polygon_soup(PointRange &points,
|
|||
Sequential_tag
|
||||
> ::type Concurrency_tag;
|
||||
|
||||
// constexpr bool parallel_execution = std::is_same_v<Parallel_tag, Concurrency_tag>;
|
||||
constexpr bool parallel_execution = false;
|
||||
constexpr bool parallel_execution = std::is_same_v<Parallel_tag, Concurrency_tag>;
|
||||
// constexpr bool parallel_execution = false;
|
||||
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
static_assert (!parallel_execution,
|
||||
|
|
@ -154,10 +156,11 @@ bool snap_polygon_soup(PointRange &points,
|
|||
|
||||
// Get the grid size from the named parameter, the grid size could not be greater than 52
|
||||
const unsigned int grid_size = (std::min)(52,choose_parameter(get_parameter(np, internal_np::snap_grid_size), 23));
|
||||
const unsigned int max_nb_of_iteration = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 20);
|
||||
const unsigned int max_nb_of_iteration = choose_parameter(get_parameter(np, internal_np::number_of_iterations), 15);
|
||||
|
||||
#ifdef PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||
std::cout << "Compute the scaling of the coordinates" << std::endl;
|
||||
std::cout << grid_size << std::endl;
|
||||
#endif
|
||||
|
||||
auto exp = [](const double v)
|
||||
|
|
@ -345,7 +348,6 @@ bool snap_polygon_soup(PointRange &points,
|
|||
|
||||
|
||||
repair_polygon_soup(points, triangles, np);
|
||||
//TODO do not pass all triangles
|
||||
#ifdef PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||
std::cout << "Model size: " << points.size() << " " << triangles.size() << std::endl;
|
||||
std::cout << "Autorefine the soup" << std::endl;
|
||||
|
|
@ -355,6 +357,6 @@ bool snap_polygon_soup(PointRange &points,
|
|||
return false;
|
||||
}
|
||||
|
||||
} } //end of CGAL::Polygon_mesh_processing namespace
|
||||
} } } //end of CGAL::Polygon_mesh_processing::internal namespace
|
||||
|
||||
#endif //CGAL_POLYGON_MESH_PROCESSING_POLYGON_SOUP_ROUNDING_H
|
||||
#endif //CGAL_POLYGON_MESH_PROCESSING_SNAP_POLYGON_SOUP_H
|
||||
|
|
@ -220,6 +220,7 @@ CGAL_add_named_parameter(scan_angle_t, scan_angle_map, scan_angle_map)
|
|||
CGAL_add_named_parameter(scanline_id_t, scanline_id_map, scanline_id_map)
|
||||
CGAL_add_named_parameter(min_points_per_cell_t, min_points_per_cell, min_points_per_cell)
|
||||
CGAL_add_named_parameter(scalar_t, scalar_map, scalar_map)
|
||||
CGAL_add_named_parameter(do_snap_t, do_snap, do_snap)
|
||||
CGAL_add_named_parameter(snap_grid_size_t, snap_grid_size, snap_grid_size)
|
||||
|
||||
// List of named parameters used in Surface_mesh_approximation package
|
||||
|
|
|
|||
Loading…
Reference in New Issue