diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h index fdc57bf0c05..219a4925c24 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_polygon_soup.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -604,22 +605,31 @@ Polygon construct_canonical_polygon_with_markers(const Polygon& polygon, const bool reversed) { const std::size_t polygon_size = polygon.size(); + Polygon canonical_polygon; + CGAL::internal::resize(canonical_polygon, polygon_size); if(reversed) { - std::size_t rfirst = polygon_size - 1 - first; - canonical_polygon.insert(canonical_polygon.end(), polygon.rbegin() + rfirst, polygon.rend()); - canonical_polygon.insert(canonical_polygon.end(), polygon.rbegin(), polygon.rbegin() + rfirst); + std::size_t rfirst = first + 1; + std::size_t pos = 0; + for(std::size_t i=rfirst; i --> 0 ;) // first to 0 + canonical_polygon[pos++] = polygon[i]; + for(std::size_t i=polygon_size; i --> rfirst ;) // polygon_size-1 to first+1 + canonical_polygon[pos++] = polygon[i]; } else { - canonical_polygon.insert(canonical_polygon.end(), polygon.begin() + first, polygon.end()); - canonical_polygon.insert(canonical_polygon.end(), polygon.begin(), polygon.begin() + first); + std::size_t pos = 0; + for(std::size_t i=first; i::Polygon_3> +struct Polygon_soup_fixer +{ + template + void operator()(PointRange& points, + PolygonRange& polygons, + const NamedParameters& np) const + { + using parameters::get_parameter; + using parameters::choose_parameter; + + typedef typename GetPolygonGeomTraits::type Traits; + Traits traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); + + #ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE + std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " polygons" << std::endl; + #endif + + merge_duplicate_points_in_polygon_soup(points, polygons, np); + simplify_polygons_in_polygon_soup(points, polygons, traits); + split_pinched_polygons_in_polygon_soup(points, polygons, traits); + remove_invalid_polygons_in_polygon_soup(points, polygons); + merge_duplicate_polygons_in_polygon_soup(points, polygons, np); + remove_isolated_points_in_polygon_soup(points, polygons); + } +}; + +// Specialization if the polygon soup is an array +// Disable repair functions that are meaningless for arrays +template +struct Polygon_soup_fixer > +{ + template + void operator()(PointRange& points, + PolygonRange& polygons, + const NamedParameters& np) const + { + #ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE + std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " arrays" << std::endl; + #endif + + merge_duplicate_points_in_polygon_soup(points, polygons, np); +// skipped steps: +// simplify_polygons_in_polygon_soup(points, polygons, traits); +// split_pinched_polygons_in_polygon_soup(points, polygons, traits); + remove_invalid_polygons_in_polygon_soup(points, polygons); + merge_duplicate_polygons_in_polygon_soup(points, polygons, np); + remove_isolated_points_in_polygon_soup(points, polygons); + } +}; + +} // namespace internal + /// \ingroup PMP_repairing_grp /// /// \brief cleans a given polygon soup through various repairing operations. @@ -1044,22 +1110,8 @@ void repair_polygon_soup(PointRange& points, PolygonRange& polygons, const NamedParameters& np = parameters::default_values()) { - using parameters::get_parameter; - using parameters::choose_parameter; - - typedef typename internal::GetPolygonGeomTraits::type Traits; - Traits traits = choose_parameter(get_parameter(np, internal_np::geom_traits)); - -#ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE - std::cout << "Repairing soup with " << points.size() << " points and " << polygons.size() << " polygons" << std::endl; -#endif - - merge_duplicate_points_in_polygon_soup(points, polygons, np); - internal::simplify_polygons_in_polygon_soup(points, polygons, traits); - internal::split_pinched_polygons_in_polygon_soup(points, polygons, traits); - internal::remove_invalid_polygons_in_polygon_soup(points, polygons); - merge_duplicate_polygons_in_polygon_soup(points, polygons, np); - remove_isolated_points_in_polygon_soup(points, polygons); + internal::Polygon_soup_fixer fixer; + fixer(points, polygons, np); } } // end namespace Polygon_mesh_processing diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_repair_polygon_soup.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_repair_polygon_soup.cpp index 68ca3351965..4b9b0abbd3e 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_repair_polygon_soup.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_repair_polygon_soup.cpp @@ -564,6 +564,21 @@ void test_slit_pinched_polygons(const bool /*verbose*/ = false) int main() { + // test compilation with different polygon soup types + std::vector vpoints; + std::vector > vpolygons; + PMP::repair_polygon_soup(vpoints, vpolygons); + + std::vector > dpolygons; + PMP::repair_polygon_soup(vpoints, dpolygons); + + std::deque > dvpolygons; + PMP::repair_polygon_soup(vpoints, dvpolygons); + + std::deque > apolygons; + PMP::repair_polygon_soup(vpoints, apolygons); + + // test functions test_polygon_canonicalization(true); test_merge_duplicate_points(false); test_merge_duplicate_polygons(false);