diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index 534593c93cb..14550d82272 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -152,6 +152,12 @@ defined(BOOST_NO_CXX11_HDR_ARRAY) || BOOST_VERSION < 104000 #define CGAL_CFG_NO_CPP0X_ARRAY 1 #endif +#if defined(BOOST_NO_0X_HDR_UNORDERED_SET) || \ + defined(BOOST_NO_0X_HDR_UNORDERED_MAP) || \ + defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) || \ + defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) +#define CGAL_CFG_NO_CPP0X_UNORDERED 1 +#endif #if defined(BOOST_NO_DECLTYPE) || \ defined(BOOST_NO_CXX11_DECLTYPE) || (BOOST_VERSION < 103600) #define CGAL_CFG_NO_CPP0X_DECLTYPE 1 diff --git a/Point_set_processing_3/include/CGAL/grid_simplify_point_set.h b/Point_set_processing_3/include/CGAL/grid_simplify_point_set.h index d1af212b2e6..f93b440246b 100644 --- a/Point_set_processing_3/include/CGAL/grid_simplify_point_set.h +++ b/Point_set_processing_3/include/CGAL/grid_simplify_point_set.h @@ -26,9 +26,10 @@ #include #include #include +#include +#include #include -#include #include #include #include @@ -44,11 +45,17 @@ namespace CGAL { namespace internal { -/// Utility class for grid_simplify_point_set(): -/// Less_epsilon_points_3 defines a 3D points order / 2 points are equal -/// iff they belong to the same cell of a grid of cell size = epsilon. +// Round number to multiples of epsilon +inline double round_epsilon(double value, double epsilon) +{ + return std::floor(value / epsilon); +} + +/// Utility class for grid_simplify_point_set(): Hash_epsilon_points_3 +/// defines a 3D point hash / 2 points are equal iff they belong to +/// the same cell of a grid of cell size = epsilon. template -struct Less_epsilon_points_3 +struct Hash_epsilon_points_3 { private: @@ -57,7 +64,37 @@ private: typedef typename boost::property_traits::value_type Point; public: - Less_epsilon_points_3 (double epsilon, PointPMap p_pmap) + Hash_epsilon_points_3 (double epsilon, PointPMap p_pmap) + : m_epsilon (epsilon), point_pmap(p_pmap) + { + CGAL_point_set_processing_precondition(epsilon > 0); + } + + std::size_t operator() (const Point_3& a) const + { + const Point& pa = get(point_pmap,a); + std::size_t result = boost::hash_value(round_epsilon(pa.x(), m_epsilon)); + boost::hash_combine(result, boost::hash_value(round_epsilon(pa.y(), m_epsilon))); + boost::hash_combine(result, boost::hash_value(round_epsilon(pa.z(), m_epsilon))); + return result; + } + +}; + +/// Utility class for grid_simplify_point_set(): Hash_epsilon_points_3 +/// defines a 3D point equality / 2 points are equal iff they belong +/// to the same cell of a grid of cell size = epsilon. +template +struct Equal_epsilon_points_3 +{ +private: + + const double m_epsilon; + PointPMap point_pmap; + typedef typename boost::property_traits::value_type Point; +public: + + Equal_epsilon_points_3 (const double& epsilon, PointPMap p_pmap) : m_epsilon (epsilon), point_pmap(p_pmap) { CGAL_point_set_processing_precondition(epsilon > 0); @@ -65,29 +102,24 @@ public: bool operator() (const Point_3& a, const Point_3& b) const { - // Round points to multiples of m_epsilon, then compare. - return round_epsilon( get(point_pmap,a), m_epsilon ) < - round_epsilon( get(point_pmap,b), m_epsilon ); - } + const Point& pa = get(point_pmap,a); + const Point& pb = get(point_pmap,b); -private: - - // Round number to multiples of epsilon - static inline double round_epsilon(double value, double epsilon) - { - return std::floor(value/epsilon) * epsilon; - } - - static inline Point round_epsilon(const Point& p, double epsilon) - { - return Point( round_epsilon(p.x(), epsilon), - round_epsilon(p.y(), epsilon), - round_epsilon(p.z(), epsilon) ); + double ra = round_epsilon(pa.x(), m_epsilon); + double rb = round_epsilon(pb.x(), m_epsilon); + if (ra != rb) + return false; + ra = round_epsilon(pa.y(), m_epsilon); + rb = round_epsilon(pb.y(), m_epsilon); + if (ra != rb) + return false; + ra = round_epsilon(pa.z(), m_epsilon); + rb = round_epsilon(pb.z(), m_epsilon); + return ra == rb; } }; - } /* namespace internal */ @@ -106,17 +138,22 @@ private: template class Epsilon_point_set_3 - : public std::set > + : public cpp11::unordered_set, + internal::Equal_epsilon_points_3 > { private: // superclass - typedef std::set > Base; + typedef cpp11::unordered_set, + internal::Equal_epsilon_points_3 > Base; public: Epsilon_point_set_3 (double epsilon, PointPMap point_pmap) - : Base( internal::Less_epsilon_points_3(epsilon, point_pmap) ) + : Base(10, internal::Hash_epsilon_points_3(epsilon, point_pmap), + internal::Equal_epsilon_points_3(epsilon, point_pmap)) { CGAL_point_set_processing_precondition(epsilon > 0); } diff --git a/STL_Extension/include/CGAL/unordered.h b/STL_Extension/include/CGAL/unordered.h new file mode 100644 index 00000000000..56b3adfb1ac --- /dev/null +++ b/STL_Extension/include/CGAL/unordered.h @@ -0,0 +1,48 @@ +// Copyright (c) 2017 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_UNORDERED_H +#define CGAL_UNORDERED_H + +#include +#ifndef CGAL_CFG_NO_CPP0X_UNORDERED +# include +# include +#else +# include +# include +#endif + +namespace CGAL { + +namespace cpp11 { + +#ifndef CGAL_CFG_NO_CPP0X_UNORDERED +using std::unordered_set; +using std::unordered_map; +#else +using boost::unordered_set; +using boost::unordered_map; +#endif + +} // cpp11 + +} //namespace CGAL + +#endif // CGAL_UNORDERED_H