40 #include <pcl/common/point_tests.h>
41 #include <pcl/console/print.h>
50 #include <pcl/octree/impl/octree_pointcloud.hpp>
53 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
59 OctreeBase<LeafContainerT, BranchContainerT>>(resolution_arg)
63 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
69 float minX = std::numeric_limits<float>::max(),
70 minY = std::numeric_limits<float>::max(),
71 minZ = std::numeric_limits<float>::max();
72 float maxX = -std::numeric_limits<float>::max(),
73 maxY = -std::numeric_limits<float>::max(),
74 maxZ = -std::numeric_limits<float>::max();
76 for (std::size_t i = 0; i < input_->size(); ++i) {
79 transform_func_(temp);
96 this->defineBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
100 leaf_vector_.reserve(this->getLeafCount());
101 for (
auto leaf_itr = this->leaf_depth_begin(); leaf_itr != this->leaf_depth_end();
103 OctreeKey leaf_key = leaf_itr.getCurrentOctreeKey();
104 LeafContainerT* leaf_container = &(leaf_itr.getLeafContainer());
107 leaf_container->computeData();
109 computeNeighbors(leaf_key, leaf_container);
111 leaf_vector_.push_back(leaf_container);
114 assert(leaf_vector_.size() == this->getLeafCount());
118 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
123 if (transform_func_) {
125 transform_func_(temp);
130 key_arg.
x =
static_cast<uindex_t>((temp.x - this->min_x_) / this->resolution_);
131 key_arg.
y =
static_cast<uindex_t>((temp.y - this->min_y_) / this->resolution_);
132 key_arg.
z =
static_cast<uindex_t>((temp.z - this->min_z_) / this->resolution_);
140 key_arg.
x =
static_cast<uindex_t>((point_arg.x - this->min_x_) / this->resolution_);
141 key_arg.
y =
static_cast<uindex_t>((point_arg.y - this->min_y_) / this->resolution_);
142 key_arg.
z =
static_cast<uindex_t>((point_arg.z - this->min_z_) / this->resolution_);
147 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
154 assert(pointIdx_arg < this->input_->size());
156 const PointT& point = (*this->input_)[pointIdx_arg];
161 this->genOctreeKeyforPoint(point, key);
163 LeafContainerT* container = this->createLeaf(key);
164 container->addPoint(point);
168 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
174 if (key_arg.
x > this->max_key_.x || key_arg.
y > this->max_key_.y ||
175 key_arg.
z > this->max_key_.z) {
176 PCL_ERROR(
"OctreePointCloudAdjacency::computeNeighbors Requested neighbors for "
177 "invalid octree key\n");
182 int dx_min = (key_arg.
x > 0) ? -1 : 0;
183 int dy_min = (key_arg.
y > 0) ? -1 : 0;
184 int dz_min = (key_arg.
z > 0) ? -1 : 0;
185 int dx_max = (key_arg.
x == this->max_key_.x) ? 0 : 1;
186 int dy_max = (key_arg.
y == this->max_key_.y) ? 0 : 1;
187 int dz_max = (key_arg.
z == this->max_key_.z) ? 0 : 1;
189 for (
int dx = dx_min; dx <= dx_max; ++dx) {
190 for (
int dy = dy_min; dy <= dy_max; ++dy) {
191 for (
int dz = dz_min; dz <= dz_max; ++dz) {
192 neighbor_key.
x =
static_cast<std::uint32_t
>(key_arg.
x + dx);
193 neighbor_key.
y =
static_cast<std::uint32_t
>(key_arg.
y + dy);
194 neighbor_key.
z =
static_cast<std::uint32_t
>(key_arg.
z + dz);
195 LeafContainerT* neighbor = this->findLeaf(neighbor_key);
197 leaf_container->addNeighbor(neighbor);
205 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
211 LeafContainerT* leaf =
nullptr;
213 this->genOctreeKeyforPoint(point_arg, key);
215 leaf = this->findLeaf(key);
221 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
228 voxel_adjacency_graph.clear();
230 std::map<LeafContainerT*, VoxelID> leaf_vertex_id_map;
232 this->leaf_depth_begin();
233 leaf_itr != this->leaf_depth_end();
235 OctreeKey leaf_key = leaf_itr.getCurrentOctreeKey();
237 this->genLeafNodeCenterFromOctreeKey(leaf_key, centroid_point);
238 VoxelID node_id = add_vertex(voxel_adjacency_graph);
240 voxel_adjacency_graph[node_id] = centroid_point;
241 LeafContainerT* leaf_container = &(leaf_itr.getLeafContainer());
242 leaf_vertex_id_map[leaf_container] = node_id;
246 for (
auto leaf_itr = leaf_vector_.begin(); leaf_itr != leaf_vector_.end();
248 VoxelID u = (leaf_vertex_id_map.find(*leaf_itr))->second;
249 PointT p_u = voxel_adjacency_graph[u];
250 for (
auto neighbor_itr = (*leaf_itr)->cbegin(), neighbor_end = (*leaf_itr)->cend();
251 neighbor_itr != neighbor_end;
253 LeafContainerT* neighbor_container = *neighbor_itr;
256 VoxelID v = (leaf_vertex_id_map.find(neighbor_container))->second;
257 boost::tie(edge, edge_added) = add_edge(u, v, voxel_adjacency_graph);
259 PointT p_v = voxel_adjacency_graph[v];
260 float dist = (p_v.getVector3fMap() - p_u.getVector3fMap()).norm();
261 voxel_adjacency_graph[edge] = dist;
267 template <
typename Po
intT,
typename LeafContainerT,
typename BranchContainerT>
273 this->genOctreeKeyforPoint(point_arg, key);
275 Eigen::Vector3f sensor(camera_pos.x, camera_pos.y, camera_pos.z);
277 Eigen::Vector3f leaf_centroid(
278 static_cast<float>((
static_cast<double>(key.
x) + 0.5f) * this->resolution_ +
280 static_cast<float>((
static_cast<double>(key.
y) + 0.5f) * this->resolution_ +
282 static_cast<float>((
static_cast<double>(key.
z) + 0.5f) * this->resolution_ +
284 Eigen::Vector3f direction = sensor - leaf_centroid;
286 float norm = direction.norm();
287 direction.normalize();
288 float precision = 1.0f;
289 const float step_size =
static_cast<const float>(resolution_) * precision;
290 const auto nsteps = std::max<std::size_t>(1, norm / step_size);
294 Eigen::Vector3f p = leaf_centroid;
296 for (std::size_t i = 0; i < nsteps; ++i) {
298 p += (direction * step_size);
305 this->genOctreeKeyforPoint(octree_p, key);
308 if ((key == prev_key))
313 LeafContainerT* leaf = this->findLeaf(key);
324 #define PCL_INSTANTIATE_OctreePointCloudAdjacency(T) \
325 template class PCL_EXPORTS pcl::octree::OctreePointCloudAdjacency<T>;
Octree leaf node iterator class.
typename VoxelAdjacencyList::vertex_descriptor VoxelID
void genOctreeKeyforPoint(const PointT &point_arg, OctreeKey &key_arg) const
Generates octree key for specified point (uses transform if provided).
bool testForOcclusion(const PointT &point_arg, const PointXYZ &camera_pos=PointXYZ(0, 0, 0))
Tests whether input point is occluded from specified camera point by other voxels.
void computeVoxelAdjacencyGraph(VoxelAdjacencyList &voxel_adjacency_graph)
Computes an adjacency graph of voxel relations.
LeafContainerT * getLeafContainerAtPoint(const PointT &point_arg) const
Gets the leaf container for a given point.
void addPointsFromInputCloud()
Adds points from cloud to the octree.
typename VoxelAdjacencyList::edge_descriptor EdgeID
void addPointIdx(uindex_t point_idx_arg) override
Add point at index from input pointcloud dataset to octree.
void computeNeighbors(OctreeKey &key_arg, LeafContainerT *leaf_container)
Fills in the neighbors fields for new voxels.
OctreePointCloudAdjacency(const double resolution_arg)
Constructor.
boost::adjacency_list< boost::setS, boost::setS, boost::undirectedS, PointT, float > VoxelAdjacencyList
void addPointsFromInputCloud()
Add points from input point cloud to octree.
detail::int_type_t< detail::index_type_size, false > uindex_t
Type used for an unsigned index in PCL.
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
A point structure representing Euclidean xyz coordinates.
A point structure representing Euclidean xyz coordinates, and the RGB color.