diff --git a/Frechet_distance/examples/Frechet_distance/parallel_Frechet_DS_2.cpp b/Frechet_distance/examples/Frechet_distance/parallel_Frechet_DS_2.cpp index f07fa6d3408..2221eb6e77b 100644 --- a/Frechet_distance/examples/Frechet_distance/parallel_Frechet_DS_2.cpp +++ b/Frechet_distance/examples/Frechet_distance/parallel_Frechet_DS_2.cpp @@ -37,14 +37,14 @@ int main() curves.pop_back(); using Neighbor_search = CGAL::Frechet_distance::Neighbor_search; - Neighbor_search ds(curves, CGAL::Parallel_tag()); + Neighbor_search ds(curves, CGAL::Parallel_if_available_tag()); for(const Curve& c : curves){ std::pair res = CGAL::bounded_error_Frechet_distance(c, query, 0.000001); std::cout << "The Frechet distance between the polylines is between " << res.first << " and " << res.second << std::endl; } double distance = 16; - std::vector result = ds.get_close_curves(query, distance); + std::vector result = ds.get_close_curves(query, distance); std::cout << result.size() << " curves at Frechet distance closer than " << distance << std::endl; } diff --git a/Frechet_distance/include/CGAL/Frechet_distance/Neighbor_search.h b/Frechet_distance/include/CGAL/Frechet_distance/Neighbor_search.h index f31f52042fe..9ba6c54f66a 100644 --- a/Frechet_distance/include/CGAL/Frechet_distance/Neighbor_search.h +++ b/Frechet_distance/include/CGAL/Frechet_distance/Neighbor_search.h @@ -67,10 +67,22 @@ public: using Point = Traits::Point_d; #endif + std::vector get_close_curves(const PointRange& query, double distance, Sequential_tag); + std::vector get_close_curves(const PointRange& query, double distance, Parallel_tag); + /*! returns the indices of the inserted polylines that are closer than `distance` to the polyline `query`. + * \param query the query polyline + * \param distance the distance bound + * \tparam ConcurrencyTag enables sequential versus parallel computation. + * Possible values are `Sequential_tag`, `Parallel_tag`, and `Parallel_if_available_tag`. + * \return a vector of indices of the inserted polylines that are closer than `distance` to the polyline `query`. */ - std::vector get_close_curves(const PointRange& query, double distance); + template + std::vector get_close_curves(const PointRange& query, double distance) + { + return get_close_curves(query, distance, ConcurrencyTag()); + } private: Polylines curves; @@ -85,7 +97,7 @@ std::vector auto #endif Neighbor_search::get_close_curves( - const PointRange& curve, double distance) -> std::vector + const PointRange& curve, double distance, Sequential_tag) -> std::vector { auto result = kd_tree.search(curve, distance); @@ -103,6 +115,38 @@ Neighbor_search::get_close_curves( return result; } +template +#ifdef DOXYGEN_RUNNING +std::vector +#else +auto +#endif +Neighbor_search::get_close_curves( + const PointRange& curve, double distance, Parallel_tag) -> std::vector +{ + std::vector result; +#ifdef CGAL_LINKED_WITH_TBB + result = kd_tree.search(curve, distance); + std::vector to_remove(result.size(), 0); + + tbb::parallel_for(tbb::blocked_range(0, result.size()), [&](const tbb::blocked_range& r) { + for (std::size_t i = r.begin(); i != r.end(); ++i) { + to_remove[i] = is_Frechet_distance_larger(curve, curves[result[i]], distance, parameters::geom_traits(Traits())); + } + }); + + int compact = 0; + for(int i = 0; i < to_remove.size(); ++i) { + if(! to_remove[i]) { + result[compact] = result[i]; + ++compact; + } + } + result.resize(compact); +#endif + return result; +} + } } // end of namespace CGAL