mirror of https://github.com/CGAL/cgal
Merge pull request #1929 from sgiraudot/Point_set_processing-Optimize_grid_simplify-GF
Optimizations for grid simplication
This commit is contained in:
commit
52a2242b60
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@
|
|||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
#include <CGAL/unordered.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
|
@ -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 <class Point_3, class PointPMap>
|
||||
struct Less_epsilon_points_3
|
||||
struct Hash_epsilon_points_3
|
||||
{
|
||||
private:
|
||||
|
||||
|
|
@ -57,7 +64,37 @@ private:
|
|||
typedef typename boost::property_traits<PointPMap>::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 <class Point_3, class PointPMap>
|
||||
struct Equal_epsilon_points_3
|
||||
{
|
||||
private:
|
||||
|
||||
const double m_epsilon;
|
||||
PointPMap point_pmap;
|
||||
typedef typename boost::property_traits<PointPMap>::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 Point_3, class PointPMap>
|
||||
class Epsilon_point_set_3
|
||||
: public std::set<Point_3, internal::Less_epsilon_points_3<Point_3, PointPMap> >
|
||||
: public cpp11::unordered_set<Point_3,
|
||||
internal::Hash_epsilon_points_3<Point_3, PointPMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap> >
|
||||
{
|
||||
private:
|
||||
|
||||
// superclass
|
||||
typedef std::set<Point_3, internal::Less_epsilon_points_3<Point_3, PointPMap> > Base;
|
||||
typedef cpp11::unordered_set<Point_3,
|
||||
internal::Hash_epsilon_points_3<Point_3, PointPMap>,
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap> > Base;
|
||||
|
||||
public:
|
||||
|
||||
Epsilon_point_set_3 (double epsilon, PointPMap point_pmap)
|
||||
: Base( internal::Less_epsilon_points_3<Point_3, PointPMap>(epsilon, point_pmap) )
|
||||
: Base(10, internal::Hash_epsilon_points_3<Point_3, PointPMap>(epsilon, point_pmap),
|
||||
internal::Equal_epsilon_points_3<Point_3, PointPMap>(epsilon, point_pmap))
|
||||
{
|
||||
CGAL_point_set_processing_precondition(epsilon > 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <CGAL/config.h>
|
||||
#ifndef CGAL_CFG_NO_CPP0X_UNORDERED
|
||||
# include <unordered_set>
|
||||
# include <unordered_map>
|
||||
#else
|
||||
# include <boost/unordered_set.hpp>
|
||||
# include <boost/unordered_map.hpp>
|
||||
#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
|
||||
Loading…
Reference in New Issue