diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestPointQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestPointQuery.h deleted file mode 100644 index c3b43c8c7..000000000 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestPointQuery.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. -*/ - -#pragma once - -#include "../kdTreeQuery.h" -#include "../../query.h" -#include "../Iterator/kdTreeKNearestIterator.h" - -namespace Ponca { - -template -class KdTreeKNearestPointQuery : public KdTreeQuery, - public KNearestPointQuery -{ -public: - using DataPoint = typename Traits::DataPoint; - using IndexType = typename Traits::IndexType; - using Scalar = typename DataPoint::Scalar; - using VectorType = typename DataPoint::VectorType; - using QueryType = KNearestPointQuery; - using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeKNearestIterator; - - inline KdTreeKNearestPointQuery(const KdTreeBase* kdtree, IndexType k, const VectorType& point) : - KdTreeQuery(kdtree), KNearestPointQuery(k, point) - { - } - -public: - inline Iterator begin(){ - QueryAccelType::reset(); - QueryType::reset(); - this->search(); - return Iterator(QueryType::m_queue.begin()); - } - inline Iterator end(){ - return Iterator(QueryType::m_queue.end()); - } - -protected: - inline void search(){ - KdTreeQuery::search_internal(QueryType::input(), - [](IndexType, IndexType){}, - [this](){return QueryType::descentDistanceThreshold();}, - [](IndexType){return false;}, - [this](IndexType idx, IndexType, Scalar d){QueryType::m_queue.push({idx, d}); return false;} - ); - } -}; -} // namespace Ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestIndexQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestQueries.h similarity index 52% rename from Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestIndexQuery.h rename to Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestQueries.h index d7b72c754..dcc1da1ce 100644 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestIndexQuery.h +++ b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestQueries.h @@ -12,43 +12,48 @@ namespace Ponca { -template -class KdTreeKNearestIndexQuery : public KdTreeQuery, - public KNearestIndexQuery +template typename IteratorType, + typename QueryType> +class KdTreeKNearestQueryBase : public KdTreeQuery, public QueryType { public: using DataPoint = typename Traits::DataPoint; using IndexType = typename Traits::IndexType; using Scalar = typename DataPoint::Scalar; using VectorType = typename DataPoint::VectorType; - using QueryType = KNearestIndexQuery; using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeKNearestIterator; + using Iterator = IteratorType; - KdTreeKNearestIndexQuery(const KdTreeBase* kdtree, IndexType k, IndexType index) : - KdTreeQuery(kdtree), KNearestIndexQuery(k, index) - { - } + inline KdTreeKNearestQueryBase(const KdTreeBase* kdtree, IndexType k, typename QueryType::InputType input) : + KdTreeQuery(kdtree), QueryType(k, input) { } public: - Iterator begin(){ + inline Iterator begin(){ QueryAccelType::reset(); QueryType::reset(); this->search(); return Iterator(QueryType::m_queue.begin()); } - Iterator end(){ + inline Iterator end(){ return Iterator(QueryType::m_queue.end()); } protected: - void search(){ - KdTreeQuery::search_internal(QueryAccelType::m_kdtree->point_data()[QueryType::input()].pos(), + inline void search(){ + KdTreeQuery::search_internal(QueryType::getInputPosition(QueryAccelType::m_kdtree->point_data()), [](IndexType, IndexType){}, [this](){return QueryType::descentDistanceThreshold();}, - [this](IndexType idx){return QueryType::input() == idx;}, + [this](IndexType idx){return QueryType::skipIndexFunctor(idx);}, [this](IndexType idx, IndexType, Scalar d){QueryType::m_queue.push({idx, d}); return false;} ); } }; + +template +using KdTreeKNearestIndexQuery = KdTreeKNearestQueryBase< Traits, KdTreeKNearestIterator, + KNearestIndexQuery>; +template +using KdTreeKNearestPointQuery = KdTreeKNearestQueryBase< Traits, KdTreeKNearestIterator, + KNearestPointQuery>; } // namespace ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestPointQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestPointQuery.h deleted file mode 100644 index 29d949fcf..000000000 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestPointQuery.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. -*/ - -#pragma once - -#include "../kdTreeQuery.h" -#include "../../query.h" -#include "../Iterator/kdTreeNearestIterator.h" - -namespace Ponca { - -template -class KdTreeNearestPointQuery : public KdTreeQuery, - public NearestPointQuery -{ -public: - using DataPoint = typename Traits::DataPoint; - using IndexType = typename Traits::IndexType; - using Scalar = typename DataPoint::Scalar; - using VectorType = typename DataPoint::VectorType; - using QueryType = NearestPointQuery; - using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeNearestIterator; - - inline KdTreeNearestPointQuery(const KdTreeBase* kdtree, const VectorType& point) : - KdTreeQuery(kdtree), NearestPointQuery(point) - { - } - -public: - inline Iterator begin(){ - QueryAccelType::reset(); - QueryType::reset(); - this->search(); - return Iterator(QueryType::m_nearest); - } - Iterator end(){ - return Iterator(QueryType::m_nearest + 1); - } - -protected: - inline void search(){ - KdTreeQuery::search_internal(QueryType::input(), - [](IndexType, IndexType){}, - [this](){return QueryType::descentDistanceThreshold();}, - [](IndexType){return false;}, - [this](IndexType idx, IndexType, Scalar d) - { - QueryType::m_nearest = idx; - QueryType::m_squared_distance = d; - return false; - } - ); - } -}; -} // namespace ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestIndexQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestQueries.h similarity index 59% rename from Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestIndexQuery.h rename to Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestQueries.h index a9f6b3138..e2de94536 100644 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestIndexQuery.h +++ b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestQueries.h @@ -12,23 +12,21 @@ namespace Ponca { -template -class KdTreeNearestIndexQuery : public KdTreeQuery, - public NearestIndexQuery +template typename IteratorType, + typename QueryType> +class KdTreeNearestQueryBase : public KdTreeQuery, public QueryType { public: using DataPoint = typename Traits::DataPoint; using IndexType = typename Traits::IndexType; using Scalar = typename DataPoint::Scalar; using VectorType = typename DataPoint::VectorType; - using QueryType = NearestIndexQuery; using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeNearestIterator; + using Iterator = IteratorType; - KdTreeNearestIndexQuery(const KdTreeBase* kdtree, IndexType index) : - KdTreeQuery(kdtree), NearestIndexQuery(index) - { - } + KdTreeNearestQueryBase(const KdTreeBase* kdtree, typename QueryType::InputType input) : + KdTreeQuery(kdtree), QueryType(input){} public: inline Iterator begin(){ @@ -37,16 +35,16 @@ class KdTreeNearestIndexQuery : public KdTreeQuery, this->search(); return Iterator(QueryType::m_nearest); } - Iterator end(){ + inline Iterator end(){ return Iterator(QueryType::m_nearest + 1); } protected: - void search(){ - KdTreeQuery::search_internal(QueryAccelType::m_kdtree->point_data()[QueryType::input()].pos(), + inline void search(){ + KdTreeQuery::search_internal(QueryType::getInputPosition(QueryAccelType::m_kdtree->point_data()), [](IndexType, IndexType){}, [this](){return QueryType::descentDistanceThreshold();}, - [this](IndexType idx){return QueryType::input() == idx;}, + [this](IndexType idx){return QueryType::skipIndexFunctor(idx);}, [this](IndexType idx, IndexType, Scalar d) { QueryType::m_nearest = idx; @@ -56,4 +54,11 @@ class KdTreeNearestIndexQuery : public KdTreeQuery, ); } }; + +template +using KdTreeNearestIndexQuery = KdTreeNearestQueryBase< Traits, KdTreeNearestIterator, + NearestIndexQuery>; +template +using KdTreeNearestPointQuery = KdTreeNearestQueryBase< Traits, KdTreeNearestIterator, + NearestPointQuery>; } // namespace ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangePointQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangePointQuery.h deleted file mode 100644 index c220f2df0..000000000 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangePointQuery.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. -*/ - -#pragma once - -#include "../kdTreeQuery.h" -#include "../../query.h" -#include "../Iterator/kdTreeRangeIterator.h" - -namespace Ponca { - -template -class KdTreeRangePointQuery : public KdTreeQuery, - public RangePointQuery -{ -public: - using DataPoint = typename Traits::DataPoint; - using IndexType = typename Traits::IndexType; - using Scalar = typename DataPoint::Scalar; - using VectorType = typename DataPoint::VectorType; - using QueryType = RangePointQuery; - using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeRangeIterator; - -protected: - friend Iterator; - -public: - inline KdTreeRangePointQuery(const KdTreeBase* kdtree, Scalar radius, const VectorType& point) : - KdTreeQuery(kdtree), RangePointQuery(radius, point) - { - } - -public: - inline Iterator begin(){ - QueryAccelType::reset(); - QueryType::reset(); - Iterator it(this); - this->advance(it); - return it; - } - inline Iterator end(){ - return Iterator(this, QueryAccelType::m_kdtree->point_count()); - } - -protected: - inline void advance(Iterator& it){ - const auto& points = QueryAccelType::m_kdtree->point_data(); - const auto& indices = QueryAccelType::m_kdtree->index_data(); - const auto& point = QueryType::input(); - - auto descentDistanceThreshold = [this](){return QueryType::descentDistanceThreshold();}; - auto skipFunctor = [](IndexType){return false;}; - auto processNeighborFunctor = [&it](IndexType idx, IndexType i, Scalar) - { - it.m_index = idx; - it.m_start = i+1; - return true; - }; - - if (points.empty() || indices.empty()) - throw std::invalid_argument("Empty KdTree"); - - for(IndexType i=it.m_start; i::search_internal(point, - [&it](IndexType start, IndexType end) - { - it.m_start = start; - it.m_end = end; - }, - descentDistanceThreshold, - skipFunctor, - processNeighborFunctor)) - it.m_index = static_cast(points.size()); - } -}; -} // namespace ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeIndexQuery.h b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeQueries.h similarity index 71% rename from Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeIndexQuery.h rename to Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeQueries.h index 7df435214..ca2a463c5 100644 --- a/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeIndexQuery.h +++ b/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeQueries.h @@ -12,28 +12,26 @@ namespace Ponca { -template -class KdTreeRangeIndexQuery : public KdTreeQuery, - public RangeIndexQuery +template typename IteratorType, + typename QueryType> +class KdTreeRangeQueryBase : public KdTreeQuery, public QueryType + //public RangeIndexQuery { public: using DataPoint = typename Traits::DataPoint; using IndexType = typename Traits::IndexType; using Scalar = typename DataPoint::Scalar; using VectorType = typename DataPoint::VectorType; - using QueryType = RangeIndexQuery; using QueryAccelType = KdTreeQuery; - using Iterator = KdTreeRangeIterator; + using Iterator = IteratorType; protected: friend Iterator; public: - - KdTreeRangeIndexQuery(const KdTreeBase* kdtree, Scalar radius, IndexType index) : - KdTreeQuery(kdtree), RangeIndexQuery(radius, index) - { - } + KdTreeRangeQueryBase(const KdTreeBase* kdtree, Scalar radius, typename QueryType::InputType input) : + KdTreeQuery(kdtree), QueryType(radius, input){} public: inline Iterator begin(){ @@ -51,10 +49,10 @@ class KdTreeRangeIndexQuery : public KdTreeQuery, inline void advance(Iterator& it){ const auto& points = QueryAccelType::m_kdtree->point_data(); const auto& indices = QueryAccelType::m_kdtree->index_data(); - const auto& point = QueryAccelType::m_kdtree->point_data()[QueryType::input()].pos(); + const auto& point = QueryType::getInputPosition(points); auto descentDistanceThreshold = [this](){return QueryType::descentDistanceThreshold();}; - auto skipFunctor = [this](IndexType idx){return QueryType::input() == idx;}; + auto skipFunctor = [this](IndexType idx){return QueryType::skipIndexFunctor(idx);}; auto processNeighborFunctor = [&it](IndexType idx, IndexType i, Scalar) { it.m_index = idx; @@ -89,4 +87,11 @@ class KdTreeRangeIndexQuery : public KdTreeQuery, it.m_index = static_cast(points.size()); } }; + +template +using KdTreeRangeIndexQuery = KdTreeRangeQueryBase< Traits, KdTreeRangeIterator, + RangeIndexQuery>; +template +using KdTreeRangePointQuery = KdTreeRangeQueryBase< Traits, KdTreeRangeIterator, + RangePointQuery>; } // namespace ponca diff --git a/Ponca/src/SpatialPartitioning/KdTree/kdTree.h b/Ponca/src/SpatialPartitioning/KdTree/kdTree.h index 1ee0c837f..b25f8759a 100644 --- a/Ponca/src/SpatialPartitioning/KdTree/kdTree.h +++ b/Ponca/src/SpatialPartitioning/KdTree/kdTree.h @@ -18,12 +18,9 @@ #include "../../Common/Assert.h" -#include "Query/kdTreeNearestPointQuery.h" -#include "Query/kdTreeNearestIndexQuery.h" -#include "Query/kdTreeKNearestPointQuery.h" -#include "Query/kdTreeKNearestIndexQuery.h" -#include "Query/kdTreeRangeIndexQuery.h" -#include "Query/kdTreeRangePointQuery.h" +#include "Query/kdTreeNearestQueries.h" +#include "Query/kdTreeKNearestQueries.h" +#include "Query/kdTreeRangeQueries.h" namespace Ponca { template class KdTreeBase; diff --git a/Ponca/src/SpatialPartitioning/query.h b/Ponca/src/SpatialPartitioning/query.h index 3aad23921..af30d2cfc 100644 --- a/Ponca/src/SpatialPartitioning/query.h +++ b/Ponca/src/SpatialPartitioning/query.h @@ -87,6 +87,14 @@ struct OUT_TYPE##PointQuery : Query, \ inline QueryInputIsIndex(const InputType &point = -1) : Base(point) {} + protected: + /// Functor used to check if a given Idx must be skipped + template + inline bool skipIndexFunctor(IndexType idx) const {return Base::input() == idx;}; + /// Generic method to access input position. Container is expected to hold kdtree positions + template + inline auto getInputPosition(const Container &c) -> const typename Container::value_type::VectorType + { return c[Base::input()].pos(); } }; /// \brief Base class for queries storing points @@ -97,6 +105,14 @@ struct OUT_TYPE##PointQuery : Query, \ inline QueryInputIsPosition(const InputType &point = InputType::Zero()) : Base(point) {} + protected: + /// Functor used to check if a given Idx must be skipped + template + inline bool skipIndexFunctor(IndexType idx) const {return false;}; + /// Generic method to access input position. Container is expected to hold kdtree positions + template + inline auto getInputPosition(const Container &) -> const typename Container::value_type::VectorType + { return Base::input(); } }; /// \brief Base class for range queries diff --git a/cmake/PoncaConfigureSpatialPartitioning.cmake b/cmake/PoncaConfigureSpatialPartitioning.cmake index 0c39b1dad..93858c136 100644 --- a/cmake/PoncaConfigureSpatialPartitioning.cmake +++ b/cmake/PoncaConfigureSpatialPartitioning.cmake @@ -7,12 +7,9 @@ set(ponca_SpatialPartitioning_INCLUDE "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/kdTree.hpp" "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/kdTreeQuery.h" "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/kdTreeTraits.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestIndexQuery.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestPointQuery.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestIndexQuery.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestPointQuery.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeIndexQuery.h" - "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangePointQuery.h" + "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeKNearestQueries.h" + "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeNearestQueries.h" + "${PONCA_src_ROOT}/Ponca/src/SpatialPartitioning/KdTree/Query/kdTreeRangeQueries.h" ) add_library(SpatialPartitioning INTERFACE)