Skip to content

Commit fb2a166

Browse files
committed
Added format_mnist.hpp.
Moved formats to pico_toolshed. Small documentation and formatting updates.
1 parent 3eb35dd commit fb2a166

22 files changed

+204
-106
lines changed

CMakeLists.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,37 @@
22
# CMake version 3.9 provides OpenMP per language.
33
cmake_minimum_required(VERSION 3.12)
44

5-
include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake)
5+
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/utils.cmake)
66

77
project(pico_tree
88
LANGUAGES CXX
99
VERSION 0.8.0
1010
DESCRIPTION "PicoTree is a C++ header only library for fast nearest neighbor searches and range searches using a KdTree."
1111
HOMEPAGE_URL "https://github.com/Jaybro/pico_tree")
1212

13-
if (NOT CMAKE_BUILD_TYPE)
13+
if(NOT CMAKE_BUILD_TYPE)
1414
set(CMAKE_BUILD_TYPE "Release")
1515
endif()
1616

17-
################################################################################
17+
# ##############################################################################
1818
# PicoTree, examples, unit tests and documentation.
19-
################################################################################
20-
19+
# ##############################################################################
2120
set(PROJECT_PACKAGE_NAME "PicoTree")
2221
add_subdirectory(src)
2322

2423
# Ignored when running cmake from setup.py using scikit-build.
2524
if(NOT SKBUILD)
2625
option(BUILD_EXAMPLES "Enable the creation of PicoTree examples." ON)
26+
2727
if(BUILD_EXAMPLES)
2828
add_subdirectory(examples)
2929
endif()
3030

3131
include(CTest)
3232
find_package(GTest QUIET)
33+
3334
if(BUILD_TESTING)
34-
if (GTEST_FOUND)
35+
if(GTEST_FOUND)
3536
# Tests are dependent on some common code.
3637
# For now, the understory is considered important enough to be tested.
3738
if(NOT TARGET pico_toolshed)
@@ -49,12 +50,13 @@ if(NOT SKBUILD)
4950

5051
find_package(Doxygen QUIET)
5152
option(BUILD_DOCS "Build documentation with Doxygen." ON)
53+
5254
if(BUILD_DOCS)
5355
if(DOXYGEN_FOUND)
5456
set(DOC_TARGET_NAME ${PROJECT_NAME}_doc)
57+
5558
# Hide the internal namespace from the documentation.
5659
# set(DOXYGEN_EXCLUDE_SYMBOLS "internal")
57-
5860
doxygen_add_docs(
5961
${DOC_TARGET_NAME}
6062
src/pico_tree)

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ Available under the [MIT](https://en.wikipedia.org/wiki/MIT_License) license.
2727

2828
KdTree:
2929
* Nearest neighbor, approximate nearest neighbor, radius, box, and customizable nearest neighbor searches.
30-
* [Metrics](https://en.wikipedia.org/wiki/Metric_(mathematics)):
30+
* Different [metric spaces](https://en.wikipedia.org/wiki/Metric_space):
3131
* Support for topological spaces with identifications. E.g., points on the circle `[-pi, pi]`.
32-
* Available metrics: `L1`, `L2Squared`, `LInf`, `SO2`, and `SE2Squared`. Metrics can be customized.
32+
* Available distance functions: `L1`, `L2Squared`, `LInf`, `SO2`, and `SE2Squared`.
33+
* Metrics can be customized.
3334
* Multiple tree splitting rules: `kLongestMedian`, `kMidpoint` and `kSlidingMidpoint`.
3435
* Compile time and run time known dimensions.
3536
* Static tree builds.

examples/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_subdirectory(pico_understory)
99
add_subdirectory(kd_tree)
1010

1111
find_package(Eigen3 QUIET)
12+
1213
if(Eigen3_FOUND)
1314
message(STATUS "Eigen3 found. Building Eigen example.")
1415
add_subdirectory(eigen)
@@ -17,6 +18,7 @@ else()
1718
endif()
1819

1920
find_package(OpenCV QUIET)
21+
2022
if(OpenCV_FOUND)
2123
message(STATUS "OpenCV found. Building OpenCV example.")
2224
add_subdirectory(opencv)
@@ -25,6 +27,7 @@ else()
2527
endif()
2628

2729
find_package(benchmark QUIET)
30+
2831
if(benchmark_FOUND)
2932
message(STATUS "benchmark found. Building PicoTree benchmarks.")
3033
add_subdirectory(benchmark)

examples/benchmark/CMakeLists.txt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ function(add_benchmark TARGET_NAME)
33
set_default_target_properties(${TARGET_NAME})
44
target_link_libraries(${TARGET_NAME}
55
PRIVATE
6-
pico_toolshed
7-
benchmark::benchmark
6+
pico_toolshed
7+
benchmark::benchmark
88
)
99
endfunction()
1010

11-
################################################################################
11+
# ##############################################################################
1212
# bm_pico_kd_tree, bm_pico_cover_tree, bm_nanoflann, bm_opencv_flann
13-
################################################################################
14-
13+
# ##############################################################################
1514
add_benchmark(bm_pico_kd_tree)
1615

1716
add_benchmark(bm_pico_cover_tree)
1817
target_link_libraries(bm_pico_cover_tree PRIVATE pico_understory)
1918

2019
find_package(nanoflann QUIET)
20+
2121
if(nanoflann_FOUND)
2222
message(STATUS "nanoflann found. Building nanoflann benchmark.")
2323
add_benchmark(bm_nanoflann)
@@ -29,6 +29,7 @@ endif()
2929
# The FLANN respository does not provide a flannConfig.cmake. So it's more
3030
# easy to go with the OpenCV one.
3131
find_package(OpenCV COMPONENTS core flann QUIET)
32+
3233
if(OpenCV_FOUND)
3334
message(STATUS "OpenCV found. Building OpenCV FLANN benchmark.")
3435
add_benchmark(bm_opencv_flann)
@@ -37,25 +38,23 @@ else()
3738
message(STATUS "OpenCV not found. OpenCV FLANN benchmark skipped.")
3839
endif()
3940

40-
################################################################################
41+
# ##############################################################################
4142
# uosr_to_bin
42-
################################################################################
43-
43+
# ##############################################################################
4444
add_executable(uosr_to_bin uosr_to_bin.cpp)
4545
set_default_target_properties(uosr_to_bin)
4646
target_link_libraries(uosr_to_bin PRIVATE pico_toolshed)
4747

48-
################################################################################
48+
# ##############################################################################
4949
# bin_to_ascii
50-
################################################################################
51-
50+
# ##############################################################################
5251
add_executable(bin_to_ascii bin_to_ascii.cpp)
5352
set_default_target_properties(bin_to_ascii)
5453
target_link_libraries(bin_to_ascii PRIVATE pico_toolshed)
5554

56-
################################################################################
55+
# ##############################################################################
5756
# plot_benchmarks
58-
################################################################################
57+
# ##############################################################################
5958

6059
# TODO These don't get deleted when running: make clean
6160
add_custom_target(plot_benchmarks ALL

examples/benchmark/benchmark.hpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#include <benchmark/benchmark.h>
22

3+
#include <pico_toolshed/format/format_bin.hpp>
34
#include <pico_toolshed/point.hpp>
45

5-
#include "format_bin.hpp"
6-
76
// It seems that there is a "threshold" to the number of functions being
87
// benchmarked. Having "too many" of them makes them become slow(er). This
98
// appears to be due to code alignment. See similar issue and video referencing
@@ -28,8 +27,8 @@ class Benchmark : public benchmark::Fixture {
2827
Benchmark() {
2928
// Here you may need to be patient depending on the size of the binaries.
3029
// Loaded for each benchmark.
31-
pico_tree::ReadBin("./scans0.bin", &points_tree_);
32-
pico_tree::ReadBin("./scans1.bin", &points_test_);
30+
pico_tree::ReadBin("./scans0.bin", points_tree_);
31+
pico_tree::ReadBin("./scans1.bin", points_test_);
3332
}
3433

3534
protected:

examples/benchmark/bin_to_ascii.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#include <filesystem>
2+
#include <pico_toolshed/format/format_ascii.hpp>
3+
#include <pico_toolshed/format/format_bin.hpp>
24
#include <pico_toolshed/point.hpp>
35

4-
#include "format_ascii.hpp"
5-
#include "format_bin.hpp"
6-
76
int main() {
87
std::filesystem::path dirname_root = ".";
98
std::filesystem::path filename_bin = "scans.bin";
@@ -16,7 +15,7 @@ int main() {
1615
} else if (!std::filesystem::exists(path_ascii)) {
1716
std::cout << "Reading points in bin format..." << std::endl;
1817
std::vector<Point3f> points;
19-
pico_tree::ReadBin(path_bin.string(), &points);
18+
pico_tree::ReadBin(path_bin.string(), points);
2019
std::cout << "Read " << points.size() << " points." << std::endl;
2120
std::cout << "Writing points to ascii xyz format..." << std::endl;
2221
pico_tree::WriteAscii(path_ascii.string(), points);

examples/benchmark/uosr_to_bin.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include <filesystem>
2-
3-
#include "format_bin.hpp"
4-
#include "format_uosr.hpp"
2+
#include <pico_toolshed/format/format_bin.hpp>
3+
#include <pico_toolshed/format/format_uosr.hpp>
54

65
int main() {
76
std::filesystem::path dirname_root = ".";
@@ -11,7 +10,7 @@ int main() {
1110
if (!std::filesystem::exists(path_bin)) {
1211
std::cout << "Reading scans in uosr format..." << std::endl;
1312
std::vector<Point3f> points;
14-
pico_tree::ReadUosr(dirname_root.string(), &points);
13+
pico_tree::ReadUosr(dirname_root.string(), points);
1514
std::cout << "Read " << points.size() << " points." << std::endl;
1615
std::cout << "Writing scans to bin xyz format..." << std::endl;
1716
pico_tree::WriteBin(path_bin.string(), points);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <cstddef>
4+
#include <type_traits>
5+
6+
namespace pico_tree::internal {
7+
8+
template <typename T>
9+
T SwapEndian(T const& u) {
10+
T s;
11+
12+
std::byte const* up = reinterpret_cast<std::byte const*>(&u);
13+
std::byte* sp = reinterpret_cast<std::byte*>(&s);
14+
for (std::size_t i = 0; i < sizeof(T); ++i) {
15+
sp[i] = up[sizeof(T) - i - 1];
16+
}
17+
18+
return s;
19+
}
20+
21+
template <typename T_>
22+
T_ BigEndianToNative(T_ v) {
23+
static_assert(std::is_integral_v<T_>, "NOT_AN_INTEGRAL_TYPE");
24+
static_assert(sizeof(T_) <= sizeof(std::size_t), "SIZE_UNSUPPORTED");
25+
26+
std::byte* v_object = reinterpret_cast<std::byte*>(&v);
27+
28+
T_ native{};
29+
for (std::size_t i = 0; i < sizeof(T_); ++i) {
30+
native |= static_cast<T_>(
31+
static_cast<std::size_t>(v_object[i]) << ((sizeof(T_) - 1 - i) * 8));
32+
}
33+
34+
return native;
35+
}
36+
37+
//! \brief Stores the value of an integral type assuming big endian byte
38+
//! ordering.
39+
//! \details The idea is to be oblivious to the native endianness. When a big
40+
//! endian value is read it can be converted to its native counterpart. If the
41+
//! native endianness equals big endian then we're basically making a very
42+
//! elaborate copy. However, use of this class should be quite minimal.
43+
template <typename T_>
44+
struct BigEndian {
45+
static_assert(std::is_integral_v<T_>, "NOT_AN_INTEGRAL_TYPE");
46+
47+
T_ operator()() const { return BigEndianToNative(value); }
48+
49+
operator T_() const { return this->operator()(); }
50+
51+
T_ value;
52+
};
53+
54+
} // namespace pico_tree::internal

examples/benchmark/format_bin.hpp renamed to examples/pico_toolshed/pico_toolshed/format/format_bin.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ void WriteBin(std::string const& filename, std::vector<T> const& v) {
1818
}
1919

2020
template <typename T>
21-
void ReadBin(std::string const& filename, std::vector<T>* v) {
21+
void ReadBin(std::string const& filename, std::vector<T>& v) {
2222
std::fstream stream =
2323
internal::OpenStream(filename, std::ios::in | std::ios::binary);
2424

@@ -36,8 +36,8 @@ void ReadBin(std::string const& filename, std::vector<T>* v) {
3636
std::size_t const element_size = sizeof(T);
3737
std::size_t const element_count =
3838
static_cast<std::size_t>(byte_count / element_size);
39-
v->resize(element_count);
40-
stream.read(reinterpret_cast<char*>(&(*v)[0]), element_size * element_count);
39+
v.resize(element_count);
40+
stream.read(reinterpret_cast<char*>(&v[0]), element_size * element_count);
4141
}
4242

4343
} // namespace pico_tree

0 commit comments

Comments
 (0)