From 575720c65043b01c24e0a29685d6a5ecc873fae2 Mon Sep 17 00:00:00 2001 From: Sergey Alexandrov Date: Sun, 19 Jan 2014 18:13:13 +0100 Subject: [PATCH 1/3] Fix a bug in `OctreePointCloudAdjacency::computeNeighbors()` The `x`, `y`, and `z` fields of `OctreeKey` are unsigned integers, so in some cases unsigned integer underflow occurs and the tree is queried for non-existing leaves with huge keys. Due to the way `findLeaf()` is implemented, such queries occasionally succeed and return some random leaves. --- .../octree/impl/octree_pointcloud_adjacency.hpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp b/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp index 8d84f627b00..f9ba3d39c68 100644 --- a/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp +++ b/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp @@ -184,13 +184,22 @@ pcl::octree::OctreePointCloudAdjacency for (int dx = -1; dx <= 1; ++dx) { + int x = dx + key_arg.x; + if (x < 0 || x > this->max_key_.x) + continue; + neighbor_key.x = static_cast (x); for (int dy = -1; dy <= 1; ++dy) { + int y = dy + key_arg.y; + if (y < 0 || y > this->max_key_.y) + continue; + neighbor_key.y = static_cast (y); for (int dz = -1; dz <= 1; ++dz) { - neighbor_key.x = key_arg.x + dx; - neighbor_key.y = key_arg.y + dy; - neighbor_key.z = key_arg.z + dz; + int z = dz + key_arg.z; + if (z < 0 || z > this->max_key_.z) + continue; + neighbor_key.z = static_cast (z); LeafContainerT *neighbor = this->findLeaf (neighbor_key); if (neighbor) { From 6846e421795bb1f6b7a5b58401b0b412006321ca Mon Sep 17 00:00:00 2001 From: Jeremie Papon Date: Mon, 20 Jan 2014 11:14:14 +0100 Subject: [PATCH 2/3] Updated the fix for compute neighbors octree key bug --- .../impl/octree_pointcloud_adjacency.hpp | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp b/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp index f9ba3d39c68..2c4f0839aad 100644 --- a/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp +++ b/octree/include/pcl/octree/impl/octree_pointcloud_adjacency.hpp @@ -179,27 +179,30 @@ pcl::octree::OctreePointCloudAdjacency template void pcl::octree::OctreePointCloudAdjacency::computeNeighbors (OctreeKey &key_arg, LeafContainerT* leaf_container) { + //Make sure requested key is valid + if (key_arg.x > this->max_key_.x || key_arg.y > this->max_key_.y || key_arg.z > this->max_key_.z) + { + PCL_ERROR ("OctreePointCloudAdjacency::computeNeighbors Requested neighbors for invalid octree key\n"); + return; + } OctreeKey neighbor_key; - - for (int dx = -1; dx <= 1; ++dx) + int dx_min = (key_arg.x > 0) ? -1 : 0; + int dy_min = (key_arg.y > 0) ? -1 : 0; + int dz_min = (key_arg.z > 0) ? -1 : 0; + int dx_max = (key_arg.x == this->max_key_.x) ? 0 : 1; + int dy_max = (key_arg.y == this->max_key_.y) ? 0 : 1; + int dz_max = (key_arg.z == this->max_key_.z) ? 0 : 1; + + for (int dx = dx_min; dx <= dx_max; ++dx) { - int x = dx + key_arg.x; - if (x < 0 || x > this->max_key_.x) - continue; - neighbor_key.x = static_cast (x); - for (int dy = -1; dy <= 1; ++dy) + for (int dy = dy_min; dy <= dy_max; ++dy) { - int y = dy + key_arg.y; - if (y < 0 || y > this->max_key_.y) - continue; - neighbor_key.y = static_cast (y); - for (int dz = -1; dz <= 1; ++dz) + for (int dz = dz_min; dz <= dz_max; ++dz) { - int z = dz + key_arg.z; - if (z < 0 || z > this->max_key_.z) - continue; - neighbor_key.z = static_cast (z); + neighbor_key.x = static_cast (key_arg.x + dx); + neighbor_key.y = static_cast (key_arg.y + dy); + neighbor_key.z = static_cast (key_arg.z + dz); LeafContainerT *neighbor = this->findLeaf (neighbor_key); if (neighbor) { From fbb1195d26c540ec23885e290248804f3354be68 Mon Sep 17 00:00:00 2001 From: Jeremie Papon Date: Mon, 20 Jan 2014 13:10:58 +0100 Subject: [PATCH 3/3] Added header for PCL_ERROR macro --- octree/include/pcl/octree/octree_pointcloud_adjacency.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/octree/include/pcl/octree/octree_pointcloud_adjacency.h b/octree/include/pcl/octree/octree_pointcloud_adjacency.h index 69b821623a0..b54f664abe2 100644 --- a/octree/include/pcl/octree/octree_pointcloud_adjacency.h +++ b/octree/include/pcl/octree/octree_pointcloud_adjacency.h @@ -40,6 +40,7 @@ #ifndef PCL_OCTREE_POINTCLOUD_ADJACENCY_H_ #define PCL_OCTREE_POINTCLOUD_ADJACENCY_H_ +#include #include #include #include @@ -53,8 +54,6 @@ //DEBUG TODO REMOVE #include - - namespace pcl {