mirror of https://github.com/CGAL/cgal
make the construction of the search tree lazy
This commit is contained in:
parent
c5ba7d4621
commit
5f05c610d1
|
|
@ -61,6 +61,8 @@ namespace CGAL {
|
||||||
// type of the primitives container
|
// type of the primitives container
|
||||||
typedef std::vector<typename AABBTraits::Primitive> Primitives;
|
typedef std::vector<typename AABBTraits::Primitive> Primitives;
|
||||||
|
|
||||||
|
typedef internal::Primitive_helper<AABBTraits> Helper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef AABBTraits AABB_traits;
|
typedef AABBTraits AABB_traits;
|
||||||
|
|
||||||
|
|
@ -169,14 +171,15 @@ namespace CGAL {
|
||||||
return m_traits;
|
return m_traits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the tree.
|
/// Clears the tree and the search tree if it was constructed,
|
||||||
|
/// and switches on the usage of the search tree to find the hints for the distance queries
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
// clear AABB tree
|
// clear AABB tree
|
||||||
clear_nodes();
|
clear_nodes();
|
||||||
m_primitives.clear();
|
m_primitives.clear();
|
||||||
clear_search_tree();
|
clear_search_tree();
|
||||||
m_use_search_tree = true;
|
m_use_default_search_tree = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the axis-aligned bounding box of the whole tree.
|
/// Returns the axis-aligned bounding box of the whole tree.
|
||||||
|
|
@ -441,8 +444,7 @@ public:
|
||||||
template<typename ConstPointIterator>
|
template<typename ConstPointIterator>
|
||||||
bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond)
|
bool accelerate_distance_queries(ConstPointIterator first, ConstPointIterator beyond)
|
||||||
{
|
{
|
||||||
clear_search_tree();
|
m_use_default_search_tree = false;
|
||||||
m_use_search_tree = false; // not a default kd-tree
|
|
||||||
return build_kd_tree(first,beyond);
|
return build_kd_tree(first,beyond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -480,14 +482,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// clears internal KD tree
|
// clears internal KD tree
|
||||||
void clear_search_tree() const
|
void clear_search_tree()
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_HAS_THREADS
|
||||||
|
if ( m_atomic_search_tree_constructed.load() )
|
||||||
|
#else
|
||||||
if ( m_search_tree_constructed )
|
if ( m_search_tree_constructed )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
CGAL_assertion( m_p_search_tree!=nullptr );
|
CGAL_assertion( m_p_search_tree!=nullptr );
|
||||||
delete m_p_search_tree;
|
delete m_p_search_tree;
|
||||||
m_p_search_tree = nullptr;
|
m_p_search_tree = nullptr;
|
||||||
|
#ifdef CGAL_HAS_THREADS
|
||||||
|
m_atomic_search_tree_constructed.store(false);
|
||||||
|
#else
|
||||||
m_search_tree_constructed = false;
|
m_search_tree_constructed = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,13 +529,28 @@ public:
|
||||||
{
|
{
|
||||||
CGAL_assertion(!empty());
|
CGAL_assertion(!empty());
|
||||||
return Point_and_primitive_id(
|
return Point_and_primitive_id(
|
||||||
internal::Primitive_helper<AABB_traits>::get_reference_point(m_primitives[0],m_traits), m_primitives[0].id()
|
Helper::get_reference_point(m_primitives[0],m_traits), m_primitives[0].id()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Point_and_primitive_id best_hint(const Point& query) const
|
Point_and_primitive_id best_hint(const Point& query) const
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_HAS_THREADS
|
||||||
|
bool m_search_tree_constructed = m_atomic_search_tree_constructed.load(std::memory_order_acquire);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// lazily build the search tree in case the default should be used
|
||||||
|
if (m_use_default_search_tree && !m_search_tree_constructed)
|
||||||
|
{
|
||||||
|
#ifdef CGAL_HAS_THREADS
|
||||||
|
CGAL_SCOPED_LOCK(build_mutex);
|
||||||
|
m_search_tree_constructed = m_atomic_search_tree_constructed.load(std::memory_order_relaxed);
|
||||||
|
if (!m_search_tree_constructed)
|
||||||
|
#endif
|
||||||
|
m_search_tree_constructed = const_cast<AABB_tree*>(this)->build_kd_tree();
|
||||||
|
}
|
||||||
|
|
||||||
if(m_search_tree_constructed)
|
if(m_search_tree_constructed)
|
||||||
return m_p_search_tree->closest_point(query);
|
return m_p_search_tree->closest_point(query);
|
||||||
else
|
else
|
||||||
|
|
@ -534,14 +559,13 @@ public:
|
||||||
|
|
||||||
//! Returns the datum (geometric object) represented `p`.
|
//! Returns the datum (geometric object) represented `p`.
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
typename internal::Primitive_helper<AABBTraits>::Datum_type
|
typename Helper::Datum_type
|
||||||
#else
|
#else
|
||||||
typename AABBTraits::Primitive::Datum_reference
|
typename AABBTraits::Primitive::Datum_reference
|
||||||
#endif
|
#endif
|
||||||
datum(Primitive& p)const
|
datum(Primitive& p)const
|
||||||
{
|
{
|
||||||
return internal::Primitive_helper<AABBTraits>::
|
return Helper::get_datum(p, this->traits());
|
||||||
get_datum(p, this->traits());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -579,13 +603,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// search KD-tree
|
// search KD-tree
|
||||||
mutable const Search_tree* m_p_search_tree;
|
const Search_tree* m_p_search_tree;
|
||||||
mutable bool m_search_tree_constructed;
|
bool m_use_default_search_tree; // indicates whether the internal kd-tree should be built
|
||||||
bool m_use_search_tree; // indicates whether the internal kd-tree should be built
|
|
||||||
#ifdef CGAL_HAS_THREADS
|
#ifdef CGAL_HAS_THREADS
|
||||||
std::atomic<bool> m_atomic_need_build;
|
std::atomic<bool> m_atomic_need_build;
|
||||||
|
std::atomic<bool> m_atomic_search_tree_constructed;
|
||||||
#else
|
#else
|
||||||
bool m_need_build;
|
bool m_need_build;
|
||||||
|
bool m_search_tree_constructed;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -604,12 +629,13 @@ public:
|
||||||
, m_primitives()
|
, m_primitives()
|
||||||
, m_p_root_node(nullptr)
|
, m_p_root_node(nullptr)
|
||||||
, m_p_search_tree(nullptr)
|
, m_p_search_tree(nullptr)
|
||||||
, m_search_tree_constructed(false)
|
, m_use_default_search_tree(true)
|
||||||
, m_use_search_tree(true)
|
|
||||||
#ifdef CGAL_HAS_THREADS
|
#ifdef CGAL_HAS_THREADS
|
||||||
, m_atomic_need_build(false)
|
, m_atomic_need_build(false)
|
||||||
|
, m_atomic_search_tree_constructed(false)
|
||||||
#else
|
#else
|
||||||
, m_need_build(false)
|
, m_need_build(false)
|
||||||
|
, m_search_tree_constructed(false)
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -622,12 +648,13 @@ public:
|
||||||
, m_primitives()
|
, m_primitives()
|
||||||
, m_p_root_node(nullptr)
|
, m_p_root_node(nullptr)
|
||||||
, m_p_search_tree(nullptr)
|
, m_p_search_tree(nullptr)
|
||||||
, m_search_tree_constructed(false)
|
, m_use_default_search_tree(true)
|
||||||
, m_use_search_tree(true)
|
|
||||||
#ifdef CGAL_HAS_THREADS
|
#ifdef CGAL_HAS_THREADS
|
||||||
, m_atomic_need_build(false)
|
, m_atomic_need_build(false)
|
||||||
|
, m_atomic_search_tree_constructed(false)
|
||||||
#else
|
#else
|
||||||
, m_need_build(false)
|
, m_need_build(false)
|
||||||
|
, m_search_tree_constructed(false)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Insert each primitive into tree
|
// Insert each primitive into tree
|
||||||
|
|
@ -640,6 +667,8 @@ public:
|
||||||
ConstPrimitiveIterator beyond,
|
ConstPrimitiveIterator beyond,
|
||||||
T&& ... t)
|
T&& ... t)
|
||||||
{
|
{
|
||||||
|
if (m_use_default_search_tree && first!=beyond)
|
||||||
|
clear_search_tree();
|
||||||
set_shared_data(std::forward<T>(t)...);
|
set_shared_data(std::forward<T>(t)...);
|
||||||
while(first != beyond)
|
while(first != beyond)
|
||||||
{
|
{
|
||||||
|
|
@ -680,6 +709,8 @@ public:
|
||||||
template<typename Tr>
|
template<typename Tr>
|
||||||
void AABB_tree<Tr>::insert(const Primitive& p)
|
void AABB_tree<Tr>::insert(const Primitive& p)
|
||||||
{
|
{
|
||||||
|
if (m_use_default_search_tree)
|
||||||
|
clear_search_tree();
|
||||||
m_primitives.push_back(p);
|
m_primitives.push_back(p);
|
||||||
#ifdef CGAL_HAS_THREADS
|
#ifdef CGAL_HAS_THREADS
|
||||||
m_atomic_need_build.store(true);
|
m_atomic_need_build.store(true);
|
||||||
|
|
@ -721,12 +752,6 @@ public:
|
||||||
m_need_build = false;
|
m_need_build = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case the users has switched on the accelerated distance query
|
|
||||||
// data structure with the default arguments, then it has to be
|
|
||||||
// /built/rebuilt.
|
|
||||||
if(!empty() && m_use_search_tree && !m_search_tree_constructed)
|
|
||||||
build_kd_tree();
|
|
||||||
}
|
}
|
||||||
// constructs the search KD tree from given points
|
// constructs the search KD tree from given points
|
||||||
// to accelerate the distance queries
|
// to accelerate the distance queries
|
||||||
|
|
@ -736,17 +761,11 @@ public:
|
||||||
// iterate over primitives to get reference points on them
|
// iterate over primitives to get reference points on them
|
||||||
std::vector<Point_and_primitive_id> points;
|
std::vector<Point_and_primitive_id> points;
|
||||||
points.reserve(m_primitives.size());
|
points.reserve(m_primitives.size());
|
||||||
typename Primitives::const_iterator it;
|
for(const Primitive& p : m_primitives)
|
||||||
for(it = m_primitives.begin(); it != m_primitives.end(); ++it)
|
points.push_back( Point_and_primitive_id( Helper::get_reference_point(p, m_traits), p.id() ) );
|
||||||
points.push_back( Point_and_primitive_id(
|
|
||||||
internal::Primitive_helper<AABB_traits>::get_reference_point(
|
|
||||||
*it,m_traits), it->id() ) );
|
|
||||||
|
|
||||||
// clears current KD tree
|
// clears current KD tree
|
||||||
clear_search_tree();
|
return build_kd_tree(points.begin(), points.end());
|
||||||
bool res = build_kd_tree(points.begin(), points.end());
|
|
||||||
m_use_search_tree = true;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructs the search KD tree from given points
|
// constructs the search KD tree from given points
|
||||||
|
|
@ -756,11 +775,16 @@ public:
|
||||||
bool AABB_tree<Tr>::build_kd_tree(ConstPointIterator first,
|
bool AABB_tree<Tr>::build_kd_tree(ConstPointIterator first,
|
||||||
ConstPointIterator beyond)
|
ConstPointIterator beyond)
|
||||||
{
|
{
|
||||||
|
clear_search_tree();
|
||||||
m_p_search_tree = new Search_tree(first, beyond);
|
m_p_search_tree = new Search_tree(first, beyond);
|
||||||
|
|
||||||
if(m_p_search_tree != nullptr)
|
if(m_p_search_tree != nullptr)
|
||||||
{
|
{
|
||||||
|
#ifdef CGAL_HAS_THREADS
|
||||||
|
m_atomic_search_tree_constructed.store(false, std::memory_order_release); // in case build_kd_tree() is triggered by a call to best_hint()
|
||||||
|
#else
|
||||||
m_search_tree_constructed = true;
|
m_search_tree_constructed = true;
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -774,7 +798,7 @@ public:
|
||||||
void AABB_tree<Tr>::do_not_accelerate_distance_queries()
|
void AABB_tree<Tr>::do_not_accelerate_distance_queries()
|
||||||
{
|
{
|
||||||
clear_search_tree();
|
clear_search_tree();
|
||||||
m_use_search_tree = false;
|
m_use_default_search_tree = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -782,23 +806,9 @@ public:
|
||||||
template<typename Tr>
|
template<typename Tr>
|
||||||
bool AABB_tree<Tr>::accelerate_distance_queries()
|
bool AABB_tree<Tr>::accelerate_distance_queries()
|
||||||
{
|
{
|
||||||
|
m_use_default_search_tree = true;
|
||||||
if(m_primitives.empty()) return true;
|
if(m_primitives.empty()) return true;
|
||||||
|
return build_kd_tree();
|
||||||
#ifdef CGAL_HAS_THREADS
|
|
||||||
bool m_need_build = m_atomic_need_build.load();;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_use_search_tree)
|
|
||||||
{
|
|
||||||
if (!m_need_build) return m_search_tree_constructed;
|
|
||||||
return true; // default return type, no tree built
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_use_search_tree = true;
|
|
||||||
|
|
||||||
build_kd_tree();
|
|
||||||
|
|
||||||
return m_search_tree_constructed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Tr>
|
template<typename Tr>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue