/* * Copyright (C) 2007 Simon Perreault * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef OCTREE_H #define OCTREE_H #include template< typename T, int AS = 1 > class Octree { public: Octree( int size, const T& emptyValue = T(0) ); Octree( const Octree& o ); ~Octree(); // Accessors int size() const; const T& emptyValue() const; static unsigned long branchBytes(); static unsigned long aggregateBytes(); static unsigned long leafBytes(); unsigned long bytes() const; int nodes() const; int nodesAtSize( int size ) const; // Mutators void setEmptyValue( const T& emptyValue ); void swap( Octree& o ); Octree& operator= ( Octree o ); // Indexing operators T& operator() ( int x, int y, int z ); const T& operator() ( int x, int y, int z ) const; const T& at( int x, int y, int z ) const; void set( int x, int y, int z, const T& value ); void erase( int x, int y, int z ); //Array2D zSlice( int z ) const; // I/O functions /*void writeBinary( std::ostream& out ) const; void readBinary( std::istream& in );*/ protected: // Octree node types class Node; class Branch; class Aggregate; class Leaf; enum NodeType { BranchNode, AggregateNode, LeafNode }; Node*& root(); const Node* root() const; static void deleteNode( Node** node ); private: // Recursive helper functions void eraseRecursive( Node** node, int size, int x, int y, int z ); static unsigned long bytesRecursive( const Node* node ); static int nodesRecursive( const Node* node ); static int nodesAtSizeRecursive( int targetSize, int size, Node* node ); /*void zSliceRecursive( Array2D slice, const Node* node, int size, int x, int y, int z, int targetZ ) const;*/ /*static void writeBinaryRecursive( std::ostream& out, const Node* node ); static void readBinaryRecursive( std::istream& in, Node** node );*/ protected: // Node classes class Node { public: NodeType type() const; protected: Node( NodeType type ); ~Node() {} private: NodeType type_ : 2; }; class Branch : public Node { public: Branch(); Branch( const Branch& b ); ~Branch(); const Node* child( int x, int y, int z ) const; Node*& child( int x, int y, int z ); const Node* child( int index ) const; Node*& child( int index ); friend void Octree::deleteNode( Node** node ); private: Branch& operator= ( Branch b ); private: Node* children[2][2][2]; }; class Aggregate : public Node { public: Aggregate( const T& v ); const T& value( int x, int y, int z ) const; T& value( int x, int y, int z ); void setValue( int x, int y, int z, const T& v ); const T& value( int i ) const; T& value( int i ); void setValue( int i, const T& v ); friend void Octree::deleteNode( Node** node ); private: ~Aggregate() {} private: T value_[AS][AS][AS]; }; class Leaf : public Node { public: Leaf( const T& v ); const T& value() const; T& value(); void setValue( const T& v ); friend void Octree::deleteNode( Node** node ); private: ~Leaf() {} private: T value_; }; static const int aggregateSize_ = AS; private: Node* root_; T emptyValue_; int size_; }; #include "octree.hpp" #endif