mirror of https://github.com/CGAL/cgal
Allow to enable/disable cache of points
This commit is contained in:
parent
efce74597e
commit
e9c35e3861
|
|
@ -41,7 +41,11 @@
|
|||
namespace CGAL {
|
||||
|
||||
//template <class SearchTraits, class Splitter_=Median_of_rectangle<SearchTraits>, class UseExtendedNode = Tag_true >
|
||||
template <class SearchTraits, class Splitter_=Sliding_midpoint<SearchTraits>, class UseExtendedNode = Tag_true >
|
||||
template <
|
||||
class SearchTraits,
|
||||
class Splitter_=Sliding_midpoint<SearchTraits>,
|
||||
class UseExtendedNode = Tag_true,
|
||||
class EnablePointsCache = Tag_false>
|
||||
class Kd_tree {
|
||||
|
||||
public:
|
||||
|
|
@ -51,11 +55,11 @@ public:
|
|||
typedef typename Splitter::Container Point_container;
|
||||
|
||||
typedef typename SearchTraits::FT FT;
|
||||
typedef Kd_tree_node<SearchTraits, Splitter, UseExtendedNode > Node;
|
||||
typedef Kd_tree_leaf_node<SearchTraits, Splitter, UseExtendedNode > Leaf_node;
|
||||
typedef Kd_tree_internal_node<SearchTraits, Splitter, UseExtendedNode > Internal_node;
|
||||
typedef Kd_tree<SearchTraits, Splitter> Tree;
|
||||
typedef Kd_tree<SearchTraits, Splitter,UseExtendedNode> Self;
|
||||
typedef Kd_tree_node<SearchTraits, Splitter, UseExtendedNode, EnablePointsCache> Node;
|
||||
typedef Kd_tree_leaf_node<SearchTraits, Splitter, UseExtendedNode, EnablePointsCache> Leaf_node;
|
||||
typedef Kd_tree_internal_node<SearchTraits, Splitter, UseExtendedNode, EnablePointsCache> Internal_node;
|
||||
typedef Kd_tree<SearchTraits, Splitter, UseExtendedNode, EnablePointsCache> Tree;
|
||||
typedef Kd_tree<SearchTraits, Splitter, UseExtendedNode, EnablePointsCache> Self;
|
||||
|
||||
typedef Node* Node_handle;
|
||||
typedef const Node* Node_const_handle;
|
||||
|
|
@ -73,6 +77,8 @@ public:
|
|||
|
||||
typedef typename internal::Get_dimension_tag<SearchTraits>::Dimension D;
|
||||
|
||||
typedef EnablePointsCache Enable_points_cache;
|
||||
|
||||
private:
|
||||
SearchTraits traits_;
|
||||
Splitter split;
|
||||
|
|
@ -282,13 +288,18 @@ public:
|
|||
//Reorder vector for spatial locality
|
||||
std::vector<Point_d> ptstmp;
|
||||
ptstmp.resize(pts.size());
|
||||
points_cache.reserve(dim * pts.size());
|
||||
for (std::size_t i = 0; i < pts.size(); ++i){
|
||||
for (std::size_t i = 0; i < pts.size(); ++i)
|
||||
ptstmp[i] = *data[i];
|
||||
|
||||
// Cache?
|
||||
if (Enable_points_cache::value)
|
||||
{
|
||||
typename SearchTraits::Construct_cartesian_const_iterator_d construct_it = traits_.construct_cartesian_const_iterator_d_object();
|
||||
points_cache.insert(points_cache.end(), construct_it(ptstmp[i]), construct_it(ptstmp[i], 0));
|
||||
points_cache.reserve(dim * pts.size());
|
||||
for (std::size_t i = 0; i < pts.size(); ++i)
|
||||
points_cache.insert(points_cache.end(), construct_it(ptstmp[i]), construct_it(ptstmp[i], 0));
|
||||
}
|
||||
|
||||
for(std::size_t i = 0; i < leaf_nodes.size(); ++i){
|
||||
std::ptrdiff_t tmp = leaf_nodes[i].begin() - pts.begin();
|
||||
leaf_nodes[i].data = ptstmp.begin() + tmp;
|
||||
|
|
|
|||
|
|
@ -28,27 +28,27 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template <class SearchTraits, class Splitter, class UseExtendedNode>
|
||||
template <class SearchTraits, class Splitter, class UseExtendedNode, class EnablePointsCache>
|
||||
class Kd_tree;
|
||||
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode >
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode, class EnablePointsCache >
|
||||
class Kd_tree_node {
|
||||
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>;
|
||||
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_const_handle Node_const_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Internal_node_handle Internal_node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Internal_node_const_handle Internal_node_const_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Leaf_node_handle Leaf_node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Leaf_node_const_handle Leaf_node_const_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Node_const_handle Node_const_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Internal_node_handle Internal_node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Internal_node_const_handle Internal_node_const_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Leaf_node_handle Leaf_node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Leaf_node_const_handle Leaf_node_const_handle;
|
||||
typedef typename TreeTraits::Point_d Point_d;
|
||||
|
||||
typedef typename TreeTraits::FT FT;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Point_d_iterator Point_d_iterator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::iterator iterator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::D D;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Point_d_iterator Point_d_iterator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::iterator iterator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::D D;
|
||||
|
||||
bool leaf;
|
||||
|
||||
|
|
@ -264,13 +264,13 @@ namespace CGAL {
|
|||
};
|
||||
|
||||
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode >
|
||||
class Kd_tree_leaf_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode >{
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode, class EnablePointsCache >
|
||||
class Kd_tree_leaf_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode, EnablePointsCache >{
|
||||
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>;
|
||||
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::iterator iterator;
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode> Base;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::iterator iterator;
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode, EnablePointsCache> Base;
|
||||
typedef typename TreeTraits::Point_d Point_d;
|
||||
|
||||
private:
|
||||
|
|
@ -329,18 +329,18 @@ namespace CGAL {
|
|||
|
||||
|
||||
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode>
|
||||
class Kd_tree_internal_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode >{
|
||||
template < class TreeTraits, class Splitter, class UseExtendedNode, class EnablePointsCache>
|
||||
class Kd_tree_internal_node : public Kd_tree_node< TreeTraits, Splitter, UseExtendedNode, EnablePointsCache >{
|
||||
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode>;
|
||||
friend class Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>;
|
||||
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode> Base;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Node_const_handle Node_const_handle;
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, UseExtendedNode, EnablePointsCache> Base;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Node_const_handle Node_const_handle;
|
||||
|
||||
typedef typename TreeTraits::FT FT;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode>::D D;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,UseExtendedNode,EnablePointsCache>::D D;
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -477,18 +477,19 @@ namespace CGAL {
|
|||
}
|
||||
};//internal node
|
||||
|
||||
template < class TreeTraits, class Splitter>
|
||||
class Kd_tree_internal_node<TreeTraits,Splitter,Tag_false> : public Kd_tree_node< TreeTraits, Splitter, Tag_false >{
|
||||
template < class TreeTraits, class Splitter, class EnablePointsCache>
|
||||
class Kd_tree_internal_node<TreeTraits,Splitter,Tag_false,EnablePointsCache>
|
||||
: public Kd_tree_node< TreeTraits, Splitter, Tag_false, EnablePointsCache >
|
||||
{
|
||||
friend class Kd_tree<TreeTraits,Splitter,Tag_false,EnablePointsCache>;
|
||||
|
||||
friend class Kd_tree<TreeTraits,Splitter,Tag_false>;
|
||||
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, Tag_false> Base;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Node_const_handle Node_const_handle;
|
||||
typedef Kd_tree_node< TreeTraits, Splitter, Tag_false, EnablePointsCache> Base;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false,EnablePointsCache>::Node_handle Node_handle;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false,EnablePointsCache>::Node_const_handle Node_const_handle;
|
||||
|
||||
typedef typename TreeTraits::FT FT;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false>::D D;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false,EnablePointsCache>::Separator Separator;
|
||||
typedef typename Kd_tree<TreeTraits,Splitter,Tag_false,EnablePointsCache>::D D;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include <CGAL/internal/K_neighbor_search.h>
|
||||
#include <CGAL/Has_member.h>
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class SearchTraits,
|
||||
|
|
@ -47,6 +49,7 @@ private:
|
|||
|
||||
CGAL_GENERATE_MEMBER_DETECTOR(transformed_distance_from_coordinates);
|
||||
CGAL_GENERATE_MEMBER_DETECTOR(interruptable_transformed_distance);
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Enable_points_cache, Enable_points_cache, false)
|
||||
|
||||
// If transformed_distance_from_coordinates does not exist in `Distance`
|
||||
template <bool has_transformed_distance_from_coordinates = has_transformed_distance_from_coordinates<Distance>::value>
|
||||
|
|
@ -71,6 +74,7 @@ private:
|
|||
return this->distance_instance.transformed_distance_from_coordinates(q, it_coord_begin, it_coord_end);
|
||||
}
|
||||
|
||||
// *** Version with cache ***
|
||||
// If interruptable_transformed_distance does not exist in `Distance`
|
||||
template <bool has_interruptable_distance_computation = has_interruptable_transformed_distance<Distance>::value>
|
||||
FT
|
||||
|
|
@ -97,6 +101,30 @@ private:
|
|||
q, it_coord_begin, it_coord_end, stop_if_geq_to_this);
|
||||
}
|
||||
|
||||
// *** Version without cache ***
|
||||
// If interruptable_transformed_distance does not exist in `Distance`
|
||||
template <bool has_interruptable_distance_computation = has_interruptable_transformed_distance<Distance>::value>
|
||||
FT
|
||||
interruptable_transformed_distance(
|
||||
const typename Base::Query_item& q,
|
||||
Point const& p,
|
||||
FT)
|
||||
{
|
||||
return this->distance_instance.transformed_distance(q, p);
|
||||
}
|
||||
// ... or if it exists
|
||||
template <>
|
||||
FT
|
||||
interruptable_transformed_distance<true>(
|
||||
const typename Base::Query_item& q,
|
||||
Point const& p,
|
||||
FT stop_if_geq_to_this)
|
||||
{
|
||||
typename SearchTraits::Construct_cartesian_const_iterator_d construct_it = m_tree.traits().construct_cartesian_const_iterator_d_object();
|
||||
return this->distance_instance.interruptable_transformed_distance(
|
||||
q, construct_it(p), construct_it(p, 0), stop_if_geq_to_this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Orthogonal_k_neighbor_search(const Tree& tree, const typename Base::Query_item& q,
|
||||
|
|
@ -124,14 +152,76 @@ public:
|
|||
compute_furthest_neighbors_orthogonally(tree.root(), distance_to_root);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (sorted) this->queue.sort();
|
||||
}
|
||||
private:
|
||||
|
||||
template<bool use_cache = (has_Enable_points_cache<Tree>::value && Tree::Enable_points_cache::value)>
|
||||
void search_in_leaf(typename Tree::Leaf_node_const_handle node);
|
||||
|
||||
// With cache
|
||||
template<>
|
||||
void search_in_leaf<true>(typename Tree::Leaf_node_const_handle node)
|
||||
{
|
||||
typename Tree::iterator it_node_point = node->begin(), it_node_point_end = node->end();
|
||||
typename std::vector<FT>::const_iterator cache_point_begin = m_tree.cache_begin() + m_dim*(it_node_point - m_tree.begin());
|
||||
for (; !this->queue.full() && it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
transformed_distance_from_coordinates(this->query_object, *it_node_point, cache_point_begin, cache_point_begin + m_dim);
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
|
||||
cache_point_begin += m_dim;
|
||||
}
|
||||
FT worst_dist = this->queue.top().second;
|
||||
for (; it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
interruptable_transformed_distance(this->query_object, *it_node_point, cache_point_begin, cache_point_begin + m_dim, worst_dist);
|
||||
|
||||
if (distance_to_query_object < worst_dist)
|
||||
{
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
worst_dist = this->queue.top().second;
|
||||
}
|
||||
|
||||
cache_point_begin += m_dim;
|
||||
}
|
||||
}
|
||||
|
||||
// Without cache
|
||||
template<>
|
||||
void search_in_leaf<false>(typename Tree::Leaf_node_const_handle node)
|
||||
{
|
||||
typename Tree::iterator it_node_point = node->begin(), it_node_point_end = node->end();
|
||||
for (; !this->queue.full() && it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
this->distance_instance.transformed_distance(this->query_object, *it_node_point);
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
}
|
||||
FT worst_dist = this->queue.top().second;
|
||||
for (; it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
interruptable_transformed_distance(this->query_object, *it_node_point, worst_dist);
|
||||
|
||||
if (distance_to_query_object < worst_dist)
|
||||
{
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
worst_dist = this->queue.top().second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void compute_nearest_neighbors_orthogonally(typename Base::Node_const_handle N, FT rd)
|
||||
{
|
||||
if (N->is_leaf())
|
||||
|
|
@ -141,36 +231,7 @@ private:
|
|||
static_cast<typename Tree::Leaf_node_const_handle>(N);
|
||||
this->number_of_leaf_nodes_visited++;
|
||||
if (node->size() > 0)
|
||||
{
|
||||
typename Tree::iterator it_node_point = node->begin(), it_node_point_end = node->end();
|
||||
typename std::vector<FT>::const_iterator cache_point_begin = m_tree.cache_begin() + m_dim*(it_node_point - m_tree.begin());
|
||||
for (; !this->queue.full() && it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
transformed_distance_from_coordinates(this->query_object, *it_node_point, cache_point_begin, cache_point_begin + m_dim);
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
|
||||
cache_point_begin += m_dim;
|
||||
}
|
||||
FT worst_dist = this->queue.top().second;
|
||||
for (; it_node_point != it_node_point_end; ++it_node_point)
|
||||
{
|
||||
this->number_of_items_visited++;
|
||||
|
||||
FT distance_to_query_object =
|
||||
interruptable_transformed_distance(this->query_object, *it_node_point, cache_point_begin, cache_point_begin + m_dim, worst_dist);
|
||||
|
||||
if (distance_to_query_object < worst_dist)
|
||||
{
|
||||
this->queue.insert(std::make_pair(&(*it_node_point), distance_to_query_object));
|
||||
worst_dist = this->queue.top().second;
|
||||
}
|
||||
|
||||
cache_point_begin += m_dim;
|
||||
}
|
||||
}
|
||||
search_in_leaf(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue