19 : m_root(nullptr), m_associatedCloud(nullptr), m_cellCount(0) {}
25 unsigned cloudsize = cloud->
size();
32 if (cloudsize == 0)
return false;
43 for (
unsigned i = 0; i < cloudsize; i++)
m_indexes[i] = i;
47 progressCb->
setInfo(
"Building KD-tree");
55 if (progressCb) progressCb->
stop();
91 static bool ComparisonX(
const unsigned &a,
const unsigned &b) {
97 static bool ComparisonY(
const unsigned &a,
const unsigned &b) {
111 unsigned &nbBuildCell,
114 if (!cell)
return nullptr;
117 unsigned dim = (father ==
nullptr ? 0 : ((father->
cuttingDim + 1) % 3));
133 cell->
leSon =
nullptr;
134 cell->
gSon =
nullptr;
149 unsigned split = (first + last) / 2;
157 if (cell->
leSon ==
nullptr) {
164 buildSubTree(split + 1, last, cell, nbBuildCell, progressCb);
165 if (cell->
gSon ==
nullptr) {
179 unsigned &nearestPointIndex,
180 ScalarType maxDist) {
181 if (
m_root ==
nullptr)
return false;
188 while (cellPtr->
leSon !=
nullptr || cellPtr->
gSon !=
nullptr) {
190 cellPtr = cellPtr->
leSon;
192 cellPtr = cellPtr->
gSon;
198 for (
unsigned i = 0; i < cellPtr->
nbPoints; i++) {
202 if (sqrdist < maxDist) {
203 maxDist =
static_cast<ScalarType
>(sqrdist);
211 while (cellPtr !=
nullptr) {
212 KdCell *prevPtr = cellPtr;
213 cellPtr = cellPtr->
father;
214 if (cellPtr !=
nullptr) {
216 if (sqrdist >= 0 && sqrdist * sqrdist < maxDist) {
218 (cellPtr->
leSon == prevPtr ? cellPtr->
gSon
223 nearestPointIndex = a;
246 while (cellPtr->
leSon !=
nullptr || cellPtr->
gSon !=
nullptr) {
248 cellPtr = cellPtr->
leSon;
250 cellPtr = cellPtr->
gSon;
252 if (
nullptr == cellPtr) {
260 for (
unsigned i = 0; i < cellPtr->
nbPoints; i++) {
268 while (cellPtr !=
nullptr) {
269 KdCell *prevPtr = cellPtr;
270 cellPtr = cellPtr->
father;
271 if (cellPtr !=
nullptr) {
273 if (sqrdist >= 0 && sqrdist * sqrdist < maxDist) {
275 (cellPtr->
leSon == prevPtr ? cellPtr->
gSon
290 ScalarType tolerance,
291 std::vector<unsigned> &pointndexes) {
298 return static_cast<unsigned>(pointndexes.size());
302 ScalarType maxDist) {
303 if (
m_root ==
nullptr)
return false;
310 while (!(cellPtr->
leSon ==
nullptr && cellPtr->
gSon ==
nullptr)) {
312 cellPtr = cellPtr->
leSon;
314 cellPtr = cellPtr->
gSon;
319 for (
unsigned i = 0; i < cellPtr->
nbPoints; i++) {
327 while (cellPtr !=
nullptr) {
328 KdCell *prevPtr = cellPtr;
329 cellPtr = cellPtr->
father;
330 if (cellPtr !=
nullptr) {
332 if (sqrdist >= 0 && sqrdist * sqrdist < maxDist) {
334 (cellPtr->
leSon == prevPtr ? cellPtr->
gSon
350 ScalarType tolerance,
351 std::vector<unsigned> &
points) {
352 if (
m_root ==
nullptr)
return 0;
356 return static_cast<unsigned>(
points.size());
360 if (cell->
leSon !=
nullptr && cell->
gSon !=
nullptr) {
377 for (
unsigned i = 1; i < cell->
nbPoints; i++) {
391 if (cell->
father ==
nullptr) {
394 unsigned char bound = 1;
443 return static_cast<ScalarType
>(dx * dx + dy * dy + dz * dz);
459 max =
static_cast<ScalarType
>(sqrt(dx * dx + dy * dy + dz * dz));
492 if (dx < 0 && dy < 0 && dz < 0)
return -1;
495 if (dx < 0) dx =
max;
496 if (dy < 0) dy =
max;
497 if (dz < 0) dz =
max;
503 ScalarType &maxSqrDist,
507 if (cell->
leSon ==
nullptr && cell->
gSon ==
nullptr) {
509 for (
unsigned i = 0; i < cell->
nbPoints; i++) {
513 if (
dist < maxSqrDist) {
515 maxSqrDist =
static_cast<ScalarType
>(
dist);
523 if (b >= 0)
return b;
529 ScalarType &maxSqrDist,
533 if (cell->
leSon ==
nullptr && cell->
gSon ==
nullptr) {
534 for (
unsigned i = 0; i < cell->
nbPoints; i++) {
538 if (
dist < maxSqrDist)
return true;
553 ScalarType tolerance,
555 std::vector<unsigned> &localArray) {
560 if ((
min <= distance + tolerance) && (
max >= distance - tolerance)) {
561 if ((cell->
leSon !=
nullptr) && (cell->
gSon !=
nullptr)) {
567 for (
unsigned i = 0; i < cell->
nbPoints; i++) {
572 if (distance - tolerance <=
dist &&
573 dist <= distance + tolerance)
574 localArray.push_back(
static bool ComparisonX(const unsigned &a, const unsigned &b)
Compares X coordinates of two points designated by their index.
static cloudViewer::GenericIndexedCloud * s_comparisonCloud
static bool ComparisonY(const unsigned &a, const unsigned &b)
Compares Y coordinates of two points designated by their index.
static bool ComparisonZ(const unsigned &a, const unsigned &b)
Compares Z coordinates of two points designated by their index.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static PointCoordinateType vdistance(const PointCoordinateType p[], const PointCoordinateType q[])
static PointCoordinateType vdistance2(const PointCoordinateType p[], const PointCoordinateType q[])
virtual unsigned size() const =0
Returns the number of points.
A generic 3D point cloud with index-based point access.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
virtual void stop()=0
Notifies the fact that the process has ended.
virtual void setInfo(const char *infoStr)=0
Notifies some information about the ongoing process.
virtual bool textCanBeEdited() const
Returns whether the dialog title and info can be updated or not.
virtual void update(float percent)=0
Notifies the algorithm progress.
void deleteSubTree(KdCell *cell)
Deletes a sub tree.
virtual ~KDTree()
Destructor.
std::vector< unsigned > m_indexes
Point indexes.
void updateOutsideBoundingBox(KdCell *cell)
unsigned findPointsLyingToDistance(const PointCoordinateType *queryPoint, ScalarType distance, ScalarType tolerance, std::vector< unsigned > &points)
KDTree()
Default constructor.
GenericIndexedCloud * m_associatedCloud
Associated cloud.
unsigned m_cellCount
Number of cells.
void pointToCellDistances(const PointCoordinateType *queryPoint, KdCell *cell, ScalarType &min, ScalarType &max)
bool findNearestNeighbour(const PointCoordinateType *queryPoint, unsigned &nearestPointIndex, ScalarType maxDist)
Nearest point search.
ScalarType pointToCellSquareDistance(const PointCoordinateType *queryPoint, KdCell *cell)
Computes the distance between a point and a cell inside bounding box.
ScalarType insidePointToCellDistance(const PointCoordinateType *queryPoint, KdCell *cell)
int checkNearerPointInSubTree(const PointCoordinateType *queryPoint, ScalarType &maxSqrDist, KdCell *cell)
void updateInsideBoundingBox(KdCell *cell)
bool findPointBelowDistance(const PointCoordinateType *queryPoint, ScalarType maxDist)
Optimized version of nearest point search method.
KdCell * buildSubTree(unsigned first, unsigned last, KdCell *father, unsigned &nbBuildCell, GenericProgressCallback *progressCb=nullptr)
Builds a sub tree.
KdCell * m_root
Tree root.
unsigned radiusSearch(const PointCoordinateType *queryPoint, ScalarType distance, ScalarType tolerance, std::vector< unsigned > &pointndexes)
void distanceScanTree(const PointCoordinateType *queryPoint, ScalarType distance, ScalarType tolerance, KdCell *cell, std::vector< unsigned > &localArray)
bool findNearestNeighbourWithMaxDist(const PointCoordinateType *queryPoint, ScalarType maxDist)
Optimized version of findNearestNeighbour with a maximum distance.
bool checkDistantPointInSubTree(const PointCoordinateType *queryPoint, ScalarType &maxSqrDist, KdCell *cell)
bool buildFromCloud(GenericIndexedCloud *cloud, GenericProgressCallback *progressCb=nullptr)
Builds the KD-tree.
__host__ __device__ int2 abs(int2 v)
static double dist(double x1, double y1, double x2, double y2)
Generic file read and write utility for python interface.
CCVector3 outbbmin
Outside bounding box min point.
PointCoordinateType cuttingCoordinate
Place where the space is cut into two sub-spaces (children)
unsigned char boundsMask
Mask to know if the outside box is bounded for a given dimmension.
struct KdCell * father
To go up in the tree.
CCVector3 inbbmin
Inside bounding box min point.
CCVector3 outbbmax
Outside bounding box max point.
CCVector3 inbbmax
Inside bounding box max point.
unsigned nbPoints
Number of elements in this cell.
unsigned startingPointIndex
Index of the first element that belongs to this cell.