@chapsummary
Data structures used by the Boxm2 library
@endchapsummary


@section Boxm2 Scene data structures
The data structures used in boxm2 are optimized to be used both by a CPU and GPU.  
A scene is composed of @code{blocks}, which are specified in the @code{scene.xml} file.  
Each @code{block} is a fixed grid of octrees, also referred to as @code{sub_blocks} in 
the code.  The dimension of a @code{sub_block} and the number of @code{sub_blocks} in 
each block are specified in the @code{scene.xml} file.  

The voxel structure of each block is encoded in its own file which is located in the
directory specified by the @code{scene.xml} file.  Each block has a unique 
@code{boxm2_block_id}, which consists of three integers.  This block id 
is how blocks and their corresponding data are identified on disk.  


@subsection Boxm2 Block: octree based voxel structure

A @code{boxm2_block} contains the following buffers: 
@itemize
@item @code{boxm2_array_3d<uchar16> trees_} : a three-d buffer of bit-encoded octrees.  It's dimensions are indicated in the @code{scene.xml} file. 
@item @code{boxm2_array_2d<int>     tree_ptrs_} : a two-d buffer that mirrors the location of corresponding data cells.  
@item @code{boxm2_array_1d<ushort>  trees_in_buffers_} : a one-d buffer that indicates how many trees are in each row of @code{tree_ptrs} (as they may not be full).  
@item @code{boxm2_array_1d<ushort2> mem_ptrs_} : a one-d buffer that indicates where data is stored in each row of data buffers.  
@end itemize

@subsection bit_trees
The voxel structure of a block is encoded in the 3d array @code{trees_}, which contains bit-encoded
octrees of maximum depth 4.  A bit is reserved for each potential inner node (73 on 
a depth 4 octree), which indicates whether or not that node has children.  This tree is full, 
meaning all nodes either have zero children or 8 children.  The first 10 bytes (index 0-9) 
are reserved to encode the voxel structure.  Bytes (10,11) and (12,13) encode two 
@code{unsigned shorts} that index into any data buffer with the same ID as the block.  
This index points to the data that corresponds with the root node of the tree.  From there, 
a simple counting bits algorithm is performed to find the data of a particular cell, 
specified by it's bit_index.  

These algorithms are implemented in both OpenCL and C++.  The C++ object 
@code{boct_bit_tree2} is our latest implementation of the bit encoded octree.  
It is located in @code{src/contrib/brl/bseg/boct/}.  

The structure of the data buffer is described below.  

@subsection Data structures.
The @code{boxm2_data<T>} object is a wrapper around a @code{boxm2_array_1d<T>} buffer.  
The template parameter is a @code{boxm2_data_type} as specified in the file 
@code{boxm2_data_traits.h}.  Currently, we have the following data types implemented:

@itemize
@item BOXM2_ALPHA : data type is float
@item BOXM2_MOG3_GREY : data type is uchar8 (a typedef of @code{vnl_vector_fixed<unsigned char, 8>})
@item BOXM2_NUM_OBS : data type is ushort4 (a typedef of @code{vnl_vector_fixed<unsigned short, 4>})
@item BOXM2_AUX : data type is int4 (a typedef of @code{vnl_vector_fixed<int, 4>})
@item BOXM2_UNKNOWN : whose data type is undefined
@end itemize

Each data buffer is split into a two dimensional array, whose size is determined by: 
@itemize
@item number of buffers: determined by the maximum size of a block, as specified in the @code{scene.xml} file
@item number cells in each buffer: currently hardcoded to 65536 (maximum value of an @code{unsigned short}). 
@end itemize
The cell size for each data buffer can be statically called by using 
@code{boxm2_data_traits<DATA_TYPE>::datasize()}.  

For any empty scene, the data corresponding to each tree (for the root node) is randomly
distributed among the buffers.  This is to ensure that trees located at surfaces are 
uniformly distributed, allowing for efficient usage of space and maximum growth.   

The @code{unsigned short} encoded in bytes (12,13) of a tree indicate which buffer
its data is in.  The @code{unsigned short} encoded in bytes (10,11) indicate the 
offset within the buffer that points to the root node's data.  The tree's data is 
then stored in breadth first search order within the data buffer.  Given the location 
of the tree cell (bit index in [0,585] for a depth 4 tree), and the location of 
its root data, it is a simple bit counting algorithm to find the specified cell's
data.  This algorithm runs in log time on the index of the tree, and is further
accelerated by caching tree bit counts in the OpenCL implementation.  

Furthermore, all data buffers with the same @code{boxm2_block_id} have the same
structure.  This means that any indexing any data buffer with the same 
@code{(buffIndex, buffOffset)} will give you the data that corresponds to the 
exact same voxel.  This inherent structure is important, as it allows for 
data modularity accross different algorithms.  


@section Boxm2 Basic
The sub-library @code{boxm2_basic} includes wrappers around buffers that make 
multi-dimensional indexing easy.  We currently have @code{boxm2_array_1d<T>}, 
@code{boxm2_array_2d<T>}, and @code{boxm2_array_3d<T>} implemented.  These arrays 
only allocate memory to assist multi-dimensional indexing, and will not destroy 
the original flat buffer upon destruction.  These wrappers are designed to merely 
wrap memory, not manage it.  

