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();
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;
428 dx = std::min(std::abs(queryPoint[0] - cell->
inbbmin.
x),
429 std::abs(queryPoint[0] - cell->
inbbmax.
x));
434 dy = std::min(std::abs(queryPoint[1] - cell->
inbbmin.
y),
435 std::abs(queryPoint[1] - cell->
inbbmax.
y));
440 dz = std::min(std::abs(queryPoint[2] - cell->
inbbmin.
z),
441 std::abs(queryPoint[2] - cell->
inbbmax.
z));
443 return static_cast<ScalarType
>(dx * dx + dy * dy + dz * dz);
453 dx = std::max(std::abs(queryPoint[0] - cell->
inbbmin.
x),
454 std::abs(queryPoint[0] - cell->
inbbmax.
x));
455 dy = std::max(std::abs(queryPoint[1] - cell->
inbbmin.
y),
456 std::abs(queryPoint[1] - cell->
inbbmax.
y));
457 dz = std::max(std::abs(queryPoint[2] - cell->
inbbmin.
z),
458 std::abs(queryPoint[2] - cell->
inbbmax.
z));
459 max =
static_cast<ScalarType
>(sqrt(dx * dx + dy * dy + dz * dz));
469 dx = std::min(std::abs(queryPoint[0] - cell->
outbbmin.
x),
470 std::abs(queryPoint[0] - cell->
outbbmax.
x));
472 dx = std::abs(queryPoint[0] - cell->
outbbmin.
x);
474 dx = std::abs(queryPoint[0] - cell->
outbbmax.
x);
477 dy = std::min(std::abs(queryPoint[1] - cell->
outbbmin.
y),
478 std::abs(queryPoint[1] - cell->
outbbmax.
y));
480 dy = std::abs(queryPoint[1] - cell->
outbbmin.
y);
482 dy = std::abs(queryPoint[1] - cell->
outbbmax.
y);
485 dz = std::min(std::abs(queryPoint[2] - cell->
outbbmin.
z),
486 std::abs(queryPoint[2] - cell->
outbbmax.
z));
488 dz = std::abs(queryPoint[2] - cell->
outbbmin.
z);
490 dz = std::abs(queryPoint[2] - cell->
outbbmax.
z);
492 if (dx < 0 && dy < 0 && dz < 0)
return -1;
494 max = std::max(dx, std::max(dy, dz));
495 if (dx < 0) dx = max;
496 if (dy < 0) dy = max;
497 if (dz < 0) dz = max;
499 return static_cast<ScalarType
>(std::min(dx, std::min(dy, dz)));
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) {
561 if ((cell->
leSon !=
nullptr) && (cell->
gSon !=
nullptr)) {
567 for (
unsigned i = 0; i < cell->
nbPoints; i++) {
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.
static double distance(T *pot1, T *pot2)
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.