Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
10.7.x.x (relative to 10.7.1.3)
========

Features
--------

- KDTree : Added enclosedPoints method that takes list of half-spaces defined by origins and normals.

Fixes
-----

- SceneCacheFileFormat : Fixed `Unsupported Spec Type for </>` error when a scene cache is added as a sublayer of a live stage.

API
------------

- KDTree : Updated methods taking OutputIterator to take functors instead.

10.7.1.3 (relative to 10.7.1.2)
========

Expand Down
60 changes: 49 additions & 11 deletions include/IECore/KDTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

IECORE_PUSH_DEFAULT_VISIBILITY
#include "Imath/ImathVec.h"
#include "Imath/ImathBox.h"
IECORE_POP_DEFAULT_VISIBILITY

#include <set>
Expand All @@ -48,6 +49,15 @@ IECORE_POP_DEFAULT_VISIBILITY
namespace IECore
{

namespace Detail
{
// \todo - ugly machinery needed until we deprecate the old signature of enclosedPoints
template <typename, typename = void>
struct IsIterator : std::false_type {};
template <typename T>
struct IsIterator<T, std::void_t< typename std::iterator_traits<std::remove_cv_t<std::remove_reference_t<T>>>::iterator_category >> : std::true_type {};
}

/// The KDTree class provides accelerated searching of pointsets. It is
/// templated so that it can operate on a wide variety of datatypes, and uses
/// the VectorTraits.h and VectorOps.h functionality to assist in this.
Expand Down Expand Up @@ -93,22 +103,35 @@ class KDTree
/// \threading May be called by multiple concurrent threads.
PointIterator nearestNeighbour( const Point &p, BaseType &distSquared ) const;

/// Populates the passed vector of iterators with the neighbours of point p which are closer than radius r. Returns the number of points found.
/// \todo There should be a form where nearNeighbours is an output iterator, to allow any container to be filled.
/// See enclosedPoints for an example of this form.
/// \threading May be called by multiple concurrent threads provided they are each using a different vector for the result.
/// Call a functor for each neighbour of point p which is closer than radius r.
/// The functor must take a PointIterator.
template<typename F>
void nearestNeighbours( const Point &p, BaseType r, F &&functor ) const;
/// \deprecated - use the form above that takes a functor, rather than this version that populates a vector.
unsigned int nearestNeighbours( const Point &p, BaseType r, std::vector<PointIterator> &nearNeighbours ) const;

class Neighbour;
/// Populates the passed vector with the N closest neighbours to p, sorted with the closest first. Returns the number found.
/// \threading May be called by multiple concurrent threads provided they are each using a different vector for the result.
unsigned int nearestNNeighbours( const Point &p, unsigned int numNeighbours, std::vector<Neighbour> &nearNeighbours ) const;

/// Finds all the points contained by the specified bound, outputting them to the specified iterator.
/// Finds all the points contained by the specified bound, outputting them to the specified functor,
/// which must take a PointIterator.
/// \threading May be called by multiple concurrent threads.
template<typename Box, typename OutputIterator>
template<typename Box, typename F, std::enable_if_t< !Detail::IsIterator<F>::value, bool > = true>
void enclosedPoints( const Box &bound, F &&functor ) const;
/// \deprecated - use the form above that takes a functor ( once we get rid of this deprecated signature,
/// we can get rid of the ugly enable_if guard above ).
template<typename Box, typename OutputIterator, std::enable_if_t< Detail::IsIterator<OutputIterator>::value, bool > = true>
void enclosedPoints( const Box &bound, OutputIterator it ) const;

// Finds all the points contained within a set of half-spaces, passing them to the given
// functor which must take a PointIterator.
// A half-space is specified with an origin and a plane normal ( the normal points towards the region that
// is included )
template<typename F>
void enclosedPoints( const std::vector<Point> &normals, const std::vector<Point> &origins, F &&functor ) const;

/// Returns the number of nodes in the tree.
inline NodeIndex numNodes() const;
/// Returns the specified Node of the tree. See rootIndex(), lowChildIndex() and highChildIndex() for
Expand All @@ -132,15 +155,30 @@ class KDTree

class AxisSort;

unsigned char majorAxis( PermutationConstIterator permFirst, PermutationConstIterator permLast );
void build( NodeIndex nodeIndex, PermutationIterator permFirst, PermutationIterator permLast );
// -- Utilities used when building the tree --

// Compute min/max of a list of points
std::pair<Point,Point> bound( PermutationConstIterator permFirst, PermutationConstIterator permLast );
// Return which axis of the bounding box is largest
unsigned char majorAxis( const std::pair<Point,Point> &bound );
// Recursively build the tree
void build( NodeIndex nodeIndex, PermutationIterator permFirst, PermutationIterator permLast, int preComputedAxis = -1 );


// -- Walk functions that implement the recursive searches --

void nearestNeighbourWalk( NodeIndex nodeIndex, const Point &p, PointIterator &closestPoint, BaseType &distSquared ) const;

void nearestNeighboursWalk( NodeIndex nodeIndex, const Point &p, BaseType r2, std::vector<PointIterator> &nearNeighbours ) const;
template<typename F>
void nearestNeighboursWalk( NodeIndex nodeIndex, const Point &p, BaseType r2, F &&functor ) const;

template<typename Box, typename F>
void enclosedPointsWalk( NodeIndex nodeIndex, const Box &bound, F &&functor ) const;

struct HalfSpaceWorkingData;

template<typename Box, typename OutputIterator>
void enclosedPointsWalk( NodeIndex nodeIndex, const Box &bound, OutputIterator it ) const;
template<typename F>
void enclosedPointsHalfSpacesWalk( NodeIndex nodeIndex, std::vector<HalfSpaceWorkingData> &working, F &&functor ) const;

void nearestNNeighboursWalk( NodeIndex nodeIndex, const Point &p, unsigned int numNeighbours, std::vector<Neighbour> &nearNeighbours, BaseType &maxDistSquared ) const;

Expand Down
Loading