Skip to content

Commit

Permalink
Add examples: nanoflann_gui_example_R3_knn and nanoflann_gui_example_…
Browse files Browse the repository at this point in the history
…R3_radius
  • Loading branch information
jlblancoc committed Nov 27, 2023
1 parent 92bae2a commit c6eca96
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
nanoflann 1.5.1: UNRELEASED
* **API changes:**
- Add missing `SearchParameters` argument to `KDTreeSingleIndexDynamicAdaptor_::knnSearch()` ([PR#213](https://github.com/jlblancoc/nanoflann/pull/213) by [ManosPapadakis95](https://github.com/ManosPapadakis95)).
* **Other changes**:
- Add examples: `nanoflann_gui_example_R3_knn` and `nanoflann_gui_example_R3_radius`


nanoflann 1.5.0: Released Jun 16, 2023
* **API changes:**
Expand Down
15 changes: 11 additions & 4 deletions examples/examples_gui/nanoflann_gui_example_R3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ project(nanoflann_gui_example_R3)
find_package(nanoflann REQUIRED)
find_package(mrpt-gui REQUIRED)

add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp)
add_executable(${PROJECT_NAME}_radius ${PROJECT_NAME}.cpp)
add_executable(${PROJECT_NAME}_knn ${PROJECT_NAME}.cpp)

target_compile_definitions(${PROJECT_NAME}_radius PRIVATE USE_RADIUS_SEARCH)
target_compile_definitions(${PROJECT_NAME}_knn PRIVATE USE_KNN_SEARCH)

# optimized build:
if (CMAKE_COMPILER_IS_GNUCXX)
target_compile_options(${PROJECT_NAME} PRIVATE -O2 -mtune=native)
target_compile_options(${PROJECT_NAME}_radius PRIVATE -O2 -mtune=native)
target_compile_options(${PROJECT_NAME}_knn PRIVATE -O2 -mtune=native)
endif()

# Make sure the include path is used:
target_link_libraries(${PROJECT_NAME} nanoflann::nanoflann mrpt::gui)
target_link_libraries(${PROJECT_NAME}_radius nanoflann::nanoflann mrpt::gui)
target_link_libraries(${PROJECT_NAME}_knn nanoflann::nanoflann mrpt::gui)

# for this example to find "../utils.h"
target_include_directories(${PROJECT_NAME} PRIVATE ".")
target_include_directories(${PROJECT_NAME}_radius PRIVATE ".")
target_include_directories(${PROJECT_NAME}_knn PRIVATE ".")
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ void kdtree_demo(const size_t N)
glFoundPts->setColor_u8(0x00, 0x00, 0xff, 0x80);
scene->insert(glFoundPts);

#if defined(USE_RADIUS_SEARCH)
glQuerySphere->setColor_u8(0xe0, 0xe0, 0xe0, 0x30);
glQuerySphere->enableDrawSolid3D(true);
#else
glQuerySphere->setColor_u8(0xe0, 0xe0, 0xe0, 0x30);
glQuerySphere->enableDrawSolid3D(false);
#endif
scene->insert(glQuerySphere);
}

Expand All @@ -99,40 +105,69 @@ void kdtree_demo(const size_t N)

auto& rng = mrpt::random::getRandomGenerator();

// Declare here to avoid reallocations:
// Declare here to avoid reallocations:
#if defined(USE_RADIUS_SEARCH)
std::vector<nanoflann::ResultItem<size_t, double>> indicesDists;
#elif defined(USE_KNN_SEARCH)
std::vector<size_t> indices;
std::vector<double> distances;
#else
#error Expected either KNN or radius search build flag!
#endif

// Loop: different searches until the window is closed:
while (win.isOpen())
{
// Unsorted radius search:
#if defined(USE_RADIUS_SEARCH)
const double radius = rng.drawUniform(0.1, maxRangeXY * 0.5);
const double sqRadius = radius * radius;

#else
const size_t nnToSearch = (rng.drawUniform32bit() % 10) + 1;
#endif
const double queryPt[3] = {
rng.drawUniform(-0.3, maxRangeXY + 0.3),
rng.drawUniform(-0.3, maxRangeXY + 0.3),
rng.drawUniform(-0.3, maxRangeZ + 0.3)};

mrpt::system::CTimeLoggerEntry tle2(profiler, "query");

#if defined(USE_RADIUS_SEARCH)
indicesDists.clear();
nanoflann::RadiusResultSet<double, size_t> resultSet(
sqRadius, indicesDists);
index.findNeighbors(resultSet, queryPt);
#else
nanoflann::KNNResultSet<double, size_t> resultSet(nnToSearch);
indices.resize(nnToSearch);
distances.resize(nnToSearch);
resultSet.init(indices.data(), distances.data());

index.findNeighbors(resultSet, queryPt);

indices.resize(resultSet.size());
distances.resize(resultSet.size());

const double worstDist = std::sqrt(resultSet.worstDist());
#endif
tle2.stop();

std::cout << "\nQuery point: (" << queryPt[0] << "," << queryPt[1]
<< "," << queryPt[2] << ") => " << resultSet.size()
<< " results.\n";

if (!resultSet.empty())
{
#if defined(USE_RADIUS_SEARCH)
nanoflann::ResultItem<size_t, double> worstPair =
resultSet.worst_item();
std::cout << "Worst pair: idx=" << worstPair.first
<< " dist=" << std::sqrt(worstPair.second) << std::endl;
#else
std::cout << "nnToSearch=" << nnToSearch
<< " actual found=" << indices.size()
<< " Worst found dist=" << worstDist << std::endl;
#endif
}

// Color results:
Expand All @@ -143,12 +178,19 @@ void kdtree_demo(const size_t N)
glQueryPt->insertPoint(queryPt[0], queryPt[1], queryPt[2]);

glQuerySphere->setLocation(queryPt[0], queryPt[1], queryPt[2]);
#if defined(USE_RADIUS_SEARCH)
glQuerySphere->setRadius(radius);

#else
glQuerySphere->setRadius(worstDist);
#endif
glFoundPts->clear();
for (const auto& ptIdx : indicesDists)
#if defined(USE_RADIUS_SEARCH)
for (const auto& [idx, dist] : indicesDists)
#else
for (const auto idx : indices)
#endif
{
const auto& pt = cloud.pts.at(ptIdx.first);
const auto& pt = cloud.pts.at(idx);
glFoundPts->insertPoint(pt.x, pt.y, pt.z);
}

Expand Down

0 comments on commit c6eca96

Please sign in to comment.