From fe4b69aec84b3e765105a55427ab52f2557b37f0 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 27 Feb 2020 15:08:44 +0100 Subject: [PATCH 01/30] Factorize KD-tree calls in PSP + replace TBB functors by lambdas + some cleaning --- .../internal/Neighbor_query.h | 190 ++++++++++ .../internal/neighbor_query.h | 104 ------ .../include/CGAL/bilateral_smooth_point_set.h | 342 +++++------------- .../include/CGAL/compute_average_spacing.h | 77 ++-- .../include/CGAL/jet_estimate_normals.h | 144 +++----- .../include/CGAL/jet_smooth_point_set.h | 138 +++---- .../include/CGAL/mst_orient_normals.h | 51 +-- .../include/CGAL/pca_estimate_normals.h | 139 +++---- .../include/CGAL/remove_outliers.h | 44 +-- 9 files changed, 494 insertions(+), 735 deletions(-) create mode 100644 Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h delete mode 100644 Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/neighbor_query.h diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h new file mode 100644 index 00000000000..74ed1e17b5b --- /dev/null +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h @@ -0,0 +1,190 @@ +// Copyright (c) 2019 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H +#define CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H + +#include + +#include +#include +#include +#include + +#include + +namespace CGAL { +namespace Point_set_processing_3 { +namespace internal { + +struct Maximum_points_reached_exception : public std::exception { }; + +template +class Neighbor_query +{ +public: + + typedef Kernel_ Kernel; + typedef PointRange Point_range; + typedef PointMap Point_map; + + typedef typename Kernel::FT FT; + typedef typename Kernel::Point_3 Point_3; + + typedef typename PointRange::iterator input_iterator; + typedef typename input_iterator::value_type value_type; + + typedef CGAL::Prevent_deref iterator; + + struct Deref_point_map + { + typedef iterator key_type; + typedef typename boost::property_traits::reference reference; + typedef typename boost::property_traits::value_type value_type; + typedef typename boost::property_traits::category category; + + PointMap point_map; + + Deref_point_map () { } + Deref_point_map (PointMap point_map) : point_map(point_map) { } + + friend reference get (const Deref_point_map& map, key_type it) + { + return get(map.point_map, **it); + } + }; + + typedef CGAL::Search_traits_3 Tree_traits_base; + typedef CGAL::Search_traits_adapter Tree_traits; + typedef CGAL::Sliding_midpoint Splitter; + typedef CGAL::Distance_adapter > Distance; + typedef CGAL::Kd_tree Tree; + typedef CGAL::Fuzzy_sphere Sphere; + + typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; + typedef typename Neighbor_search::iterator Search_iterator; + +private: + + PointRange& m_points; + PointMap m_point_map; + Deref_point_map m_deref_map; + Tree_traits m_traits; + Tree m_tree; + Distance m_distance; + + // Forbid copy + Neighbor_query (const Neighbor_query&) { } + +public: + + Neighbor_query (PointRange& points, PointMap point_map) + : m_points (points) + , m_point_map (point_map) + , m_deref_map (point_map) + , m_traits (m_deref_map) + , m_tree (iterator(m_points.begin()), iterator(m_points.end()), Splitter(), m_traits) + , m_distance (m_deref_map) + { + m_tree.build(); + } + + // Hack to avoid problems with const ranges + Neighbor_query (const PointRange& points, PointMap point_map) + : m_points (const_cast(points)) + , m_point_map (point_map) + , m_deref_map (point_map) + , m_traits (m_deref_map) + , m_tree (iterator(m_points.begin()), iterator(m_points.end()), Splitter(), m_traits) + , m_distance (m_deref_map) + { + m_tree.build(); + } + + PointMap point_map() const { return m_point_map; } + + template + void get_iterators (const Point_3& query, unsigned int k, FT neighbor_radius, + OutputIterator output) const + { + if (neighbor_radius != FT(0)) + { + Sphere fs (query, neighbor_radius, 0, m_traits); + + // if k=0, no limit on the number of neighbors returned + if (k == 0) + k = (std::numeric_limits::max)(); + + unsigned int nb = 0; + + try + { + std::function output_iterator_with_limit + = [&](const iterator& it) + { + *(output ++) = *it; + if (++ nb == k) + throw Maximum_points_reached_exception(); + }; + + auto function_output_iterator + = boost::make_function_output_iterator (output_iterator_with_limit); + + m_tree.search (function_output_iterator, fs); + } + catch (const Maximum_points_reached_exception&) + { } + + // Fallback, if less than 3 points are return, search for the 3 + // first points + if (nb < 3) + k = 3; + // Else, no need to search for K nearest neighbors + else + k = 0; + } + + if (k != 0) + { + // Gather set of (k+1) neighboring points. + // Perform k+1 queries (as in point set, the query point is + // output first). Search may be aborted if k is greater + // than number of input points. + + Neighbor_search search (m_tree, query, k+1, 0, true, m_distance); + Search_iterator search_iterator = search.begin(); + unsigned int i; + for (i = 0; i < (k+1); ++ i) + { + if(search_iterator == search.end()) + break; // premature ending + *(output ++) = *(search_iterator->first); + search_iterator++; + } + } + } + + template + void get_points (const Point_3& query, unsigned int k, FT neighbor_radius, + OutputIterator output) const + { + return get_iterators(query, k, neighbor_radius, + boost::make_function_output_iterator + ([&](const input_iterator& it) + { + *(output ++) = get (m_point_map, *it); + })); + } +}; + +} } } // namespace CGAL::Point_set_processing_3::internal + +#endif // CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/neighbor_query.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/neighbor_query.h deleted file mode 100644 index 93a82d432fb..00000000000 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/neighbor_query.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H -#define CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H - -#include - -#include -#include -#include -#include - -#include - -namespace CGAL { -namespace Point_set_processing_3 { -namespace internal { - -struct Maximum_points_reached_exception : public std::exception { }; - -template -void neighbor_query (const Point& query, - const CGAL::Kd_tree& tree, - unsigned int k, - FT neighbor_radius, - PointContainer& points) -{ - typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::iterator Search_iterator; - typedef CGAL::Fuzzy_sphere Sphere; - - if (neighbor_radius != FT(0)) - { - Sphere fs (query, neighbor_radius, 0, tree.traits()); - - // if k=0, no limit on the number of neighbors returned - if (k == 0) - k = (std::numeric_limits::max)(); - - try - { - std::function back_insert_with_limit - = [&](const Point& point) -> void - { - points.push_back (point); - if (points.size() == k) - throw Maximum_points_reached_exception(); - }; - - auto function_output_iterator - = boost::make_function_output_iterator (back_insert_with_limit); - - tree.search (function_output_iterator, fs); - } - catch (const Maximum_points_reached_exception&) - { } - - // Fallback, if less than 3 points are return, search for the 3 - // first points - if (points.size() < 3) - k = 3; - // Else, no need to search for K nearest neighbors - else - k = 0; - } - - if (k != 0) - { - // Gather set of (k+1) neighboring points. - // Perform k+1 queries (as in point set, the query point is - // output first). Search may be aborted if k is greater - // than number of input points. - points.reserve(k+1); - Neighbor_search search(tree,query,k+1); - Search_iterator search_iterator = search.begin(); - unsigned int i; - for(i=0;i<(k+1);i++) - { - if(search_iterator == search.end()) - break; // premature ending - points.push_back(search_iterator->first); - search_iterator++; - } - CGAL_point_set_processing_precondition(points.size() >= 1); - } -} - -} } } // namespace CGAL::Point_set_processing_3::internal - -#endif // CGAL_PSP_INTERNAL_NEIGHBOR_QUERY_H diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index a01a9eba86e..ca871cca2cb 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -17,12 +17,9 @@ #include #include -#include -#include -#include +#include #include #include -#include #include #include @@ -66,47 +63,6 @@ namespace CGAL { namespace bilateral_smooth_point_set_internal{ -// Item in the Kd-tree: position (Point_3) + index -template -class Kd_tree_element : public Point_with_normal_3 -{ -public: - unsigned int index; - - // basic geometric types - typedef typename CGAL::Origin Origin; - typedef CGAL::Point_with_normal_3 Base; - - Kd_tree_element(const Origin& o = ORIGIN, unsigned int id=0) - : Base(o), index(id) - {} - Kd_tree_element(const Base& p, unsigned int id=0) - : Base(p), index(id) - {} - Kd_tree_element(const Kd_tree_element& other) - : Base(other), index(other.index) - {} - - Kd_tree_element& operator=(const Kd_tree_element&)=default; -}; - - -// Helper class for the Kd-tree -template -class Kd_tree_gt : public Kernel -{ -public: - typedef Kd_tree_element Point_3; -}; - -template -class Kd_tree_traits : public CGAL::Search_traits_3 > -{ -public: - typedef typename Kernel::Point_3 PointType; -}; - - /// Compute bilateral projection for each point /// according to their KNN neighborhood points /// @@ -117,12 +73,14 @@ public: /// /// @return -template -CGAL::Point_with_normal_3 +template +std::pair compute_denoise_projection( - const CGAL::Point_with_normal_3& query, ///< 3D point to project - const std::vector, - CGAL_PSP3_DEFAULT_ALLOCATOR > >& neighbor_pwns, // + const typename PointRange::iterator::value_type& vt, + PointMap point_map, + VectorMap normal_map, + const std::vector& neighbor_pwns, typename Kernel::FT radius, ///< accept neighborhood radius typename Kernel::FT sharpness_angle ///< control sharpness(0-90) ) @@ -133,7 +91,6 @@ compute_denoise_projection( // basic geometric types typedef typename Kernel::FT FT; - typedef CGAL::Point_with_normal_3 Pwn; typedef typename Kernel::Vector_3 Vector; typedef typename Kernel::Point_3 Point; @@ -148,23 +105,21 @@ compute_denoise_projection( FT cos_sigma = cos(sharpness_angle * CGAL_PI / 180.0); FT sharpness_bandwidth = std::pow((CGAL::max)(1e-8, 1 - cos_sigma), 2); - typename std::vector >::const_iterator - pwn_iter = neighbor_pwns.begin(); - for (; pwn_iter != neighbor_pwns.end(); ++pwn_iter) + for (typename PointRange::iterator it : neighbor_pwns) { - const Point& np = pwn_iter->position(); - const Vector& nn = pwn_iter->normal(); + const Point& np = get(point_map, *it); + const Vector& nn = get(normal_map, *it); - FT dist2 = CGAL::squared_distance(query.position(), np); + FT dist2 = CGAL::squared_distance(get(point_map, vt), np); if (dist2 < radius2) { FT theta = std::exp(dist2 * iradius16); - FT psi = std::exp(-std::pow(1 - query.normal() * nn, 2) + FT psi = std::exp(-std::pow(1 - get(normal_map, vt) * nn, 2) / sharpness_bandwidth); weight = theta * psi; - project_dist_sum += ((query.position() - np) * nn) * weight; + project_dist_sum += ((get(point_map, vt) - np) * nn) * weight; project_weight_sum += weight; normal_sum = normal_sum + nn * weight; } @@ -173,10 +128,10 @@ compute_denoise_projection( Vector update_normal = normal_sum / project_weight_sum; update_normal = update_normal / sqrt(update_normal.squared_length()); - Point update_point = query.position() - update_normal * + Point update_point = get(point_map, vt) - update_normal * (project_dist_sum / project_weight_sum); - return Pwn(update_point, update_normal); + return std::make_pair (update_point, update_normal); } /// Computes max-spacing of one query point from K nearest neighbors. @@ -187,41 +142,31 @@ compute_denoise_projection( /// @tparam Tree KD-tree. /// /// @return max spacing. -template < typename Kernel, - typename Tree > -typename Kernel::FT +template +typename NeighborQuery::Kernel::FT compute_max_spacing( - const CGAL::Point_with_normal_3& query, ///< 3D point - Tree& tree, ///< KD-tree + const typename NeighborQuery::value_type& vt, + typename NeighborQuery::Point_map point_map, + VectorMap normal_map, + NeighborQuery& neighbor_query, ///< KD-tree unsigned int k) ///< number of neighbors { // basic geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::FT FT; - typedef CGAL::Point_with_normal_3 Pwn; - - // types for K nearest neighbors search - typedef bilateral_smooth_point_set_internal::Kd_tree_traits Tree_traits; - typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::iterator Search_iterator; // performs k + 1 queries (if unique the query point is // output first). search may be aborted when k is greater // than number of input points - Neighbor_search search(tree,query,k+1); - Search_iterator search_iterator = search.begin(); - ++search_iterator; FT max_distance = (FT)0.0; - unsigned int i; - for(i = 0; i < (k+1) ; ++i) - { - if(search_iterator == search.end()) - break; // premature ending - - Pwn pwn = search_iterator->first; - double dist2 = CGAL::squared_distance(query.position(), pwn.position()); - max_distance = (CGAL::max)(dist2, max_distance); - ++search_iterator; - } + neighbor_query.get_iterators + (get(point_map, vt), k, (FT)(0.0), + boost::make_function_output_iterator + ([&](const typename NeighborQuery::input_iterator& it) + { + double dist2 = CGAL::squared_distance (get(point_map, vt), get(point_map, *it)); + max_distance = (CGAL::max)(dist2, max_distance); + })); // output max spacing return std::sqrt(max_distance); @@ -231,102 +176,6 @@ compute_max_spacing( /// \endcond -#ifdef CGAL_LINKED_WITH_TBB -/// \cond SKIP_IN_MANUAL -/// This is for parallelization of function: bilateral_smooth_point_set() -template -class Compute_pwns_neighbors -{ - typedef typename CGAL::Point_with_normal_3 Pwn; - typedef typename std::vector > Pwns; - typedef typename std::vector > - Pwns_neighbors; - typedef typename Kernel::FT FT; - - unsigned int m_k; - FT m_neighbor_radius; - const Tree & m_tree; - const Pwns & m_pwns; - Pwns_neighbors & m_pwns_neighbors; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - -public: - Compute_pwns_neighbors(unsigned int k, FT neighbor_radius, const Tree &tree, - const Pwns &pwns, Pwns_neighbors &neighbors, - cpp11::atomic& advancement, - cpp11::atomic& interrupted) - : m_k(k), m_neighbor_radius (neighbor_radius), m_tree(tree) - , m_pwns(pwns), m_pwns_neighbors(neighbors) - , advancement (advancement), interrupted (interrupted) {} - - void operator() ( const tbb::blocked_range& r ) const - { - for (size_t i = r.begin(); i!=r.end(); i++) - { - if (interrupted) - break; - - CGAL::Point_set_processing_3::internal::neighbor_query - (m_pwns[i], m_tree, m_k, m_neighbor_radius, m_pwns_neighbors[i]); - - ++ advancement; - } - } -}; -/// \endcond - -/// \cond SKIP_IN_MANUAL -/// This is for parallelization of function: compute_denoise_projection() -template -class Pwn_updater -{ - typedef typename CGAL::Point_with_normal_3 Pwn; - typedef typename std::vector > Pwns; - typedef typename Kernel::FT FT; - - FT sharpness_angle; - FT radius; - Pwns* pwns; - Pwns* update_pwns; - std::vector >* pwns_neighbors; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - -public: - Pwn_updater(FT sharpness, - FT r, - Pwns *in, - Pwns *out, - std::vector >* neighbors, - cpp11::atomic& advancement, - cpp11::atomic& interrupted): - sharpness_angle(sharpness), - radius(r), - pwns(in), - update_pwns(out), - pwns_neighbors(neighbors), - advancement (advancement), - interrupted (interrupted) {} - - void operator() ( const tbb::blocked_range& r ) const - { - for (size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - (*update_pwns)[i] = bilateral_smooth_point_set_internal:: - compute_denoise_projection((*pwns)[i], - (*pwns_neighbors)[i], - radius, - sharpness_angle); - ++ advancement; - } - } -}; -/// \endcond -#endif // CGAL_LINKED_WITH_TBB - // ---------------------------------------------------------------------------- // Public section @@ -400,16 +249,18 @@ bilateral_smooth_point_set( using parameters::get_parameter; // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetNormalMap::type NormalMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; + typedef typename Kernel::Point_3 Point_3; + typedef typename Kernel::Vector_3 Vector_3; CGAL_static_assertion_msg(!(boost::is_same::NoMap>::value), "Error: no normal map"); - typedef typename CGAL::Point_with_normal_3 Pwn; - typedef typename std::vector > Pwns; typedef typename Kernel::FT FT; double sharpness_angle = choose_parameter(get_parameter(np, internal_np::sharpness_angle), 30.); @@ -420,43 +271,20 @@ bilateral_smooth_point_set( CGAL_point_set_processing_precondition(k > 1); // types for K nearest neighbors search structure - typedef bilateral_smooth_point_set_internal:: - Kd_tree_element Kd_tree_element; - typedef bilateral_smooth_point_set_internal::Kd_tree_traits Tree_traits; - typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; PointMap point_map = choose_parameter(get_parameter(np, internal_np::point_map), PointMap()); NormalMap normal_map = choose_parameter(get_parameter(np, internal_np::normal_map), NormalMap()); FT neighbor_radius = choose_parameter(get_parameter(np, internal_np::neighbor_radius), FT(0)); - // copy points and normals - Pwns pwns; - for(typename PointRange::iterator it = points.begin(); it != points.end(); ++it) - { - typename boost::property_traits::reference p = get(point_map, *it); - typename boost::property_traits::reference n = get(normal_map, *it); - CGAL_point_set_processing_precondition(n.squared_length() > 1e-10); - - pwns.push_back(Pwn(p, n)); - } - - std::size_t nb_points = pwns.size(); + std::size_t nb_points = points.size(); #ifdef CGAL_PSP3_VERBOSE std::cout << "Initialization and compute max spacing: " << std::endl; #endif // initiate a KD-tree search for points - std::vector > treeElements; - treeElements.reserve(pwns.size()); - typename std::vector >::iterator - pwn_iter = pwns.begin(); - for (unsigned int i = 0; pwn_iter != pwns.end(); ++pwn_iter) - { - treeElements.push_back(Kd_tree_element(*pwn_iter, i)); - } - Tree tree(treeElements.begin(), treeElements.end()); + Neighbor_query neighbor_query (points, point_map); + // Guess spacing #ifdef CGAL_PSP3_VERBOSE CGAL::Real_timer task_timer; @@ -464,10 +292,10 @@ bilateral_smooth_point_set( #endif FT guess_neighbor_radius = 0.0; - for(pwn_iter = pwns.begin(); pwn_iter != pwns.end(); ++pwn_iter) + for (const value_type& vt : points) { FT max_spacing = bilateral_smooth_point_set_internal:: - compute_max_spacing(*pwn_iter, tree, k); + compute_max_spacing (vt, point_map, normal_map, neighbor_query, k); guess_neighbor_radius = (CGAL::max)(max_spacing, guess_neighbor_radius); } @@ -486,7 +314,7 @@ bilateral_smooth_point_set( task_timer.start(); #endif // compute all neighbors - std::vector > pwns_neighbors; + std::vector > pwns_neighbors; pwns_neighbors.resize(nb_points); #ifndef CGAL_LINKED_WITH_TBB @@ -498,10 +326,20 @@ bilateral_smooth_point_set( Point_set_processing_3::internal::Parallel_callback parallel_callback (callback, 2 * nb_points); - Compute_pwns_neighbors f(k, neighbor_radius, tree, pwns, pwns_neighbors, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(tbb::blocked_range(0, nb_points), f); + tbb::parallel_for(tbb::blocked_range(0, nb_points), + [&](const tbb::blocked_range& r) + { + for (size_t i = r.begin(); i!=r.end(); i++) + { + if (parallel_callback.interrupted()) + break; + + neighbor_query.get_iterators (get(point_map, *(points.begin() + i)), k, neighbor_radius, + std::back_inserter (pwns_neighbors[i])); + + ++ parallel_callback.advancement(); + } + }); bool interrupted = parallel_callback.interrupted(); @@ -516,17 +354,14 @@ bilateral_smooth_point_set( else #endif { - typename std::vector >::iterator - pwns_iter = pwns_neighbors.begin(); - std::size_t nb = 0; - for(pwn_iter = pwns.begin(); pwn_iter != pwns.end(); ++pwn_iter, ++pwns_iter, ++ nb) + for (const value_type& vt : points) { - CGAL::Point_set_processing_3::internal::neighbor_query - (*pwn_iter, tree, k, neighbor_radius, *pwns_iter); + neighbor_query.get_iterators (get (point_map, vt), k, neighbor_radius, std::back_inserter (pwns_neighbors[nb])); if (callback && !callback ((nb+1) / double(2. * nb_points))) return std::numeric_limits::quiet_NaN(); + ++ nb; } } @@ -541,7 +376,7 @@ bilateral_smooth_point_set( task_timer.start(); #endif // update points and normals - Pwns update_pwns(nb_points); + std::vector > update_pwns(nb_points); #ifdef CGAL_LINKED_WITH_TBB if(boost::is_convertible::value) @@ -549,16 +384,23 @@ bilateral_smooth_point_set( Point_set_processing_3::internal::Parallel_callback parallel_callback (callback, 2 * nb_points, nb_points); - //tbb::task_scheduler_init init(4); - tbb::blocked_range block(0, nb_points); - Pwn_updater pwn_updater(sharpness_angle, - guess_neighbor_radius, - &pwns, - &update_pwns, - &pwns_neighbors, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(block, pwn_updater); + tbb::parallel_for(tbb::blocked_range (0, nb_points), + [&](const tbb::blocked_range& r) + { + for (size_t i = r.begin(); i != r.end(); ++i) + { + if (parallel_callback.interrupted()) + break; + update_pwns[i] = bilateral_smooth_point_set_internal:: + compute_denoise_projection + (*(points.begin() + i), + point_map, normal_map, + pwns_neighbors[i], + guess_neighbor_radius, + sharpness_angle); + ++ parallel_callback.advancement(); + } + }); parallel_callback.join(); @@ -569,23 +411,18 @@ bilateral_smooth_point_set( else #endif // CGAL_LINKED_WITH_TBB { - std::size_t nb = nb_points; - - typename std::vector >::iterator - update_iter = update_pwns.begin(); - typename std::vector >::iterator - neighbor_iter = pwns_neighbors.begin(); - for(pwn_iter = pwns.begin(); pwn_iter != pwns.end(); - ++pwn_iter, ++update_iter, ++neighbor_iter, ++ nb) + std::size_t nb = 0; + for (const value_type& vt : points) { - *update_iter = bilateral_smooth_point_set_internal:: - compute_denoise_projection - (*pwn_iter, - *neighbor_iter, + update_pwns[nb] =bilateral_smooth_point_set_internal:: + compute_denoise_projection + (vt, point_map, normal_map, + pwns_neighbors[nb], guess_neighbor_radius, sharpness_angle); if (callback && !callback ((nb+1) / double(2. * nb_points))) return std::numeric_limits::quiet_NaN(); + ++ nb; } } #ifdef CGAL_PSP3_VERBOSE @@ -596,13 +433,14 @@ bilateral_smooth_point_set( #endif // save results FT sum_move_error = 0; + std::size_t nb = 0; typename PointRange::iterator it = points.begin(); - for(unsigned int i = 0 ; it != points.end(); ++it, ++i) + for (const value_type& vt : points) { - typename boost::property_traits::reference p = get(point_map, *it); - sum_move_error += CGAL::squared_distance(p, update_pwns[i].position()); - put (point_map, *it, update_pwns[i].position()); - put (normal_map, *it, update_pwns[i].normal()); + sum_move_error += CGAL::squared_distance(get(point_map, vt), update_pwns[nb].first); + put (point_map, vt, update_pwns[nb].first); + put (normal_map, vt, update_pwns[nb].second); + ++ nb; } return sum_move_error / nb_points; diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index 375a8932a03..dd8242912d0 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -60,38 +60,31 @@ namespace internal { /// @tparam Tree KD-tree. /// /// @return average spacing (scalar). -template < typename Kernel, - typename Tree > -typename Kernel::FT -compute_average_spacing(const typename Kernel::Point_3& query, ///< 3D point whose spacing we want to compute - const Tree& tree, ///< KD-tree +template +typename NeighborQuery::Kernel::FT +compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, ///< 3D point whose spacing we want to compute + const NeighborQuery& neighbor_query, ///< KD-tree unsigned int k) ///< number of neighbors { // basic geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::FT FT; typedef typename Kernel::Point_3 Point; - // types for K nearest neighbors search - typedef Search_traits_3 Tree_traits; - typedef Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::iterator Search_iterator; // performs k + 1 queries (if unique the query point is // output first). search may be aborted when k is greater // than number of input points - Neighbor_search search(tree,query,k+1); - Search_iterator search_iterator = search.begin(); FT sum_distances = (FT)0.0; unsigned int i; - for(i=0;i<(k+1);i++) - { - if(search_iterator == search.end()) - break; // premature ending - - Point p = search_iterator->first; - sum_distances += std::sqrt(CGAL::squared_distance(query,p)); - search_iterator++; - } + neighbor_query.get_points + (query, k, 0, + boost::make_function_output_iterator + ([&](const Point& p) + { + sum_distances += std::sqrt(CGAL::squared_distance (query,p)); + ++ i; + })); // output average spacing return sum_distances / (FT)i; @@ -195,6 +188,8 @@ compute_average_spacing( using parameters::get_parameter; // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::const_type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -206,9 +201,7 @@ compute_average_spacing( // types for K nearest neighbors search structure typedef typename Kernel::FT FT; - typedef Search_traits_3 Tree_traits; - typedef Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -219,16 +212,13 @@ compute_average_spacing( CGAL_point_set_processing_precondition(k >= 2); // Instanciate a KD-tree search. - // Note: We have to convert each input iterator to Point_3. - std::vector kd_tree_points; - for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++) - kd_tree_points.push_back(get(point_map, *it)); - Tree tree(kd_tree_points.begin(), kd_tree_points.end()); + Neighbor_query neighbor_query (points, point_map); // iterate over input points, compute and output normal // vectors (already normalized) FT sum_spacings = (FT)0.0; std::size_t nb = 0; + std::size_t nb_points = points.size(); #ifndef CGAL_LINKED_WITH_TBB CGAL_static_assertion_msg (!(boost::is_convertible::value), @@ -237,14 +227,23 @@ compute_average_spacing( if (boost::is_convertible::value) { Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, kd_tree_points.size()); + parallel_callback (callback, nb_points); - std::vector spacings (kd_tree_points.size (), -1); - CGAL::internal::Compute_average_spacings - f (tree, k, kd_tree_points, spacings, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(tbb::blocked_range(0, kd_tree_points.size ()), f); + std::vector spacings (nb_points, -1); + tbb::parallel_for(tbb::blocked_range(0, nb_points), + [&](const tbb::blocked_range& r) + { + for( std::size_t i = r.begin(); i != r.end(); ++i) + { + if (parallel_callback.interrupted()) + break; + + spacings[i] = CGAL::internal::compute_average_spacing + (get(point_map, *(points.begin() + i)), neighbor_query, k); + ++ parallel_callback.advancement(); + } + + }); for (unsigned int i = 0; i < spacings.size (); ++ i) if (spacings[i] >= 0.) @@ -260,10 +259,10 @@ compute_average_spacing( { for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++, nb++) { - sum_spacings += internal::compute_average_spacing( + sum_spacings += internal::compute_average_spacing( get(point_map,*it), - tree,k); - if (callback && !callback ((nb+1) / double(kd_tree_points.size()))) + neighbor_query,k); + if (callback && !callback ((nb+1) / double(nb_points))) { ++ nb; break; diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index 9b6fb4a1869..5095bfacb70 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -17,9 +17,7 @@ #include #include -#include -#include -#include +#include #include #include #include @@ -58,18 +56,16 @@ namespace internal { /// @tparam Tree KD-tree. /// /// @return Computed normal. Orientation is random. -template < typename Kernel, - typename SvdTraits, - typename Tree -> -typename Kernel::Vector_3 -jet_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute the normal at - Tree& tree, ///< KD-tree +template +typename NeighborQuery::Kernel::Vector_3 +jet_estimate_normal(const typename NeighborQuery::Point_3& query, ///< point to compute the normal at + const NeighborQuery& neighbor_query, ///< KD-tree unsigned int k, ///< number of neighbors - typename Kernel::FT neighbor_radius, + typename NeighborQuery::FT neighbor_radius, unsigned int degree_fitting) { // basic geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::Point_3 Point; // types for jet fitting @@ -79,8 +75,7 @@ jet_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute typedef typename Monge_jet_fitting::Monge_form Monge_form; std::vector points; - CGAL::Point_set_processing_3::internal::neighbor_query - (query, tree, k, neighbor_radius, points); + neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); // performs jet fitting Monge_jet_fitting monge_fit; @@ -92,49 +87,6 @@ jet_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute return monge_form.normal_direction(); } -#ifdef CGAL_LINKED_WITH_TBB - template - class Jet_estimate_normals { - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - const Tree& tree; - const unsigned int k; - const FT neighbor_radius; - const unsigned int degree_fitting; - const std::vector& input; - std::vector& output; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - - public: - Jet_estimate_normals(Tree& tree, unsigned int k, FT neighbor_radius, - std::vector& points, - unsigned int degree_fitting, std::vector& output, - cpp11::atomic& advancement, - cpp11::atomic& interrupted) - : tree(tree), k (k), neighbor_radius (neighbor_radius) - , degree_fitting (degree_fitting), input (points), output (output) - , advancement (advancement) - , interrupted (interrupted) - { } - - void operator()(const tbb::blocked_range& r) const - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - output[i] = CGAL::internal::jet_estimate_normal(input[i], tree, k, neighbor_radius, degree_fitting); - ++ advancement; - } - } - - }; -#endif // CGAL_LINKED_WITH_TBB - - - } /* namespace internal */ /// \endcond @@ -202,6 +154,8 @@ jet_estimate_normals( CGAL_TRACE("Calls jet_estimate_normals()\n"); // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetNormalMap::type NormalMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -229,9 +183,7 @@ jet_estimate_normals( typedef typename boost::property_traits::value_type Vector; // types for K nearest neighbors search structure - typedef typename CGAL::Search_traits_3 Tree_traits; - typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -244,59 +196,57 @@ jet_estimate_normals( std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Creates KD-tree\n"); - typename PointRange::iterator it; - - // Instanciate a KD-tree search. - // Note: We have to convert each input iterator to Point_3. - std::vector kd_tree_points; - for(it = points.begin(); it != points.end(); it++) - kd_tree_points.push_back(get(point_map, *it)); - Tree tree(kd_tree_points.begin(), kd_tree_points.end()); + Neighbor_query neighbor_query (points, point_map); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Computes normals\n"); + std::size_t nb_points = points.size(); + // iterate over input points, compute and output normal // vectors (already normalized) #ifndef CGAL_LINKED_WITH_TBB CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); + "Parallel_tag is enabled but TBB is unavailable."); #else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, kd_tree_points.size()); + if (boost::is_convertible::value) + { + Point_set_processing_3::internal::Parallel_callback + parallel_callback (callback, nb_points); - std::vector normals (kd_tree_points.size (), - CGAL::NULL_VECTOR); - CGAL::internal::Jet_estimate_normals - f (tree, k, neighbor_radius, - kd_tree_points, degree_fitting, normals, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(tbb::blocked_range(0, kd_tree_points.size ()), f); - std::size_t i = 0; - for(it = points.begin(); it != points.end(); ++ it, ++ i) - if (normals[i] != CGAL::NULL_VECTOR) - put (normal_map, *it, normals[i]); + tbb::parallel_for(tbb::blocked_range(0, points.size ()), + [&](const tbb::blocked_range& r) + { + for( std::size_t i = r.begin(); i != r.end(); ++i) + { + if (parallel_callback.interrupted()) + break; + put (normal_map, *(points.begin() + i), + CGAL::internal::jet_estimate_normal + (get(point_map, *(points.begin() + i)), neighbor_query, k, neighbor_radius, degree_fitting)); + ++ parallel_callback.advancement(); + } + }); - parallel_callback.join(); - } - else + parallel_callback.join(); + } + else #endif + { + std::size_t nb = 0; + for (const value_type& vt : points) { - std::size_t nb = 0; - for(it = points.begin(); it != points.end(); it++, ++ nb) - { - Vector normal = internal::jet_estimate_normal( - get(point_map,*it), - tree, k, neighbor_radius, degree_fitting); + put (normal_map, vt, + internal::jet_estimate_normal( + get(point_map, vt), + neighbor_query, k, neighbor_radius, degree_fitting)); - put(normal_map, *it, normal); // normal_map[it] = normal - if (callback && !callback ((nb+1) / double(kd_tree_points.size()))) - break; - } + if (callback && !callback ((nb+1) / double(nb_points))) + break; + + ++ nb; } + } memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); diff --git a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h index bde1da19f37..acf12856e4b 100644 --- a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h @@ -17,9 +17,7 @@ #include #include -#include -#include -#include +#include #include #include #include @@ -57,20 +55,20 @@ namespace internal { /// @tparam Tree KD-tree. /// /// @return computed point -template -typename Kernel::Point_3 +typename NeighborQuery::Kernel::Point_3 jet_smooth_point( - const typename Kernel::Point_3& query, ///< 3D point to project - Tree& tree, ///< KD-tree + const typename NeighborQuery::Kernel::Point_3& query, ///< 3D point to project + NeighborQuery& neighbor_query, ///< KD-tree const unsigned int k, ///< number of neighbors. - typename Kernel::FT neighbor_radius, + typename NeighborQuery::Kernel::FT neighbor_radius, const unsigned int degree_fitting, const unsigned int degree_monge) { // basic geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::Point_3 Point; // types for jet fitting @@ -79,9 +77,8 @@ jet_smooth_point( SvdTraits> Monge_jet_fitting; typedef typename Monge_jet_fitting::Monge_form Monge_form; - std::vector points; - CGAL::Point_set_processing_3::internal::neighbor_query - (query, tree, k, neighbor_radius, points); + std::vector points; + neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); // performs jet fitting Monge_jet_fitting monge_fit; @@ -92,50 +89,6 @@ jet_smooth_point( return monge_form.origin(); } -#ifdef CGAL_LINKED_WITH_TBB - template - class Jet_smooth_pwns { - typedef typename Kernel::Point_3 Point; - const Tree& tree; - const unsigned int k; - const typename Kernel::FT neighbor_radius; - unsigned int degree_fitting; - unsigned int degree_monge; - const std::vector& input; - std::vector& output; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - - public: - Jet_smooth_pwns (Tree& tree, unsigned int k, typename Kernel::FT neighbor_radius, - std::vector& points, - unsigned int degree_fitting, unsigned int degree_monge, std::vector& output, - cpp11::atomic& advancement, - cpp11::atomic& interrupted) - : tree(tree), k (k), neighbor_radius(neighbor_radius) - , degree_fitting (degree_fitting) - , degree_monge (degree_monge), input (points), output (output) - , advancement (advancement) - , interrupted (interrupted) - { } - - void operator()(const tbb::blocked_range& r) const - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - output[i] = CGAL::internal::jet_smooth_point(input[i], tree, k, - neighbor_radius, - degree_fitting, - degree_monge); - ++ advancement; - } - } - - }; -#endif // CGAL_LINKED_WITH_TBB - } /* namespace internal */ @@ -204,6 +157,8 @@ jet_smooth_point_set( using parameters::get_parameter; // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; typedef typename GetSvdTraits::type SvdTraits; @@ -223,9 +178,7 @@ jet_smooth_point_set( typedef typename Kernel::Point_3 Point; // types for K nearest neighbors search structure - typedef typename CGAL::Search_traits_3 Tree_traits; - typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -234,19 +187,15 @@ jet_smooth_point_set( // precondition: at least 2 nearest neighbors CGAL_point_set_processing_precondition(k >= 2); - - typename PointRange::iterator it; // Instanciate a KD-tree search. - // Note: We have to convert each input iterator to Point_3. - std::vector kd_tree_points; - for(it = points.begin(); it != points.end(); it++) - kd_tree_points.push_back(get(point_map, *it)); - Tree tree(kd_tree_points.begin(), kd_tree_points.end()); + Neighbor_query neighbor_query (points, point_map); // Iterates over input points and mutates them. // Implementation note: the cast to Point& allows to modify only the point's position. + std::size_t nb_points = points.size(); + #ifndef CGAL_LINKED_WITH_TBB CGAL_static_assertion_msg (!(boost::is_convertible::value), "Parallel_tag is enabled but TBB is unavailable."); @@ -254,37 +203,52 @@ jet_smooth_point_set( if (boost::is_convertible::value) { Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, kd_tree_points.size()); + parallel_callback (callback, nb_points); - std::vector mutated_points (kd_tree_points.size (), CGAL::ORIGIN); - CGAL::internal::Jet_smooth_pwns - f (tree, k, neighbor_radius, kd_tree_points, degree_fitting, degree_monge, - mutated_points, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(tbb::blocked_range(0, kd_tree_points.size ()), f); + std::vector mutated_points (nb_points, CGAL::ORIGIN); + tbb::parallel_for(tbb::blocked_range(0, nb_points), + [&](const tbb::blocked_range& r) + { + for( std::size_t i = r.begin(); i != r.end(); ++i) + { + if (parallel_callback.interrupted()) + break; + mutated_points[i] = + CGAL::internal::jet_smooth_point + (get (point_map, *(points.begin() + i)), neighbor_query, + k, + neighbor_radius, + degree_fitting, + degree_monge); + ++ parallel_callback.advancement(); + } + }); + unsigned int i = 0; - for(it = points.begin(); it != points.end(); ++ it, ++ i) + for (const value_type& vt : points) + { if (mutated_points[i] != CGAL::ORIGIN) - put(point_map, *it, mutated_points[i]); + put(point_map, vt, mutated_points[i]); + ++ i; + } parallel_callback.join(); } else #endif + { + std::size_t nb = 0; + for (const value_type& vt : points) { - std::size_t nb = 0; - for(it = points.begin(); it != points.end(); it++, ++ nb) - { - const typename boost::property_traits::reference p = get(point_map, *it); - put(point_map, *it , - internal::jet_smooth_point( - p,tree,k,neighbor_radius,degree_fitting,degree_monge) ); - if (callback && !callback ((nb+1) / double(kd_tree_points.size()))) - break; - } + put(point_map, vt, + internal::jet_smooth_point + (get (point_map, vt), neighbor_query,k,neighbor_radius,degree_fitting,degree_monge) ); + if (callback && !callback ((nb+1) / double(nb_points))) + break; + ++ nb; } + } } diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index b8c7030498b..1db0b213053 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -17,10 +17,7 @@ #include #include -#include -#include -#include -#include +#include #include #include #include @@ -296,17 +293,16 @@ mst_find_source( /// @tparam Kernel Geometric traits class. /// /// @return the Riemannian graph -template -Riemannian_graph +Riemannian_graph create_riemannian_graph( - ForwardIterator first, ///< iterator over the first input point. - ForwardIterator beyond, ///< past-the-end iterator over the input points. + PointRange& points, ///< input points PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3 NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3 IndexMap index_map, ///< property map ForwardIterator -> index @@ -320,11 +316,8 @@ create_riemannian_graph( typedef typename boost::property_traits::reference Vector_ref; // Types for K nearest neighbors search structure - typedef Point_vertex_handle_3 Point_vertex_handle_3; - typedef internal::Search_traits_vertex_handle_3 Traits; - typedef Euclidean_distance_vertex_handle_3 KDistance; - typedef Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef typename PointRange::iterator ForwardIterator; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // Riemannian_graph types typedef internal::Riemannian_graph Riemannian_graph; @@ -337,26 +330,12 @@ create_riemannian_graph( CGAL_point_set_processing_precondition(k >= 2); // Number of input points - const std::size_t num_input_points = distance(first, beyond); + const std::size_t num_input_points = points.size(); std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Creates KD-tree\n"); - // Instanciate a KD-tree search. - // Notes: We have to wrap each input point by a Point_vertex_handle_3. - // The KD-tree is allocated dynamically to recover RAM as soon as possible. - std::vector kd_tree_points; kd_tree_points.reserve(num_input_points); - for (ForwardIterator it = first; it != beyond; it++) - { - - Point_ref point = get(point_map, *it); - Point_vertex_handle_3 point_wrapper(point.x(), point.y(), point.z(), it); - kd_tree_points.push_back(point_wrapper); - } - boost::shared_ptr tree( new Tree(kd_tree_points.begin(), kd_tree_points.end()) ); - - // Recover RAM - kd_tree_points.clear(); + Neighbor_query neighbor_query (points, point_map); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Creates Riemannian Graph\n"); @@ -369,7 +348,7 @@ create_riemannian_graph( Riemannian_graph riemannian_graph; // // add vertices - for (ForwardIterator it = first; it != beyond; it++) + for (ForwardIterator it = points.begin(); it != points.end(); it++) { typename Riemannian_graph::vertex_descriptor v = add_vertex(riemannian_graph); CGAL_point_set_processing_assertion(v == get(index_map,it)); @@ -383,16 +362,14 @@ create_riemannian_graph( // // add edges Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph); - for (ForwardIterator it = first; it != beyond; it++) + for (ForwardIterator it = points.begin(); it != points.end(); it++) { std::size_t it_index = get(index_map,it); Vector_ref it_normal_vector = get(normal_map,*it); Point_ref point = get(point_map, *it); - Point_vertex_handle_3 point_wrapper(point.x(), point.y(), point.z(), it); - std::vector neighbor_points; - CGAL::Point_set_processing_3::internal::neighbor_query - (point_wrapper, *tree, k, neighbor_radius, neighbor_points); + std::vector neighbor_points; + neighbor_query.get_iterators (point, k, neighbor_radius, std::back_inserter(neighbor_points)); for (std::size_t i = 0; i < neighbor_points.size(); ++ i) { @@ -665,7 +642,7 @@ mst_orient_normals( if (boost::is_same::NoMap>::value) - riemannian_graph = create_riemannian_graph(points.begin(), points.end(), + riemannian_graph = create_riemannian_graph(points, point_map, normal_map, index_map, Default_constrained_map (mst_find_source(points.begin(), points.end(), @@ -675,7 +652,7 @@ mst_orient_normals( neighbor_radius, kernel); else - riemannian_graph = create_riemannian_graph(points.begin(), points.end(), + riemannian_graph = create_riemannian_graph(points, point_map, normal_map, index_map, constrained_map, k, diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 3a6ead3d5fd..63c9782b60c 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -18,9 +18,7 @@ #include #include -#include -#include -#include +#include #include #include #include @@ -58,22 +56,20 @@ namespace internal { /// @tparam Tree KD-tree. /// /// @return Computed normal. Orientation is random. -template < typename Kernel, - typename Tree -> -typename Kernel::Vector_3 -pca_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute the normal at - const Tree& tree, ///< KD-tree +template +typename NeighborQuery::Kernel::Vector_3 +pca_estimate_normal(const typename NeighborQuery::Kernel::Point_3& query, ///< point to compute the normal at + const NeighborQuery& neighbor_query, ///< KD-tree unsigned int k, ///< number of neighbors - typename Kernel::FT neighbor_radius) + typename NeighborQuery::Kernel::FT neighbor_radius) { // basic geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::Point_3 Point; typedef typename Kernel::Plane_3 Plane; std::vector points; - CGAL::Point_set_processing_3::internal::neighbor_query - (query, tree, k, neighbor_radius, points); + neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); // performs plane fitting by point-based PCA Plane plane; @@ -83,48 +79,6 @@ pca_estimate_normal(const typename Kernel::Point_3& query, ///< point to compute return plane.orthogonal_vector(); } - -#ifdef CGAL_LINKED_WITH_TBB - template - class PCA_estimate_normals { - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - const Tree& tree; - const unsigned int k; - const FT neighbor_radius; - const std::vector& input; - std::vector& output; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - - public: - PCA_estimate_normals(Tree& tree, unsigned int k, FT neighbor_radius, - std::vector& points, - std::vector& output, - cpp11::atomic& advancement, - cpp11::atomic& interrupted) - : tree(tree), k (k), neighbor_radius (neighbor_radius) - , input (points), output (output) - , advancement (advancement) - , interrupted (interrupted) - { } - - void operator()(const tbb::blocked_range& r) const - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - output[i] = CGAL::internal::pca_estimate_normal(input[i], tree, k, neighbor_radius); - ++ advancement; - } - } - - }; -#endif // CGAL_LINKED_WITH_TBB - - } /* namespace internal */ /// \endcond @@ -209,12 +163,12 @@ pca_estimate_normals( typedef typename Kernel::Point_3 Point; // Input points types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename boost::property_traits::value_type Vector; // types for K nearest neighbors search structure - typedef typename CGAL::Search_traits_3 Tree_traits; - typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -227,18 +181,13 @@ pca_estimate_normals( std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Creates KD-tree\n"); - typename PointRange::iterator it; - - // Instanciate a KD-tree search. - // Note: We have to convert each input iterator to Point_3. - std::vector kd_tree_points; - for(it = points.begin(); it != points.end(); it++) - kd_tree_points.push_back(get(point_map, *it)); - Tree tree(kd_tree_points.begin(), kd_tree_points.end()); + Neighbor_query neighbor_query (points, point_map); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Computes normals\n"); + std::size_t nb_points = points.size(); + // iterate over input points, compute and output normal // vectors (already normalized) #ifndef CGAL_LINKED_WITH_TBB @@ -246,40 +195,44 @@ pca_estimate_normals( "Parallel_tag is enabled but TBB is unavailable."); #else if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, kd_tree_points.size()); + { + Point_set_processing_3::internal::Parallel_callback + parallel_callback (callback, nb_points); - std::vector normals (kd_tree_points.size (), - CGAL::NULL_VECTOR); - CGAL::internal::PCA_estimate_normals - f (tree, k, neighbor_radius, kd_tree_points, normals, - parallel_callback.advancement(), - parallel_callback.interrupted()); - tbb::parallel_for(tbb::blocked_range(0, kd_tree_points.size ()), f); - unsigned int i = 0; - for(it = points.begin(); it != points.end(); ++ it, ++ i) - if (normals[i] != CGAL::NULL_VECTOR) - put (normal_map, *it, normals[i]); + tbb::parallel_for(tbb::blocked_range(0, nb_points), + [&](const tbb::blocked_range& r) + { + for( std::size_t i = r.begin(); i != r.end(); ++i) + { + if (parallel_callback.interrupted()) + break; + + put (normal_map, *(points.begin() + i), + CGAL::internal::pca_estimate_normal + (get(point_map, *(points.begin() + i)), neighbor_query, k, neighbor_radius)); + + ++ parallel_callback.advancement(); + } + }); - parallel_callback.join(); - } + parallel_callback.join(); + } else #endif + { + std::size_t nb = 0; + for (const value_type& vt : points) { - std::size_t nb = 0; - for(it = points.begin(); it != points.end(); it++, ++ nb) - { - Vector normal = internal::pca_estimate_normal( - get(point_map,*it), - tree, - k, neighbor_radius); - - put(normal_map, *it, normal); // normal_map[it] = normal - if (callback && !callback ((nb+1) / double(kd_tree_points.size()))) - break; - } + put (normal_map, vt, + internal::pca_estimate_normal( + get(point_map, vt), + neighbor_query, + k, neighbor_radius)); + if (callback && !callback ((nb+1) / double(nb_points))) + break; + ++ nb; } + } memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE("End of pca_estimate_normals()\n"); diff --git a/Point_set_processing_3/include/CGAL/remove_outliers.h b/Point_set_processing_3/include/CGAL/remove_outliers.h index 60a5f2c4af0..63b4754216c 100644 --- a/Point_set_processing_3/include/CGAL/remove_outliers.h +++ b/Point_set_processing_3/include/CGAL/remove_outliers.h @@ -16,9 +16,7 @@ #include -#include -#include -#include +#include #include #include #include @@ -49,12 +47,11 @@ namespace internal { /// @tparam Tree KD-tree. /// /// @return computed distance. -template < typename Kernel, - typename Tree > -typename Kernel::FT +template +typename NeighborQuery::Kernel::FT compute_avg_knn_sq_distance_3( - const typename Kernel::Point_3& query, ///< 3D point to project - Tree& tree, ///< KD-tree + const typename NeighborQuery::Kernel::Point_3& query, ///< 3D point to project + NeighborQuery& neighbor_query, ///< KD-tree unsigned int k, ///< number of neighbors typename Kernel::FT neighbor_radius) { @@ -63,8 +60,7 @@ compute_avg_knn_sq_distance_3( typedef typename Kernel::Point_3 Point; std::vector points; - CGAL::Point_set_processing_3::internal::neighbor_query - (query, tree, k, neighbor_radius, points); + neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); // compute average squared distance typename Kernel::Compute_squared_distance_3 sqd; @@ -162,15 +158,15 @@ remove_outliers( typedef typename Kernel::FT FT; // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Kernel::Point_3 Point; // actual type of input points typedef typename std::iterator_traits::value_type Enriched_point; // types for K nearest neighbors search structure - typedef typename CGAL::Search_traits_3 Tree_traits; - typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef typename Neighbor_search::Tree Tree; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -182,26 +178,22 @@ remove_outliers( CGAL_point_set_processing_precondition(threshold_percent >= 0 && threshold_percent <= 100); - typename PointRange::iterator it; + Neighbor_query neighbor_query (points, point_map); - // Instanciate a KD-tree search. - // Note: We have to convert each input iterator to Point_3. - std::vector kd_tree_points; - for(it = points.begin(); it != points.end(); it++) - kd_tree_points.push_back( get(point_map, *it) ); - Tree tree(kd_tree_points.begin(), kd_tree_points.end()); + std::size_t nb_points = points.size(); // iterate over input points and add them to multimap sorted by distance to k std::multimap sorted_points; std::size_t nb = 0; - for(it = points.begin(); it != points.end(); it++, ++ nb) + for(const value_type& vt : points) { - FT sq_distance = internal::compute_avg_knn_sq_distance_3( - get(point_map,*it), - tree, k, neighbor_radius); - sorted_points.insert( std::make_pair(sq_distance, *it) ); - if (callback && !callback ((nb+1) / double(kd_tree_points.size()))) + FT sq_distance = internal::compute_avg_knn_sq_distance_3( + get(point_map, vt), + neighbor_query, k, neighbor_radius); + sorted_points.insert( std::make_pair(sq_distance, vt) ); + if (callback && !callback ((nb+1) / double(nb_points))) return points.end(); + ++ nb; } // Replaces [points.begin(), points.end()) range by the multimap content. From b99402f9535fe8029ac4828e78a20cd1da67fbb2 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 2 Mar 2020 12:23:10 +0100 Subject: [PATCH 02/30] Add convenient for_each to transparently use sequential/parallel/randomaccess/not --- STL_Extension/include/CGAL/for_each.h | 142 ++++++++++++++++++ STL_Extension/include/CGAL/iterator.h | 11 ++ .../test/STL_Extension/CMakeLists.txt | 4 + .../test/STL_Extension/test_for_each.cpp | 44 ++++++ 4 files changed, 201 insertions(+) create mode 100644 STL_Extension/include/CGAL/for_each.h create mode 100644 STL_Extension/test/STL_Extension/test_for_each.cpp diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h new file mode 100644 index 00000000000..8096592370d --- /dev/null +++ b/STL_Extension/include/CGAL/for_each.h @@ -0,0 +1,142 @@ +// Copyright (c) 2020 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_FOR_EACH_H +#define CGAL_FOR_EACH_H + +#include + +#ifdef CGAL_LINKED_WITH_TBB +#include +#include +#include +#endif // CGAL_LINKED_WITH_TBB + +namespace CGAL { + +namespace internal { + +// To emulate either a "break" in sequential and a "return" in +// parallel, we use an interal throw/catch mechanism +struct stop_for_each : public std::exception { }; + +template +void for_each (RangeRef range, + const std::function::type>::reference)>& functor, + const Sequential_tag&, + const IteratorCategory&) +{ + for (typename std::iterator_traits + ::type>::reference r : range) + try + { + functor(r); + } + catch (stop_for_each) + { + break; + } +} + +#ifdef CGAL_LINKED_WITH_TBB +template +void for_each (RangeRef range, + const std::function::type>::reference)>& functor, + const Parallel_tag&, + const IteratorCategory&) +{ + std::size_t range_size = std::distance (range.begin(), range.end()); + + std::vector::type> iterators; + iterators.reserve (range_size); + for (typename Range_iterator_type::type it = range.begin(); it != range.end(); ++ it) + iterators.push_back (it); + + tbb::parallel_for (tbb::blocked_range(0, range_size), + [&](const tbb::blocked_range& r) + { + for (std::size_t i = r.begin(); i != r.end(); ++ i) + try + { + functor (*(iterators[i])); + } + catch (stop_for_each) + { + return; + } + }); +} + +template +void for_each (const RangeRef range, + const std::function::type>::reference)>& functor, + const Parallel_tag&, + const std::random_access_iterator_tag&) +{ + std::size_t range_size = std::distance (range.begin(), range.end()); + + tbb::parallel_for (tbb::blocked_range(0, range_size), + [&](const tbb::blocked_range& r) + { + for (std::size_t i = r.begin(); i != r.end(); ++ i) + try + { + functor (*(range.begin() + i)); + } + catch (stop_for_each) + { + return; + } + }); +} +#endif + +} // namespace internal + +template +void for_each (const Range& range, + const std::function::reference)>& functor) +{ +#ifndef CGAL_LINKED_WITH_TBB + CGAL_static_assertion_msg (!(boost::is_convertible::value), + "Parallel_tag is enabled but TBB is unavailable."); +#endif + + internal::for_each + (range, functor, + ConcurrencyTag(), + typename std::iterator_traits::iterator_category()); +} + +template +void for_each (Range& range, + const std::function::reference)>& functor) +{ +#ifndef CGAL_LINKED_WITH_TBB + CGAL_static_assertion_msg (!(boost::is_convertible::value), + "Parallel_tag is enabled but TBB is unavailable."); +#endif + + internal::for_each + (range, functor, + ConcurrencyTag(), + typename std::iterator_traits::iterator_category()); +} + +} // namespace CGAL + + +#endif // CGAL_FOR_EACH_H diff --git a/STL_Extension/include/CGAL/iterator.h b/STL_Extension/include/CGAL/iterator.h index a219fdf3226..4875fb69aa5 100644 --- a/STL_Extension/include/CGAL/iterator.h +++ b/STL_Extension/include/CGAL/iterator.h @@ -1471,6 +1471,17 @@ dispatch_or_drop_output(O... o) return Dispatch_or_drop_output_iterator, std::tuple >(o...); } + +// Trick to select iterator or const_iterator depending on the range constness +template +struct Range_iterator_type { typedef int type; }; // Should generate errors +template +struct Range_iterator_type { typedef typename RangeRef::iterator type; }; +template +struct Range_iterator_type { typedef typename RangeRef::const_iterator type; }; + + + } //namespace CGAL #include diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index 419220ed841..105fb37149f 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -42,6 +42,10 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_Uncertain.cpp" ) create_single_source_cgal_program( "test_vector.cpp" ) create_single_source_cgal_program( "test_join_iterators.cpp" ) + create_single_source_cgal_program( "test_for_each.cpp" ) + if(TBB_FOUND) + CGAL_target_use_TBB(test_for_each) + endif() else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/STL_Extension/test/STL_Extension/test_for_each.cpp b/STL_Extension/test/STL_Extension/test_for_each.cpp new file mode 100644 index 00000000000..b82ba01468c --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_for_each.cpp @@ -0,0 +1,44 @@ +#include + +#include +#include + +int main() +{ + std::vector vec { 0, 1, 2, 3, 4, 5 }; + std::list list { 0, 1, 2, 3, 4, 5 }; + + std::cerr << "Testing sequential random access" << std::endl; + CGAL::for_each + (vec, [](int& i) { i *= 2; }); + + for (const int& i : vec) + std::cerr << i << " "; + std::cerr << std::endl; + + std::cerr << "Testing parallel random access" << std::endl; + CGAL::for_each + (vec, [](int& i) { i *= 2; }); + + for (const int& i : vec) + std::cerr << i << " "; + std::cerr << std::endl; + + std::cerr << "Testing sequential non-random access" << std::endl; + CGAL::for_each + (list, [](int& i) { i *= 2; }); + + for (const int& i : list) + std::cerr << i << " "; + std::cerr << std::endl; + + std::cerr << "Testing parallel non-random access" << std::endl; + CGAL::for_each + (list, [](int& i) { i *= 2; }); + + for (const int& i : list) + std::cerr << i << " "; + std::cerr << std::endl; + + return 0; +} From db8650a8758357663aa01e4cb259265c1e55ed12 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 2 Mar 2020 12:23:56 +0100 Subject: [PATCH 03/30] Make filter iterator copiable --- .../include/CGAL/Poisson_reconstruction_function.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index 09b119bbe3b..bc434ba814a 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -106,13 +106,13 @@ struct Poisson_visitor { struct Poisson_skip_vertices { double ratio; - Random& m_random; - Poisson_skip_vertices(const double ratio, Random& random) + Random* m_random; + Poisson_skip_vertices(const double ratio = 0, Random* random = nullptr) : ratio(ratio), m_random(random) {} template bool operator()(Iterator) const { - return m_random.get_double() < ratio; + return m_random->get_double() < ratio; } }; @@ -419,7 +419,7 @@ public: Poisson_skip_vertices> Some_points_iterator; //make it deterministic Random random(0); - Poisson_skip_vertices skip(1.-approximation_ratio,random); + Poisson_skip_vertices skip(1.-approximation_ratio,&random); CGAL_TRACE_STREAM << "SPECIAL PASS that uses an approximation of the result (approximation ratio: " << approximation_ratio << ")" << std::endl; From 50ae0aeba4b9eae5bda72088d9e11ac381a05895 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 2 Mar 2020 12:24:40 +0100 Subject: [PATCH 04/30] Replace Parallel_callback by Callback_wrapper + cleaning/improvements of factorized KD Tree --- .../internal/Neighbor_query.h | 40 ++--- .../internal/Parallel_callback.h | 108 ----------- .../include/CGAL/bilateral_smooth_point_set.h | 165 +++++++---------- .../include/CGAL/compute_average_spacing.h | 126 ++++--------- .../include/CGAL/jet_estimate_normals.h | 65 ++----- .../include/CGAL/jet_smooth_point_set.h | 77 +++----- .../include/CGAL/mst_orient_normals.h | 2 +- .../include/CGAL/pca_estimate_normals.h | 72 +++----- .../include/CGAL/remove_outliers.h | 2 +- .../wlop_simplify_and_regularize_point_set.h | 168 ++++-------------- 10 files changed, 204 insertions(+), 621 deletions(-) delete mode 100644 Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Parallel_callback.h diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h index 74ed1e17b5b..1160fb3a3e5 100644 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h @@ -19,6 +19,8 @@ #include #include +#include + #include namespace CGAL { @@ -27,26 +29,26 @@ namespace internal { struct Maximum_points_reached_exception : public std::exception { }; -template +template class Neighbor_query { public: typedef Kernel_ Kernel; - typedef PointRange Point_range; + typedef PointRangeRef Point_range; typedef PointMap Point_map; typedef typename Kernel::FT FT; typedef typename Kernel::Point_3 Point_3; - typedef typename PointRange::iterator input_iterator; + typedef typename Range_iterator_type::type input_iterator; typedef typename input_iterator::value_type value_type; typedef CGAL::Prevent_deref iterator; struct Deref_point_map { - typedef iterator key_type; + typedef input_iterator key_type; typedef typename boost::property_traits::reference reference; typedef typename boost::property_traits::value_type value_type; typedef typename boost::property_traits::category category; @@ -58,14 +60,14 @@ public: friend reference get (const Deref_point_map& map, key_type it) { - return get(map.point_map, **it); + return get(map.point_map, *it); } }; typedef CGAL::Search_traits_3 Tree_traits_base; - typedef CGAL::Search_traits_adapter Tree_traits; + typedef CGAL::Search_traits_adapter Tree_traits; typedef CGAL::Sliding_midpoint Splitter; - typedef CGAL::Distance_adapter > Distance; + typedef CGAL::Distance_adapter > Distance; typedef CGAL::Kd_tree Tree; typedef CGAL::Fuzzy_sphere Sphere; @@ -74,7 +76,7 @@ public: private: - PointRange& m_points; + PointRangeRef m_points; PointMap m_point_map; Deref_point_map m_deref_map; Tree_traits m_traits; @@ -86,7 +88,7 @@ private: public: - Neighbor_query (PointRange& points, PointMap point_map) + Neighbor_query (PointRangeRef points, PointMap point_map) : m_points (points) , m_point_map (point_map) , m_deref_map (point_map) @@ -97,18 +99,6 @@ public: m_tree.build(); } - // Hack to avoid problems with const ranges - Neighbor_query (const PointRange& points, PointMap point_map) - : m_points (const_cast(points)) - , m_point_map (point_map) - , m_deref_map (point_map) - , m_traits (m_deref_map) - , m_tree (iterator(m_points.begin()), iterator(m_points.end()), Splitter(), m_traits) - , m_distance (m_deref_map) - { - m_tree.build(); - } - PointMap point_map() const { return m_point_map; } template @@ -127,10 +117,10 @@ public: try { - std::function output_iterator_with_limit - = [&](const iterator& it) + std::function output_iterator_with_limit + = [&](const input_iterator& it) { - *(output ++) = *it; + *(output ++) = it; if (++ nb == k) throw Maximum_points_reached_exception(); }; @@ -166,7 +156,7 @@ public: { if(search_iterator == search.end()) break; // premature ending - *(output ++) = *(search_iterator->first); + *(output ++) = search_iterator->first; search_iterator++; } } diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Parallel_callback.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Parallel_callback.h deleted file mode 100644 index 0064a9da985..00000000000 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Parallel_callback.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2018 GeometryFactory (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_PSP_INTERNAL_PARALLEL_CALLBACK_H -#define CGAL_PSP_INTERNAL_PARALLEL_CALLBACK_H - -#include - -#include - -#include - -namespace CGAL { -namespace Point_set_processing_3 { -namespace internal { - -class Parallel_callback -{ - const std::function& m_callback; - cpp11::atomic* m_advancement; - cpp11::atomic* m_interrupted; - std::size_t m_size; - bool m_creator; - cpp11::thread* m_thread; - - // assignment operator shouldn't be used (m_callback is const ref) - Parallel_callback& operator= (const Parallel_callback&) - { - return *this; - } - -public: - Parallel_callback (const std::function& callback, - std::size_t size, - std::size_t advancement = 0, - bool interrupted = false) - : m_callback (callback) - , m_advancement (new cpp11::atomic()) - , m_interrupted (new cpp11::atomic()) - , m_size (size) - , m_creator (true) - , m_thread (nullptr) - { - // cpp11::atomic only has default constructor, initialization done in two steps - *m_advancement = advancement; - *m_interrupted = interrupted; - if (m_callback) - m_thread = new cpp11::thread (*this); - } - - Parallel_callback (const Parallel_callback& other) - : m_callback (other.m_callback) - , m_advancement (other.m_advancement) - , m_interrupted (other.m_interrupted) - , m_size (other.m_size) - , m_creator (false) - , m_thread (nullptr) - { - - } - - - ~Parallel_callback () - { - if (m_creator) - { - delete m_advancement; - delete m_interrupted; - } - if (m_thread != nullptr) - delete m_thread; - } - - cpp11::atomic& advancement() { return *m_advancement; } - cpp11::atomic& interrupted() { return *m_interrupted; } - void join() - { - if (m_thread != nullptr) - m_thread->join(); - } - - void operator()() - { - while (*m_advancement != m_size) - { - if (!m_callback (*m_advancement / double(m_size))) - *m_interrupted = true; - if (*m_interrupted) - return; - cpp11::sleep_for (0.00001); - } - m_callback (1.); - } -}; - -} // namespace internal -} // namespace Point_set_processing_3 -} // namespace CGAL - -#endif // CGAL_PSP_INTERNAL_PARALLEL_CALLBACK_H diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index ca871cca2cb..7a5ce9d36de 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,8 @@ #include #include +#include + #include #include #include @@ -35,23 +39,6 @@ #include #include -#ifdef CGAL_LINKED_WITH_TBB - -#include -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB - -// Default allocator: use TBB allocators if available -#ifdef CGAL_LINKED_WITH_TBB -# define CGAL_PSP3_DEFAULT_ALLOCATOR tbb::scalable_allocator -#else // CGAL_LINKED_WITH_TBB -# define CGAL_PSP3_DEFAULT_ALLOCATOR std::allocator -#endif // CGAL_LINKED_WITH_TBB - - //#define CGAL_PSP3_VERBOSE namespace CGAL { @@ -271,7 +258,7 @@ bilateral_smooth_point_set( CGAL_point_set_processing_precondition(k > 1); // types for K nearest neighbors search structure - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; PointMap point_map = choose_parameter(get_parameter(np, internal_np::point_map), PointMap()); NormalMap normal_map = choose_parameter(get_parameter(np, internal_np::normal_map), NormalMap()); @@ -314,56 +301,38 @@ bilateral_smooth_point_set( task_timer.start(); #endif // compute all neighbors - std::vector > pwns_neighbors; + typedef std::vector iterators; + std::vector pwns_neighbors; pwns_neighbors.resize(nb_points); -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, 2 * nb_points); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, 2 * nb_points); - tbb::parallel_for(tbb::blocked_range(0, nb_points), - [&](const tbb::blocked_range& r) - { - for (size_t i = r.begin(); i!=r.end(); i++) - { - if (parallel_callback.interrupted()) - break; + typedef boost::zip_iterator::iterator> > Zip_iterator; - neighbor_query.get_iterators (get(point_map, *(points.begin() + i)), k, neighbor_radius, - std::back_inserter (pwns_neighbors[i])); + CGAL::for_each + (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple (points.begin(), pwns_neighbors.begin())), + boost::make_zip_iterator (boost::make_tuple (points.end(), pwns_neighbors.end()))), + [&](const typename Zip_iterator::reference& t) + { + if (callback_wrapper.interrupted()) + throw CGAL::internal::stop_for_each(); + + neighbor_query.get_iterators (get(point_map, get<0>(t)), k, neighbor_radius, + std::back_inserter (get<1>(t))); - ++ parallel_callback.advancement(); - } - }); + ++ callback_wrapper.advancement(); + }); - bool interrupted = parallel_callback.interrupted(); + bool interrupted = callback_wrapper.interrupted(); - // We interrupt by hand as counter only goes halfway and won't terminate by itself - parallel_callback.interrupted() = true; - parallel_callback.join(); + // We interrupt by hand as counter only goes halfway and won't terminate by itself + callback_wrapper.interrupted() = true; + callback_wrapper.join(); - // If interrupted during this step, nothing is computed, we return NaN - if (interrupted) - return std::numeric_limits::quiet_NaN(); - } - else -#endif - { - std::size_t nb = 0; - for (const value_type& vt : points) - { - neighbor_query.get_iterators (get (point_map, vt), k, neighbor_radius, std::back_inserter (pwns_neighbors[nb])); - - if (callback && !callback ((nb+1) / double(2. * nb_points))) - return std::numeric_limits::quiet_NaN(); - ++ nb; - } - } + // If interrupted during this step, nothing is computed, we return NaN + if (interrupted) + return std::numeric_limits::quiet_NaN(); #ifdef CGAL_PSP3_VERBOSE task_timer.stop(); @@ -378,53 +347,41 @@ bilateral_smooth_point_set( // update points and normals std::vector > update_pwns(nb_points); -#ifdef CGAL_LINKED_WITH_TBB - if(boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, 2 * nb_points, nb_points); + callback_wrapper.reset (2 * nb_points, nb_points); + + typedef boost::zip_iterator + ::iterator, + typename std::vector >::iterator> > Zip_iterator_2; + - tbb::parallel_for(tbb::blocked_range (0, nb_points), - [&](const tbb::blocked_range& r) - { - for (size_t i = r.begin(); i != r.end(); ++i) - { - if (parallel_callback.interrupted()) - break; - update_pwns[i] = bilateral_smooth_point_set_internal:: - compute_denoise_projection - (*(points.begin() + i), - point_map, normal_map, - pwns_neighbors[i], - guess_neighbor_radius, - sharpness_angle); - ++ parallel_callback.advancement(); - } - }); + CGAL::for_each + (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple + (points.begin(), pwns_neighbors.begin(), update_pwns.begin())), + boost::make_zip_iterator (boost::make_tuple + (points.end(), pwns_neighbors.end(), update_pwns.end()))), + [&](const typename Zip_iterator_2::reference& t) + { + if (callback_wrapper.interrupted()) + throw CGAL::internal::stop_for_each(); - parallel_callback.join(); + get<2>(t) = bilateral_smooth_point_set_internal:: + compute_denoise_projection + (get<0>(t), + point_map, normal_map, + get<1>(t), + guess_neighbor_radius, + sharpness_angle); + + ++ callback_wrapper.advancement(); + }); + + callback_wrapper.join(); - // If interrupted during this step, nothing is computed, we return NaN - if (parallel_callback.interrupted()) - return std::numeric_limits::quiet_NaN(); - } - else -#endif // CGAL_LINKED_WITH_TBB - { - std::size_t nb = 0; - for (const value_type& vt : points) - { - update_pwns[nb] =bilateral_smooth_point_set_internal:: - compute_denoise_projection - (vt, point_map, normal_map, - pwns_neighbors[nb], - guess_neighbor_radius, - sharpness_angle); - if (callback && !callback ((nb+1) / double(2. * nb_points))) - return std::numeric_limits::quiet_NaN(); - ++ nb; - } - } + // If interrupted during this step, nothing is computed, we return NaN + if (callback_wrapper.interrupted()) + return std::numeric_limits::quiet_NaN(); + #ifdef CGAL_PSP3_VERBOSE task_timer.stop(); memory = CGAL::Memory_sizer().virtual_size(); diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index dd8242912d0..dfa111c50d6 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -27,15 +29,12 @@ #include #include +#include + #include #include -#ifdef CGAL_LINKED_WITH_TBB -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB + #ifdef DOXYGEN_RUNNING #define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters @@ -91,43 +90,6 @@ compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, // } -#ifdef CGAL_LINKED_WITH_TBB - template - class Compute_average_spacings { - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::FT FT; - const Tree& tree; - const unsigned int k; - const std::vector& input; - std::vector& output; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - - public: - Compute_average_spacings(Tree& tree, unsigned int k, std::vector& points, - std::vector& output, - cpp11::atomic& advancement, - cpp11::atomic& interrupted) - : tree(tree), k (k), input (points), output (output) - , advancement (advancement) - , interrupted (interrupted) - { } - - void operator()(const tbb::blocked_range& r) const - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - - output[i] = CGAL::internal::compute_average_spacing(input[i], tree, k); - ++ advancement; - } - } - - }; -#endif // CGAL_LINKED_WITH_TBB - } /* namespace internal */ /// \endcond @@ -188,7 +150,7 @@ compute_average_spacing( using parameters::get_parameter; // basic geometric types - typedef typename PointRange::iterator iterator; + typedef typename PointRange::const_iterator iterator; typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::const_type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -201,7 +163,7 @@ compute_average_spacing( // types for K nearest neighbors search structure typedef typename Kernel::FT FT; - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -218,60 +180,38 @@ compute_average_spacing( // vectors (already normalized) FT sum_spacings = (FT)0.0; std::size_t nb = 0; - std::size_t nb_points = points.size(); + std::size_t nb_points = std::distance(points.begin(), points.end()); -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, nb_points); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, nb_points); - std::vector spacings (nb_points, -1); - tbb::parallel_for(tbb::blocked_range(0, nb_points), - [&](const tbb::blocked_range& r) - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (parallel_callback.interrupted()) - break; - - spacings[i] = CGAL::internal::compute_average_spacing - (get(point_map, *(points.begin() + i)), neighbor_query, k); - ++ parallel_callback.advancement(); - } + std::vector spacings (nb_points, -1); - }); - - for (unsigned int i = 0; i < spacings.size (); ++ i) - if (spacings[i] >= 0.) - { - sum_spacings += spacings[i]; - ++ nb; - } - - parallel_callback.join(); - } - else -#endif + typedef boost::zip_iterator::iterator> > Zip_iterator; + + CGAL::for_each + (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple (points.begin(), spacings.begin())), + boost::make_zip_iterator (boost::make_tuple (points.end(), spacings.end()))), + [&](const typename Zip_iterator::reference& t) { - for(typename PointRange::const_iterator it = points.begin(); it != points.end(); it++, nb++) - { - sum_spacings += internal::compute_average_spacing( - get(point_map,*it), - neighbor_query,k); - if (callback && !callback ((nb+1) / double(nb_points))) - { - ++ nb; - break; - } - } - } + if (callback_wrapper.interrupted()) + throw CGAL::internal::stop_for_each(); + + get<1>(t) = CGAL::internal::compute_average_spacing + (get(point_map, get<0>(t)), neighbor_query, k); + ++ callback_wrapper.advancement(); + }); + + for (unsigned int i = 0; i < spacings.size (); ++ i) + if (spacings[i] >= 0.) + { + sum_spacings += spacings[i]; + ++ nb; + } + callback_wrapper.join(); // return average spacing - return sum_spacings / (FT)(nb); + return sum_spacings / (FT)(nb); } /// \cond SKIP_IN_MANUAL diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index 5095bfacb70..61affa8787b 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -30,13 +32,6 @@ #include #include -#ifdef CGAL_LINKED_WITH_TBB -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB - namespace CGAL { @@ -183,7 +178,7 @@ jet_estimate_normals( typedef typename boost::property_traits::value_type Vector; // types for K nearest neighbors search structure - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -203,51 +198,23 @@ jet_estimate_normals( std::size_t nb_points = points.size(); - // iterate over input points, compute and output normal - // vectors (already normalized) -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, nb_points); - - tbb::parallel_for(tbb::blocked_range(0, points.size ()), - [&](const tbb::blocked_range& r) - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (parallel_callback.interrupted()) - break; - put (normal_map, *(points.begin() + i), - CGAL::internal::jet_estimate_normal - (get(point_map, *(points.begin() + i)), neighbor_query, k, neighbor_radius, degree_fitting)); - ++ parallel_callback.advancement(); - } - }); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, nb_points); - parallel_callback.join(); - } - else -#endif - { - std::size_t nb = 0; - for (const value_type& vt : points) + CGAL::for_each + (points, + [&](const value_type& vt) { + if (callback_wrapper.interrupted()) + throw internal::stop_for_each(); + put (normal_map, vt, - internal::jet_estimate_normal( - get(point_map, vt), - neighbor_query, k, neighbor_radius, degree_fitting)); - - if (callback && !callback ((nb+1) / double(nb_points))) - break; - - ++ nb; - } - } + CGAL::internal::jet_estimate_normal + (get(point_map, vt), neighbor_query, k, neighbor_radius, degree_fitting)); + ++ callback_wrapper.advancement(); + }); + callback_wrapper.join(); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE("End of jet_estimate_normals()\n"); diff --git a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h index acf12856e4b..8f4e5134ef2 100644 --- a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -29,13 +31,6 @@ #include #include -#ifdef CGAL_LINKED_WITH_TBB -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB - namespace CGAL { @@ -178,7 +173,7 @@ jet_smooth_point_set( typedef typename Kernel::Point_3 Point; // types for K nearest neighbors search structure - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -196,59 +191,27 @@ jet_smooth_point_set( std::size_t nb_points = points.size(); -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, nb_points); - - std::vector mutated_points (nb_points, CGAL::ORIGIN); - tbb::parallel_for(tbb::blocked_range(0, nb_points), - [&](const tbb::blocked_range& r) - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (parallel_callback.interrupted()) - break; - mutated_points[i] = - CGAL::internal::jet_smooth_point - (get (point_map, *(points.begin() + i)), neighbor_query, - k, - neighbor_radius, - degree_fitting, - degree_monge); - ++ parallel_callback.advancement(); - } - }); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, nb_points); - unsigned int i = 0; - for (const value_type& vt : points) + CGAL::for_each + (points, + [&](value_type vt) { - if (mutated_points[i] != CGAL::ORIGIN) - put(point_map, vt, mutated_points[i]); - ++ i; - } + if (callback_wrapper.interrupted()) + throw internal::stop_for_each(); - parallel_callback.join(); + put (point_map, vt, + CGAL::internal::jet_smooth_point + (get (point_map, vt), neighbor_query, + k, + neighbor_radius, + degree_fitting, + degree_monge)); + ++ callback_wrapper.advancement(); + }); - } - else -#endif - { - std::size_t nb = 0; - for (const value_type& vt : points) - { - put(point_map, vt, - internal::jet_smooth_point - (get (point_map, vt), neighbor_query,k,neighbor_radius,degree_fitting,degree_monge) ); - if (callback && !callback ((nb+1) / double(nb_points))) - break; - ++ nb; - } - } + callback_wrapper.join(); } diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index 1db0b213053..2b21c7b31d7 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -317,7 +317,7 @@ create_riemannian_graph( // Types for K nearest neighbors search structure typedef typename PointRange::iterator ForwardIterator; - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // Riemannian_graph types typedef internal::Riemannian_graph Riemannian_graph; diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 63c9782b60c..515e8489de3 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -31,13 +33,6 @@ #include #include -#ifdef CGAL_LINKED_WITH_TBB -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB - namespace CGAL { @@ -168,7 +163,7 @@ pca_estimate_normals( typedef typename boost::property_traits::value_type Vector; // types for K nearest neighbors search structure - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points @@ -188,51 +183,24 @@ pca_estimate_normals( std::size_t nb_points = points.size(); - // iterate over input points, compute and output normal - // vectors (already normalized) -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, nb_points); - - tbb::parallel_for(tbb::blocked_range(0, nb_points), - [&](const tbb::blocked_range& r) - { - for( std::size_t i = r.begin(); i != r.end(); ++i) - { - if (parallel_callback.interrupted()) - break; - - put (normal_map, *(points.begin() + i), - CGAL::internal::pca_estimate_normal - (get(point_map, *(points.begin() + i)), neighbor_query, k, neighbor_radius)); - - ++ parallel_callback.advancement(); - } - }); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, nb_points); - parallel_callback.join(); - } - else -#endif - { - std::size_t nb = 0; - for (const value_type& vt : points) - { - put (normal_map, vt, - internal::pca_estimate_normal( - get(point_map, vt), - neighbor_query, - k, neighbor_radius)); - if (callback && !callback ((nb+1) / double(nb_points))) - break; - ++ nb; - } - } + CGAL::for_each + (points, + [&](const value_type& vt) + { + if (callback_wrapper.interrupted()) + throw internal::stop_for_each(); + + put (normal_map, vt, + CGAL::internal::pca_estimate_normal + (get(point_map, vt), neighbor_query, k, neighbor_radius)); + + ++ callback_wrapper.advancement(); + }); + + callback_wrapper.join(); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE("End of pca_estimate_normals()\n"); diff --git a/Point_set_processing_3/include/CGAL/remove_outliers.h b/Point_set_processing_3/include/CGAL/remove_outliers.h index 63b4754216c..4a625c181a5 100644 --- a/Point_set_processing_3/include/CGAL/remove_outliers.h +++ b/Point_set_processing_3/include/CGAL/remove_outliers.h @@ -166,7 +166,7 @@ remove_outliers( typedef typename std::iterator_traits::value_type Enriched_point; // types for K nearest neighbors search structure - typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; + typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; // precondition: at least one element in the container. // to fix: should have at least three distinct points diff --git a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h index cbe5b1ca5fb..388a2a23ed1 100644 --- a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h +++ b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h @@ -32,12 +32,8 @@ #include #include -#ifdef CGAL_LINKED_WITH_TBB -#include -#include -#include -#include -#endif // CGAL_LINKED_WITH_TBB +#include +#include #include #include @@ -329,67 +325,6 @@ compute_density_weight_for_sample_point( /// \endcond -#ifdef CGAL_LINKED_WITH_TBB -/// \cond SKIP_IN_MANUAL -/// This is for parallelization of function: compute_denoise_projection() -template -class Sample_point_updater -{ - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::FT FT; - - std::vector &update_sample_points; - std::vector &sample_points; - const Tree &original_kd_tree; - const Tree &sample_kd_tree; - const typename Kernel::FT radius; - const std::vector &original_densities; - const std::vector &sample_densities; - cpp11::atomic& advancement; - cpp11::atomic& interrupted; - -public: - Sample_point_updater( - std::vector &out, - std::vector &in, - const Tree &_original_kd_tree, - const Tree &_sample_kd_tree, - const typename Kernel::FT _radius, - const std::vector &_original_densities, - const std::vector &_sample_densities, - cpp11::atomic& advancement, - cpp11::atomic& interrupted): - update_sample_points(out), - sample_points(in), - original_kd_tree(_original_kd_tree), - sample_kd_tree(_sample_kd_tree), - radius(_radius), - original_densities(_original_densities), - sample_densities(_sample_densities), - advancement (advancement), - interrupted (interrupted) {} - - void operator() ( const tbb::blocked_range& r ) const - { - for (size_t i = r.begin(); i != r.end(); ++i) - { - if (interrupted) - break; - update_sample_points[i] = simplify_and_regularize_internal:: - compute_update_sample_point( - sample_points[i], - original_kd_tree, - sample_kd_tree, - radius, - original_densities, - sample_densities); - ++ advancement; - } - } -}; -/// \endcond -#endif // CGAL_LINKED_WITH_TBB - // ---------------------------------------------------------------------------- // Public section @@ -464,6 +399,8 @@ wlop_simplify_and_regularize_point_set( using parameters::get_parameter; // basic geometric types + typedef typename PointRange::iterator iterator; + typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -587,80 +524,49 @@ wlop_simplify_and_regularize_point_set( sample_density_weights.push_back(density); } - - typename std::vector::iterator update_iter = update_sample_points.begin(); -#ifndef CGAL_LINKED_WITH_TBB - CGAL_static_assertion_msg (!(boost::is_convertible::value), - "Parallel_tag is enabled but TBB is unavailable."); -#else - //parallel - if (boost::is_convertible::value) - { - Point_set_processing_3::internal::Parallel_callback - parallel_callback (callback, iter_number * number_of_sample, iter_n * number_of_sample); - - tbb::blocked_range block(0, number_of_sample); - Sample_point_updater sample_updater( - update_sample_points, - sample_points, - original_kd_tree, - sample_kd_tree, - radius2, - original_density_weights, - sample_density_weights, - parallel_callback.advancement(), - parallel_callback.interrupted()); + typedef boost::zip_iterator::iterator, + typename std::vector::iterator> > Zip_iterator; - tbb::parallel_for(block, sample_updater); + Point_set_processing_3::internal::Callback_wrapper + callback_wrapper (callback, iter_number * number_of_sample, iter_n * number_of_sample); - bool interrupted = parallel_callback.interrupted(); + CGAL::for_each + (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple (sample_points.begin(), update_sample_points.begin())), + boost::make_zip_iterator (boost::make_tuple (sample_points.end(), update_sample_points.end()))), + [&](const typename Zip_iterator::reference& t) + { + if (callback_wrapper.interrupted()) + throw internal::stop_for_each(); + + get<1>(t) = simplify_and_regularize_internal:: + compute_update_sample_point( + get<0>(t), + original_kd_tree, + sample_kd_tree, + radius, + original_density_weights, + sample_density_weights); + ++ callback_wrapper.advancement(); + }); + + bool interrupted = callback_wrapper.interrupted(); - // We interrupt by hand as counter only goes halfway and won't terminate by itself - parallel_callback.interrupted() = true; - parallel_callback.join(); + // We interrupt by hand as counter only goes halfway and won't terminate by itself + callback_wrapper.interrupted() = true; + callback_wrapper.join(); - // If interrupted during this step, nothing is computed, we return NaN - if (interrupted) - return output; - }else -#endif - { - //sequential - std::size_t nb = iter_n * number_of_sample; - for (sample_iter = sample_points.begin(); - sample_iter != sample_points.end(); ++sample_iter, ++update_iter, ++ nb) - { - *update_iter = simplify_and_regularize_internal:: - compute_update_sample_point - (*sample_iter, - original_kd_tree, - sample_kd_tree, - radius2, - original_density_weights, - sample_density_weights); - if (callback && !callback ((nb+1) / double(iter_number * number_of_sample))) - return output; - } - } + // If interrupted during this step, nothing is computed, we return NaN + if (interrupted) + return output; sample_iter = sample_points.begin(); - for (update_iter = update_sample_points.begin(); - update_iter != update_sample_points.end(); - ++update_iter, ++sample_iter) - { - *sample_iter = *update_iter; - } + for (std::size_t i = 0; i < sample_points.size(); ++ i) + sample_points[i] = update_sample_points[i]; } // final output - for(sample_iter = sample_points.begin(); - sample_iter != sample_points.end(); ++sample_iter) - { - *output++ = *sample_iter; - } + std::copy (sample_points.begin(), sample_points.end(), output); return output; } From fb3ed791484c9f8529ec70fe0e2c877e0c35bdc4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 2 Mar 2020 13:26:23 +0100 Subject: [PATCH 05/30] Add missing file --- .../internal/Callback_wrapper.h | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h new file mode 100644 index 00000000000..c8ea5f10dfa --- /dev/null +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h @@ -0,0 +1,182 @@ +// Copyright (c) 2018 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_PSP_INTERNAL_CALLBACK_WRAPPER_H +#define CGAL_PSP_INTERNAL_CALLBACK_WRAPPER_H + +#include + +#include + +#include + +namespace CGAL { +namespace Point_set_processing_3 { +namespace internal { + +template +class Callback_wrapper +{ + std::size_t m_advancement; + bool m_interrupted; + +public: + Callback_wrapper (const std::function&, std::size_t, std::size_t, bool = false) { } + void reset (std::size_t, std::size_t, bool = false) { } + std::size_t& advancement() { return m_advancement; } + bool& interrupted() { return m_interrupted; } + void join() { } +}; + +template <> +class Callback_wrapper +{ + const std::function& m_callback; + std::size_t m_advancement; + bool m_interrupted; + std::size_t m_size; + +public: + + Callback_wrapper (const std::function& callback, + std::size_t size, + std::size_t advancement = 0, + bool interrupted = false) + : m_callback (callback) + , m_advancement (advancement) + , m_interrupted (interrupted) + , m_size (size) + { } + + Callback_wrapper (const Callback_wrapper& other) + : m_callback (other.m_callback) + , m_advancement (other.m_advancement) + , m_interrupted (other.m_interrupted) + , m_size (other.m_size) + { } + + ~Callback_wrapper () { } + + void reset (std::size_t size, std::size_t advancement, bool interrupted = false) + { + m_size = size; + m_advancement = advancement; + m_interrupted = interrupted; + } + std::size_t& advancement() + { + return m_advancement; + } + + bool& interrupted() + { + m_interrupted = (m_callback(m_advancement / double(m_size))); + return m_interrupted; + } + + void join() { } +}; + +#ifdef CGAL_LINKED_WITH_TBB +template <> +class Callback_wrapper +{ + const std::function& m_callback; + cpp11::atomic* m_advancement; + cpp11::atomic* m_interrupted; + std::size_t m_size; + bool m_creator; + cpp11::thread* m_thread; + + // assignment operator shouldn't be used (m_callback is const ref) + Callback_wrapper& operator= (const Callback_wrapper&) + { + return *this; + } + +public: + Callback_wrapper (const std::function& callback, + std::size_t size, + std::size_t advancement = 0, + bool interrupted = false) + : m_callback (callback) + , m_advancement (new cpp11::atomic()) + , m_interrupted (new cpp11::atomic()) + , m_size (size) + , m_creator (true) + , m_thread (nullptr) + { + // cpp11::atomic only has default constructor, initialization done in two steps + *m_advancement = advancement; + *m_interrupted = interrupted; + if (m_callback) + m_thread = new cpp11::thread (*this); + } + + Callback_wrapper (const Callback_wrapper& other) + : m_callback (other.m_callback) + , m_advancement (other.m_advancement) + , m_interrupted (other.m_interrupted) + , m_size (other.m_size) + , m_creator (false) + , m_thread (nullptr) + { + + } + + ~Callback_wrapper () + { + if (m_creator) + { + delete m_advancement; + delete m_interrupted; + } + if (m_thread != nullptr) + delete m_thread; + } + + void reset (std::size_t size, std::size_t advancement, bool interrupted = false) + { + m_size = size; + *m_advancement = advancement; + *m_interrupted = interrupted; + if (m_callback) + m_thread = new cpp11::thread (*this); + } + + cpp11::atomic& advancement() { return *m_advancement; } + cpp11::atomic& interrupted() { return *m_interrupted; } + void join() + { + if (m_thread != nullptr) + m_thread->join(); + } + + void operator()() + { + while (*m_advancement != m_size) + { + if (!m_callback (*m_advancement / double(m_size))) + *m_interrupted = true; + if (*m_interrupted) + return; + cpp11::sleep_for (0.00001); + } + m_callback (1.); + } +}; +#endif + +} // namespace internal +} // namespace Point_set_processing_3 +} // namespace CGAL + +#endif // CGAL_PSP_INTERNAL_CALLBACK_WRAPPER_H From 90f7d81291f79fbd0ef533bfdc1cc64969844d6a Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 2 Mar 2020 16:11:55 +0100 Subject: [PATCH 06/30] Fix callback wrapper if no callback provided --- .../internal/Callback_wrapper.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h index c8ea5f10dfa..e6b13e234fe 100644 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h @@ -47,9 +47,9 @@ class Callback_wrapper public: Callback_wrapper (const std::function& callback, - std::size_t size, - std::size_t advancement = 0, - bool interrupted = false) + std::size_t size, + std::size_t advancement = 0, + bool interrupted = false) : m_callback (callback) , m_advancement (advancement) , m_interrupted (interrupted) @@ -78,7 +78,8 @@ public: bool& interrupted() { - m_interrupted = (m_callback(m_advancement / double(m_size))); + if (m_callback) + m_interrupted = (m_callback(m_advancement / double(m_size))); return m_interrupted; } @@ -164,13 +165,14 @@ public: { while (*m_advancement != m_size) { - if (!m_callback (*m_advancement / double(m_size))) + if (m_callback && !m_callback (*m_advancement / double(m_size))) *m_interrupted = true; if (*m_interrupted) return; cpp11::sleep_for (0.00001); } - m_callback (1.); + if (m_callback) + m_callback (1.); } }; #endif From 74151aea0f437641f32ed5bc1abb4812ceb22eb9 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 5 Mar 2020 10:01:01 +0100 Subject: [PATCH 07/30] Fix constness error --- Point_set_processing_3/include/CGAL/jet_estimate_normals.h | 2 +- Point_set_processing_3/include/CGAL/pca_estimate_normals.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index 61affa8787b..c78c3f9951f 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -203,7 +203,7 @@ jet_estimate_normals( CGAL::for_each (points, - [&](const value_type& vt) + [&](value_type& vt) { if (callback_wrapper.interrupted()) throw internal::stop_for_each(); diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 515e8489de3..50dd11631ed 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -188,7 +188,7 @@ pca_estimate_normals( CGAL::for_each (points, - [&](const value_type& vt) + [&](value_type& vt) { if (callback_wrapper.interrupted()) throw internal::stop_for_each(); From 10676940593368f8b9f2138eeab214f65e575ce7 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 5 Mar 2020 11:44:45 +0100 Subject: [PATCH 08/30] Fix some errors --- .../include/CGAL/bilateral_smooth_point_set.h | 2 +- Point_set_processing_3/include/CGAL/remove_outliers.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index 7a5ce9d36de..9c4d7cd8cf7 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -392,7 +392,7 @@ bilateral_smooth_point_set( FT sum_move_error = 0; std::size_t nb = 0; typename PointRange::iterator it = points.begin(); - for (const value_type& vt : points) + for (value_type& vt : points) { sum_move_error += CGAL::squared_distance(get(point_map, vt), update_pwns[nb].first); put (point_map, vt, update_pwns[nb].first); diff --git a/Point_set_processing_3/include/CGAL/remove_outliers.h b/Point_set_processing_3/include/CGAL/remove_outliers.h index 4a625c181a5..f49932d308a 100644 --- a/Point_set_processing_3/include/CGAL/remove_outliers.h +++ b/Point_set_processing_3/include/CGAL/remove_outliers.h @@ -53,9 +53,10 @@ compute_avg_knn_sq_distance_3( const typename NeighborQuery::Kernel::Point_3& query, ///< 3D point to project NeighborQuery& neighbor_query, ///< KD-tree unsigned int k, ///< number of neighbors - typename Kernel::FT neighbor_radius) + typename NeighborQuery::Kernel::FT neighbor_radius) { // geometric types + typedef typename NeighborQuery::Kernel Kernel; typedef typename Kernel::FT FT; typedef typename Kernel::Point_3 Point; From b2db69f8f1a6e7e2c066a3958ed5ac0ad721f1a6 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 5 Mar 2020 14:36:38 +0100 Subject: [PATCH 09/30] Fix license --- STL_Extension/include/CGAL/for_each.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index 8096592370d..819e95f063d 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -5,7 +5,7 @@ // // $URL$ // $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Simon Giraudot From 0fe2ee40e88822430d203587e42f00ef1db346b7 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 12 Mar 2020 10:27:59 +0100 Subject: [PATCH 10/30] Fix outdated precondition --- Point_set_processing_3/include/CGAL/mst_orient_normals.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index 2b21c7b31d7..ce1b00ce43f 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -323,9 +323,6 @@ create_riemannian_graph( typedef internal::Riemannian_graph Riemannian_graph; typedef typename boost::property_map::type Riemannian_graph_weight_map; - // Precondition: at least one element in the container. - CGAL_point_set_processing_precondition(first != beyond); - // Precondition: at least 2 nearest neighbors CGAL_point_set_processing_precondition(k >= 2); From 6b2242356d3d5271184625421981986983f734f4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 17 Mar 2020 12:03:58 +0100 Subject: [PATCH 11/30] Fix uninitialized variable --- Point_set_processing_3/include/CGAL/compute_average_spacing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index dfa111c50d6..2ee0b8ad0bc 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -75,7 +75,7 @@ compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, // // output first). search may be aborted when k is greater // than number of input points FT sum_distances = (FT)0.0; - unsigned int i; + unsigned int i = 0; neighbor_query.get_points (query, k, 0, boost::make_function_output_iterator From a27ab3aa66f585dbe7a144e1143599508a070107 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 09:05:57 +0100 Subject: [PATCH 12/30] Fix unused variable --- Point_set_processing_3/include/CGAL/jet_smooth_point_set.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h index 8f4e5134ef2..c29d67c55c1 100644 --- a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h @@ -170,8 +170,6 @@ jet_smooth_point_set( const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); - typedef typename Kernel::Point_3 Point; - // types for K nearest neighbors search structure typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; From 61b51605b2ae3f2a5725d1aa772d81baf73cd487 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 09:06:09 +0100 Subject: [PATCH 13/30] Fix sequential callback wrapper --- .../CGAL/Point_set_processing_3/internal/Callback_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h index e6b13e234fe..8612be034fd 100644 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h @@ -79,7 +79,7 @@ public: bool& interrupted() { if (m_callback) - m_interrupted = (m_callback(m_advancement / double(m_size))); + m_interrupted = !(m_callback(m_advancement / double(m_size))); return m_interrupted; } From 61d331f45698fb518383526d3efbc3c28ef5c62b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 09:11:41 +0100 Subject: [PATCH 14/30] Fix for_each --- STL_Extension/include/CGAL/for_each.h | 8 ++++---- STL_Extension/include/CGAL/iterator.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index 819e95f063d..e0ac595c753 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -41,7 +41,7 @@ void for_each (RangeRef range, { functor(r); } - catch (stop_for_each) + catch (const stop_for_each&) { break; } @@ -70,7 +70,7 @@ void for_each (RangeRef range, { functor (*(iterators[i])); } - catch (stop_for_each) + catch (const stop_for_each&) { return; } @@ -78,7 +78,7 @@ void for_each (RangeRef range, } template -void for_each (const RangeRef range, +void for_each (RangeRef range, const std::function::type>::reference)>& functor, const Parallel_tag&, @@ -94,7 +94,7 @@ void for_each (const RangeRef range, { functor (*(range.begin() + i)); } - catch (stop_for_each) + catch (const stop_for_each&) { return; } diff --git a/STL_Extension/include/CGAL/iterator.h b/STL_Extension/include/CGAL/iterator.h index 4875fb69aa5..8424af8487f 100644 --- a/STL_Extension/include/CGAL/iterator.h +++ b/STL_Extension/include/CGAL/iterator.h @@ -1474,7 +1474,7 @@ dispatch_or_drop_output(O... o) // Trick to select iterator or const_iterator depending on the range constness template -struct Range_iterator_type { typedef int type; }; // Should generate errors +struct Range_iterator_type; template struct Range_iterator_type { typedef typename RangeRef::iterator type; }; template From 49674688dc931a79cfe26ce501ee9f81cc8429f3 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 14:03:31 +0100 Subject: [PATCH 15/30] Fix unused typedefs --- Point_set_processing_3/include/CGAL/jet_estimate_normals.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index c78c3f9951f..302fdadc19c 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -172,11 +172,6 @@ jet_estimate_normals( const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); - typedef typename Kernel::Point_3 Point; - - // Input points types - typedef typename boost::property_traits::value_type Vector; - // types for K nearest neighbors search structure typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; From 8d9dac02eabb10d190d21331737dc1762f68dacc Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 16:14:00 +0100 Subject: [PATCH 16/30] Fix many warnings --- .../include/CGAL/bilateral_smooth_point_set.h | 6 ++---- .../include/CGAL/compute_average_spacing.h | 3 --- Point_set_processing_3/include/CGAL/pca_estimate_normals.h | 3 --- Point_set_processing_3/include/CGAL/remove_outliers.h | 1 - .../include/CGAL/wlop_simplify_and_regularize_point_set.h | 5 +---- 5 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index 9c4d7cd8cf7..12ee8b09411 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -129,12 +129,11 @@ compute_denoise_projection( /// @tparam Tree KD-tree. /// /// @return max spacing. -template +template typename NeighborQuery::Kernel::FT compute_max_spacing( const typename NeighborQuery::value_type& vt, typename NeighborQuery::Point_map point_map, - VectorMap normal_map, NeighborQuery& neighbor_query, ///< KD-tree unsigned int k) ///< number of neighbors { @@ -282,7 +281,7 @@ bilateral_smooth_point_set( for (const value_type& vt : points) { FT max_spacing = bilateral_smooth_point_set_internal:: - compute_max_spacing (vt, point_map, normal_map, neighbor_query, k); + compute_max_spacing (vt, point_map, neighbor_query, k); guess_neighbor_radius = (CGAL::max)(max_spacing, guess_neighbor_radius); } @@ -391,7 +390,6 @@ bilateral_smooth_point_set( // save results FT sum_move_error = 0; std::size_t nb = 0; - typename PointRange::iterator it = points.begin(); for (value_type& vt : points) { sum_move_error += CGAL::squared_distance(get(point_map, vt), update_pwns[nb].first); diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index 2ee0b8ad0bc..c202f9b4dc5 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -151,12 +151,9 @@ compute_average_spacing( // basic geometric types typedef typename PointRange::const_iterator iterator; - typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::const_type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; - typedef typename Kernel::Point_3 Point; - PointMap point_map = choose_parameter(get_parameter(np, internal_np::point_map), PointMap()); const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 50dd11631ed..648edbbb953 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -155,12 +155,9 @@ pca_estimate_normals( const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); - typedef typename Kernel::Point_3 Point; - // Input points types typedef typename PointRange::iterator iterator; typedef typename iterator::value_type value_type; - typedef typename boost::property_traits::value_type Vector; // types for K nearest neighbors search structure typedef Point_set_processing_3::internal::Neighbor_query Neighbor_query; diff --git a/Point_set_processing_3/include/CGAL/remove_outliers.h b/Point_set_processing_3/include/CGAL/remove_outliers.h index f49932d308a..47e35435d18 100644 --- a/Point_set_processing_3/include/CGAL/remove_outliers.h +++ b/Point_set_processing_3/include/CGAL/remove_outliers.h @@ -161,7 +161,6 @@ remove_outliers( // basic geometric types typedef typename PointRange::iterator iterator; typedef typename iterator::value_type value_type; - typedef typename Kernel::Point_3 Point; // actual type of input points typedef typename std::iterator_traits::value_type Enriched_point; diff --git a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h index 388a2a23ed1..91ef43575d3 100644 --- a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h +++ b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h @@ -7,7 +7,7 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez +// Author(s) : Shihao Wu, Cl:mement Jamin, Pierre Alliez #ifndef CGAL_wlop_simplify_and_regularize_point_set_H #define CGAL_wlop_simplify_and_regularize_point_set_H @@ -399,8 +399,6 @@ wlop_simplify_and_regularize_point_set( using parameters::get_parameter; // basic geometric types - typedef typename PointRange::iterator iterator; - typedef typename iterator::value_type value_type; typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -466,7 +464,6 @@ wlop_simplify_and_regularize_point_set( #endif } - FT radius2 = radius * radius; CGAL_point_set_processing_precondition(radius > 0); // Initiate a KD-tree search for original points From de64512f5c08485b4b3c2f2d78c26232c86e68e1 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 18 Mar 2020 16:33:40 +0100 Subject: [PATCH 17/30] Fix mistake introduced in header --- .../include/CGAL/wlop_simplify_and_regularize_point_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h index 91ef43575d3..b631d225db3 100644 --- a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h +++ b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h @@ -7,7 +7,7 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Shihao Wu, Cl:mement Jamin, Pierre Alliez +// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez #ifndef CGAL_wlop_simplify_and_regularize_point_set_H #define CGAL_wlop_simplify_and_regularize_point_set_H From 1f3f57ecc39bc21d901b3af4302688a45c650dec Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 19 Mar 2020 10:24:52 +0100 Subject: [PATCH 18/30] Fix poisson non-deterministic iterator filtering --- .../include/CGAL/Poisson_reconstruction_function.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index bc434ba814a..b0f0f095e1f 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -106,13 +106,13 @@ struct Poisson_visitor { struct Poisson_skip_vertices { double ratio; - Random* m_random; - Poisson_skip_vertices(const double ratio = 0, Random* random = nullptr) - : ratio(ratio), m_random(random) {} + Poisson_skip_vertices(const double ratio = 0) + : ratio(ratio) {} template - bool operator()(Iterator) const { - return m_random->get_double() < ratio; + bool operator()(Iterator it) const { + // make the result deterministic for each iterator + return Random((std::size_t)(&*it)).get_double() < ratio; } }; @@ -417,9 +417,7 @@ public: typedef Filter_iterator Some_points_iterator; - //make it deterministic - Random random(0); - Poisson_skip_vertices skip(1.-approximation_ratio,&random); + Poisson_skip_vertices skip(1.-approximation_ratio); CGAL_TRACE_STREAM << "SPECIAL PASS that uses an approximation of the result (approximation ratio: " << approximation_ratio << ")" << std::endl; From 16625cda016b88269169a1618ee1fddad7411f3c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 19 Mar 2020 10:38:58 +0100 Subject: [PATCH 19/30] Fix for_each and add a comment on what it does --- STL_Extension/include/CGAL/for_each.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index e0ac595c753..9a320177344 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -20,6 +20,19 @@ #include #endif // CGAL_LINKED_WITH_TBB +/* + CGAL::for_each(Range, Function) does the following: + + - if Sequential_tag is used, apply Function to all elements of Range + - if Parallel_tag is used: + * static assert that TBB is available + * if Range has random access iterators, use a TBB parallel_for + loop to apply Function to all elements of Range + * if Range doesn't have random access iterators, first copy the + iterators in a vector and then use a TBB parallel_for loop to + apply Function to all elements of Range +*/ + namespace CGAL { namespace internal { @@ -33,7 +46,7 @@ void for_each (RangeRef range, const std::function::type>::reference)>& functor, const Sequential_tag&, - const IteratorCategory&) + IteratorCategory) { for (typename std::iterator_traits ::type>::reference r : range) @@ -53,7 +66,7 @@ void for_each (RangeRef range, const std::function::type>::reference)>& functor, const Parallel_tag&, - const IteratorCategory&) + IteratorCategory) { std::size_t range_size = std::distance (range.begin(), range.end()); @@ -82,7 +95,7 @@ void for_each (RangeRef range, const std::function::type>::reference)>& functor, const Parallel_tag&, - const std::random_access_iterator_tag&) + std::random_access_iterator_tag) { std::size_t range_size = std::distance (range.begin(), range.end()); From 0c23a6502879c503ea3a6bd5d94bb7b606973a52 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 19 Mar 2020 15:50:11 +0100 Subject: [PATCH 20/30] Add variant identity map read only without lvalue --- Property_map/include/CGAL/property_map.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index 159b18a64da..e86feb322ff 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -216,6 +216,22 @@ struct Identity_property_map /// @} }; + +/// \cond SKIP_IN_MANUAL +template +struct Identity_property_map_no_lvalue +{ + typedef T key_type; ///< typedef to `T` + typedef T value_type; ///< typedef to `T` + typedef T reference; ///< typedef to `T` + typedef boost::readable_property_map_tag category; ///< `boost::readable_property_map_tag` + + typedef Identity_property_map_no_lvalue Self; + + friend reference get(const Self&, const key_type& k) {return k;} +}; +/// \endcond + /// Free function to create a `Identity_property_map` property map. /// /// \relates Identity_property_map From 37a6a4360f3189d0b24cc6cb1527fe86a05e7125 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 19 Mar 2020 15:50:22 +0100 Subject: [PATCH 21/30] Fix warnings --- .../demo/Optimal_transportation_reconstruction_2/scene.h | 2 +- Spatial_searching/include/CGAL/Kd_tree_rectangle.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h index 5693f0fbb30..2947db39636 100644 --- a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h +++ b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h @@ -407,7 +407,7 @@ public: Point_3_from_sample()), boost::make_transform_iterator (m_samples.end(), Point_3_from_sample())), - 3); + 3, CGAL::parameters::point_map (CGAL::Identity_property_map_no_lvalue())); std::cerr << "Average spacing = " << spacing << std::endl; } diff --git a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h index 297c2203f6c..f0b9b68e48f 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h +++ b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h @@ -105,6 +105,7 @@ namespace CGAL { } Kd_tree_rectangle() + : max_span_coord_(-1) {} From c8aa0c8f573cb4542b48040d826dcdfa5df8fe1b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 19 Mar 2020 15:54:53 +0100 Subject: [PATCH 22/30] Prevent from testing Parallel_tag if TBB is not here --- STL_Extension/test/STL_Extension/test_for_each.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/STL_Extension/test/STL_Extension/test_for_each.cpp b/STL_Extension/test/STL_Extension/test_for_each.cpp index b82ba01468c..d540297dead 100644 --- a/STL_Extension/test/STL_Extension/test_for_each.cpp +++ b/STL_Extension/test/STL_Extension/test_for_each.cpp @@ -15,7 +15,8 @@ int main() for (const int& i : vec) std::cerr << i << " "; std::cerr << std::endl; - + +#ifdef CGAL_LINKED_WITH_TBB std::cerr << "Testing parallel random access" << std::endl; CGAL::for_each (vec, [](int& i) { i *= 2; }); @@ -23,6 +24,7 @@ int main() for (const int& i : vec) std::cerr << i << " "; std::cerr << std::endl; +#endif std::cerr << "Testing sequential non-random access" << std::endl; CGAL::for_each @@ -32,6 +34,7 @@ int main() std::cerr << i << " "; std::cerr << std::endl; +#ifdef CGAL_LINKED_WITH_TBB std::cerr << "Testing parallel non-random access" << std::endl; CGAL::for_each (list, [](int& i) { i *= 2; }); @@ -39,6 +42,7 @@ int main() for (const int& i : list) std::cerr << i << " "; std::cerr << std::endl; +#endif return 0; } From 320876ab230479dc0c2db40b0383bfb6e064df01 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 23 Mar 2020 08:27:55 +0100 Subject: [PATCH 23/30] Replace exception by return value to stop for_each loops --- .../include/CGAL/bilateral_smooth_point_set.h | 8 +++- .../include/CGAL/compute_average_spacing.h | 4 +- .../include/CGAL/jet_estimate_normals.h | 4 +- .../include/CGAL/jet_smooth_point_set.h | 4 +- .../include/CGAL/pca_estimate_normals.h | 4 +- .../wlop_simplify_and_regularize_point_set.h | 4 +- STL_Extension/include/CGAL/for_each.h | 45 ++++++------------- 7 files changed, 34 insertions(+), 39 deletions(-) diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index d382ce2b792..4246460d55a 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -315,12 +315,14 @@ bilateral_smooth_point_set( [&](const typename Zip_iterator::reference& t) { if (callback_wrapper.interrupted()) - throw CGAL::internal::stop_for_each(); + return false; neighbor_query.get_iterators (get(point_map, get<0>(t)), k, neighbor_radius, std::back_inserter (get<1>(t))); ++ callback_wrapper.advancement(); + + return true; }); bool interrupted = callback_wrapper.interrupted(); @@ -362,7 +364,7 @@ bilateral_smooth_point_set( [&](const typename Zip_iterator_2::reference& t) { if (callback_wrapper.interrupted()) - throw CGAL::internal::stop_for_each(); + return false; get<2>(t) = bilateral_smooth_point_set_internal:: compute_denoise_projection @@ -373,6 +375,8 @@ bilateral_smooth_point_set( sharpness_angle); ++ callback_wrapper.advancement(); + + return true; }); callback_wrapper.join(); diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index 192a7c537a1..3156d0ff469 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -192,11 +192,13 @@ compute_average_spacing( [&](const typename Zip_iterator::reference& t) { if (callback_wrapper.interrupted()) - throw CGAL::internal::stop_for_each(); + return false; get<1>(t) = CGAL::internal::compute_average_spacing (get(point_map, get<0>(t)), neighbor_query, k); ++ callback_wrapper.advancement(); + + return true; }); for (unsigned int i = 0; i < spacings.size (); ++ i) diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index e88405ca49d..9a021398c6a 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -201,12 +201,14 @@ jet_estimate_normals( [&](value_type& vt) { if (callback_wrapper.interrupted()) - throw internal::stop_for_each(); + return false; put (normal_map, vt, CGAL::internal::jet_estimate_normal (get(point_map, vt), neighbor_query, k, neighbor_radius, degree_fitting)); ++ callback_wrapper.advancement(); + + return true; }); callback_wrapper.join(); diff --git a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h index 0920b89ec30..6203dc76e0c 100644 --- a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h @@ -197,7 +197,7 @@ jet_smooth_point_set( [&](value_type vt) { if (callback_wrapper.interrupted()) - throw internal::stop_for_each(); + return false; put (point_map, vt, CGAL::internal::jet_smooth_point @@ -207,6 +207,8 @@ jet_smooth_point_set( degree_fitting, degree_monge)); ++ callback_wrapper.advancement(); + + return true; }); callback_wrapper.join(); diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 8bc566253de..845978f73d6 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -188,13 +188,15 @@ pca_estimate_normals( [&](value_type& vt) { if (callback_wrapper.interrupted()) - throw internal::stop_for_each(); + return false; put (normal_map, vt, CGAL::internal::pca_estimate_normal (get(point_map, vt), neighbor_query, k, neighbor_radius)); ++ callback_wrapper.advancement(); + + return true; }); callback_wrapper.join(); diff --git a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h index 49c246c56b0..0648df4e386 100644 --- a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h +++ b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h @@ -534,7 +534,7 @@ wlop_simplify_and_regularize_point_set( [&](const typename Zip_iterator::reference& t) { if (callback_wrapper.interrupted()) - throw internal::stop_for_each(); + return false; get<1>(t) = simplify_and_regularize_internal:: compute_update_sample_point( @@ -545,6 +545,8 @@ wlop_simplify_and_regularize_point_set( original_density_weights, sample_density_weights); ++ callback_wrapper.advancement(); + + return true; }); bool interrupted = callback_wrapper.interrupted(); diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index 9a320177344..e65c1ec9ade 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -31,39 +31,32 @@ * if Range doesn't have random access iterators, first copy the iterators in a vector and then use a TBB parallel_for loop to apply Function to all elements of Range + + The loop is interrupted if `functor` returns false (it carries on + until the end otherwise). */ namespace CGAL { namespace internal { -// To emulate either a "break" in sequential and a "return" in -// parallel, we use an interal throw/catch mechanism -struct stop_for_each : public std::exception { }; - template void for_each (RangeRef range, - const std::function::type>::reference)>& functor, const Sequential_tag&, IteratorCategory) { for (typename std::iterator_traits ::type>::reference r : range) - try - { - functor(r); - } - catch (const stop_for_each&) - { + if (!functor(r)) break; - } } #ifdef CGAL_LINKED_WITH_TBB template void for_each (RangeRef range, - const std::function::type>::reference)>& functor, const Parallel_tag&, IteratorCategory) @@ -79,20 +72,14 @@ void for_each (RangeRef range, [&](const tbb::blocked_range& r) { for (std::size_t i = r.begin(); i != r.end(); ++ i) - try - { - functor (*(iterators[i])); - } - catch (const stop_for_each&) - { - return; - } + if (!functor (*(iterators[i]))) + break; }); } template void for_each (RangeRef range, - const std::function::type>::reference)>& functor, const Parallel_tag&, std::random_access_iterator_tag) @@ -103,14 +90,8 @@ void for_each (RangeRef range, [&](const tbb::blocked_range& r) { for (std::size_t i = r.begin(); i != r.end(); ++ i) - try - { - functor (*(range.begin() + i)); - } - catch (const stop_for_each&) - { - return; - } + if (!functor (*(range.begin() + i))) + break; }); } #endif @@ -119,7 +100,7 @@ void for_each (RangeRef range, template void for_each (const Range& range, - const std::function::reference)>& functor) { #ifndef CGAL_LINKED_WITH_TBB @@ -135,7 +116,7 @@ void for_each (const Range& range, template void for_each (Range& range, - const std::function::reference)>& functor) { #ifndef CGAL_LINKED_WITH_TBB From 0b1d13e815ce91e45f5c9ee51076c4d39c55f1db Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 23 Mar 2020 09:49:17 +0100 Subject: [PATCH 24/30] Fix conversion warning --- Spatial_searching/include/CGAL/Search_traits_adapter.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index d7ac0549565..d1d0b3bc43f 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -182,7 +182,11 @@ public: } Dereference_type& - dereference() const { return const_cast((*point)[idx]); } + dereference() const + { + // Point::operator[] takes an int as parameter... + return const_cast((*point)[static_cast(idx)]); + } }; From 63c1090c04635fc6f8d1a24ddd049643e735ca71 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 23 Mar 2020 13:42:45 +0100 Subject: [PATCH 25/30] Upate test_for_each --- STL_Extension/test/STL_Extension/test_for_each.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/STL_Extension/test/STL_Extension/test_for_each.cpp b/STL_Extension/test/STL_Extension/test_for_each.cpp index d540297dead..cfb003a4aa3 100644 --- a/STL_Extension/test/STL_Extension/test_for_each.cpp +++ b/STL_Extension/test/STL_Extension/test_for_each.cpp @@ -10,7 +10,7 @@ int main() std::cerr << "Testing sequential random access" << std::endl; CGAL::for_each - (vec, [](int& i) { i *= 2; }); + (vec, [](int& i) -> bool { i *= 2; return true; }); for (const int& i : vec) std::cerr << i << " "; @@ -19,7 +19,7 @@ int main() #ifdef CGAL_LINKED_WITH_TBB std::cerr << "Testing parallel random access" << std::endl; CGAL::for_each - (vec, [](int& i) { i *= 2; }); + (vec, [](int& i) -> bool { i *= 2; return true; }); for (const int& i : vec) std::cerr << i << " "; @@ -28,7 +28,7 @@ int main() std::cerr << "Testing sequential non-random access" << std::endl; CGAL::for_each - (list, [](int& i) { i *= 2; }); + (list, [](int& i) -> bool { i *= 2; return true; }); for (const int& i : list) std::cerr << i << " "; @@ -37,7 +37,7 @@ int main() #ifdef CGAL_LINKED_WITH_TBB std::cerr << "Testing parallel non-random access" << std::endl; CGAL::for_each - (list, [](int& i) { i *= 2; }); + (list, [](int& i) -> bool { i *= 2; return true; }); for (const int& i : list) std::cerr << i << " "; From 929e1e4bcee50e09ec2b5860a6ceaaf7db2d21b4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 24 Mar 2020 16:05:44 +0100 Subject: [PATCH 26/30] Fix "may be used uninitialized" warning --- Spatial_searching/include/CGAL/Kd_tree_rectangle.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h index f0b9b68e48f..3cb7132be3e 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h +++ b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h @@ -139,6 +139,7 @@ namespace CGAL { template // was PointIter Kd_tree_rectangle(int, PointPointerIter begin, PointPointerIter end,const Construct_cartesian_const_iterator_d& construct_it) + : max_span_coord_(-1) { update_from_point_pointers(begin,end,construct_it); } @@ -289,7 +290,7 @@ namespace CGAL { } Kd_tree_rectangle() - : coords_(0), dim(0) + : coords_(0), dim(0), max_span_coord_(-1) { } @@ -324,7 +325,7 @@ namespace CGAL { template // was PointIter Kd_tree_rectangle(int d, PointPointerIter begin, PointPointerIter end,const Construct_cartesian_const_iterator_d& construct_it) - : coords_(new FT[2*d]), dim(d) + : coords_(new FT[2*d]), dim(d), max_span_coord_(-1) { update_from_point_pointers(begin,end,construct_it); } From 2e180ac58999134ee17e7dd6c76af2d682447664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 26 Mar 2020 19:29:44 +0100 Subject: [PATCH 27/30] extra run of the script to remove tabs and trailing whitespaces --- .../scene.h | 10 +- .../internal/Callback_wrapper.h | 4 +- .../internal/Neighbor_query.h | 16 +- .../include/CGAL/bilateral_smooth_point_set.h | 68 ++--- .../include/CGAL/compute_average_spacing.h | 10 +- .../include/CGAL/jet_estimate_normals.h | 12 +- .../include/CGAL/jet_smooth_point_set.h | 12 +- .../include/CGAL/mst_orient_normals.h | 28 +- .../include/CGAL/pca_estimate_normals.h | 12 +- .../include/CGAL/remove_outliers.h | 6 +- .../wlop_simplify_and_regularize_point_set.h | 84 +++--- .../CGAL/Poisson_reconstruction_function.h | 110 ++++---- Property_map/include/CGAL/property_map.h | 32 +-- STL_Extension/include/CGAL/for_each.h | 4 +- STL_Extension/include/CGAL/iterator.h | 128 ++++----- .../test/STL_Extension/CMakeLists.txt | 4 +- .../test/STL_Extension/test_for_each.cpp | 10 +- .../include/CGAL/Kd_tree_rectangle.h | 252 +++++++++--------- .../include/CGAL/Search_traits_adapter.h | 66 ++--- 19 files changed, 434 insertions(+), 434 deletions(-) diff --git a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h index 2947db39636..6e804dc87a3 100644 --- a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h +++ b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h @@ -92,7 +92,7 @@ private: return K::Point_3 (sample.point().x(), sample.point().y(), 0.); } }; - + // data std::vector m_samples; @@ -106,10 +106,10 @@ private: double m_bbox_x; double m_bbox_y; double m_bbox_size; - + //Random CGAL::Random random; - + template Vector random_vec(const double scale) { @@ -410,7 +410,7 @@ public: 3, CGAL::parameters::point_map (CGAL::Identity_property_map_no_lvalue())); std::cerr << "Average spacing = " << spacing << std::endl; } - + void print_vertex(Vertex vertex) { std::cout << "vertex " << vertex << std::endl; } @@ -639,7 +639,7 @@ public: if (view_tolerance) draw_tolerance(viewer); - + if (view_edges) m_pwsrec->draw_edges(0.5f * line_thickness, 0.9f, 0.9f, 0.9f); diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h index 8612be034fd..c52826db44b 100644 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Callback_wrapper.h @@ -75,7 +75,7 @@ public: { return m_advancement; } - + bool& interrupted() { if (m_callback) @@ -102,7 +102,7 @@ class Callback_wrapper { return *this; } - + public: Callback_wrapper (const std::function& callback, std::size_t size, diff --git a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h index 1160fb3a3e5..5e8996db035 100644 --- a/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h +++ b/Point_set_processing_3/include/CGAL/Point_set_processing_3/internal/Neighbor_query.h @@ -33,14 +33,14 @@ template class Neighbor_query { public: - + typedef Kernel_ Kernel; typedef PointRangeRef Point_range; typedef PointMap Point_map; typedef typename Kernel::FT FT; typedef typename Kernel::Point_3 Point_3; - + typedef typename Range_iterator_type::type input_iterator; typedef typename input_iterator::value_type value_type; @@ -70,10 +70,10 @@ public: typedef CGAL::Distance_adapter > Distance; typedef CGAL::Kd_tree Tree; typedef CGAL::Fuzzy_sphere Sphere; - + typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; typedef typename Neighbor_search::iterator Search_iterator; - + private: PointRangeRef m_points; @@ -112,9 +112,9 @@ public: // if k=0, no limit on the number of neighbors returned if (k == 0) k = (std::numeric_limits::max)(); - + unsigned int nb = 0; - + try { std::function output_iterator_with_limit @@ -124,7 +124,7 @@ public: if (++ nb == k) throw Maximum_points_reached_exception(); }; - + auto function_output_iterator = boost::make_function_output_iterator (output_iterator_with_limit); @@ -141,7 +141,7 @@ public: else k = 0; } - + if (k != 0) { // Gather set of (k+1) neighboring points. diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index 4246460d55a..cd208ce0b41 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -7,7 +7,7 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez +// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez #ifndef CGAL_BILATERAL_SMOOTH_POINT_SET_H #define CGAL_BILATERAL_SMOOTH_POINT_SET_H @@ -39,7 +39,7 @@ #include #include -//#define CGAL_PSP3_VERBOSE +//#define CGAL_PSP3_VERBOSE namespace CGAL { @@ -52,13 +52,13 @@ namespace bilateral_smooth_point_set_internal{ /// Compute bilateral projection for each point /// according to their KNN neighborhood points -/// +/// /// \pre `k >= 2`, radius > 0 , sharpness_angle > 0 && sharpness_angle < 90 /// /// @tparam Kernel Geometric traits class. /// @tparam Tree KD-tree. /// -/// @return +/// @return template @@ -87,7 +87,7 @@ compute_denoise_projection( FT iradius16 = -(FT)4.0/radius2; FT project_dist_sum = FT(0.0); FT project_weight_sum = FT(0.0); - Vector normal_sum = CGAL::NULL_VECTOR; + Vector normal_sum = CGAL::NULL_VECTOR; FT cos_sigma = cos(sharpness_angle * CGAL_PI / 180.0); FT sharpness_bandwidth = std::pow((CGAL::max)(1e-8, 1 - cos_sigma), 2); @@ -115,8 +115,8 @@ compute_denoise_projection( Vector update_normal = normal_sum / project_weight_sum; update_normal = update_normal / sqrt(update_normal.squared_length()); - Point update_point = get(point_map, vt) - update_normal * - (project_dist_sum / project_weight_sum); + Point update_point = get(point_map, vt) - update_normal * + (project_dist_sum / project_weight_sum); return std::make_pair (update_point, update_normal); } @@ -170,17 +170,17 @@ compute_max_spacing( /** \ingroup PkgPointSetProcessing3Algorithms - - This function smooths an input point set by iteratively projecting each + + This function smooths an input point set by iteratively projecting each point onto the implicit surface patch fitted over its nearest neighbors. Bilateral projection preserves sharp features according to the normal - (gradient) information. Both point positions and normals will be modified. - For more details, please see section 4 in \cgalCite{ear-2013}. + (gradient) information. Both point positions and normals will be modified. + For more details, please see section 4 in \cgalCite{ear-2013}. - A parallel version of this function is provided and requires the executable to be + A parallel version of this function is provided and requires the executable to be linked against the Intel TBB library. To control the number of threads used, the user may use the tbb::task_scheduler_init class. - See the TBB documentation + See the TBB documentation for more details. \pre Normals must be unit vectors @@ -233,7 +233,7 @@ bilateral_smooth_point_set( { using parameters::choose_parameter; using parameters::get_parameter; - + // basic geometric types typedef typename PointRange::iterator iterator; typedef typename iterator::value_type value_type; @@ -246,13 +246,13 @@ bilateral_smooth_point_set( CGAL_static_assertion_msg(!(boost::is_same::NoMap>::value), "Error: no normal map"); - + typedef typename Kernel::FT FT; - + double sharpness_angle = choose_parameter(get_parameter(np, internal_np::sharpness_angle), 30.); const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); - + CGAL_point_set_processing_precondition(points.begin() != points.end()); CGAL_point_set_processing_precondition(k > 1); @@ -262,7 +262,7 @@ bilateral_smooth_point_set( PointMap point_map = choose_parameter(get_parameter(np, internal_np::point_map)); NormalMap normal_map = choose_parameter(get_parameter(np, internal_np::normal_map)); FT neighbor_radius = choose_parameter(get_parameter(np, internal_np::neighbor_radius), FT(0)); - + std::size_t nb_points = points.size(); #ifdef CGAL_PSP3_VERBOSE @@ -270,21 +270,21 @@ bilateral_smooth_point_set( #endif // initiate a KD-tree search for points Neighbor_query neighbor_query (points, point_map); - + // Guess spacing #ifdef CGAL_PSP3_VERBOSE CGAL::Real_timer task_timer; task_timer.start(); #endif - FT guess_neighbor_radius = 0.0; + FT guess_neighbor_radius = 0.0; for (const value_type& vt : points) { FT max_spacing = bilateral_smooth_point_set_internal:: compute_max_spacing (vt, point_map, neighbor_query, k); - guess_neighbor_radius = (CGAL::max)(max_spacing, guess_neighbor_radius); + guess_neighbor_radius = (CGAL::max)(max_spacing, guess_neighbor_radius); } - + #ifdef CGAL_PSP3_VERBOSE task_timer.stop(); #endif @@ -303,7 +303,7 @@ bilateral_smooth_point_set( typedef std::vector iterators; std::vector pwns_neighbors; pwns_neighbors.resize(nb_points); - + Point_set_processing_3::internal::Callback_wrapper callback_wrapper (callback, 2 * nb_points); @@ -319,14 +319,14 @@ bilateral_smooth_point_set( neighbor_query.get_iterators (get(point_map, get<0>(t)), k, neighbor_radius, std::back_inserter (get<1>(t))); - + ++ callback_wrapper.advancement(); return true; }); bool interrupted = callback_wrapper.interrupted(); - + // We interrupt by hand as counter only goes halfway and won't terminate by itself callback_wrapper.interrupted() = true; callback_wrapper.join(); @@ -334,7 +334,7 @@ bilateral_smooth_point_set( // If interrupted during this step, nothing is computed, we return NaN if (interrupted) return std::numeric_limits::quiet_NaN(); - + #ifdef CGAL_PSP3_VERBOSE task_timer.stop(); memory = CGAL::Memory_sizer().virtual_size(); @@ -355,7 +355,7 @@ bilateral_smooth_point_set( typename std::vector::iterator, typename std::vector >::iterator> > Zip_iterator_2; - + CGAL::for_each (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple (points.begin(), pwns_neighbors.begin(), update_pwns.begin())), @@ -373,20 +373,20 @@ bilateral_smooth_point_set( get<1>(t), guess_neighbor_radius, sharpness_angle); - + ++ callback_wrapper.advancement(); - + return true; }); - + callback_wrapper.join(); // If interrupted during this step, nothing is computed, we return NaN if (callback_wrapper.interrupted()) return std::numeric_limits::quiet_NaN(); - + #ifdef CGAL_PSP3_VERBOSE - task_timer.stop(); + task_timer.stop(); memory = CGAL::Memory_sizer().virtual_size(); std::cout << "done: " << task_timer.time() << " seconds, " << (memory>>20) << " Mb allocated" << std::endl; @@ -401,12 +401,12 @@ bilateral_smooth_point_set( put (normal_map, vt, update_pwns[nb].second); ++ nb; } - + return sum_move_error / nb_points; } /// \cond SKIP_IN_MANUAL -// variant with default NP +// variant with default NP template double diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index 3156d0ff469..968c60f1242 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -133,7 +133,7 @@ compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, // of `points`. */ template #ifdef DOXYGEN_RUNNING @@ -181,11 +181,11 @@ compute_average_spacing( Point_set_processing_3::internal::Callback_wrapper callback_wrapper (callback, nb_points); - + std::vector spacings (nb_points, -1); typedef boost::zip_iterator::iterator> > Zip_iterator; - + CGAL::for_each (CGAL::make_range (boost::make_zip_iterator (boost::make_tuple (points.begin(), spacings.begin())), boost::make_zip_iterator (boost::make_tuple (points.end(), spacings.end()))), @@ -193,7 +193,7 @@ compute_average_spacing( { if (callback_wrapper.interrupted()) return false; - + get<1>(t) = CGAL::internal::compute_average_spacing (get(point_map, get<0>(t)), neighbor_query, k); ++ callback_wrapper.advancement(); @@ -208,7 +208,7 @@ compute_average_spacing( ++ nb; } callback_wrapper.join(); - + // return average spacing return sum_spacings / (FT)(nb); } diff --git a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h index 9a021398c6a..b70bb6a7dda 100644 --- a/Point_set_processing_3/include/CGAL/jet_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/jet_estimate_normals.h @@ -71,7 +71,7 @@ jet_estimate_normal(const typename NeighborQuery::Point_3& query, ///< point to std::vector points; neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); - + // performs jet fitting Monge_jet_fitting monge_fit; const unsigned int degree_monge = 1; // we seek for normal and not more. @@ -134,7 +134,7 @@ jet_estimate_normal(const typename NeighborQuery::Point_3& query, ///< point to \cgalNamedParamsEnd */ template void @@ -145,7 +145,7 @@ jet_estimate_normals( { using parameters::choose_parameter; using parameters::get_parameter; - + CGAL_TRACE("Calls jet_estimate_normals()\n"); // basic geometric types @@ -168,7 +168,7 @@ jet_estimate_normals( NormalMap normal_map = choose_parameter(get_parameter(np, internal_np::normal_map)); unsigned int degree_fitting = choose_parameter(get_parameter(np, internal_np::degree_fitting), 2); FT neighbor_radius = choose_parameter(get_parameter(np, internal_np::neighbor_radius), FT(0)); - + const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); @@ -202,7 +202,7 @@ jet_estimate_normals( { if (callback_wrapper.interrupted()) return false; - + put (normal_map, vt, CGAL::internal::jet_estimate_normal (get(point_map, vt), neighbor_query, k, neighbor_radius, degree_fitting)); @@ -221,7 +221,7 @@ jet_estimate_normals( /// \cond SKIP_IN_MANUAL // variant with default NP template + typename PointRange> void jet_estimate_normals( PointRange& points, diff --git a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h index 6203dc76e0c..474c6754ac9 100644 --- a/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/jet_smooth_point_set.h @@ -71,7 +71,7 @@ jet_smooth_point( Simple_cartesian, SvdTraits> Monge_jet_fitting; typedef typename Monge_jet_fitting::Monge_form Monge_form; - + std::vector points; neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); @@ -139,7 +139,7 @@ jet_smooth_point( */ template void @@ -150,7 +150,7 @@ jet_smooth_point_set( { using parameters::choose_parameter; using parameters::get_parameter; - + // basic geometric types typedef typename PointRange::iterator iterator; typedef typename iterator::value_type value_type; @@ -207,7 +207,7 @@ jet_smooth_point_set( degree_fitting, degree_monge)); ++ callback_wrapper.advancement(); - + return true; }); @@ -218,7 +218,7 @@ jet_smooth_point_set( /// \cond SKIP_IN_MANUAL // variant with default NP template + typename PointRange> void jet_smooth_point_set( PointRange& points, @@ -228,7 +228,7 @@ jet_smooth_point_set( (points, k, CGAL::Point_set_processing_3::parameters::all_default(points)); } /// \endcond - + } //namespace CGAL diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index 62cc02fa4aa..59cd06298a1 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -122,7 +122,7 @@ public: typedef value_type reference; private: - + ForwardIterator m_source_point; public: @@ -185,7 +185,7 @@ struct Propagate_normal_orientation // Gets target vertex_descriptor target_vertex = target(edge, mst_graph); bool& target_normal_is_oriented = ((MST_graph&)mst_graph)[target_vertex].is_oriented; - + // special case if vertex is source vertex (and thus has no related point/normal) if (source_vertex == m_source) { @@ -199,7 +199,7 @@ struct Propagate_normal_orientation // Gets target Vector_ref target_normal = get( mst_graph.m_normal_map, *(mst_graph[target_vertex].input_point) ); - + if ( ! target_normal_is_oriented ) { // -> -> @@ -258,10 +258,10 @@ mst_find_source( ForwardIterator top_point = first; for (ForwardIterator v = ++first; v != beyond; v++) { - + double top_z = get(point_map,*top_point).z(); // top_point's Z coordinate double z = get(point_map,*v).z(); - + if (top_z < z) top_point = v; } @@ -363,7 +363,7 @@ create_riemannian_graph( { std::size_t it_index = get(index_map,it); Vector_ref it_normal_vector = get(normal_map,*it); - + Point_ref point = get(point_map, *it); std::vector neighbor_points; neighbor_query.get_iterators (point, k, neighbor_radius, std::back_inserter(neighbor_points)); @@ -385,7 +385,7 @@ create_riemannian_graph( // -> -> // Computes edge weight = 1 - | normal1 * normal2 | // where normal1 and normal2 are the normal at the edge extremities. - + Vector_ref neighbor_normal_vector = get(normal_map,*neighbor); double weight = 1.0 - std::abs(it_normal_vector * neighbor_normal_vector); if (weight < 0) @@ -406,7 +406,7 @@ create_riemannian_graph( riemannian_graph_weight_map[e] = 0.; } - + } return riemannian_graph; @@ -470,7 +470,7 @@ create_mst_graph( // Computes Minimum Spanning Tree. std::size_t source_point_index = num_input_points; - + Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph); typedef std::vector PredecessorMap; PredecessorMap predecessor(num_input_points + 1); @@ -498,11 +498,11 @@ create_mst_graph( mst_graph[v].input_point = it; mst_graph[v].is_oriented = false; } - + typename MST_graph::vertex_descriptor v = add_vertex(mst_graph); CGAL_point_set_processing_assertion(v == source_point_index); mst_graph[v].is_oriented = true; - + // add edges for (std::size_t i=0; i < predecessor.size(); i++) // add edges { @@ -527,7 +527,7 @@ create_mst_graph( // Public section // ---------------------------------------------------------------------------- -/** +/** \ingroup PkgPointSetProcessing3Algorithms Orients the normals of the range of `points` using the propagation of a seed orientation through a minimum spanning tree of the Riemannian graph. @@ -562,7 +562,7 @@ create_mst_graph( limit is wanted, use `k=0`.\cgalParamEnd \cgalParamBegin{point_is_constrained_map} a model of `ReadablePropertyMap` with value type `bool`. Points with a `true` value will be used as seed points: their normal will be considered as already - oriented, it won't be altered and it will be propagated to its neighbors. If this parameter is omitted, + oriented, it won't be altered and it will be propagated to its neighbors. If this parameter is omitted, the highest point (highest Z coordinate) will be used as the unique seed with an upward oriented normal\cgalParamEnd \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd @@ -668,7 +668,7 @@ mst_orient_normals( const std::size_t num_input_points = distance(points.begin(), points.end()); std::size_t source_point_index = num_input_points; - + // Traverse the point set along the MST to propagate source_point's orientation Propagate_normal_orientation orienter(source_point_index); diff --git a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h index 845978f73d6..db146e1d94a 100644 --- a/Point_set_processing_3/include/CGAL/pca_estimate_normals.h +++ b/Point_set_processing_3/include/CGAL/pca_estimate_normals.h @@ -65,7 +65,7 @@ pca_estimate_normal(const typename NeighborQuery::Kernel::Point_3& query, ///< p std::vector points; neighbor_query.get_points (query, k, neighbor_radius, std::back_inserter(points)); - + // performs plane fitting by point-based PCA Plane plane; linear_least_squares_fitting_3(points.begin(),points.end(),plane,Dimension_tag<0>()); @@ -125,7 +125,7 @@ pca_estimate_normal(const typename NeighborQuery::Kernel::Point_3& query, ///< p \cgalNamedParamsEnd */ template void @@ -189,18 +189,18 @@ pca_estimate_normals( { if (callback_wrapper.interrupted()) return false; - + put (normal_map, vt, CGAL::internal::pca_estimate_normal (get(point_map, vt), neighbor_query, k, neighbor_radius)); - + ++ callback_wrapper.advancement(); return true; }); callback_wrapper.join(); - + memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE("End of pca_estimate_normals()\n"); } @@ -208,7 +208,7 @@ pca_estimate_normals( /// \cond SKIP_IN_MANUAL // variant with default NP template void pca_estimate_normals( diff --git a/Point_set_processing_3/include/CGAL/remove_outliers.h b/Point_set_processing_3/include/CGAL/remove_outliers.h index 78626502d0e..611269da396 100644 --- a/Point_set_processing_3/include/CGAL/remove_outliers.h +++ b/Point_set_processing_3/include/CGAL/remove_outliers.h @@ -143,7 +143,7 @@ remove_outliers( { using parameters::choose_parameter; using parameters::get_parameter; - + // geometric types typedef typename CGAL::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -155,9 +155,9 @@ remove_outliers( double threshold_distance = choose_parameter(get_parameter(np, internal_np::threshold_distance), 0.); const std::function& callback = choose_parameter(get_parameter(np, internal_np::callback), std::function()); - + typedef typename Kernel::FT FT; - + // basic geometric types typedef typename PointRange::iterator iterator; typedef typename iterator::value_type value_type; diff --git a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h index 0648df4e386..b586a59a08a 100644 --- a/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h +++ b/Point_set_processing_3/include/CGAL/wlop_simplify_and_regularize_point_set.h @@ -7,7 +7,7 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // -// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez +// Author(s) : Shihao Wu, Clement Jamin, Pierre Alliez #ifndef CGAL_wlop_simplify_and_regularize_point_set_H #define CGAL_wlop_simplify_and_regularize_point_set_H @@ -83,9 +83,9 @@ public: typedef typename Kernel::Point_3 PointType; }; -/// Compute average and repulsion term, then +/// Compute average and repulsion term, then /// compute and update sample point locations -/// +/// /// \pre `radius > 0` /// /// @tparam Kernel Geometric traits class. @@ -101,8 +101,8 @@ compute_update_sample_point( const Tree& original_kd_tree, ///< original Kd-tree const Tree& sample_kd_tree, ///< sample Kd-tree const typename Kernel::FT radius, ///< neighborhood radius square - const std::vector& original_densities, ///< - const std::vector& sample_densities ///< + const std::vector& original_densities, ///< + const std::vector& sample_densities ///< ) { CGAL_point_set_processing_precondition(radius > 0); @@ -126,7 +126,7 @@ compute_update_sample_point( //Compute average term FT radius2 = radius * radius; - Vector average = CGAL::NULL_VECTOR; + Vector average = CGAL::NULL_VECTOR; FT weight = (FT)0.0, average_weight_sum = (FT)0.0; FT iradius16 = -(FT)4.0 / radius2; @@ -158,10 +158,10 @@ compute_update_sample_point( } else { - average = average / average_weight_sum; + average = average / average_weight_sum; } neighbor_original_points.clear(); - + //Compute repulsion term @@ -171,7 +171,7 @@ compute_update_sample_point( weight = (FT)0.0; FT repulsion_weight_sum = (FT)0.0; - Vector repulsion = CGAL::NULL_VECTOR; + Vector repulsion = CGAL::NULL_VECTOR; iter = neighbor_sample_points.begin(); for(; iter != neighbor_sample_points.end(); ++iter) @@ -184,9 +184,9 @@ compute_update_sample_point( FT dist2 = CGAL::squared_distance(query, np); if (dist2 < 1e-10) continue; FT dist = std::sqrt(dist2); - + weight = std::exp(dist2 * iradius16) * std::pow(FT(1.0) / dist, 2); // L1 - + if (!is_sample_densities_empty) { weight *= sample_densities[sample_index]; @@ -204,7 +204,7 @@ compute_update_sample_point( } else { - repulsion = repulsion / repulsion_weight_sum; + repulsion = repulsion / repulsion_weight_sum; } neighbor_sample_points.clear(); @@ -216,7 +216,7 @@ compute_update_sample_point( /// Compute density weight for each original points, /// according to their neighbor original points -/// +/// /// \pre `k >= 2`, radius > 0 /// /// @tparam Kernel Geometric traits class. @@ -236,7 +236,7 @@ compute_density_weight_for_original_point( // basic geometric types typedef typename Kernel::Point_3 Point; typedef typename Kernel::FT FT; - + //types for range search typedef simplify_and_regularize_internal::Kd_tree_element Kd_tree_point; typedef simplify_and_regularize_internal::Kd_tree_traits Traits; @@ -262,7 +262,7 @@ compute_density_weight_for_original_point( FT dist2 = CGAL::squared_distance(query, np); if (dist2 < 1e-8) continue; - + density_weight += std::exp(dist2 * iradius16); } @@ -273,7 +273,7 @@ compute_density_weight_for_original_point( /// Compute density weight for sample point, /// according to their neighbor sample points -/// +/// /// \pre `k >= 2`, radius > 0 /// /// @tparam Kernel Geometric traits class. @@ -317,7 +317,7 @@ compute_density_weight_for_sample_point( FT dist2 = CGAL::squared_distance(query, np); density_weight += std::exp(dist2 * iradius16); } - + return density_weight; } @@ -333,24 +333,24 @@ compute_density_weight_for_sample_point( /** \ingroup PkgPointSetProcessing3Algorithms This is an implementation of the Weighted Locally Optimal Projection (WLOP) simplification algorithm. - The WLOP simplification algorithm can produce a set of - denoised, outlier-free and evenly distributed particles over the original - dense point cloud. + The WLOP simplification algorithm can produce a set of + denoised, outlier-free and evenly distributed particles over the original + dense point cloud. The core of the algorithm is a Weighted Locally Optimal Projection operator - with a density uniformization term. + with a density uniformization term. For more details, please refer to \cgalCite{wlop-2009}. - A parallel version of WLOP is provided and requires the executable to be + A parallel version of WLOP is provided and requires the executable to be linked against the Intel TBB library. To control the number of threads used, the user may use the tbb::task_scheduler_init class. - See the TBB documentation + See the TBB documentation for more details. \tparam ConcurrencyTag enables sequential versus parallel algorithm. Possible values are `Sequential_tag`, `Parallel_tag`, and `Parallel_if_available_tag`. \tparam PointRange is a model of `Range`. The value type of its iterator is the key type of the named parameter `point_map`. - \tparam OutputIterator Type of the output iterator. + \tparam OutputIterator Type of the output iterator. It must accept objects of type `geom_traits::Point_3`. \param points input point range. @@ -362,11 +362,11 @@ compute_density_weight_for_sample_point( If this parameter is omitted, `CGAL::Identity_property_map` is used.\cgalParamEnd \cgalParamBegin{normal_map} a model of `ReadWritePropertyMap` with value type `geom_traits::Vector_3`.\cgalParamEnd - \cgalParamBegin{select_percentage} percentage of points to retain. The default value is set to + \cgalParamBegin{select_percentage} percentage of points to retain. The default value is set to 5 (\%).\cgalParamEnd \cgalParamBegin{neighbor_radius} spherical neighborhood radius. This is a key parameter that needs to be - finely tuned. The result will be irregular if too small, but a larger value will impact the runtime. In - practice, choosing a radius such that the neighborhood of each sample point includes at least two rings + finely tuned. The result will be irregular if too small, but a larger value will impact the runtime. In + practice, choosing a radius such that the neighborhood of each sample point includes at least two rings of neighboring sample points gives satisfactory result. If this parameter is not provided, it is automatically set to 8 times the average spacing of the point set.\cgalParamEnd \cgalParamBegin{number_of_iterations} number of iterations to solve the optimsation problem. The default @@ -397,7 +397,7 @@ wlop_simplify_and_regularize_point_set( { using parameters::choose_parameter; using parameters::get_parameter; - + // basic geometric types typedef typename CGAL::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; @@ -423,15 +423,15 @@ wlop_simplify_and_regularize_point_set( // to fix: should have at least three distinct points // but this is costly to check CGAL_point_set_processing_precondition(points.begin() != points.end()); - CGAL_point_set_processing_precondition(select_percentage >= 0 + CGAL_point_set_processing_precondition(select_percentage >= 0 && select_percentage <= 100); // Random shuffle CGAL::cpp98::random_shuffle (points.begin(), points.end()); - // Computes original(input) and sample points size + // Computes original(input) and sample points size std::size_t number_of_original = std::distance(points.begin(), points.end()); - std::size_t number_of_sample = (std::size_t)(FT(number_of_original) * + std::size_t number_of_sample = (std::size_t)(FT(number_of_original) * (select_percentage / FT(100.0))); std::size_t first_index_to_sample = number_of_original - number_of_sample; @@ -444,13 +444,13 @@ wlop_simplify_and_regularize_point_set( //Copy sample points std::vector sample_points; sample_points.reserve(number_of_sample); - unsigned int i; + unsigned int i; for(it = first_sample_iter; it != points.end(); ++it) { sample_points.push_back(get(point_map, *it)); } - + //compute default neighbor_radius, if no radius in if (radius < 0) { @@ -470,13 +470,13 @@ wlop_simplify_and_regularize_point_set( std::vector original_treeElements; for (it = first_original_iter, i=0 ; it != points.end() ; ++it, ++i) original_treeElements.push_back( Kd_tree_element(get(point_map, *it), i) ); - Kd_Tree original_kd_tree(original_treeElements.begin(), + Kd_Tree original_kd_tree(original_treeElements.begin(), original_treeElements.end()); std::vector update_sample_points(number_of_sample); typename std::vector::iterator sample_iter; - + // Compute original density weight for original points if user needed std::vector original_density_weights; @@ -489,7 +489,7 @@ wlop_simplify_and_regularize_point_set( compute_density_weight_for_original_point ( get(point_map, *it), - original_kd_tree, + original_kd_tree, radius); original_density_weights.push_back(density); @@ -515,8 +515,8 @@ wlop_simplify_and_regularize_point_set( { FT density = simplify_and_regularize_internal:: compute_density_weight_for_sample_point - (*sample_iter, - sample_kd_tree, + (*sample_iter, + sample_kd_tree, radius); sample_density_weights.push_back(density); @@ -541,7 +541,7 @@ wlop_simplify_and_regularize_point_set( get<0>(t), original_kd_tree, sample_kd_tree, - radius, + radius, original_density_weights, sample_density_weights); ++ callback_wrapper.advancement(); @@ -550,15 +550,15 @@ wlop_simplify_and_regularize_point_set( }); bool interrupted = callback_wrapper.interrupted(); - + // We interrupt by hand as counter only goes halfway and won't terminate by itself callback_wrapper.interrupted() = true; - callback_wrapper.join(); + callback_wrapper.join(); // If interrupted during this step, nothing is computed, we return NaN if (interrupted) return output; - + sample_iter = sample_points.begin(); for (std::size_t i = 0; i < sample_points.size(); ++ i) sample_points[i] = update_sample_points[i]; diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index b0f0f095e1f..c92c70990a2 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -48,7 +48,7 @@ #include #include -/*! +/*! \file Poisson_reconstruction_function.h */ @@ -104,7 +104,7 @@ struct Poisson_visitor { {} }; -struct Poisson_skip_vertices { +struct Poisson_skip_vertices { double ratio; Poisson_skip_vertices(const double ratio = 0) : ratio(ratio) {} @@ -123,7 +123,7 @@ template struct Special_wrapper_of_two_functions_keep_pointers { F1 *f1; F2 *f2; - Special_wrapper_of_two_functions_keep_pointers(F1* f1, F2* f2) + Special_wrapper_of_two_functions_keep_pointers(F1* f1, F2* f2) : f1(f1), f2(f2) {} template @@ -136,16 +136,16 @@ struct Special_wrapper_of_two_functions_keep_pointers { return (std::max)((*f1)(x), CGAL::square((*f2)(x))); } }; // end struct Special_wrapper_of_two_functions_keep_pointers -/// \endcond +/// \endcond /*! \ingroup PkgPoissonSurfaceReconstruction3Ref \brief Implementation of the Poisson Surface Reconstruction method. - + Given a set of 3D points with oriented normals sampled on the boundary -of a 3D solid, the Poisson Surface Reconstruction method \cgalCite{Kazhdan06} +of a 3D solid, the Poisson Surface Reconstruction method \cgalCite{Kazhdan06} solves for an approximate indicator function of the inferred solid, whose gradient best matches the input normals. The output scalar function, represented in an adaptive octree, is then @@ -155,7 +155,7 @@ iso-contoured using an adaptive marching cubes. algorithm which solves for a piecewise linear function on a 3D Delaunay triangulation instead of an adaptive octree. -\tparam Gt Geometric traits class. +\tparam Gt Geometric traits class. \cgalModels `ImplicitFunction` @@ -166,7 +166,7 @@ class Poisson_reconstruction_function // Public types public: - /// \name Types + /// \name Types /// @{ typedef Gt Geom_traits; ///< Geometric traits class @@ -180,7 +180,7 @@ public: typedef typename Geom_traits::FT FT; ///< number type. typedef typename Geom_traits::Point_3 Point; ///< point type. typedef typename Geom_traits::Vector_3 Vector; ///< vector type. - typedef typename Geom_traits::Sphere_3 Sphere; + typedef typename Geom_traits::Sphere_3 Sphere; /// @} @@ -269,22 +269,22 @@ private: // Public methods public: - /// \name Creation + /// \name Creation /// @{ - /*! - Creates a Poisson implicit function from the range of points `[first, beyond)`. + /*! + Creates a Poisson implicit function from the range of points `[first, beyond)`. - \tparam InputIterator iterator over input points. + \tparam InputIterator iterator over input points. \tparam PointPMap is a model of `ReadablePropertyMap` with a `value_type = Point`. It can be omitted if `InputIterator` - `value_type` is convertible to `Point`. - + `value_type` is convertible to `Point`. + \tparam NormalPMap is a model of `ReadablePropertyMap` with a `value_type = Vector`. - */ + */ template > ) , average_spacing(CGAL::compute_average_spacing(CGAL::make_range(first, beyond), 6)) { - forward_constructor(first, beyond, + forward_constructor(first, beyond, make_identity_property_map( typename std::iterator_traits::value_type()), normal_pmap, Poisson_visitor()); @@ -355,12 +355,12 @@ public: { return m_tr->bounding_sphere(); } - + /// \cond SKIP_IN_MANUAL const Triangulation& tr() const { return *m_tr; } - + // This variant requires all parameters. template @@ -368,7 +368,7 @@ public: SparseLinearAlgebraTraits_d solver,// = SparseLinearAlgebraTraits_d(), Visitor visitor, double approximation_ratio = 0, - double average_spacing_ratio = 5) + double average_spacing_ratio = 5) { CGAL::Timer task_timer; task_timer.start(); CGAL_TRACE_STREAM << "Delaunay refinement...\n"; @@ -382,7 +382,7 @@ public: internal::Poisson::Constant_sizing_field sizing_field(CGAL::square(cell_radius_bound)); - std::vector NB; + std::vector NB; NB.push_back( delaunay_refinement(radius_edge_ratio_bound,sizing_field,max_vertices,enlarge_ratio)); @@ -391,7 +391,7 @@ public: NB.push_back( delaunay_refinement(radius_edge_ratio_bound,sizing_field,max_vertices,enlarge_ratio)); } - if(approximation_ratio > 0. && + if(approximation_ratio > 0. && approximation_ratio * std::distance(m_tr->input_points_begin(), m_tr->input_points_end()) > 20) { @@ -418,13 +418,13 @@ public: typedef Filter_iterator Some_points_iterator; Poisson_skip_vertices skip(1.-approximation_ratio); - + CGAL_TRACE_STREAM << "SPECIAL PASS that uses an approximation of the result (approximation ratio: " << approximation_ratio << ")" << std::endl; CGAL::Timer approximation_timer; approximation_timer.start(); CGAL::Timer sizing_field_timer; sizing_field_timer.start(); - Poisson_reconstruction_function + Poisson_reconstruction_function coarse_poisson_function(Some_points_iterator(m_tr->input_points_end(), skip, m_tr->input_points_begin()), @@ -433,18 +433,18 @@ public: Normal_of_point_with_normal_map() ); coarse_poisson_function.compute_implicit_function(solver, Poisson_visitor(), 0.); - internal::Poisson::Constant_sizing_field + internal::Poisson::Constant_sizing_field min_sizing_field(CGAL::square(average_spacing)); - internal::Poisson::Constant_sizing_field + internal::Poisson::Constant_sizing_field sizing_field_ok(CGAL::square(average_spacing*average_spacing_ratio)); Special_wrapper_of_two_functions_keep_pointers< internal::Poisson::Constant_sizing_field, Poisson_reconstruction_function > sizing_field2(&min_sizing_field, &coarse_poisson_function); - + sizing_field_timer.stop(); - std::cerr << "Construction time of the sizing field: " << sizing_field_timer.time() + std::cerr << "Construction time of the sizing field: " << sizing_field_timer.time() << " seconds" << std::endl; NB.push_back( delaunay_refinement(radius_edge_ratio_bound, @@ -456,12 +456,12 @@ public: CGAL_TRACE_STREAM << "SPECIAL PASS END (" << approximation_timer.time() << " seconds)" << std::endl; } - + // Prints status CGAL_TRACE_STREAM << "Delaunay refinement: " << "added "; for(std::size_t i = 0; i < NB.size()-1; i++){ - CGAL_TRACE_STREAM << NB[i] << " + "; - } + CGAL_TRACE_STREAM << NB[i] << " + "; + } CGAL_TRACE_STREAM << NB.back() << " Steiner points, " << task_timer.time() << " seconds, " << std::endl; @@ -508,12 +508,12 @@ public: If \ref thirdpartyEigen "Eigen" 3.1 (or greater) is available and `CGAL_EIGEN3_ENABLED` is defined, an overload with \link Eigen_solver_traits Eigen_solver_traits::EigenType> > \endlink as default solver is provided. - + \param solver sparse linear solver. \param smoother_hole_filling controls if the Delaunay refinement is done for the input points, or for an approximation of the surface obtained from a first pass of the algorithm on a sample of the points. - \return `false` if the linear solver fails. - */ + \return `false` if the linear solver fails. + */ template bool compute_implicit_function(SparseLinearAlgebraTraits_d solver, bool smoother_hole_filling = false) { @@ -553,14 +553,14 @@ public: } /// \endcond - /*! - `ImplicitFunction` interface: evaluates the implicit function at a - given 3D query point. The function `compute_implicit_function()` must be - called before the first call to `operator()`. - */ + /*! + `ImplicitFunction` interface: evaluates the implicit function at a + given 3D query point. The function `compute_implicit_function()` must be + called before the first call to `operator()`. + */ FT operator()(const Point& p) const { - m_hint = m_tr->locate(p ,m_hint); + m_hint = m_tr->locate(p ,m_hint); if(m_tr->is_infinite(m_hint)) { int i = m_hint->index(m_tr->infinite_vertex()); @@ -574,7 +574,7 @@ public: c * m_hint->vertex(2)->f() + d * m_hint->vertex(3)->f(); } - + /// \cond SKIP_IN_MANUAL void initialize_cell_indices() { @@ -614,7 +614,7 @@ public: void initialize_duals() const { - Dual.resize(m_tr->number_of_cells()); + Dual.resize(m_tr->number_of_cells()); int i = 0; for(Finite_cells_iterator fcit = m_tr->finite_cells_begin(); fcit != m_tr->finite_cells_end(); @@ -640,18 +640,18 @@ public: const Point& pb = ch->vertex(1)->point(); const Point& pc = ch->vertex(2)->point(); const Point& pd = ch->vertex(3)->point(); - + Vector va = pa - pd; Vector vb = pb - pd; Vector vc = pc - pd; - + internal::invert(va.x(), va.y(), va.z(), vb.x(), vb.y(), vb.z(), vc.x(), vc.y(), vc.z(), entry[0],entry[1],entry[2],entry[3],entry[4],entry[5],entry[6],entry[7],entry[8]); } /// \endcond - + /// Returns a point located inside the inferred surface. Point get_inner_point() const { @@ -682,7 +682,7 @@ private: internal::Poisson::Constant_sizing_field()); } - template unsigned int delaunay_refinement(FT radius_edge_ratio_bound, ///< radius edge ratio bound (ignored if zero) Sizing_field sizing_field, ///< cell radius bound (ignored if zero) @@ -792,12 +792,12 @@ private: // it is closed using the smallest part of the sphere). std::vector convex_hull; m_tr->adjacent_vertices (m_tr->infinite_vertex (), - std::back_inserter (convex_hull)); + std::back_inserter (convex_hull)); unsigned int nb_negative = 0; for (std::size_t i = 0; i < convex_hull.size (); ++ i) if (convex_hull[i]->f() < 0.0) ++ nb_negative; - + if(nb_negative > convex_hull.size () / 2) flip_f(); @@ -814,7 +814,7 @@ private: Finite_vertices_iterator v, e; for(v = m_tr->finite_vertices_begin(), e= m_tr->finite_vertices_end(); - v != e; + v != e; v++) if(v->type() == Triangulation::INPUT) values.push_back(v->f()); @@ -933,14 +933,14 @@ private: // TODO: Some entities are computed too often // - nn and area should not be computed for the face and its opposite face - // + // // divergent FT div_normalized(Vertex_handle v) { std::vector cells; cells.reserve(32); m_tr->incident_cells(v,std::back_inserter(cells)); - + FT div = 0; typename std::vector::iterator it; for(it = cells.begin(); it != cells.end(); it++) @@ -986,7 +986,7 @@ private: std::vector cells; cells.reserve(32); m_tr->incident_cells(v,std::back_inserter(cells)); - + FT div = 0.0; typename std::vector::iterator it; for(it = cells.begin(); it != cells.end(); it++) @@ -994,14 +994,14 @@ private: Cell_handle cell = *it; if(m_tr->is_infinite(cell)) continue; - + const int index = cell->index(v); const Point& a = cell->vertex(m_tr->vertex_triple_index(index, 0))->point(); const Point& b = cell->vertex(m_tr->vertex_triple_index(index, 1))->point(); const Point& c = cell->vertex(m_tr->vertex_triple_index(index, 2))->point(); const Vector nn = CGAL::cross_product(b-a,c-a); - div+= nn * (//v->normal() + + div+= nn * (//v->normal() + cell->vertex((index+1)%4)->normal() + cell->vertex((index+2)%4)->normal() + cell->vertex((index+3)%4)->normal()); @@ -1198,7 +1198,7 @@ private: A.set_coef(vi->index(),vi->index(), diagonal, true /*new*/); } } - + /// Computes enlarged geometric bounding sphere of the embedded triangulation. Sphere enlarged_bounding_sphere(FT ratio) const diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index e86feb322ff..f58413b9755 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -184,7 +184,7 @@ struct Dereference_property_map /// Free function to create a `Dereference_property_map` property map. /// -/// \relates Dereference_property_map +/// \relates Dereference_property_map template // Type convertible to `key_type` Dereference_property_map::type> make_dereference_property_map(Iter) @@ -234,7 +234,7 @@ struct Identity_property_map_no_lvalue /// Free function to create a `Identity_property_map` property map. /// -/// \relates Identity_property_map +/// \relates Identity_property_map template // Key and value type Identity_property_map make_identity_property_map(T) @@ -244,8 +244,8 @@ Identity_property_map /// \ingroup PkgPropertyMapRef -/// Property map that accesses the first item of a `std::pair`. -/// \tparam Pair Instance of `std::pair`. +/// Property map that accesses the first item of a `std::pair`. +/// \tparam Pair Instance of `std::pair`. /// \cgalModels `LvaluePropertyMap` /// /// \sa `CGAL::Second_of_pair_property_map` @@ -269,9 +269,9 @@ struct First_of_pair_property_map /// @} }; -/// Free function to create a `First_of_pair_property_map` property map. +/// Free function to create a `First_of_pair_property_map` property map. /// -/// \relates First_of_pair_property_map +/// \relates First_of_pair_property_map template // Pair type First_of_pair_property_map make_first_of_pair_property_map(Pair) @@ -280,13 +280,13 @@ First_of_pair_property_map } /// \ingroup PkgPropertyMapRef -/// -/// Property map that accesses the second item of a `std::pair`. -/// -/// \tparam Pair Instance of `std::pair`. -/// +/// +/// Property map that accesses the second item of a `std::pair`. +/// +/// \tparam Pair Instance of `std::pair`. +/// /// \cgalModels `LvaluePropertyMap` -/// +/// /// \sa `CGAL::First_of_pair_property_map` template struct Second_of_pair_property_map @@ -310,7 +310,7 @@ struct Second_of_pair_property_map /// Free function to create a Second_of_pair_property_map property map. /// -/// \relates Second_of_pair_property_map +/// \relates Second_of_pair_property_map template // Pair type Second_of_pair_property_map make_second_of_pair_property_map(Pair) @@ -319,12 +319,12 @@ Second_of_pair_property_map } /// \ingroup PkgPropertyMapRef -/// +/// /// Property map that accesses the Nth item of a `boost::tuple` or a `std::tuple`. -/// +/// /// \tparam N %Index of the item to access. /// \tparam Tuple Instance of `boost::tuple` or `std::tuple`. -/// +/// /// \cgalModels `LvaluePropertyMap` template struct Nth_of_tuple_property_map diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index e65c1ec9ade..65aeedef9d6 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -67,7 +67,7 @@ void for_each (RangeRef range, iterators.reserve (range_size); for (typename Range_iterator_type::type it = range.begin(); it != range.end(); ++ it) iterators.push_back (it); - + tbb::parallel_for (tbb::blocked_range(0, range_size), [&](const tbb::blocked_range& r) { @@ -85,7 +85,7 @@ void for_each (RangeRef range, std::random_access_iterator_tag) { std::size_t range_size = std::distance (range.begin(), range.end()); - + tbb::parallel_for (tbb::blocked_range(0, range_size), [&](const tbb::blocked_range& r) { diff --git a/STL_Extension/include/CGAL/iterator.h b/STL_Extension/include/CGAL/iterator.h index 8424af8487f..16733969b61 100644 --- a/STL_Extension/include/CGAL/iterator.h +++ b/STL_Extension/include/CGAL/iterator.h @@ -1,16 +1,16 @@ -// Copyright (c) 2003 +// Copyright (c) 2003 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. +// and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Michael Hoffmann // Lutz Kettner @@ -172,11 +172,11 @@ class Oneset_iterator void, void, void, void > { T* t; - + public: // types typedef Oneset_iterator Self; - + public: Oneset_iterator(T& t) : t(&t) {} @@ -202,65 +202,65 @@ public: template < typename T > class Const_oneset_iterator { public: - + // types typedef std::random_access_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; typedef T value_type; typedef value_type* pointer; typedef value_type& reference; - + typedef Const_oneset_iterator Self; typedef difference_type Diff; typedef value_type Val; typedef pointer Ptr; typedef reference Ref; - + // construction Const_oneset_iterator( const T& t = T(), Diff n = 0) : value( t), index( n) { } - + // access Ref operator * ( ) { return value; } const value_type& operator * ( ) const { return value; } Ptr operator -> ( ) { return &value; } const value_type* operator -> ( ) const { return &value; } - + // equality operator bool operator == ( const Self& x) const { return ( index==x.index); } bool operator != ( const Self& x) const { return ( index!=x.index); } - + // forward operations // ------------------ Self& operator ++ ( ) { ++index; return *this; } Self operator ++ ( int) { Self tmp = *this; ++index; return tmp; } - + // bidirectional operations // ------------------------ Self& operator -- ( ) { --index; return *this; } Self operator -- ( int) { Self tmp = *this; --index; return tmp; } - + // random access operations // ------------------------ // access Ref operator [] ( Diff ) { return value;} const value_type& operator [] ( Diff ) const { return value;} - + // less operator bool operator < ( const Self& x) const { return ( index < x.index);} - + // arithmetic operations Self& operator += ( Diff n) { index += n; return *this; } Self& operator -= ( Diff n) { index -= n; return *this; } - + Self operator + ( Diff n) const { Self tmp = *this; return tmp+=n; } Self operator - ( Diff n) const { Self tmp = *this; return tmp-=n; } - + Diff operator - ( const Self& x) const { return index - x.index; } - + private: - + // data members Val value; Diff index; @@ -443,12 +443,12 @@ public: }; // Microsoft 1300 cannot handle the default template parameters. Hence, ... -template < class I, int N, class Ref, class Ptr, - class Val, class Dist, class Ctg > +template < class I, int N, class Ref, class Ptr, + class Val, class Dist, class Ctg > inline N_step_adaptor operator+(typename N_step_adaptor::difference_type n, - N_step_adaptor i) + N_step_adaptor i) { return i += n; } template < class I, int N> @@ -605,7 +605,7 @@ public: --(*this); return tmp; } - + reference operator*() const { return *c_; } pointer operator->() const { return &*c_; } const Predicate& predicate() const { return p_; } @@ -678,9 +678,9 @@ public: : i1(it.i1), op(it.op) {} Join_input_iterator_1(I1 i,const Op& o=Op()) : i1(i), op(o) {} - + I1 current_iterator1() const { return i1; } - + bool operator==(const Self& i) const { return i1 == i.i1; } @@ -695,12 +695,12 @@ public: op = it.op; return *this; } - - const value_type& operator*() const { + + const value_type& operator*() const { val = op(*i1); return val; } - + Self& operator++( ) { ++i1; return *this; @@ -711,12 +711,12 @@ public: return *this; } Self operator--(int) { Self tmp = *this; --(*this); return tmp; } - + const value_type& operator[](difference_type i) const { val = op(i1[i]); return val; } - + Self& operator+=(difference_type n) { i1 += n; return *this; @@ -758,17 +758,17 @@ protected: mutable value_type val; // Note: mutable is needed because we want to // return a reference in operator*() and // operator[](int) below. - + public: Join_input_iterator_2() {} Join_input_iterator_2(const Join_input_iterator_2& it) : i1(it.i1), i2(it.i2), op(it.op) {} Join_input_iterator_2(I1 i1,I2 i2,const Op& op=Op()) : i1(i1), i2(i2), op(op) {} - + I1 current_iterator1() const { return i1; } I2 current_iterator2() const { return i2; } - + bool operator==(const Self& i) const { return i1 == i.i1 && i2 == i.i2; } @@ -776,7 +776,7 @@ public: bool operator< (const Self& i) const { return i1 < i.i1 && i2 < i.i2; } - + Join_input_iterator_2& operator=(const Join_input_iterator_2& it) { i1 = it.i1; @@ -785,11 +785,11 @@ public: return *this; } - const value_type& operator*() const { + const value_type& operator*() const { val = op(*i1,*i2); return val; } - + Self& operator++( ) { ++i1; ++i2; @@ -802,12 +802,12 @@ public: return *this; } Self operator--(int) { Self tmp = *this; --(*this); return tmp; } - + const value_type& operator[](difference_type i) const { val = op(i1[i],i2[i]); return val; } - + Self& operator+=(difference_type n) { i1 += n; i2 += n; @@ -845,7 +845,7 @@ public: typedef typename std::iterator_traits::difference_type difference_type; typedef value_type* pointer; typedef value_type& reference; - + protected: I1 i1; I2 i2; @@ -854,18 +854,18 @@ protected: mutable value_type val; // Note: mutable is needed because we want to // return a reference in operator*() and // operator[](int) below. - + public: Join_input_iterator_3() {} Join_input_iterator_3(const Join_input_iterator_3& it) : i1(it.i1), i2(it.i2), i3(it.i3), op(it.op) {} Join_input_iterator_3(I1 i1,I2 i2,I3 i3,const Op& op=Op()) : i1(i1), i2(i2), i3(i3), op(op) {} - + I1 current_iterator1() const { return i1; } I2 current_iterator2() const { return i2; } I2 current_iterator3() const { return i3; } - + bool operator==(const Self& i) const { return i1 == i.i1 && i2 == i.i2 && i3 == i.i3; } @@ -873,7 +873,7 @@ public: bool operator< (const Self& i) const { return i1 < i.i1 && i2 < i.i2 && i3 < i.i3; } - + Join_input_iterator_3& operator=(const Join_input_iterator_3& it) { i1 = it.i1; @@ -883,11 +883,11 @@ public: return *this; } - const value_type& operator*() const { + const value_type& operator*() const { val = op(*i1,*i2,*i3); return val; } - + Self& operator++( ) { ++i1; ++i2; @@ -902,12 +902,12 @@ public: return *this; } Self operator--(int) { Self tmp = *this; --(*this); return tmp; } - + const value_type& operator[](difference_type i) const { val = op(i1[i],i2[i],i3[i]); return val; } - + Self& operator+=(difference_type n) { i1 += n; i2 += n; @@ -1220,17 +1220,17 @@ template public: typedef _Iterator iterator_type; - explicit Filter_output_iterator(_Iterator& __x, const Predicate& pred) - : iterator(__x), predicate(pred) + explicit Filter_output_iterator(_Iterator& __x, const Predicate& pred) + : iterator(__x), predicate(pred) {} template Filter_output_iterator& operator=(const T& t) { - if(! predicate(t)) - *iterator = t; - return *this; + if(! predicate(t)) + *iterator = t; + return *this; } Filter_output_iterator& @@ -1239,9 +1239,9 @@ template Filter_output_iterator& operator++() - { + { ++iterator; - return *this; + return *this; } Filter_output_iterator @@ -1249,7 +1249,7 @@ template { Filter_output_iterator res(*this); ++iterator; - return res; + return res; } }; @@ -1264,7 +1264,7 @@ template struct Output_visitor : boost::static_visitor { Output_visitor(OutputIterator* it) : out(it) {} OutputIterator* out; - + template OutputIterator& operator()(const T& t) { *(*out)++ = t; @@ -1298,7 +1298,7 @@ struct Derivator, std::tuple > Self& operator=(const Self&) = delete; using Base::operator=; - + D& operator=(const V1& v) { * std::get< D::size - sizeof...(V) - 1 >(static_cast(static_cast(*this))) ++ = v; @@ -1308,7 +1308,7 @@ struct Derivator, std::tuple > template void tuple_dispatch(const Tuple& t) { - * std::get< D::size - sizeof...(V) - 1 >(static_cast(static_cast(*this))) ++ = + * std::get< D::size - sizeof...(V) - 1 >(static_cast(static_cast(*this))) ++ = std::get< D::size - sizeof...(V) - 1 >(t); static_cast(*this).tuple_dispatch(t); } @@ -1366,7 +1366,7 @@ public: Dispatch_output_iterator(O... o) : std::tuple(o...) {} - + Dispatch_output_iterator(const Dispatch_output_iterator&)=default; Self& operator=(const Self& s) @@ -1374,7 +1374,7 @@ public: static_cast(*this) = static_cast(s); return *this; } - + template Self& operator=(const boost::variant& t) { internal::Output_visitor visitor(this); @@ -1402,18 +1402,18 @@ public: Self& operator*() { return *this; } const Iterator_tuple& get_iterator_tuple() const { return *this; } - + Self& operator=(const std::tuple& t) { tuple_dispatch(t); return *this; } - + operator std::tuple() { return tuple_internal::to_tuple(*this, std::index_sequence_for{}); } - + operator std::tuple()const { return tuple_internal::to_tuple(*this, std::index_sequence_for{}); @@ -1447,7 +1447,7 @@ class Dispatch_or_drop_output_iterator < std::tuple, std::tuple > public: Dispatch_or_drop_output_iterator(O... o) : Base(o...) {} - + Dispatch_or_drop_output_iterator(const Dispatch_or_drop_output_iterator&)=default; Dispatch_or_drop_output_iterator& operator=(const Dispatch_or_drop_output_iterator&)=default; diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index 105fb37149f..80563069300 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -47,8 +47,8 @@ if ( CGAL_FOUND ) CGAL_target_use_TBB(test_for_each) endif() else() - + message(STATUS "This program requires the CGAL library, and will not be compiled.") - + endif() diff --git a/STL_Extension/test/STL_Extension/test_for_each.cpp b/STL_Extension/test/STL_Extension/test_for_each.cpp index cfb003a4aa3..d1185b378b0 100644 --- a/STL_Extension/test/STL_Extension/test_for_each.cpp +++ b/STL_Extension/test/STL_Extension/test_for_each.cpp @@ -20,20 +20,20 @@ int main() std::cerr << "Testing parallel random access" << std::endl; CGAL::for_each (vec, [](int& i) -> bool { i *= 2; return true; }); - + for (const int& i : vec) std::cerr << i << " "; std::cerr << std::endl; #endif - + std::cerr << "Testing sequential non-random access" << std::endl; CGAL::for_each (list, [](int& i) -> bool { i *= 2; return true; }); - + for (const int& i : list) std::cerr << i << " "; std::cerr << std::endl; - + #ifdef CGAL_LINKED_WITH_TBB std::cerr << "Testing parallel non-random access" << std::endl; CGAL::for_each @@ -43,6 +43,6 @@ int main() std::cerr << i << " "; std::cerr << std::endl; #endif - + return 0; } diff --git a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h index 3cb7132be3e..d0db23ceb1c 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h +++ b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Hans Tangelder () @@ -31,42 +31,42 @@ namespace CGAL { T *lower; T *upper; Construct_cartesian_const_iterator_d construct_it; - - set_bounds_from_pointer(int d, T *l, T *u,Construct_cartesian_const_iterator_d construct_it_) + + set_bounds_from_pointer(int d, T *l, T *u,Construct_cartesian_const_iterator_d construct_it_) : dim(d), lower(l), upper(u), construct_it(construct_it_) {} - void - operator()(P p) + void + operator()(P p) { T h; typename Construct_cartesian_const_iterator_d::result_type pit = construct_it(*p); for (int i = 0; i < dim; ++i, ++pit) { - h=(*pit); - if (h < lower[i]) lower[i] = h; - if (h > upper[i]) upper[i] = h; + h=(*pit); + if (h < lower[i]) lower[i] = h; + if (h > upper[i]) upper[i] = h; } } }; - template + template class Kd_tree_rectangle { public: typedef FT_ FT; typedef FT T; - + private: - + //int dim; std::array lower_; std::array upper_; int max_span_coord_; - + public: - - inline void - set_upper_bound(int i, const FT& x) + + inline void + set_upper_bound(int i, const FT& x) { CGAL_assertion(i >= 0 && i < D::value); CGAL_assertion(x >= lower_[i]); @@ -74,8 +74,8 @@ namespace CGAL { set_max_span(); } - inline void - set_lower_bound(int i, const FT& x) + inline void + set_lower_bound(int i, const FT& x) { CGAL_assertion(i >= 0 && i < D::value); CGAL_assertion(x <= upper_[i]); @@ -83,20 +83,20 @@ namespace CGAL { set_max_span(); } - inline void - set_max_span() + inline void + set_max_span() { FT span = upper_[0]-lower_[0]; max_span_coord_ = 0; for (int i = 1; i < D::value; ++i) { - FT tmp = upper_[i] - lower_[i]; - if (span < tmp) { - span = tmp; - max_span_coord_ = i; - } + FT tmp = upper_[i] - lower_[i]; + if (span < tmp) { + span = tmp; + max_span_coord_ = i; + } } } - + Kd_tree_rectangle(int) : max_span_coord_(0) { @@ -104,30 +104,30 @@ namespace CGAL { upper_.fill(FT(0)); } - Kd_tree_rectangle() + Kd_tree_rectangle() : max_span_coord_(-1) {} - - - explicit + + + explicit Kd_tree_rectangle(const Kd_tree_rectangle& r) - : max_span_coord_(r.max_span_coord_) + : max_span_coord_(r.max_span_coord_) { lower_ = r.lower_; upper_ = r.upper_; } template - void update_from_point_pointers(PointPointerIter begin, + void update_from_point_pointers(PointPointerIter begin, PointPointerIter end, const Construct_cartesian_const_iterator_d& construct_it - ) + ) { if (begin ==end) return; // initialize with values of first point typename Construct_cartesian_const_iterator_d::result_type bit = construct_it(**begin); - + for (int i=0; i < D::value; ++i, ++bit) { lower_[i]= *bit; upper_[i]=lower_[i]; } @@ -136,7 +136,7 @@ namespace CGAL { std::for_each(begin, end,set_bounds_from_pointer(D::value, &(lower_[0]), &(upper_[0]), construct_it)); set_max_span(); } - + template // was PointIter Kd_tree_rectangle(int, PointPointerIter begin, PointPointerIter end,const Construct_cartesian_const_iterator_d& construct_it) : max_span_coord_(-1) @@ -144,70 +144,70 @@ namespace CGAL { update_from_point_pointers(begin,end,construct_it); } - inline int - max_span_coord() const - { - return max_span_coord_; + inline int + max_span_coord() const + { + return max_span_coord_; } - inline FT - max_span() const + inline FT + max_span() const { return upper_[max_span_coord_] - lower_[max_span_coord_]; } - inline FT - min_coord(int i) const + inline FT + min_coord(int i) const { CGAL_assume(i(s," ")); + // std::ostream_iterator(s," ")); s << "\n upper: "; for (int j=0; j < D::value; ++j) - s << upper_[j] << " "; + s << upper_[j] << " "; // std::copy(upper_, upper_ + D, - // std::ostream_iterator(s," ")); + // std::ostream_iterator(s," ")); s << "\n maximum span " << max_span() << - " at coordinate " << max_span_coord() << std::endl; + " at coordinate " << max_span_coord() << std::endl; return s; } - - // Splits rectangle by modifying itself to lower half + + // Splits rectangle by modifying itself to lower half // and returns upper half - // Kd_tree_rectangle* + // Kd_tree_rectangle* void split(Kd_tree_rectangle& r, int d, FT value) { CGAL_assertion(d >= 0 && d < D::value); CGAL_assertion(lower_[d] <= value && value <= upper_[d]); - + //Kd_tree_rectangle* r = new Kd_tree_rectangle(*this); upper_[d]=value; r.lower_[d]=value; //return r; } - - int - dimension() const + + int + dimension() const { return D::value; } @@ -216,7 +216,7 @@ namespace CGAL { T* upper() {return upper_.data();} const T* lower() const {return lower_.data();} const T* upper() const {return upper_.data();} - + Kd_tree_rectangle& operator=(const Kd_tree_rectangle& r) { @@ -224,35 +224,35 @@ namespace CGAL { if (this != &r) { lower_ = r.lower_; upper_ = r.upper_; - set_max_span(); + set_max_span(); } return *this; } - + }; // of class Kd_tree_rectangle // Partial specialization for dynamic dimension, which means dimension at runtime - template + template class Kd_tree_rectangle { public: typedef FT_ FT; typedef FT T; - + private: - + T* coords_; int dim; int max_span_coord_; - + public: - - inline void - set_upper_bound(int i, const FT& x) + + inline void + set_upper_bound(int i, const FT& x) { CGAL_assertion(i >= 0 && i < dim); CGAL_assertion(x >= lower()[i]); @@ -260,8 +260,8 @@ namespace CGAL { set_max_span(); } - inline void - set_lower_bound(int i, const FT& x) + inline void + set_lower_bound(int i, const FT& x) { CGAL_assertion(i >= 0 && i < dim); CGAL_assertion(x <= upper()[i]); @@ -269,51 +269,51 @@ namespace CGAL { set_max_span(); } - inline void - set_max_span() + inline void + set_max_span() { FT span = upper()[0]-lower()[0]; max_span_coord_ = 0; for (int i = 1; i < dim; ++i) { - FT tmp = upper()[i] - lower()[i]; - if (span < tmp) { - span = tmp; - max_span_coord_ = i; - } + FT tmp = upper()[i] - lower()[i]; + if (span < tmp) { + span = tmp; + max_span_coord_ = i; + } } } - - Kd_tree_rectangle(int d) + + Kd_tree_rectangle(int d) : coords_(new FT[2*d]), dim(d), max_span_coord_(0) { std::fill(coords_, coords_ + 2*dim, FT(0)); } - Kd_tree_rectangle() + Kd_tree_rectangle() : coords_(0), dim(0), max_span_coord_(-1) { } - - - explicit + + + explicit Kd_tree_rectangle(const Kd_tree_rectangle& r) : coords_(new FT[2*r.dim]), dim(r.dim), - max_span_coord_(r.max_span_coord_) + max_span_coord_(r.max_span_coord_) { std::copy(r.coords_, r.coords_+2*dim, lower()); } template - void update_from_point_pointers(PointPointerIter begin, + void update_from_point_pointers(PointPointerIter begin, PointPointerIter end, const Construct_cartesian_const_iterator_d& construct_it - ) + ) { if (begin ==end) return; // initialize with values of first point typename Construct_cartesian_const_iterator_d::result_type bit = construct_it(**begin); - + for (int i=0; i < dim; ++i, ++bit) { lower()[i]= *bit; upper()[i]=lower()[i]; } @@ -322,7 +322,7 @@ namespace CGAL { std::for_each(begin, end,set_bounds_from_pointer(dim, lower(), upper(),construct_it)); set_max_span(); } - + template // was PointIter Kd_tree_rectangle(int d, PointPointerIter begin, PointPointerIter end,const Construct_cartesian_const_iterator_d& construct_it) : coords_(new FT[2*d]), dim(d), max_span_coord_(-1) @@ -330,75 +330,75 @@ namespace CGAL { update_from_point_pointers(begin,end,construct_it); } - inline int - max_span_coord() const - { - return max_span_coord_; + inline int + max_span_coord() const + { + return max_span_coord_; } - inline FT - max_span() const + inline FT + max_span() const { return upper()[max_span_coord_] - lower()[max_span_coord_]; } - inline FT - min_coord(int i) const + inline FT + min_coord(int i) const { CGAL_assertion(coords_ != nullptr); return lower()[i]; } - - inline FT - max_coord(int i) const + + inline FT + max_coord(int i) const { return upper()[i]; } - - std::ostream& - print(std::ostream& s) const + + std::ostream& + print(std::ostream& s) const { s << "Rectangle dimension = " << dim; s << "\n lower: "; for (int i=0; i < dim; ++i) - s << lower()[i] << " "; + s << lower()[i] << " "; // std::copy(lower(), lower() + dim, - // std::ostream_iterator(s," ")); + // std::ostream_iterator(s," ")); s << "\n upper: "; for (int j=0; j < dim; ++j) - s << upper()[j] << " "; + s << upper()[j] << " "; // std::copy(upper(), upper() + dim, - // std::ostream_iterator(s," ")); + // std::ostream_iterator(s," ")); s << "\n maximum span " << max_span() << - " at coordinate " << max_span_coord() << std::endl; + " at coordinate " << max_span_coord() << std::endl; return s; } - - // Splits rectangle by modifying itself to lower half + + // Splits rectangle by modifying itself to lower half // and returns upper half - // Kd_tree_rectangle* + // Kd_tree_rectangle* void split(Kd_tree_rectangle& r, int d, FT value) { CGAL_assertion(d >= 0 && d < dim); CGAL_assertion(lower()[d] <= value && value <= upper()[d]); - + //Kd_tree_rectangle* r = new Kd_tree_rectangle(*this); upper()[d]=value; r.lower()[d]=value; //return r; } - - - ~Kd_tree_rectangle() + + + ~Kd_tree_rectangle() { if (dim) { - if (coords_) delete [] coords_; + if (coords_) delete [] coords_; } } - - int - dimension() const + + int + dimension() const { return dim; } @@ -407,30 +407,30 @@ namespace CGAL { T* upper() {return coords_ + dim;} const T* lower() const {return coords_;} const T* upper() const {return coords_ + dim;} - + Kd_tree_rectangle& operator=(const Kd_tree_rectangle& r) { CGAL_assertion(dimension() == r.dimension()); if (this != &r) { std::copy(r.coords_, r.coords_+2*dim, coords_); - set_max_span(); + set_max_span(); } return *this; } - + }; // of partial specialization of class Kd_tree_rectangle template - std::ostream& - operator<<(std::ostream& s, const Kd_tree_rectangle& r) + std::ostream& + operator<<(std::ostream& s, const Kd_tree_rectangle& r) { return r.print(s); } - + } // namespace CGAL #endif // CGAL_KD_TREE_RECTANGLE_H diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index d1d0b3bc43f..d3c6b49fd60 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -6,7 +6,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// +// // // Author(s) : Sebastien Loriot @@ -30,13 +30,13 @@ namespace CGAL{ using ::get; - + template class Search_traits_adapter; - + template class Distance_adapter; - + namespace internal{ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_typedef_Iso_box_d,Iso_box_d,false) @@ -55,7 +55,7 @@ struct Get_iso_box_d { typedef typename T::Iso_box_d type; }; - + template struct Spatial_searching_default_distance< ::CGAL::Search_traits_adapter >{ typedef ::CGAL::Distance_adapter }; } //namespace internal - - + + template class Search_traits_adapter : public Base_traits{ PointPropertyMap ppmap; @@ -78,21 +78,21 @@ public: const Base_traits& base=Base_traits() ):Base_traits(base),ppmap(ppmap_){} - + typedef Point_with_info Point_d; typedef typename Base_traits::FT FT; typedef typename Base_traits::Dimension Dimension; - + // Default if point map is lvalue: use Construct_cartesian_const_iterator_d struct Construct_cartesian_const_iterator_d_lvalue: public Base_traits::Construct_cartesian_const_iterator_d{ PointPropertyMap ppmap; typedef typename Base_traits::Construct_cartesian_const_iterator_d Base; - + Construct_cartesian_const_iterator_d_lvalue (const typename Base_traits::Construct_cartesian_const_iterator_d& base, const PointPropertyMap& ppmap_) :Base_traits::Construct_cartesian_const_iterator_d(base), ppmap(ppmap_){} - + typename Base_traits::Cartesian_const_iterator_d operator()(const Point_with_info& p) const { return Base::operator() (get(ppmap,p)); } @@ -100,9 +100,9 @@ public: { return Base::operator() (get(ppmap,p),0); } // These 2 additional operators forward the call to Base_traits. - // This is needed because of an undocumented requirement of - // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: - // Traits::Construct_cartesian_const_iterator should be callable + // This is needed because of an undocumented requirement of + // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: + // Traits::Construct_cartesian_const_iterator should be callable // on the query point type. If the query point type is the same as // Point_with_info, we disable it. @@ -122,7 +122,7 @@ public: ) const { return Base::operator() (p,0); } }; - + // If point map is not lvalue, use this work-around that stores a // Point object in a shared pointer to avoid iterating on a temp // object @@ -136,7 +136,7 @@ public: typename std::iterator_traits::value_type, std::random_access_iterator_tag > Facade; - + typedef typename std::iterator_traits::value_type Dereference_type; typedef typename boost::property_traits::value_type @@ -146,13 +146,13 @@ public: std::size_t idx; public: - + No_lvalue_iterator() : point(NULL), idx(0) { } No_lvalue_iterator(const Point& point) : point(new Point(point)), idx(0) { } No_lvalue_iterator(const Point& point, int) : point(new Point(point)), idx(Base::Dimension::value) { } - + private: - + friend class boost::iterator_core_access; void increment() { @@ -164,7 +164,7 @@ public: --idx; CGAL_assertion(point != boost::shared_ptr()); } - + void advance(std::ptrdiff_t n) { idx += n; @@ -174,7 +174,7 @@ public: std::ptrdiff_t distance_to(const No_lvalue_iterator& other) const { return other.idx - this->idx; - + } bool equal(const No_lvalue_iterator& other) const { @@ -195,11 +195,11 @@ public: struct Construct_cartesian_const_iterator_d_no_lvalue { typedef No_lvalue_iterator result_type; PointPropertyMap ppmap; - + Construct_cartesian_const_iterator_d_no_lvalue (const typename Base_traits::Construct_cartesian_const_iterator_d&, const PointPropertyMap& ppmap_) : ppmap(ppmap_) { } - + No_lvalue_iterator operator()(const Point_with_info& p) const { return No_lvalue_iterator(get(ppmap, p)); } @@ -207,9 +207,9 @@ public: { return No_lvalue_iterator(get(ppmap, p),0); } // These 2 additional operators forward the call to Base_traits. - // This is needed because of an undocumented requirement of - // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: - // Traits::Construct_cartesian_const_iterator should be callable + // This is needed because of an undocumented requirement of + // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: + // Traits::Construct_cartesian_const_iterator should be callable // on the query point type. If the query point type is the same as // Point_with_info, we disable it. @@ -246,7 +246,7 @@ public: Construct_cartesian_const_iterator_d_lvalue, Construct_cartesian_const_iterator_d_no_lvalue>::type Construct_cartesian_const_iterator_d; - + struct Construct_iso_box_d: public Base::Construct_iso_box_d{ PointPropertyMap ppmap; typedef typename Base_traits::FT FT; // needed for VC++, because otherwise it is taken from the private typedef of the base class @@ -260,9 +260,9 @@ public: return Base_functor::operator() (get(ppmap,p),get(ppmap,q)); } }; - + const PointPropertyMap& point_property_map() const {return ppmap;} - + Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object() const { return Construct_cartesian_const_iterator_d( Base::construct_cartesian_const_iterator_d_object(), @@ -275,7 +275,7 @@ class Distance_adapter : public Base_distance { PointPropertyMap ppmap; public: - + Distance_adapter( const PointPropertyMap& ppmap_=PointPropertyMap(), const Base_distance& distance=Base_distance() ):Base_distance(distance),ppmap(ppmap_){} @@ -286,7 +286,7 @@ public: typedef Point_with_info Point_d; typedef typename Base_distance::Query_item Query_item; - const PointPropertyMap& point_property_map() const {return ppmap;} + const PointPropertyMap& point_property_map() const {return ppmap;} FT transformed_distance(const Query_item& p1, const Point_with_info& p2) const { @@ -309,12 +309,12 @@ public: FT max_distance_to_rectangle(const Query_item& p,const CGAL::Kd_tree_rectangle& b) const { return Base_distance::max_distance_to_rectangle(p,b); - } + } template FT max_distance_to_rectangle(const Query_item& p,const CGAL::Kd_tree_rectangle& b,std::vector& dists) const { return Base_distance::max_distance_to_rectangle(p,b,dists); - } + } }; }//namespace CGAL From 6ae64e7a735154c00b74b2906dad2dadaa83d1d4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 27 Mar 2020 16:41:53 +0100 Subject: [PATCH 28/30] Make functor a template parameter in the internal function --- STL_Extension/include/CGAL/for_each.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/STL_Extension/include/CGAL/for_each.h b/STL_Extension/include/CGAL/for_each.h index 65aeedef9d6..f68bba0e80b 100644 --- a/STL_Extension/include/CGAL/for_each.h +++ b/STL_Extension/include/CGAL/for_each.h @@ -54,10 +54,9 @@ void for_each (RangeRef range, } #ifdef CGAL_LINKED_WITH_TBB -template +template void for_each (RangeRef range, - const std::function::type>::reference)>& functor, + const Fct& functor, const Parallel_tag&, IteratorCategory) { @@ -77,10 +76,9 @@ void for_each (RangeRef range, }); } -template +template void for_each (RangeRef range, - const std::function::type>::reference)>& functor, + const Fct& functor, const Parallel_tag&, std::random_access_iterator_tag) { From 0409e2b48dfdbcb9d73e87c95dc5fa2d1ad637a5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 30 Mar 2020 15:47:45 +0200 Subject: [PATCH 29/30] Fix iterator determinism in Poisson --- .../CGAL/Poisson_reconstruction_function.h | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index c92c70990a2..5f9e258fbdc 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -47,6 +47,7 @@ #include #include #include +#include /*! \file Poisson_reconstruction_function.h @@ -104,18 +105,6 @@ struct Poisson_visitor { {} }; -struct Poisson_skip_vertices { - double ratio; - Poisson_skip_vertices(const double ratio = 0) - : ratio(ratio) {} - - template - bool operator()(Iterator it) const { - // make the result deterministic for each iterator - return Random((std::size_t)(&*it)).get_double() < ratio; - } -}; - // Given f1 and f2, two sizing fields, that functor wrapper returns // max(f1, f2*f2) // The wrapper stores only pointers to the two functors. @@ -415,21 +404,24 @@ public: // then the cell is considered as small enough, and the first sizing // field, more costly, is not evaluated. - typedef Filter_iterator Some_points_iterator; - Poisson_skip_vertices skip(1.-approximation_ratio); + //make it deterministic + Random random(0); + double ratio = 1.-approximation_ratio; + std::vector some_points; + for (typename Triangulation::Input_point_iterator + it = m_tr->input_points_begin(); it != m_tr->input_points_end(); ++ it) + if (random.get_double() >= ratio) + some_points.push_back (it); + CGAL_TRACE_STREAM << "SPECIAL PASS that uses an approximation of the result (approximation ratio: " << approximation_ratio << ")" << std::endl; CGAL::Timer approximation_timer; approximation_timer.start(); CGAL::Timer sizing_field_timer; sizing_field_timer.start(); Poisson_reconstruction_function - coarse_poisson_function(Some_points_iterator(m_tr->input_points_end(), - skip, - m_tr->input_points_begin()), - Some_points_iterator(m_tr->input_points_end(), - skip), + coarse_poisson_function(boost::make_indirect_iterator (some_points.begin()), + boost::make_indirect_iterator (some_points.end()), Normal_of_point_with_normal_map() ); coarse_poisson_function.compute_implicit_function(solver, Poisson_visitor(), 0.); From 6b2dad145a163a860ee2eca55fb6ccffd0438bd8 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 1 Apr 2020 07:59:15 +0200 Subject: [PATCH 30/30] Remove trailing whitespace --- .../include/CGAL/Poisson_reconstruction_function.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index 5f9e258fbdc..aaace81b7ba 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -413,7 +413,7 @@ public: it = m_tr->input_points_begin(); it != m_tr->input_points_end(); ++ it) if (random.get_double() >= ratio) some_points.push_back (it); - + CGAL_TRACE_STREAM << "SPECIAL PASS that uses an approximation of the result (approximation ratio: " << approximation_ratio << ")" << std::endl; CGAL::Timer approximation_timer; approximation_timer.start();