Skip to content

Commit

Permalink
[SpatialPartitioning] Add support for duplicated indices in KdTree
Browse files Browse the repository at this point in the history
  • Loading branch information
nmellado committed Sep 18, 2024
1 parent ff12255 commit 9f3efa8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Ponca/src/SpatialPartitioning/KdTree/kdTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ public :

// Utilities ---------------------------------------------------------------
public:
inline bool valid() const;
/// \param ignore_duplicates By default, valid KdTree can have duplicated samples.
inline bool valid(bool ignore_duplicates = true) const;
inline void print(std::ostream& os, bool verbose = false) const;

// Data --------------------------------------------------------------------
Expand Down
8 changes: 6 additions & 2 deletions Ponca/src/SpatialPartitioning/KdTree/kdTree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ void KdTreeBase<Traits>::clear()
}

template<typename Traits>
bool KdTreeBase<Traits>::valid() const
bool KdTreeBase<Traits>::valid(bool ignore_duplicates) const
{
// Check if point container is empty
if (m_points.empty())
return m_nodes.empty() && m_indices.empty();

// Check that at least one node has been created, and index container is not empty
if(m_nodes.empty() || m_indices.empty())
{
return false;
Expand All @@ -38,7 +40,7 @@ bool KdTreeBase<Traits>::valid() const
std::vector<bool> b(point_count(), false);
for(IndexType idx : m_indices)
{
if(idx < 0 || point_count() <= idx || b[idx])
if(idx < 0 || point_count() <= idx || ( ignore_duplicates ? false : b[idx]))
{
return false;
}
Expand Down Expand Up @@ -154,6 +156,8 @@ void KdTreeBase<Traits>::build_rec(NodeIndexType node_id, IndexType start, Index
node.set_is_leaf(
end-start <= m_min_cell_size ||
level >= Traits::MAX_DEPTH ||
// Stop descending if the content of the node is not one unique point
aabb.diagonal().squaredNorm() <= Eigen::NumTraits<Scalar>::epsilon() ||
// Since we add 2 nodes per inner node we need to stop if we can't add
// them both
(NodeIndexType)m_nodes.size() > MAX_NODE_COUNT - 2);
Expand Down
29 changes: 29 additions & 0 deletions tests/src/kdtree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,35 @@ void testKdtreeWithDuplicate()
test_tree(points, ids, cellSize);
}

// Generate a small part of duplicates by extending the index container
{
const int nbDuplicates = N;

ids.resize(nbDuplicates+N);
std::generate(ids.begin()+N, ids.end(), [N]() {return Eigen::internal::random<int>(0,N-1); });

test_tree(points, ids, cellSize);
}

// Generate duplicated coordinates samples TODO
// {
// const int nbDuplicates = N/10;
// const int nbUniques = N;
//
// auto points = VectorContainer(nbUniques);
// std::generate(points.begin(), points.end(), []() {return DataPoint(VectorType::Random()); });
//
// typename KdTreeDense<DataPoint>::IndexContainer ids(nbUniques);
// std::iota(ids.begin(), ids.end(), 0);
// ids.resize(nbDuplicates*nbUniques);
//
// for (int i = 1; i < nbDuplicates; ++i)
// {
// std::copy(ids.begin(), ids.begin() + nbUniques, ids.begin()+(nbUniques*i));
// }
// test_tree(points, ids, cellSize);
// }

}

template<typename NodeType>
Expand Down

0 comments on commit 9f3efa8

Please sign in to comment.