Skip to content

Commit

Permalink
[doc] Update documentation to highlight new functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
nmellado committed Dec 14, 2023
1 parent 5591be5 commit 2f5faa7
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 2 deletions.
20 changes: 20 additions & 0 deletions Ponca/src/SpatialPartitioning/KdTree/kdTreeTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ struct KdTreeDefaultLeafNode

/*!
* \brief The node type used by default by the kd-tree.
*
* It is possible to modify the Inner and Leaf node types by inheritance. For instance, to add a Bounding box to inner
* nodes, define a custom inner node type:
*
* \snippet ponca_customize_kdtree.cpp CustomInnerNodeDefinition
*
* Define a custom node type to use it, and expose custom data (inner/leaf node are not exposed directly):
*
* \snippet ponca_customize_kdtree.cpp CustomNodeDefinition
*
* To use in the KdTree, define a type using the custom node:
*
* \snippet ponca_customize_kdtree.cpp KdTreeTypeWithCustomNode
*
* The added attribute can be accessed
*
* \snippet ponca_customize_kdtree.cpp ReadCustomProperties
*
*/
template <typename Index, typename NodeIndex, typename DataPoint,
typename LeafSize = Index,
Expand Down Expand Up @@ -221,6 +239,8 @@ struct KdTreeDefaultNode : public KdTreeCustomizableNode<Index, NodeIndex, DataP
/*!
* \brief The default traits type used by the kd-tree.
*
* \see KdTreeCustomizableNode Helper class to modify Inner/Leaf nodes without redefining a Trait class
*
* \tparam _NodeType Type used to store nodes, set by default to #KdTreeDefaultNode
*/
template <typename _DataPoint,
Expand Down
3 changes: 2 additions & 1 deletion doc/src/ponca_module_spatialpartitioning.mdoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ fit.computeWithIds( myDataStructure.range_neighbors(fitInitPos, scale), vectorPo

\subsection spatialpartitioning_kdtree_extending Extending KdTree
Ponca::KdTreeBase is a customizable version of Ponca::KdTree, which can be controlled using `Traits`.
See KdTreeDefaultTraits for customization API.
See KdTreeDefaultTraits and KdTreeCustomizableNode for customization APIs. See also:
- `examples/cpp/ponca_customize_kdtree.cpp`

\subsection spatialpartitioning_kdtree_implementation Implementation details

Expand Down
10 changes: 9 additions & 1 deletion examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@ add_dependencies(ponca-examples ponca_fit_line)
ponca_handle_eigen_dependency(ponca_fit_line)

set(ponca_neighbor_search_SRCS
ponca_neighbor_search.cpp
ponca_neighbor_search.cpp
)
add_executable(ponca_neighbor_search ${ponca_neighbor_search_SRCS})
target_include_directories(ponca_neighbor_search PRIVATE ${PONCA_src_ROOT})
add_dependencies(ponca-examples ponca_neighbor_search)
ponca_handle_eigen_dependency(ponca_neighbor_search)

set(ponca_customize_kdtree_SRCS
ponca_customize_kdtree.cpp
)
add_executable(ponca_customize_kdtree ${ponca_customize_kdtree_SRCS})
target_include_directories(ponca_customize_kdtree PRIVATE ${PONCA_src_ROOT})
add_dependencies(ponca-examples ponca_customize_kdtree)
ponca_handle_eigen_dependency(ponca_customize_kdtree)

add_subdirectory(pcl)
add_subdirectory(nanoflann)
93 changes: 93 additions & 0 deletions examples/cpp/ponca_customize_kdtree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
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/.
*/

#include <iostream>
#include <optional>
#include <Ponca/SpatialPartitioning>
#include <Eigen/Core>

struct DataPoint
{
enum {Dim = 3};
using Scalar = float;
using VectorType = Eigen::Vector<Scalar,Dim>;
inline const auto& pos() const {return m_pos;}
VectorType m_pos;
};

//! [CustomInnerNodeDefinition]
template <typename NodeIndex, typename Scalar, int DIM, typename _AabbType = Eigen::AlignedBox<Scalar, DIM>>
struct MyKdTreeInnerNode : public Ponca::KdTreeDefaultInnerNode<NodeIndex, Scalar, DIM> {
using AabbType = _AabbType;
AabbType m_aabb{};
};
//! [CustomInnerNodeDefinition]

//! [CustomNodeDefinition]
template <typename Index, typename NodeIndex, typename DataPoint, typename LeafSize = Index>
struct MyKdTreeNode : Ponca::KdTreeCustomizableNode<Index, NodeIndex, DataPoint, LeafSize,
MyKdTreeInnerNode<NodeIndex, typename DataPoint::Scalar, DataPoint::Dim>> {

using Base = Ponca::KdTreeCustomizableNode<Index, NodeIndex, DataPoint, LeafSize,
MyKdTreeInnerNode<NodeIndex, typename DataPoint::Scalar, DataPoint::Dim>>;
using AabbType = typename Base::AabbType;

void configure_range(Index start, Index size, const AabbType &aabb)
{
Base::configure_range(start, size, aabb);
if (! Base::is_leaf() )
{
Base::getAsInner().m_aabb = aabb;
}
}
[[nodiscard]] inline std::optional<AabbType> getAabb() const {
if (! Base::is_leaf())
return Base::getAsInner().m_aabb;
else
return std::optional<AabbType>();
}
};
//! [CustomNodeDefinition]

int main()
{
// generate N random points
constexpr int N = 1e5;
std::vector<DataPoint> points(N);
std::generate(points.begin(), points.end(), [](){
return DataPoint{100 * DataPoint::VectorType::Random()};});

//! [KdTreeTypeWithCustomNode]
using CustomKdTree = Ponca::KdTreeBase<Ponca::KdTreeDefaultTraits<DataPoint,MyKdTreeNode>>;
//! [KdTreeTypeWithCustomNode]

// build the k-d tree
const CustomKdTree kdtree(points);

// neighbor searches are done below from these arbitrary index and point
const int query_idx = 10;
const DataPoint::VectorType query_pt{-10.0, 0.5, 75.0};

//
// nearest neighbor search
//
std::cout << "the nearest neighbor of the point at index " << query_idx << " is at index "
<< *kdtree.nearest_neighbor(query_idx).begin() << std::endl;
std::cout << "the nearest neighbor of the point (" << query_pt.transpose() << ") is at index "
<< *kdtree.nearest_neighbor(query_pt).begin() << std::endl;

//! [ReadCustomProperties]
auto bbox = kdtree.node_data()[0].getAabb();
if (bbox) {
std::cout << "Root bounding box is as follows: \n"
<< " Center: " << bbox->center()
<< " Diagonal: " << bbox->diagonal()
<< std::endl;
}
//! [ReadCustomProperties]

return 1;
}

0 comments on commit 2f5faa7

Please sign in to comment.