C++ API reference
This is the complete reference for the (internal) C++ API of py4dgeo.
You only need to consult this documentation if you are aiming to extend the
C++ core of py4dgeo.
-
namespace py4dgeo
Typedefs
-
using EigenPointCloud = Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor>
The C++ type for a point cloud.
Point clouds are represented as (nx3) matrices from the Eigen library.
The choice of this type allows us both very efficient implementation of numeric algorithms using the Eigen library, as well as no-copy interoperability with numpy’s multidimensional arrays.
-
using EigenPointCloudRef = Eigen::Ref<EigenPointCloud>
A non-const reference type for passing around EigenPointCloud.
You should use this in function signatures that accept a point cloud as a parameter and need to modify the point cloud.
-
using EigenPointCloudConstRef = Eigen::Ref<const EigenPointCloud>
A const reference type for passing around EigenPointCloud.
You should use this in function signatures that accept a read-only point cloud.
-
using EigenNormalSet = Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor>
The C++ type to represent a set of normal vectors on a point cloud.
-
using EigenNormalSetRef = Eigen::Ref<EigenNormalSet>
A mutable reference to a set of normal vectors on a point cloud.
-
using EigenNormalSetConstRef = Eigen::Ref<const EigenNormalSet>
An immutable reference to a set of normal vectors on a point cloud.
-
using IndexType = Eigen::Index
The type used for point cloud indices.
-
using DistanceVector = std::vector<double>
The variable-sized vector type used for distances.
-
using UncertaintyVector = std::vector<DistanceUncertainty>
The variable-sized vector type used for uncertainties.
Enums
-
struct DistanceUncertainty
- #include <py4dgeo.hpp>
Return structure for the uncertainty of the distance computation.
This structured type is used to describe the uncertainty of point cloud distance at a single corepoint. It contains the level of detection, the spread within both point clouds (e.g. the standard deviation of the distance measure) and the number of sampled points.
-
struct Supervoxel
Public Functions
-
inline Supervoxel()
-
inline Supervoxel(EigenPointCloudConstRef c, EigenNormalSetConstRef n, const Eigen::Vector3d ¢er, EigenPointCloudConstRef boundary)
Public Members
-
EigenPointCloud cloud
-
EigenNormalSet normals
-
Eigen::Vector3d centroid
-
EigenPointCloud boundary_points
-
inline Supervoxel()
-
using EigenPointCloud = Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor>
-
namespace py4dgeo
-
class Epoch
- #include <epoch.hpp>
A data structure representing an epoch.
Stores the point cloud itself (without taking ownership of it) and provides two search trees: a KDTree and an Octree. This structure allows efficient spatial queries without duplicating data.
Public Static Functions
-
static inline void set_default_radius_search_tree(SearchTree tree)
-
static inline void set_default_nearest_neighbor_tree(SearchTree tree)
-
static inline SearchTree get_default_radius_search_tree()
-
static inline SearchTree get_default_nearest_neighbor_tree()
Private Members
-
std::shared_ptr<EigenPointCloud> owned_cloud
Private Static Attributes
-
static SearchTree default_radius_search_tree = SearchTree::KDTree
-
static SearchTree default_nearest_neighbor_tree = SearchTree::KDTree
-
static inline void set_default_radius_search_tree(SearchTree tree)
-
class Epoch
-
namespace py4dgeo
Typedefs
-
using RadiusSearchDistanceResult = std::vector<std::pair<IndexType, double>>
Return type used for radius searches that export calculated squared distances
-
using NearestNeighborsDistanceResult = std::vector<std::pair<std::vector<IndexType>, std::vector<double>>>
Return type used for nearest neighbor with Euclidian distances searches.
-
using NearestNeighborsResult = std::vector<std::vector<IndexType>>
Return type used for nearest neighbor searches.
-
using RadiusSearchFuncSingle = std::function<void(const Eigen::Vector3d&, RadiusSearchResult&)>
Function type for performing a single-radius search.
This function takes a 3D query point (as an Eigen vector) and outputs a vector of point indices that lie within a sphere around the query point with specified radius. The specific search algorithm (KDTree or Octree) is determined at runtime.
- Param query_point:
The 3D coordinates of the point to search around.
- Param result:
A vector of indices of points within the search radius.
-
using RadiusSearchFunc = std::function<void(const Eigen::Vector3d&, std::size_t, RadiusSearchResult&)>
Function type for performing a multi-radius search.
This function takes a 3D point and an index representing the radius to use from a precomputed list of radii. It outputs a vector of point indices that lie within the selected radius.
- Param query_point:
The 3D coordinates of the point to search around.
- Param radius_index:
The index to select the radius from a list of radii.
- Param result:
A vector of indices of points within the search radius.
-
using RadiusSearchDistanceResult = std::vector<std::pair<IndexType, double>>
Defines
-
NANOFLANN_NODE_ALIGNMENT
-
namespace py4dgeo
-
class KDTree
- #include <kdtree.hpp>
Efficient KDTree data structure for nearest neighbor/radius searches.
This data structure allows efficient radius searches in 3D point cloud data. It is based on NanoFLANN: https://github.com/jlblancoc/nanoflann
Public Functions
-
std::ostream &saveIndex(std::ostream &stream) const
Save the index to a (file) stream.
-
std::istream &loadIndex(std::istream &stream)
Load the index from a (file) stream.
-
void build_tree(int leaf)
Build the KDTree index.
This initializes the KDTree search index. Calling this method is required before performing any nearest neighbors or radius searches.
- Parameters:
leaf – The threshold parameter definining at what size the search tree is cutoff. Below the cutoff, a brute force search is performed. This parameter controls a trade off decision between search tree build time and query time.
-
std::size_t radius_search(const double *querypoint, double radius, RadiusSearchResult &result) const
Peform radius search around given query point.
This method determines all the points from the point cloud within the given radius of the query point. It returns only the indices and the result is not sorted according to distance.
- Parameters:
querypoint – [in] A pointer to the 3D coordinate of the query point
radius – [in] The radius to search within
result – [out] A data structure to hold the result. It will be cleared during application.
- Returns:
The amount of points in the return set
-
std::size_t radius_search_with_distances(const double *querypoint, double radius, RadiusSearchDistanceResult &result) const
Perform radius search around given query point exporting distance information.
This method determines all the points from the point cloud within the given radius of the query point. It returns their indices and their distances from the query point. The result is sorted by ascending distance from the query point.
- Parameters:
querypoint – [in] A pointer to the 3D coordinate of the query point
radius – [in] The radius to search within
result – [out] A data structure to hold the result. It will be cleared during application.
- Returns:
The amount of points in the return set
-
void nearest_neighbors_with_distances(EigenPointCloudConstRef cloud, NearestNeighborsDistanceResult &result, int k) const
Calculate the nearest neighbors with Euclidian distance for an entire point cloud.
- Parameters:
cloud – [in] The point cloud to use as query points
result – [out] The indexes and distances of k nearest neighbors for each point
k – [in] The amount of nearest neighbors to calculate
-
void nearest_neighbors(EigenPointCloudConstRef cloud, NearestNeighborsResult &result, int k) const
Calculate the nearest neighbors for an entire point cloud.
- Parameters:
cloud – [in] The point cloud to use as query points
result – [out] The indexes of k nearest neighbors for each point
k – [in] The amount of nearest neighbors to calculate
Public Static Functions
-
static KDTree create(const EigenPointCloudRef &cloud)
Construct instance of KDTree from a given point cloud.
This is implemented as a static function instead of a public constructor to ease the implementation of Python bindings.
- Parameters:
cloud – The point cloud to construct the search tree for
Private Types
Private Functions
-
KDTree(const EigenPointCloudRef&)
Private constructor from pointcloud - use through KDTree::create.
-
struct Adaptor
An adaptor between our Eigen data structures and NanoFLANN.
Public Functions
-
inline std::size_t kdtree_get_point_count() const
Public Members
-
EigenPointCloudRef cloud
-
inline std::size_t kdtree_get_point_count() const
-
struct NoDistancesReturnSet
A structure to perform efficient radius searches with NanoFLANN.
The built-in return set of NanoFLANN does automatically export the distances as well, which we want to omit if we already know that we do not need the distance information.
Public Types
-
using DistanceType = double
-
using DistanceType = double
-
struct WithDistancesReturnSet
A custom result set structure for collecting radius search results with squared distances using nanoflann.
This structure is used with nanoflann’s radiusSearchCustomCallback() to collect search results in a user-defined format. It stores pairs of point indices and their corresponding squared distances to the query point in a std::vector<std::pair<IndexType, double>> (RadiusSearchDistanceResult).
By using this structure instead of nanoflann::ResultItem, we avoid copying between incompatible result types and maintain compatibility with Octree which uses the same result type.
This class satisfies the interface expected by nanoflann’s custom result set:
addPoint(distance, index): stores the result if within radius
size(), full(), worstDist(): for compatibility
sort(): optional post-processing
Public Types
-
using DistanceType = double
-
std::ostream &saveIndex(std::ostream &stream) const
-
class KDTree
-
namespace py4dgeo
Functions
-
template<typename T, unsigned int BITS>
constexpr T dilate(T x) Dilate (bit-spread) a small integer so its bits occupy every third bit position.
This function takes a BITS-bit integer x and returns a value in which each original bit has been moved to position (3*i). Two zero bits are inserted between every bit of the input. This operation is the core of Morton (Z-order) encoding, where the x, y, and z bits of a coordinate are interleaved to form a single integer key.
Example (for BITS = 4): input: b3 b2 b1 b0 output: 0 0 b3 0 0 b2 0 0 b1 0 0 b0
The result corresponds to the x-axis contribution of a Morton code before interleaving with y and z bits.
-
template<typename T, unsigned int BITS, std::size_t TABLE_SIZE = (1ULL << BITS)>
static constexpr std::array<T, TABLE_SIZE> make_dilate_table() Generate a compile-time lookup table of dilated integers.
This function builds a table of size (1 << BITS), where entry i contains dilate(i). The table allows Morton encoding to be done efficiently in large fixed-size chunks (e.g., 8 bits or 5 bits at a time), instead of looping over individual bits.
These tables are computed at compile time (constexpr) and enable the encoder to construct full Morton keys using a handful of table lookups and bit shifts, which is significantly faster than iterative bit interleaving.
-
class Octree
- #include <octree.hpp>
Efficient Octree data structure for nearest neighbor/radius searches.
This data structure allows efficient radius searches in 3D point cloud data. Unlike KDTree, it recursively subdivides space into eight octants.
Public Types
-
using SpatialKey = std::uint32_t
Alias for the spatial key type used for Z-order value encoding.
-
using KeyContainer = std::vector<SpatialKey>
Return type used for cell searches.
-
using OctreeCoordinate = std::array<uint32_t, 3>
Coordinate within the octree.
-
using OctreeCoordinates = Eigen::Matrix<uint32_t, Eigen::Dynamic, 3, Eigen::RowMajor>
Coordinates within the octree.
Public Functions
-
void build_tree(bool force_cubic = false, std::optional<Eigen::Vector3d> min_corner = std::nullopt, std::optional<Eigen::Vector3d> max_corner = std::nullopt)
Build the Octree index.
This initializes the Octree search index. Calling this method is required before performing any nearest neighbors or radius searches.
- Parameters:
force_cubic – If true, the bounding box will be forced to have equal side lengths, resulting in a cubic shape.
min_corner – Optional minimum point (lower corner of the bounding box). If not provided, the minimum point is computed automatically from the input data.
max_corner – Optional maximum point (upper corner of the bounding box). If not provided, the maximum point is computed automatically from the input data.
-
void invalidate()
Clears the Octree structure, effectively resetting it.
This function deallocates the Octree by clearing the sorted array of indices and keys. This operation invalidates the current Octree, requiring it to be rebuilt before further use.
-
std::ostream &saveIndex(std::ostream &stream) const
Save the index to a (file) stream.
-
std::istream &loadIndex(std::istream &stream)
Load the index from a (file) stream.
-
inline const KeyContainer &get_spatial_keys() const
Get all spatial keys (Z-order values) of the Octree.
- Returns:
Vector of spatial keys (Z-order values)
-
inline const PointContainer &get_point_indices() const
Get all point indices corresponding to spatial keys.
- Returns:
Vector of point indices
-
std::size_t radius_search(const Eigen::Vector3d &query_point, double radius, unsigned int level, RadiusSearchResult &result) const
Perform radius search around given query point.
This method determines all the points from the point cloud within the given radius of the query point. It returns only the indices and the result is not sorted according to distance.
- Parameters:
query_point – [in] A pointer to the 3D coordinate of the query point
radius – [in] The radius to search within
level – [in] The depth level at which to perform the search
result – [out] A data structure to hold the point indices. It will be cleared during application.
- Returns:
Number of points found
-
std::size_t radius_search_with_distances(const Eigen::Vector3d &query_point, double radius, unsigned int level, RadiusSearchDistanceResult &result) const
Perform radius search around given query point.
This method determines all the points from the point cloud within the given radius of the query point. It returns only the indices and the result is not sorted according to distance.
- Parameters:
query_point – [in] A pointer to the 3D coordinate of the query point
radius – [in] The radius to search within
level – [in] The depth level at which to perform the search
result – [out] A data structure to hold the point indices and corresponding distances. It will be cleared during application.
- Returns:
Number of points found
-
inline unsigned int get_number_of_points() const
Return the number of points in the associated cloud.
-
inline constexpr unsigned int get_max_depth() const
Return the maximum octree depth.
-
inline Eigen::Vector3d get_box_size() const
Return the side length of the bounding box.
-
inline Eigen::Vector3d get_min_point() const
Return the minimum point of the bounding box.
-
inline Eigen::Vector3d get_max_point() const
Return the maximum point of the bounding box.
-
inline Eigen::Vector3d get_cell_size(unsigned int level) const
Return the size of cells at a level of depth.
-
inline constexpr unsigned int get_number_of_cells(unsigned int level) const
Return the number of cells at a level of depth.
-
inline constexpr unsigned int get_number_of_cells_per_axis(unsigned int level) const
Return the number of cells per axis at a level of depth.
-
inline unsigned int get_number_of_occupied_cells(unsigned int level) const
Return the number of occupied cells per level of depth.
-
inline unsigned int get_max_cell_population(unsigned int level) const
Return the maximum cell population per level of depth.
-
inline double get_average_cell_population(unsigned int level) const
Return the average number of points per level of depth.
-
inline double get_std_cell_population(unsigned int level) const
Return the standard deviation of number of points per level of depth.
-
std::size_t get_cell_population(SpatialKey truncated_key, unsigned int level) const
Returns the number of points lying in a single octree cell at a specified depth level.
- Parameters:
truncated_key – [in] Truncated spatial key identifying the query cell
level – [in] Octree depth level of the query cell
- Returns:
The number of points in the specified cell
-
std::vector<std::size_t> get_cell_population(const KeyContainer &truncated_keys, unsigned int level) const
Returns the cell populations for multiple octree cells at a specified depth level.
- Parameters:
truncated_keys – [in] Truncated spatial keys identifying the query cells
level – [in] Octree depth level of the query cell
- Returns:
The number of points in the specified cells
-
std::size_t get_point_indices_from_cells(SpatialKey truncated_key, unsigned int level, RadiusSearchResult &result) const
Return indices of points lying in a single octree cell at a specified depth level.
Given a spatial key identifying the octree cell (truncated to the same depth level), this function gathers all point indices belonging to this cell.
The search exploits the sorted order of the input keys to avoid redundant scans and achieve efficient sequential access.
- Parameters:
truncated_key – [in] Spatial keys of the query cell, truncated to the specified depth level
level – [in] Octree depth level of the query cells
result – [out] Container to hold the resulting point indices. Existing contents will be preserved and appended to.
- Returns:
The total number of points appended to the result container
-
std::size_t get_point_indices_from_cells(const KeyContainer &truncated_keys, unsigned int level, RadiusSearchResult &result) const
Return indices of points lying in multiple octree cells at a specified depth level.
Given a sorted list of spatial keys identifying octree cells (truncated to the same depth level), this function gathers all point indices belonging to those cells.
The search exploits the sorted order of the input keys to avoid redundant scans and achieve efficient sequential access.
- Parameters:
truncated_keys – [in] Sorted spatial keys of the query cells, truncated to the specified depth level
level – [in] Octree depth level of the query cells
result – [out] Container to hold the resulting point indices. Existing contents will be preserved and appended to.
- Returns:
The total number of points appended to the result container
-
KeyContainer get_unique_cells(unsigned int level) const
Returns the unique spatial keys of occupied cells at a specified depth level.
- Parameters:
level – [in] The depth level at which to retrieve the unique cells
- Returns:
A container of unique (truncated) spatial keys of occupied cells
-
OctreeCoordinate get_coordinates(SpatialKey truncated_key) const
Return the octree-grid coordinate (x,y,z) of a spatial key.
If no level is provided, the coordinate at maximum depth is returned.
-
OctreeCoordinates get_coordinates(const KeyContainer &truncated_keys) const
Return the octree-grid coordinates (x,y,z) of a set of spatial keys.
If no level is provided, the coordinates at maximum depth is returned.
-
OctreeCoordinates get_coordinates_at_level(unsigned int level) const
Return the octree-grid coordinates (x,y,z) of all points at a given level.
If no level is provided, the coordinates at maximum depth is returned.
-
unsigned int find_appropriate_level_for_radius_search(double radius) const
Returns the level of depth at which a radius search will be most efficient.
- Parameters:
radius – The radius of the search sphere
- Returns:
The depth level at which to perform a radius search
Public Static Functions
-
static Octree create(const EigenPointCloudRef &cloud)
Construct instance of Octree from a given point cloud.
This is implemented as a static function instead of a public constructor to ease the implementation of Python bindings.
- Parameters:
cloud – The point cloud to construct the search tree for
Private Types
Private Functions
-
Octree(const EigenPointCloudRef&)
Private constructor from point cloud - use through Octree::create.
-
inline SpatialKey compute_spatial_key(const Eigen::Vector3d &point) const
Computes a unique spatial key (Z-order value) for a given point.
This function normalizes the input point within the bounding box and maps it to an integer 3D grid of size ‘2^max_depth × 2^max_depth × 2^max_depth’. The computed grid coordinates are then interleaved using bitwise operations to generate a Z-order value key that represents the point’s hierarchical position in the Octree.
- Parameters:
point – The 3D point for which to compute the spatial key.
- Returns:
A SpatialKey (unsigned integer) representing the spatial key of the point.
-
inline SpatialKey compute_spatial_key(const OctreeCoordinate &query_cell, unsigned int level) const
Computes a unique spatial key (Z-order value) for a given octree cell.
- Parameters:
query_cell – The 3D octree coordinate for which to compute the spatial key.
- Returns:
A SpatialKey (unsigned integer) representing the spatial key of the point.
-
inline SpatialKey compute_spatial_key(SpatialKey ix, SpatialKey iy, SpatialKey iz) const
Computes a unique spatial key (Z-order value) for a given point.
This function takes integer grid coordinates and interleaves their bits to generate a Z-order value key that represents the point’s hierarchical position in the Octree.
- Parameters:
ix – The integer x-coordinate in the grid.
iy – The integer y-coordinate in the grid.
iz – The integer z-coordinate in the grid.
- Returns:
A SpatialKey (unsigned integer) representing the spatial key of the point.
-
inline OctreeCoordinate decode_spatial_key_at_level(SpatialKey key, unsigned int level) const
Decode a spatial key into (x, y, z) coordinates at a given octree level.
The input
SpatialKeyis a Morton-encoded (Z-order) spatial key where the bits of x, y, and z are interleaved as:At maximum depth (level == max_depth), decode_spatial_key() returns the full-resolution integer coordinates (max_depth bits per axis).... z2 y2 x2 z1 y1 x1 z0 y0 x0
For coarser octree levels, this function first discards the least significant Morton “triples” (x,y,z) by shifting the key to the right by
which removes all detail below the requested level while preserving the x/y/z bit-lane alignment. The truncated code is then decoded via decode_spatial_key(), yielding the cell coordinates at the requested level.bit_shift[level] = 3 * (max_depth - level)
In other words:
level == max_depth: full-resolution coordinates
level < max_depth: coordinates on a coarser 2^level grid
- Parameters:
key – Morton-encoded spatial key.
level – Target octree level in [0, max_depth].
- Returns:
(x, y, z) octree-grid coordinates at the specified level.
-
void compute_bounding_box(bool force_cubic = false, std::optional<Eigen::Vector3d> min_corner = std::nullopt, std::optional<Eigen::Vector3d> max_corner = std::nullopt)
Computes the smallest power-of-two bounding box that contains all points.
This function calculates the minimum and maximum coordinates of the point cloud and determines a cuboid that fully encloses the data. The box size is rounded up to the nearest power of two.
The computed bounding box is stored in
min_point,max_point, andbox_size.- Parameters:
force_cubic – If true, the bounding box will be forced to have equal side lengths, resulting in a cubic shape.
min_corner – Optional minimum point (lower corner of the bounding box). If not provided, the minimum point is computed automatically from the input data.
max_corner – Optional maximum point (upper corner of the bounding box). If not provided, the maximum point is computed automatically from the input data.
-
void compute_statistics()
Computes the average cell properties of occupied cells at all depth levels.
-
template<typename Reserve, typename CallbackCandidate, typename CallbackInside>
inline void radius_search_backend(const Eigen::Vector3d &query_point, double radius, unsigned int level, Reserve &&reserve, CallbackCandidate &&check_candidate, CallbackInside &&take_all) const Perform radius search with a callback for each matching point.
Searches all points within the given radius around a query point at a specified octree level. For each point inside the radius, the provided callback is called with its index and distance.
Used internally to implement both index-only and distance-returning search variants.
- Template Parameters:
Callback – A callable accepting (IndexType, double)
- Parameters:
query_point – [in] The 3D coordinates of the query point
radius – [in] The search radius
level – [in] The octree depth level
check_candidate – [in] Called for each candidate point found within the sphere
take_all – [in] Called for all points in cells that are completely within the sphere
-
std::size_t get_cells_intersected_by_sphere(const Eigen::Vector3d &query_point, double radius, unsigned int level, KeyContainer &inside, KeyContainer &intersecting) const
Returns spatial keys of cells intersected by a sphere with specified radius with it’s center at the query point.
- Parameters:
query_point – [in] A reference to of the query point
radius – [in] The radius to search within
level – [in] The depth level to be considered
inside – [out] A vector of spatial keys of the cells entirely in the sphere
intersecting – [out] A vector of spatial keys of the intersected cells
- Returns:
The number of intersected cells and cells that are fully inside the sphere
-
std::optional<IndexType> get_cell_index_start(SpatialKey truncated_key, SpatialKey bitShift, IndexType start_index, IndexType end_index) const
Returns the first occurrence of the index of a cell in the sorted array of point indices and point spatial keys.
- Parameters:
key – The spatial key of the query cell
bitShift – The bit shift corresponding to the Octree depth level of the query cell
start_index – Start index
end_index – End index
- Returns:
The index of first occurrence of the cell spatial key
-
std::optional<IndexType> get_cell_index_end(SpatialKey truncated_key, SpatialKey bitShift, IndexType start_index, IndexType end_index) const
Returns the last occurrence of the index of a cell in the sorted array of point indices and point spatial keys.
- Parameters:
truncated_key – The spatial key of the query cell
bitShift – The bit shift corresponding to the Octree depth level of the query cell
start_index – Start index
end_index – End index
- Returns:
The index of last occurrence of the cell spatial key
-
std::optional<IndexType> get_cell_index_end_exponential(SpatialKey truncated_key, unsigned int level, IndexType first_index, IndexType global_end_index) const
Efficiently finds the end index of a block of points belonging to the same truncated spatial key.
This function assumes the data is sorted by spatial keys and performs a stride-based search to narrow the interval where the last matching key may occur. The search begins from the known start index of a cell and advances by the estimated average number of points per cell (based on depth level statistics). Once a non-matching key is detected or the global bounds are exceeded, a binary search is performed within the refined interval to find the precise end.
This hybrid approach combines data-aware range narrowing with binary search for performance.
- Parameters:
truncated_key – The spatial key (already bit-shifted) identifying the target cell
level – Octree depth level (used to get average cell population)
first_index – Start index of the block in the sorted array
global_end_index – Absolute upper bound for the search (typically the size of the array)
- Returns:
Index one past the last occurrence of the given spatial key, or std::nullopt if not found
-
std::optional<std::pair<IndexType, IndexType>> get_cell_index_range(SpatialKey truncated_key, unsigned int level, IndexType search_start, IndexType search_end) const
Compute the index range of points belonging to a single octree cell.
Given a truncated spatial key identifying an octree cell at a given depth level, this function locates the contiguous block of point indices belonging to that cell in the internally sorted index structure.
The returned index range is half-open: [first, last).
- Parameters:
truncated_key – [in] Truncated spatial key identifying the query cell
level – [in] Octree depth level of the query cell
search_start – [in] Lower bound index for the search window
search_end – [in] Upper bound index for the search window (exclusive)
- Returns:
Optional pair (first, last) describing the index range of points in the cell, or std::nullopt if the cell contains no points
-
bool append_points_from_cell(SpatialKey truncated_key, unsigned int level, IndexType ¤t_start_index, IndexType search_limit_index, RadiusSearchResult &result) const
Append indices of points belonging to a single octree cell.
Finds all points contained in the specified octree cell and appends their point indices to the provided result container.
The search window is advanced to start after the current cell’s block, enabling efficient sequential processing of sorted cell queries.
- Parameters:
truncated_key – [in] Truncated spatial key identifying the query cell, truncated to the specified depth level
level – [in] Octree depth level of the query cell
current_start_index – [inout] Start index for the search window; updated to the end of the current cell’s block
search_limit_index – [in] Upper bound of the search window (exclusive)
result – [inout] Container to which point indices are appended
- Returns:
True if the cell contains points, false otherwise
Private Members
-
EigenPointCloudRef cloud
Reference to the point cloud.
-
unsigned int number_of_points = 0
Number of points in the cloud.
-
IndexAndKey indexed_keys
Pairs of spatial key (Z-order values) and corresponding index, sorted by z-order value
-
Eigen::Vector3d min_point
Min point of the bounding box.
-
Eigen::Vector3d max_point
Max point of the bounding box.
-
Eigen::Vector3d box_size
Size of the bounding box.
-
Eigen::Vector3d inv_box_size
Inverse of box size.
-
std::array<unsigned int, max_depth + 1> max_cell_population
Maximum number of points per depth level.
-
std::array<double, max_depth + 1> average_cell_population
Average number of points per depth level.
-
std::array<double, max_depth + 1> std_cell_population
Standard deviation of points per depth level.
- friend Epoch
Allow the Epoch class to directly call the private constructor.
Private Static Functions
-
static inline uint64_t compact3(uint64_t v)
Extracts and compacts every third bit from a Morton-encoded word.
Morton (Z-order) encoding interleaves the bits of three coordinates: x0 y0 z0 x1 y1 z1 x2 y2 z2 …
Given a 64-bit integer
vthat represents one of these three shifted Morton streams (i.e., eitherkey >> 0,key >> 1, orkey >> 2), this function isolates the bits belonging to one coordinate and compacts them into contiguous low-order bits:input bits: v = _ _ x2 _ _ x1 _ _ x0 (spread every 3rd bit) output: x = 0 0 0 x2 x1 x0 (packed)
The implementation applies a sequence of bit masks and shift-OR operations. Each step reduces the spacing between valid bits while preventing bits from moving across structural boundaries. This is the standard high-performance Morton decode algorithm used in libmorton, Embree, and OptiX.
The routine works for both 32-bit and 64-bit Morton keys: if
voriginates from a 32-bit Morton code, all upper bits are zero and the additional compaction steps simply have no effect. No separate 32-bit implementation is required.- Parameters:
v – The shifted Morton stream (x = key>>0, y = key>>1, z = key>>2).
- Returns:
The compacted coordinate (up to 22 bits for max depth 21).
-
static inline OctreeCoordinate decode_spatial_key(SpatialKey key)
Decodes a spatial key into integer coordinates.
A Morton (Z-order) key interleaves the bits of three coordinates x, y, z:
This function extracts each bit stream by shifting the Morton key: x-bits: key >> 0 y-bits: key >> 1 z-bits: key >> 2morton = z2 y2 x2 z1 y1 x1 z0 y0 x0 ...
and then compacts them using
compact3(). The result is the integer octree-grid coordinate of the point at the maximum tree depth. If a coarser level is required, the caller can right-shift the results by (max_depth - level).Works for both 32-bit and 64-bit Morton keys. Larger word sizes simply provide more Morton layers; compact3() automatically ignores unused bits.
- Parameters:
key – The Morton-encoded spatial key.
- Returns:
The decoded (x, y, z) octree-grid coordinate at maximum depth.
Private Static Attributes
-
static constexpr SpatialKey invalid_key = std::numeric_limits<SpatialKey>::max()
Invalid spatial key constant.
-
static constexpr unsigned int max_depth = (sizeof(SpatialKey) * 8) / 3
Max depth level, depends solely on spatial key integer representation.
-
static constexpr unsigned int grid_size = (1 << max_depth)
Number of cells per axis at the lowest level (2^max_depth)
-
static constexpr std::array<SpatialKey, max_depth + 1> bit_shift =
[]() {std::array<SpatialKey, max_depth + 1> arr{};for (std::size_t level = 0; level <= max_depth; ++level) {arr[level] = 3 * (max_depth - level);}return arr;}() Bit shift per level.
-
static constexpr auto dilate8_table = make_dilate_table<SpatialKey, 8>()
Lookup table for dilating 8-bit spatial keys (256 entries), computed at compile time.
-
static constexpr auto dilate5_table = make_dilate_table<SpatialKey, 5>()
Lookup table for dilating 5-bit spatial keys (32 entries), computed at compile time
-
static constexpr auto dilate2_table = make_dilate_table<SpatialKey, 2>()
Lookup table for dilating 2-bit spatial keys (4 entries), computed at compile time
-
static constexpr std::array<SpatialKey, max_depth + 1> number_of_cells =
[]() constexpr {std::array<SpatialKey, max_depth + 1> a{};for (unsigned int i = 0; i <= max_depth; ++i)a[i] =SpatialKey(1) << 3 * i;return a;}() Number of cells as a function of depth level.
Friends
- friend struct OctreeTestAccess
-
struct IndexAndKey
- #include <octree.hpp>
Struct combining Z-order value and original point index.
Public Members
-
KeyContainer keys
Z-order values.
-
PointContainer indices
Indices of the corresponding points in cloud.
-
KeyContainer keys
-
using SpatialKey = std::uint32_t
-
template<typename T, unsigned int BITS>
-
void py4dgeo::compute_distances(EigenPointCloudConstRef, double, const Epoch&, const Epoch&, EigenNormalSetConstRef, double, double, DistanceVector&, UncertaintyVector&, const WorkingSetFinderCallback&, const DistanceUncertaintyCalculationCallback&)
Compute M3C2 distances.
-
void py4dgeo::compute_multiscale_directions(const Epoch&, EigenPointCloudConstRef, const std::vector<double>&, EigenNormalSetConstRef, EigenNormalSetRef, std::vector<double>&)
Compute M3C2 multi scale directions.
-
namespace py4dgeo
Typedefs
-
using EigenSpatiotemporalArray = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
The type to use for the spatiotemporal distance array.
-
using EigenSpatiotemporalArrayRef = Eigen::Ref<EigenSpatiotemporalArray>
-
using EigenSpatiotemporalArrayConstRef = Eigen::Ref<const EigenSpatiotemporalArray>
-
using EigenTimeSeries = Eigen::Vector<double, Eigen::Dynamic>
The type to use for a TimeSeries.
-
using EigenTimeSeriesRef = Eigen::Ref<EigenTimeSeries>
-
using EigenTimeSeriesConstRef = Eigen::Ref<const EigenTimeSeries>
-
using TimeseriesDistanceFunction = std::function<double(const TimeseriesDistanceFunctionData&)>
The signature to use for a distance function.
-
struct TimeseriesDistanceFunctionData
- #include <segmentation.hpp>
The data object passed to time series distance functions.
-
struct ObjectByChange
- #include <segmentation.hpp>
Basic data structure for 4D change object.
-
struct RegionGrowingSeed
-
struct RegionGrowingAlgorithmData
Public Members
-
EigenSpatiotemporalArrayConstRef distances
-
double radius
-
RegionGrowingSeed seed
-
std::vector<double> thresholds
-
std::size_t min_segments
-
std::size_t max_segments
-
EigenSpatiotemporalArrayConstRef distances
-
struct ChangePointDetectionData
-
using EigenSpatiotemporalArray = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
-
namespace py4dgeo
Typedefs
-
using Transformation = Eigen::Transform<double, 3, Eigen::Affine>
The type that used for affine transformations on point clouds.
-
class DisjointSet
- #include <registration.hpp>
Union/Find data structure
-
using Transformation = Eigen::Transform<double, 3, Eigen::Affine>
-
class CallbackExceptionVault
- #include <openmp.hpp>
A container to handle exceptions in parallel regions.
OpenMP does have limited support for C++ exceptions in parallel regions: Exceptions need to be catched on the same thread they have been thrown on. This class allows to store the first thrown exception to then rethrow it after we left the parallel region. This is a necessary construct to propagate exceptions from Python callbacks through the multithreaded C++ layer back to the calling Python scope. Inspiration is taken from: https://stackoverflow.com/questions/11828539/elegant-exceptionhandling-in-openmp
Public Functions
-
template<typename Function, typename ...Parameters>
inline void run(Function &&f, Parameters&&... parameters)
-
inline void rethrow() const
Private Members
-
std::exception_ptr ptr = nullptr
-
template<typename Function, typename ...Parameters>