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 PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||||
|
#define CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Cartesian.h>
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Exact_predicates_inexact_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/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/polygon_soup_to_polygon_mesh.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
|
||||||
#include <CGAL/IO/polygon_soup_io.h>
|
#include <CGAL/IO/polygon_soup_io.h>
|
||||||
|
|
@ -14,6 +15,8 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <CGAL/Polygon_mesh_processing/internal/snap_polygon_soup.h>
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
typedef CGAL::Cartesian<double> Cartesian;
|
typedef CGAL::Cartesian<double> Cartesian;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
|
|
@ -40,15 +43,16 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
CGAL::Real_timer t;
|
CGAL::Real_timer t;
|
||||||
t.start();
|
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();
|
t.stop();
|
||||||
std::cout << "#points = " << input_points.size() << " and #triangles = " << input_triangles.size() << " in " << t.time() << " sec." << std::endl;
|
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::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)
|
for(auto &p: input_points)
|
||||||
output_points.emplace_back(CGAL::to_double(p.x()),CGAL::to_double(p.y()),CGAL::to_double(p.z()));
|
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", 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
|
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE
|
#ifdef CGAL_PMP_AUTOREFINE_USE_DEFAULT_VERBOSE
|
||||||
#define CGAL_PMP_AUTOREFINE_VERBOSE(X) std::cout << X << "\n";
|
#define CGAL_PMP_AUTOREFINE_VERBOSE(X) std::cout << X << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -975,6 +974,15 @@ void generate_subtriangles(std::size_t ti,
|
||||||
} // end of autorefine_impl
|
} // end of autorefine_impl
|
||||||
#endif
|
#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
|
* \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.
|
* `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
|
* 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
|
* 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`
|
* @tparam PointRange a model of the concept `RandomAccessContainer`
|
||||||
* whose value type is the point type
|
* whose value type is the point type
|
||||||
|
|
@ -1021,13 +1033,32 @@ void generate_subtriangles(std::size_t ti,
|
||||||
* \cgalParamDefault{`Autorefinement::Default_visitor`}
|
* \cgalParamDefault{`Autorefinement::Default_visitor`}
|
||||||
* \cgalParamExtra{The visitor will be copied.}
|
* \cgalParamExtra{The visitor will be copied.}
|
||||||
* \cgalParamNEnd
|
* \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
|
* \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>
|
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,
|
TriangleRange& soup_triangles,
|
||||||
const NamedParameters& np = parameters::default_values())
|
const NamedParameters& np = parameters::default_values())
|
||||||
|
|
||||||
{
|
{
|
||||||
using parameters::choose_parameter;
|
using parameters::choose_parameter;
|
||||||
using parameters::get_parameter;
|
using parameters::get_parameter;
|
||||||
|
|
@ -1050,6 +1081,17 @@ void autorefine_triangle_soup(PointRange& soup_points,
|
||||||
> ::type Visitor;
|
> ::type Visitor;
|
||||||
Visitor visitor(choose_parameter<Visitor>(get_parameter(np, internal_np::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>;
|
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)
|
for(std::size_t i=0; i<soup_triangles.size(); ++i)
|
||||||
visitor.verbatim_triangle_copy(i, i);
|
visitor.verbatim_triangle_copy(i, i);
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark degenerate faces so that we can ignore them
|
// 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);
|
swap(soup_triangles, soup_triangles_out);
|
||||||
|
|
||||||
CGAL_PMP_AUTOREFINE_VERBOSE("done");
|
CGAL_PMP_AUTOREFINE_VERBOSE("done");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,17 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// 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
|
#ifndef CGAL_POLYGON_MESH_PROCESSING_SNAP_POLYGON_SOUP_H
|
||||||
#define CGAL_POLYGON_MESH_PROCESSING_POLYGON_SOUP_ROUNDING_H
|
#define CGAL_POLYGON_MESH_PROCESSING_SNAP_POLYGON_SOUP_H
|
||||||
|
|
||||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
#include <CGAL/Algebraic_structure_traits.h>
|
#include <CGAL/Algebraic_structure_traits.h>
|
||||||
#include <CGAL/number_utils.h>
|
#include <CGAL/number_utils.h>
|
||||||
#include <CGAL/license/Polygon_mesh_processing/geometric_repair.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/Polygon_mesh_processing/repair_polygon_soup.h>
|
||||||
|
|
||||||
#include <CGAL/Fraction_traits.h>
|
#include <CGAL/Fraction_traits.h>
|
||||||
|
|
@ -30,7 +30,6 @@ namespace CGAL
|
||||||
namespace Polygon_mesh_processing
|
namespace Polygon_mesh_processing
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -69,7 +68,6 @@ double ceil(NT x){
|
||||||
return std::ceil(to_double(x));
|
return std::ceil(to_double(x));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -116,17 +114,21 @@ double ceil(NT x){
|
||||||
* \cgalParamNBegin{numbers_of_iteration}
|
* \cgalParamNBegin{numbers_of_iteration}
|
||||||
* \cgalParamDescription{Maximum number of iteration performed by the algorithm.}
|
* \cgalParamDescription{Maximum number of iteration performed by the algorithm.}
|
||||||
* \cgalParamType{unsigned int}
|
* \cgalParamType{unsigned int}
|
||||||
* \cgalParamDefault{20}
|
* \cgalParamDefault{15}
|
||||||
* \cgalParamNEnd
|
* \cgalParamNEnd
|
||||||
* \cgalNamedParamsEnd
|
* \cgalNamedParamsEnd
|
||||||
*
|
*
|
||||||
* \return `true` if the modified triangle soup is free from self-intersection, and `false` if the algorithm was not
|
* \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.
|
* 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,
|
bool snap_polygon_soup(PointRange &points,
|
||||||
PolygonRange &triangles,
|
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::choose_parameter;
|
||||||
using parameters::get_parameter;
|
using parameters::get_parameter;
|
||||||
|
|
@ -141,8 +143,8 @@ bool snap_polygon_soup(PointRange &points,
|
||||||
Sequential_tag
|
Sequential_tag
|
||||||
> ::type Concurrency_tag;
|
> ::type Concurrency_tag;
|
||||||
|
|
||||||
// constexpr bool parallel_execution = std::is_same_v<Parallel_tag, Concurrency_tag>;
|
constexpr bool parallel_execution = std::is_same_v<Parallel_tag, Concurrency_tag>;
|
||||||
constexpr bool parallel_execution = false;
|
// constexpr bool parallel_execution = false;
|
||||||
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
#ifndef CGAL_LINKED_WITH_TBB
|
||||||
static_assert (!parallel_execution,
|
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
|
// 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 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
|
#ifdef PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||||
std::cout << "Compute the scaling of the coordinates" << std::endl;
|
std::cout << "Compute the scaling of the coordinates" << std::endl;
|
||||||
|
std::cout << grid_size << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto exp = [](const double v)
|
auto exp = [](const double v)
|
||||||
|
|
@ -345,7 +348,6 @@ bool snap_polygon_soup(PointRange &points,
|
||||||
|
|
||||||
|
|
||||||
repair_polygon_soup(points, triangles, np);
|
repair_polygon_soup(points, triangles, np);
|
||||||
//TODO do not pass all triangles
|
|
||||||
#ifdef PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
#ifdef PMP_ROUNDING_VERTICES_IN_POLYGON_SOUP_VERBOSE
|
||||||
std::cout << "Model size: " << points.size() << " " << triangles.size() << std::endl;
|
std::cout << "Model size: " << points.size() << " " << triangles.size() << std::endl;
|
||||||
std::cout << "Autorefine the soup" << std::endl;
|
std::cout << "Autorefine the soup" << std::endl;
|
||||||
|
|
@ -355,6 +357,6 @@ bool snap_polygon_soup(PointRange &points,
|
||||||
return false;
|
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(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(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(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)
|
CGAL_add_named_parameter(snap_grid_size_t, snap_grid_size, snap_grid_size)
|
||||||
|
|
||||||
// List of named parameters used in Surface_mesh_approximation package
|
// List of named parameters used in Surface_mesh_approximation package
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue