48 #include "auxiliary.h"
50 #include <pcl/point_cloud.h>
51 #include <pcl/pcl_exports.h>
81 Data (
int id_x,
int id_y,
int id_z,
int lin_id,
void* user_data =
nullptr)
87 user_data_ (user_data)
89 n_[0] = n_[1] = n_[2] = p_[0] = p_[1] = p_[2] = 0.0f;
97 p_[0] += x; p_[1] += y; p_[2] += z;
104 if ( num_points_ < 2 )
107 aux::mult3 (p_, 1.0f/
static_cast<float> (num_points_));
112 addToNormal (
float x,
float y,
float z) { n_[0] += x; n_[1] += y; n_[2] += z;}
155 inline const std::set<Node*>&
159 float n_[3]{}, p_[3]{};
160 int id_x_{0}, id_y_{0}, id_z_{0}, lin_id_{0}, num_points_{0};
162 void *user_data_{
nullptr};
169 this->deleteChildren ();
174 setCenter(
const float *c) { center_[0] = c[0]; center_[1] = c[1]; center_[2] = c[2];}
177 setBounds(
const float *b) { bounds_[0] = b[0]; bounds_[1] = b[1]; bounds_[2] = b[2]; bounds_[3] = b[3]; bounds_[4] = b[4]; bounds_[5] = b[5];}
189 float v[3] = {0.5f*(bounds_[1]-bounds_[0]), 0.5f*(bounds_[3]-bounds_[2]), 0.5f*(bounds_[5]-bounds_[4])};
202 std::copy(bounds_, bounds_ + 6, b);
224 hasData (){
return static_cast<bool> (data_);}
255 if ( !this->getData () || !node->
getData () )
258 this->getData ()->insertNeighbor (node);
264 float center_[3]{}, bounds_[6]{}, radius_{0.0f};
265 Node *parent_{
nullptr}, *children_{
nullptr};
284 build (
const float* bounds,
float voxel_size);
294 if ( x < bounds_[0] || x > bounds_[1] ||
295 y < bounds_[2] || y > bounds_[3] ||
296 z < bounds_[4] || z > bounds_[5] )
306 for (
int l = 0 ; l < tree_levels_ ; ++l )
312 if ( x >= c[0] )
id |= 4;
313 if ( y >= c[1] )
id |= 2;
314 if ( z >= c[2] )
id |= 1;
322 static_cast<int> ((node->
getCenter ()[0] - bounds_[0])/voxel_size_),
323 static_cast<int> ((node->
getCenter ()[1] - bounds_[2])/voxel_size_),
324 static_cast<int> ((node->
getCenter ()[2] - bounds_[4])/voxel_size_),
325 static_cast<int> (full_leaves_.size ()));
328 this->insertNeighbors (node);
329 full_leaves_.push_back (node);
354 float offset = 0.5f*voxel_size_;
355 float p[3] = {bounds_[0] + offset +
static_cast<float> (i)*voxel_size_,
356 bounds_[2] + offset +
static_cast<float> (j)*voxel_size_,
357 bounds_[4] + offset +
static_cast<float> (k)*voxel_size_};
359 return (this->getLeaf (p[0], p[1], p[2]));
367 if ( x < bounds_[0] || x > bounds_[1] ||
368 y < bounds_[2] || y > bounds_[3] ||
369 z < bounds_[4] || z > bounds_[5] )
379 for (
int l = 0 ; l < tree_levels_ ; ++l )
387 if ( x >= c[0] )
id |= 4;
388 if ( y >= c[1] )
id |= 2;
389 if ( z >= c[2] )
id |= 1;
402 inline std::vector<ORROctree::Node*>&
405 inline const std::vector<ORROctree::Node*>&
426 std::copy(bounds_, bounds_ + 6, b);
436 float s = 0.5f*voxel_size_;
439 neigh = this->getLeaf (c[0]+s, c[1]+s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
440 neigh = this->getLeaf (c[0]+s, c[1]+s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
441 neigh = this->getLeaf (c[0]+s, c[1]+s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
442 neigh = this->getLeaf (c[0]+s, c[1] , c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
443 neigh = this->getLeaf (c[0]+s, c[1] , c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
444 neigh = this->getLeaf (c[0]+s, c[1] , c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
445 neigh = this->getLeaf (c[0]+s, c[1]-s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
446 neigh = this->getLeaf (c[0]+s, c[1]-s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
447 neigh = this->getLeaf (c[0]+s, c[1]-s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
449 neigh = this->getLeaf (c[0] , c[1]+s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
450 neigh = this->getLeaf (c[0] , c[1]+s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
451 neigh = this->getLeaf (c[0] , c[1]+s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
452 neigh = this->getLeaf (c[0] , c[1] , c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
454 neigh = this->getLeaf (c[0] , c[1] , c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
455 neigh = this->getLeaf (c[0] , c[1]-s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
456 neigh = this->getLeaf (c[0] , c[1]-s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
457 neigh = this->getLeaf (c[0] , c[1]-s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
459 neigh = this->getLeaf (c[0]-s, c[1]+s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
460 neigh = this->getLeaf (c[0]-s, c[1]+s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
461 neigh = this->getLeaf (c[0]-s, c[1]+s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
462 neigh = this->getLeaf (c[0]-s, c[1] , c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
463 neigh = this->getLeaf (c[0]-s, c[1] , c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
464 neigh = this->getLeaf (c[0]-s, c[1] , c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
465 neigh = this->getLeaf (c[0]-s, c[1]-s, c[2]+s);
if ( neigh ) node->
makeNeighbors (neigh);
466 neigh = this->getLeaf (c[0]-s, c[1]-s, c[2] );
if ( neigh ) node->
makeNeighbors (neigh);
467 neigh = this->getLeaf (c[0]-s, c[1]-s, c[2]-s);
if ( neigh ) node->
makeNeighbors (neigh);
471 float voxel_size_{-1.0}, bounds_[6];
472 int tree_levels_{-1};
void * getUserData() const
const float * getNormal() const
const std::set< Node * > & getNeighbors() const
void insertNeighbor(Node *node)
void addToPoint(float x, float y, float z)
void get3dId(int id[3]) const
std::set< Node * > neighbors_
Data(int id_x, int id_y, int id_z, int lin_id, void *user_data=nullptr)
void computeAveragePoint()
void setUserData(void *user_data)
void addToNormal(float x, float y, float z)
const float * getPoint() const
void setBounds(const float *b)
const float * getBounds() const
void setCenter(const float *c)
float getRadius() const
Computes the "radius" of the node which is half the diagonal length.
void getBounds(float b[6]) const
void setUserData(void *user_data)
void setParent(Node *parent)
void computeRadius()
Computes the "radius" of the node which is half the diagonal length.
const float * getCenter() const
const Node::Data * getData() const
void setData(Node::Data *data)
void makeNeighbors(Node *node)
Make this and 'node' neighbors by inserting each node in the others node neighbor set.
That's a very specialized and simple octree class.
void build(const PointCloudIn &points, float voxel_size, const PointCloudN *normals=nullptr, float enlarge_bounds=0.00001f)
Creates an octree which encloses 'points' and with leaf size equal to 'voxel_size'.
ORROctree::Node * getRoot()
void deleteBranch(Node *node)
Deletes the branch 'node' is part of.
ORROctree::Node * getLeaf(float x, float y, float z)
Returns a pointer to the leaf containing p = (x, y, z) or NULL if no such leaf exists.
void getNormalsOfFullLeaves(PointCloudN &out) const
const float * getBounds() const
void build(const float *bounds, float voxel_size)
Creates an empty octree with bounds at least as large as the ones provided as input and with leaf siz...
ORROctree::Node * createLeaf(float x, float y, float z)
Creates the leaf containing p = (x, y, z) and returns a pointer to it, however, only if p lies within...
const std::vector< ORROctree::Node * > & getFullLeaves() const
void getFullLeavesPoints(PointCloudOut &out) const
float getVoxelSize() const
void getFullLeavesIntersectedBySphere(const float *p, float radius, std::list< ORROctree::Node * > &out) const
This method returns a super set of the full leavess which are intersected by the sphere with radius '...
ORROctree::Node * getLeaf(int i, int j, int k)
Since the leaves are aligned in a rectilinear grid, each leaf has a unique id.
std::vector< ORROctree::Node * > & getFullLeaves()
Returns a vector with all octree leaves which contain at least one point.
void getBounds(float b[6]) const
void insertNeighbors(Node *node)
ORROctree::Node * getRandomFullLeafOnSphere(const float *p, float radius) const
Randomly chooses and returns a full leaf that is intersected by the sphere with center 'p' and 'radiu...
std::vector< Node * > full_leaves_
Defines all the PCL implemented PointT point type structures.
T length3(const T v[3])
Returns the length of v.
void mult3(T *v, T scalar)
v = scalar*v.