/usr/include/octomap/OcTreeBaseImpl.h is in liboctomap-dev 1.6.8+dfsg-2.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | /*
* OctoMap - An Efficient Probabilistic 3D Mapping Framework Based on Octrees
* http://octomap.github.com/
*
* Copyright (c) 2009-2013, K.M. Wurm and A. Hornung, University of Freiburg
* All rights reserved.
* License: New BSD
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the University of Freiburg nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OCTOMAP_OCTREE_BASE_IMPL_H
#define OCTOMAP_OCTREE_BASE_IMPL_H
#include <list>
#include <limits>
#include <iterator>
#include <stack>
#include "octomap_types.h"
#include "OcTreeKey.h"
#include "ScanGraph.h"
namespace octomap {
/**
* OcTree base class, to be used with with any kind of OcTreeDataNode.
*
* This tree implementation currently has a maximum depth of 16
* nodes. For this reason, coordinates values have to be, e.g.,
* below +/- 327.68 meters (2^15) at a maximum resolution of 0.01m.
*
* This limitation enables the use of an efficient key generation
* method which uses the binary representation of the data point
* coordinates.
*
* \note You should probably not use this class directly, but
* OcTreeBase or OccupancyOcTreeBase instead
*
* \tparam NODE Node class to be used in tree (usually derived from
* OcTreeDataNode)
* \tparam INTERFACE Interface to be derived from, should be either
* AbstractOcTree or AbstractOccupancyOcTree
*/
template <class NODE,class INTERFACE>
class OcTreeBaseImpl : public INTERFACE {
public:
/// Make the templated NODE type available from the outside
typedef NODE NodeType;
// the actual iterator implementation is included here
// as a member from this file
#include <octomap/OcTreeIterator.hxx>
OcTreeBaseImpl(double resolution);
virtual ~OcTreeBaseImpl();
/// Deep copy constructor
OcTreeBaseImpl(const OcTreeBaseImpl<NODE,INTERFACE>& rhs);
/**
* Swap contents of two octrees, i.e., only the underlying
* pointer / tree structure. You have to ensure yourself that the
* metadata (resolution etc) matches. No memory is cleared
* in this function
*/
void swapContent(OcTreeBaseImpl<NODE,INTERFACE>& rhs);
/// Comparison between two octrees, all meta data, all
/// nodes, and the structure must be identical
bool operator== (const OcTreeBaseImpl<NODE,INTERFACE>& rhs) const;
std::string getTreeType() const {return "OcTreeBaseImpl";}
/// Change the resolution of the octree, scaling all voxels.
/// This will not preserve the (metric) scale!
void setResolution(double r);
inline double getResolution() const { return resolution; }
inline unsigned int getTreeDepth () const { return tree_depth; }
inline double getNodeSize(unsigned depth) const {assert(depth <= tree_depth); return sizeLookupTable[depth];}
/**
* \return Pointer to the root node of the tree. This pointer
* should not be modified or deleted externally, the OcTree
* manages its memory itself. In an empty tree, root is NULL.
*/
inline NODE* getRoot() const { return root; }
/**
* Search node at specified depth given a 3d point (depth=0: search full tree depth).
* You need to check if the returned node is NULL, since it can be in unknown space.
* @return pointer to node if found, NULL otherwise
*/
NODE* search(double x, double y, double z, unsigned int depth = 0) const;
/**
* Search node at specified depth given a 3d point (depth=0: search full tree depth)
* You need to check if the returned node is NULL, since it can be in unknown space.
* @return pointer to node if found, NULL otherwise
*/
NODE* search(const point3d& value, unsigned int depth = 0) const;
/**
* Search a node at specified depth given an addressing key (depth=0: search full tree depth)
* You need to check if the returned node is NULL, since it can be in unknown space.
* @return pointer to node if found, NULL otherwise
*/
NODE* search(const OcTreeKey& key, unsigned int depth = 0) const;
/**
* Delete a node (if exists) given a 3d point. Will always
* delete at the lowest level unless depth !=0, and expand pruned inner nodes as needed.
* Pruned nodes at level "depth" will directly be deleted as a whole.
*/
bool deleteNode(double x, double y, double z, unsigned int depth = 0);
/**
* Delete a node (if exists) given a 3d point. Will always
* delete at the lowest level unless depth !=0, and expand pruned inner nodes as needed.
* Pruned nodes at level "depth" will directly be deleted as a whole.
*/
bool deleteNode(const point3d& value, unsigned int depth = 0);
/**
* Delete a node (if exists) given an addressing key. Will always
* delete at the lowest level unless depth !=0, and expand pruned inner nodes as needed.
* Pruned nodes at level "depth" will directly be deleted as a whole.
*/
bool deleteNode(const OcTreeKey& key, unsigned int depth = 0);
/// Deletes the complete tree structure
void clear();
/**
* Lossless compression of the octree: A node will replace all of its eight
* children if they have identical values. You usually don't have to call
* prune() after a regular occupancy update, updateNode() incrementally
* prunes all affected nodes.
*/
virtual void prune();
/// Expands all pruned nodes (reverse of prune())
/// \note This is an expensive operation, especially when the tree is nearly empty!
virtual void expand();
// -- statistics ----------------------
/// \return The number of nodes in the tree
virtual inline size_t size() const { return tree_size; }
/// \return Memory usage of the complete octree in bytes (may vary between architectures)
virtual size_t memoryUsage() const;
/// \return Memory usage of a single octree node
virtual inline size_t memoryUsageNode() const {return sizeof(NODE); };
/// \return Memory usage of a full grid of the same size as the OcTree in bytes (for comparison)
/// \note this can be larger than the adressable memory - size_t may not be enough to hold it!
unsigned long long memoryFullGrid() const;
double volume();
/// Size of OcTree (all known space) in meters for x, y and z dimension
virtual void getMetricSize(double& x, double& y, double& z);
/// Size of OcTree (all known space) in meters for x, y and z dimension
virtual void getMetricSize(double& x, double& y, double& z) const;
/// minimum value of the bounding box of all known space in x, y, z
virtual void getMetricMin(double& x, double& y, double& z);
/// minimum value of the bounding box of all known space in x, y, z
void getMetricMin(double& x, double& y, double& z) const;
/// maximum value of the bounding box of all known space in x, y, z
virtual void getMetricMax(double& x, double& y, double& z);
/// maximum value of the bounding box of all known space in x, y, z
void getMetricMax(double& x, double& y, double& z) const;
/// Traverses the tree to calculate the total number of nodes
size_t calcNumNodes() const;
/// Traverses the tree to calculate the total number of leaf nodes
size_t getNumLeafNodes() const;
// -- access tree nodes ------------------
/// return centers of leafs that do NOT exist (but could) in a given bounding box
void getUnknownLeafCenters(point3d_list& node_centers, point3d pmin, point3d pmax) const;
// -- raytracing -----------------------
/**
* Traces a ray from origin to end (excluding), returning an
* OcTreeKey of all nodes traversed by the beam. You still need to check
* if a node at that coordinate exists (e.g. with search()).
*
* @param origin start coordinate of ray
* @param end end coordinate of ray
* @param ray KeyRay structure that holds the keys of all nodes traversed by the ray, excluding "end"
* @return Success of operation. Returning false usually means that one of the coordinates is out of the OcTree's range
*/
bool computeRayKeys(const point3d& origin, const point3d& end, KeyRay& ray) const;
/**
* Traces a ray from origin to end (excluding), returning the
* coordinates of all nodes traversed by the beam. You still need to check
* if a node at that coordinate exists (e.g. with search()).
* @note: use the faster computeRayKeys method if possible.
*
* @param origin start coordinate of ray
* @param end end coordinate of ray
* @param ray KeyRay structure that holds the keys of all nodes traversed by the ray, excluding "end"
* @return Success of operation. Returning false usually means that one of the coordinates is out of the OcTree's range
*/
bool computeRay(const point3d& origin, const point3d& end, std::vector<point3d>& ray);
// file IO
/**
* Read all nodes from the input stream (without file header),
* for this the tree needs to be already created.
* For general file IO, you
* should probably use AbstractOcTree::read() instead.
*/
std::istream& readData(std::istream &s);
/// Write complete state of tree to stream (without file header) unmodified.
/// Pruning the tree first produces smaller files (lossless compression)
std::ostream& writeData(std::ostream &s) const;
class leaf_iterator;
class tree_iterator;
class leaf_bbx_iterator;
typedef leaf_iterator iterator;
/// @return beginning of the tree as leaf iterator
iterator begin(unsigned char maxDepth=0) const {return iterator(this, maxDepth);};
/// @return end of the tree as leaf iterator
const iterator end() const {return leaf_iterator_end;}; // TODO: RVE?
/// @return beginning of the tree as leaf iterator
leaf_iterator begin_leafs(unsigned char maxDepth=0) const {return leaf_iterator(this, maxDepth);};
/// @return end of the tree as leaf iterator
const leaf_iterator end_leafs() const {return leaf_iterator_end;}
/// @return beginning of the tree as leaf iterator in a bounding box
leaf_bbx_iterator begin_leafs_bbx(const OcTreeKey& min, const OcTreeKey& max, unsigned char maxDepth=0) const {
return leaf_bbx_iterator(this, min, max, maxDepth);
}
/// @return beginning of the tree as leaf iterator in a bounding box
leaf_bbx_iterator begin_leafs_bbx(const point3d& min, const point3d& max, unsigned char maxDepth=0) const {
return leaf_bbx_iterator(this, min, max, maxDepth);
}
/// @return end of the tree as leaf iterator in a bounding box
const leaf_bbx_iterator end_leafs_bbx() const {return leaf_iterator_bbx_end;}
/// @return beginning of the tree as iterator to all nodes (incl. inner)
tree_iterator begin_tree(unsigned char maxDepth=0) const {return tree_iterator(this, maxDepth);}
/// @return end of the tree as iterator to all nodes (incl. inner)
const tree_iterator end_tree() const {return tree_iterator_end;}
//
// Key / coordinate conversion functions
//
/// Converts from a single coordinate into a discrete key
inline unsigned short int coordToKey(double coordinate) const{
return ((int) floor(resolution_factor * coordinate)) + tree_max_val;
}
/// Converts from a single coordinate into a discrete key at a given depth
unsigned short int coordToKey(double coordinate, unsigned depth) const;
/// Converts from a 3D coordinate into a 3D addressing key
inline OcTreeKey coordToKey(const point3d& coord) const{
return OcTreeKey(coordToKey(coord(0)), coordToKey(coord(1)), coordToKey(coord(2)));
}
/// Converts from a 3D coordinate into a 3D addressing key
inline OcTreeKey coordToKey(double x, double y, double z) const{
return OcTreeKey(coordToKey(x), coordToKey(y), coordToKey(z));
}
/// Converts from a 3D coordinate into a 3D addressing key at a given depth
inline OcTreeKey coordToKey(const point3d& coord, unsigned depth) const{
if (depth == tree_depth)
return coordToKey(coord);
else
return OcTreeKey(coordToKey(coord(0), depth), coordToKey(coord(1), depth), coordToKey(coord(2), depth));
}
/// Converts from a 3D coordinate into a 3D addressing key at a given depth
inline OcTreeKey coordToKey(double x, double y, double z, unsigned depth) const{
if (depth == tree_depth)
return coordToKey(x,y,z);
else
return OcTreeKey(coordToKey(x, depth), coordToKey(y, depth), coordToKey(z, depth));
}
/**
* Adjusts a 3D key from the lowest level to correspond to a higher depth (by
* shifting the key values)
*
* @param key Input key, at the lowest tree level
* @param depth Target depth level for the new key
* @return Key for the new depth level
*/
inline OcTreeKey adjustKeyAtDepth(const OcTreeKey& key, unsigned int depth) const{
if (depth == tree_depth)
return key;
assert(depth <= tree_depth);
return OcTreeKey(adjustKeyAtDepth(key[0], depth), adjustKeyAtDepth(key[1], depth), adjustKeyAtDepth(key[2], depth));
}
/**
* Adjusts a single key value from the lowest level to correspond to a higher depth (by
* shifting the key value)
*
* @param key Input key, at the lowest tree level
* @param depth Target depth level for the new key
* @return Key for the new depth level
*/
unsigned short int adjustKeyAtDepth(unsigned short int key, unsigned int depth) const;
/**
* Converts a 3D coordinate into a 3D OcTreeKey, with boundary checking.
*
* @param coord 3d coordinate of a point
* @param key values that will be computed, an array of fixed size 3.
* @return true if point is within the octree (valid), false otherwise
*/
bool coordToKeyChecked(const point3d& coord, OcTreeKey& key) const;
/**
* Converts a 3D coordinate into a 3D OcTreeKey at a certain depth, with boundary checking.
*
* @param coord 3d coordinate of a point
* @param depth level of the key from the top
* @param key values that will be computed, an array of fixed size 3.
* @return true if point is within the octree (valid), false otherwise
*/
bool coordToKeyChecked(const point3d& coord, unsigned depth, OcTreeKey& key) const;
/**
* Converts a 3D coordinate into a 3D OcTreeKey, with boundary checking.
*
* @param x
* @param y
* @param z
* @param key values that will be computed, an array of fixed size 3.
* @return true if point is within the octree (valid), false otherwise
*/
bool coordToKeyChecked(double x, double y, double z, OcTreeKey& key) const;
/**
* Converts a 3D coordinate into a 3D OcTreeKey at a certain depth, with boundary checking.
*
* @param x
* @param y
* @param z
* @param depth level of the key from the top
* @param key values that will be computed, an array of fixed size 3.
* @return true if point is within the octree (valid), false otherwise
*/
bool coordToKeyChecked(double x, double y, double z, unsigned depth, OcTreeKey& key) const;
/**
* Converts a single coordinate into a discrete addressing key, with boundary checking.
*
* @param coordinate 3d coordinate of a point
* @param key discrete 16 bit adressing key, result
* @return true if coordinate is within the octree bounds (valid), false otherwise
*/
bool coordToKeyChecked(double coordinate, unsigned short int& key) const;
/**
* Converts a single coordinate into a discrete addressing key, with boundary checking.
*
* @param coordinate 3d coordinate of a point
* @param depth level of the key from the top
* @param key discrete 16 bit adressing key, result
* @return true if coordinate is within the octree bounds (valid), false otherwise
*/
bool coordToKeyChecked(double coordinate, unsigned depth, unsigned short int& key) const;
/// converts from a discrete key at a given depth into a coordinate
/// corresponding to the key's center
double keyToCoord(unsigned short int key, unsigned depth) const;
/// converts from a discrete key at the lowest tree level into a coordinate
/// corresponding to the key's center
inline double keyToCoord(unsigned short int key) const{
return (double( (int) key - (int) this->tree_max_val ) +0.5) * this->resolution;
}
/// converts from an addressing key at the lowest tree level into a coordinate
/// corresponding to the key's center
inline point3d keyToCoord(const OcTreeKey& key) const{
return point3d(float(keyToCoord(key[0])), float(keyToCoord(key[1])), float(keyToCoord(key[2])));
}
/// converts from an addressing key at a given depth into a coordinate
/// corresponding to the key's center
inline point3d keyToCoord(const OcTreeKey& key, unsigned depth) const{
return point3d(float(keyToCoord(key[0], depth)), float(keyToCoord(key[1], depth)), float(keyToCoord(key[2], depth)));
}
protected:
/// Constructor to enable derived classes to change tree constants.
/// This usually requires a re-implementation of some core tree-traversal functions as well!
OcTreeBaseImpl(double resolution, unsigned int tree_depth, unsigned int tree_max_val);
/// initialize non-trivial members, helper for constructors
void init();
/// recalculates min and max in x, y, z. Does nothing when tree size didn't change.
void calcMinMax();
void calcNumNodesRecurs(NODE* node, size_t& num_nodes) const;
/// recursive call of deleteNode()
bool deleteNodeRecurs(NODE* node, unsigned int depth, unsigned int max_depth, const OcTreeKey& key);
/// recursive call of prune()
void pruneRecurs(NODE* node, unsigned int depth, unsigned int max_depth, unsigned int& num_pruned);
/// recursive call of expand()
void expandRecurs(NODE* node, unsigned int depth, unsigned int max_depth);
size_t getNumLeafNodesRecurs(const NODE* parent) const;
private:
/// Assignment operator is private: don't (re-)assign octrees
/// (const-parameters can't be changed) - use the copy constructor instead.
OcTreeBaseImpl<NODE,INTERFACE>& operator=(const OcTreeBaseImpl<NODE,INTERFACE>&);
protected:
NODE* root; ///< Pointer to the root NODE, NULL for empty tree
// constants of the tree
const unsigned int tree_depth; ///< Maximum tree depth is fixed to 16 currently
const unsigned int tree_max_val;
double resolution; ///< in meters
double resolution_factor; ///< = 1. / resolution
size_t tree_size; ///< number of nodes in tree
/// flag to denote whether the octree extent changed (for lazy min/max eval)
bool size_changed;
point3d tree_center; // coordinate offset of tree
double max_value[3]; ///< max in x, y, z
double min_value[3]; ///< min in x, y, z
/// contains the size of a voxel at level i (0: root node). tree_depth+1 levels (incl. 0)
std::vector<double> sizeLookupTable;
/// data structure for ray casting, array for multithreading
std::vector<KeyRay> keyrays;
const leaf_iterator leaf_iterator_end;
const leaf_bbx_iterator leaf_iterator_bbx_end;
const tree_iterator tree_iterator_end;
};
}
#include <octomap/OcTreeBaseImpl.hxx>
#endif
|