Field3D
SparseField< Data_T > Class Template Reference

This Field subclass stores voxel data in block-allocated arrays. More...

#include <SparseField.h>

Inheritance diagram for SparseField< Data_T >:
ResizableField< Data_T > ResizableField< Data_T > WritableField< Data_T > WritableField< Data_T > WritableField< Data_T > WritableField< Data_T > Field< Data_T > Field< Data_T > Field< Data_T > Field< Data_T > Field< Data_T > Field< Data_T > Field< Data_T > Field< Data_T >

List of all members.

Classes

class  block_iterator
class  const_iterator
class  iterator

Public Types

typedef SparseField< Data_T > class_type
typedef SparseField< Data_T > class_type
typedef
CubicGenericFieldInterp
< SparseField< Data_T > > 
CubicInterp
typedef
CubicGenericFieldInterp
< SparseField< Data_T > > 
CubicInterp
typedef
LinearGenericFieldInterp
< SparseField< Data_T > > 
LinearInterp
typedef
LinearGenericFieldInterp
< SparseField< Data_T > > 
LinearInterp
typedef boost::intrusive_ptr
< SparseField
Ptr
typedef boost::intrusive_ptr
< SparseField
Ptr
typedef std::vector< PtrVec
 This is a convenience typedef for the list that Field3DInputFile::readScalarLayers() and Field3DInputFile::readVectorLayers() will return its data in.
typedef std::vector< PtrVec
 This is a convenience typedef for the list that Field3DInputFile::readScalarLayers() and Field3DInputFile::readVectorLayers() will return its data in.

Public Member Functions

void addReference (const std::string &filename, const std::string &layerPath, int valuesPerBlock, int occupiedBlocks)
 Internal function to create a Reference for the current field, for use in dynamic reading.
void addReference (const std::string &filename, const std::string &layerPath, int valuesPerBlock, int occupiedBlocks)
 Internal function to create a Reference for the current field, for use in dynamic reading.
void applyDataWindowOffset (int &i, int &j, int &k) const
 Applies data window offset.
void applyDataWindowOffset (int &i, int &j, int &k) const
 Applies data window offset.
int blockId (int blockI, int blockJ, int blockK) const
 Calculates the block number based on a block i,j,k index.
int blockId (int blockI, int blockJ, int blockK) const
 Calculates the block number based on a block i,j,k index.
bool blockIndexIsValid (int bi, int bj, int bk) const
 Returns whether a block index is valid.
bool blockIndexIsValid (int bi, int bj, int bk) const
 Returns whether a block index is valid.
bool blockIsAllocated (int bi, int bj, int bk) const
 Checks if a block is allocated.
bool blockIsAllocated (int bi, int bj, int bk) const
 Checks if a block is allocated.
int blockOrder () const
 Returns the block order.
int blockOrder () const
 Returns the block order.
V3i blockRes () const
 Returns the resolution of the block array.
V3i blockRes () const
 Returns the resolution of the block array.
int blockSize () const
 Returns the block size.
int blockSize () const
 Returns the block size.
virtual void clear (const Data_T &value)
 Clears all the voxels in the storage.
virtual void clear (const Data_T &value)
 Clears all the voxels in the storage.
Data_T & fastLValue (int i, int j, int k)
 Write access to voxel. Notice that this is non-virtual.
Data_T & fastLValue (int i, int j, int k)
 Write access to voxel. Notice that this is non-virtual.
Data_T fastValue (int i, int j, int k) const
 Read access to voxel. Notice that this is non-virtual.
Data_T fastValue (int i, int j, int k) const
 Read access to voxel. Notice that this is non-virtual.
void getBlockCoord (int i, int j, int k, int &bi, int &bj, int &bk) const
 Calculates the block coordinates that a given set of voxel coords are in.
void getBlockCoord (int i, int j, int k, int &bi, int &bj, int &bk) const
 Calculates the block coordinates that a given set of voxel coords are in.
const Data_T getBlockEmptyValue (int bi, int bj, int bk) const
 Returns the constant value of an block, whether it's allocated already or not..
const Data_T getBlockEmptyValue (int bi, int bj, int bk) const
 Returns the constant value of an block, whether it's allocated already or not..
void getVoxelInBlock (int i, int j, int k, int &vi, int &vj, int &vk) const
 Calculates the coordinates in a block for the given voxel index.
void getVoxelInBlock (int i, int j, int k, int &vi, int &vj, int &vk) const
 Calculates the coordinates in a block for the given voxel index.
template<typename Functor_T >
int releaseBlocks (Functor_T func)
 Releases any blocks that are deemed empty. This can be used to clean up after algorithms that write "zero" values to the buffer, as well as after any narrow band levelset algorithms.
template<typename Functor_T >
int releaseBlocks (Functor_T func)
 Releases any blocks that are deemed empty. This can be used to clean up after algorithms that write "zero" values to the buffer, as well as after any narrow band levelset algorithms.
void setBlockEmptyValue (int bi, int bj, int bk, const Data_T &val)
 Sets the constant value of an block. If the block is already allocated, it gets deallocated.
void setBlockEmptyValue (int bi, int bj, int bk, const Data_T &val)
 Sets the constant value of an block. If the block is already allocated, it gets deallocated.
void setBlockOrder (int order)
 Sets the block order (i.e. the power-of-2 to use as block size.
void setBlockOrder (int order)
 Sets the block order (i.e. the power-of-2 to use as block size.
void setupReferenceBlocks ()
 Internal function to setup the Reference's block pointers, for use with dynamic reading.
void setupReferenceBlocks ()
 Internal function to setup the Reference's block pointers, for use with dynamic reading.
bool voxelIsInAllocatedBlock (int i, int j, int k) const
 Checks if a voxel is in an allocated block.
bool voxelIsInAllocatedBlock (int i, int j, int k) const
 Checks if a voxel is in an allocated block.
Constructors & destructor
 SparseField ()
 Constructs an empty buffer.
 SparseField (const SparseField &o)
 Copy constructor.
 ~SparseField ()
 Destructor.
SparseFieldoperator= (const SparseField &o)
 Assignment operator. For cache-managed fields, it creates a new file reference, and for non-managed fields, it copies the data.
 SparseField ()
 Constructs an empty buffer.
 SparseField (const SparseField &o)
 Copy constructor.
 ~SparseField ()
 Destructor.
SparseFieldoperator= (const SparseField &o)
 Assignment operator. For cache-managed fields, it creates a new file reference, and for non-managed fields, it copies the data.
From Field
virtual Data_T value (int i, int j, int k) const
 Read access to a voxel. The coordinates are in integer voxel space .
virtual long long int memSize () const
 Returns the memory usage (in bytes)
virtual Data_T value (int i, int j, int k) const
 Read access to a voxel. The coordinates are in integer voxel space .
virtual long long int memSize () const
 Returns the memory usage (in bytes)
From WritableField
virtual Data_T & lvalue (int i, int j, int k)
 Write access to a voxel. The coordinates are global coordinates.
virtual Data_T & lvalue (int i, int j, int k)
 Write access to a voxel. The coordinates are global coordinates.
From FieldBase
virtual std::string className () const
 Returns the class name of the object. Used by the class pool and when writing the data to disk.
virtual FieldBase::Ptr clone () const
 Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement it.
virtual std::string className () const
 Returns the class name of the object. Used by the class pool and when writing the data to disk.
virtual FieldBase::Ptr clone () const
 Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement it.
Iterators
const_iterator cbegin () const
 Const iterator to first element. "cbegin" matches the tr1 c++ standard.
const_iterator cbegin (const Box3i &subset) const
 Const iterator to first element of specific subset.
const_iterator cend () const
 Const iterator pointing one element past the last valid one.
const_iterator cend (const Box3i &subset) const
 Const iterator pointing one element past the last valid one (for a subset)
iterator begin ()
 Iterator to first element.
iterator begin (const Box3i &subset)
 Iterator to first element of specific subset.
iterator end ()
 Iterator pointing one element past the last valid one.
iterator end (const Box3i &subset)
 Iterator pointing one element past the last valid one (for a subset)
block_iterator blockBegin () const
block_iterator blockEnd () const
 Const iterator pointing to element one past the last valid block.
const_iterator cbegin () const
 Const iterator to first element. "cbegin" matches the tr1 c++ standard.
const_iterator cbegin (const Box3i &subset) const
 Const iterator to first element of specific subset.
const_iterator cend () const
 Const iterator pointing one element past the last valid one.
const_iterator cend (const Box3i &subset) const
 Const iterator pointing one element past the last valid one (for a subset)
iterator begin ()
 Iterator to first element.
iterator begin (const Box3i &subset)
 Iterator to first element of specific subset.
iterator end ()
 Iterator pointing one element past the last valid one.
iterator end (const Box3i &subset)
 Iterator pointing one element past the last valid one (for a subset)
block_iterator blockBegin () const
block_iterator blockEnd () const
 Const iterator pointing to element one past the last valid block.

Public Attributes

 DEFINE_FIELD_RTTI_CONCRETE_CLASS

Protected Types

typedef ResizableField< Data_T > base
 Convenience typedef for referring to base class.
typedef ResizableField< Data_T > base
 Convenience typedef for referring to base class.
typedef Sparse::SparseBlock
< Data_T > 
Block
typedef Sparse::SparseBlock
< Data_T > 
Block

Protected Member Functions

virtual void sizeChanged ()
 Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.
virtual void sizeChanged ()
 Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.
Convenience methods
void setupBlocks ()
 Initializes the block structure. Will clear any existing data.
void deallocBlock (Block &block, const Data_T &emptyValue)
 Deallocated the data of the given block and sets its empty value.
void setupBlocks ()
 Initializes the block structure. Will clear any existing data.
void deallocBlock (Block &block, const Data_T &emptyValue)
 Deallocated the data of the given block and sets its empty value.

Protected Attributes

int m_blockOrder
 Block order (size = 2^blockOrder)
V3i m_blockRes
 Block array resolution.
std::vector< Blockm_blocks
 Information for all blocks in the field.
int m_blockXYSize
 Block array res.x * res.y.
Data_T m_dummy
 Dummy value used when needing to return but indicating a failed call.
int m_fileId
 File id. Used with m_fileManager if active. Otherwise -1.
SparseFileManagerm_fileManager
 Pointer to SparseFileManager. Used when doing dynamic reading. NULL if not in use.

Private Member Functions

void copyBlockStates (const SparseField< Data_T > &o)
 Internal function to copy empty values and allocated flags, without copying data, used when copying a dynamically read field.
void copyBlockStates (const SparseField< Data_T > &o)
 Internal function to copy empty values and allocated flags, without copying data, used when copying a dynamically read field.
void copySparseField (const SparseField &o)
 Copies internal data, including blocks, from another SparseField, used by copy constructor and operator=.
void copySparseField (const SparseField &o)
 Copies internal data, including blocks, from another SparseField, used by copy constructor and operator=.

Friends

class SparseFieldIO

Detailed Description

template<class Data_T>
class SparseField< Data_T >

This Field subclass stores voxel data in block-allocated arrays.

Empty blocks aren't allocated. This effectively optimizes away memory use for "empty" voxels.

Refer to using_fields for examples of how to use this in your code.

Todo:
Make this class thread safe!

Empty blocks aren't allocated. This effectively optimizes away memory use for "empty" voxels.

Refer to using_fields for examples of how to use this in your code.

Todo:
Make this class thread safe!

Definition at line 160 of file SparseField.h.


Member Typedef Documentation

template<class Data_T>
typedef boost::intrusive_ptr<SparseField> SparseField< Data_T >::Ptr

Reimplemented from ResizableField< Data_T >.

Definition at line 167 of file SparseField.h.

template<class Data_T>
typedef std::vector<Ptr> SparseField< Data_T >::Vec

This is a convenience typedef for the list that Field3DInputFile::readScalarLayers() and Field3DInputFile::readVectorLayers() will return its data in.

Reimplemented from Field< Data_T >.

Definition at line 168 of file SparseField.h.

template<class Data_T>
typedef LinearGenericFieldInterp<SparseField<Data_T> > SparseField< Data_T >::LinearInterp

Definition at line 170 of file SparseField.h.

template<class Data_T>
typedef CubicGenericFieldInterp<SparseField<Data_T> > SparseField< Data_T >::CubicInterp

Definition at line 171 of file SparseField.h.

template<class Data_T>
typedef SparseField<Data_T> SparseField< Data_T >::class_type

Reimplemented from ResizableField< Data_T >.

Definition at line 267 of file SparseField.h.

template<class Data_T>
typedef ResizableField<Data_T> SparseField< Data_T >::base [protected]

Convenience typedef for referring to base class.

Reimplemented from ResizableField< Data_T >.

Definition at line 356 of file SparseField.h.

template<class Data_T>
typedef Sparse::SparseBlock<Data_T> SparseField< Data_T >::Block [protected]

Definition at line 357 of file SparseField.h.

template<class Data_T>
typedef boost::intrusive_ptr<SparseField> SparseField< Data_T >::Ptr

Reimplemented from ResizableField< Data_T >.

Definition at line 167 of file SparseField.h.

template<class Data_T>
typedef std::vector<Ptr> SparseField< Data_T >::Vec

This is a convenience typedef for the list that Field3DInputFile::readScalarLayers() and Field3DInputFile::readVectorLayers() will return its data in.

Reimplemented from Field< Data_T >.

Definition at line 168 of file SparseField.h.

template<class Data_T>
typedef LinearGenericFieldInterp<SparseField<Data_T> > SparseField< Data_T >::LinearInterp

Definition at line 170 of file SparseField.h.

template<class Data_T>
typedef CubicGenericFieldInterp<SparseField<Data_T> > SparseField< Data_T >::CubicInterp

Definition at line 171 of file SparseField.h.

template<class Data_T>
typedef SparseField<Data_T> SparseField< Data_T >::class_type

Reimplemented from ResizableField< Data_T >.

Definition at line 267 of file SparseField.h.

template<class Data_T>
typedef ResizableField<Data_T> SparseField< Data_T >::base [protected]

Convenience typedef for referring to base class.

Reimplemented from ResizableField< Data_T >.

Definition at line 356 of file SparseField.h.

template<class Data_T>
typedef Sparse::SparseBlock<Data_T> SparseField< Data_T >::Block [protected]

Definition at line 357 of file SparseField.h.


Constructor & Destructor Documentation

template<class Data_T >
SparseField< Data_T >::SparseField ( )

Constructs an empty buffer.

Definition at line 992 of file SparseField.h.

References SparseField< Data_T >::setupBlocks().

Referenced by SparseField< Data_T >::clone().

template<class Data_T >
SparseField< Data_T >::SparseField ( const SparseField< Data_T > &  o)

Copy constructor.

Definition at line 1003 of file SparseField.h.

References SparseField< Data_T >::copySparseField().

                                                             :
  base(o)
{
  copySparseField(o);
}
template<class Data_T >
SparseField< Data_T >::~SparseField ( )

Destructor.

Definition at line 1012 of file SparseField.h.

{
  if (m_fileManager) {
    // this file is dynamically managed, so we need to ensure the
    // cache doesn't point to this field's blocks because they are
    // about to be deleted
    m_fileManager->removeFieldFromCache<Data_T>(m_fileId);
  }
}
template<class Data_T>
SparseField< Data_T >::SparseField ( )

Constructs an empty buffer.

template<class Data_T>
SparseField< Data_T >::SparseField ( const SparseField< Data_T > &  o)

Copy constructor.

template<class Data_T>
SparseField< Data_T >::~SparseField ( )

Destructor.


Member Function Documentation

template<class Data_T >
SparseField< Data_T > & SparseField< Data_T >::operator= ( const SparseField< Data_T > &  o)

Assignment operator. For cache-managed fields, it creates a new file reference, and for non-managed fields, it copies the data.

Definition at line 1026 of file SparseField.h.

{
  if (this != &o) {
    this->base::operator=(o);
    copySparseField(o);
  }
  return *this;
}
template<class Data_T >
void SparseField< Data_T >::clear ( const Data_T &  value) [virtual]

Clears all the voxels in the storage.

Reimplemented from WritableField< Data_T >.

Definition at line 1136 of file SparseField.h.

Referenced by main().

{
  // If we're clearing, we can get rid of all current blocks
  setupBlocks();
  // Then just fill in the default values
  typename std::vector<Block>::iterator i;
  for (i = m_blocks.begin(); i != m_blocks.end(); ++i) {
    i->emptyValue = value;
  }
}
template<class Data_T >
void SparseField< Data_T >::setBlockOrder ( int  order)

Sets the block order (i.e. the power-of-2 to use as block size.

Note:
This will clear out any existing data.

Definition at line 1150 of file SparseField.h.

Referenced by SparseFieldIO::read().

{
  m_blockOrder = order;
  setupBlocks();
}
template<class Data_T >
int SparseField< Data_T >::blockOrder ( ) const

Returns the block order.

Definition at line 1159 of file SparseField.h.

{
  return m_blockOrder;
}
template<class Data_T >
int SparseField< Data_T >::blockSize ( ) const

Returns the block size.

Definition at line 1167 of file SparseField.h.

Referenced by SparseField< Data_T >::block_iterator::recomputeBlockBoundingBox().

{ 
  return 1 << m_blockOrder;
}
template<class Data_T >
bool SparseField< Data_T >::voxelIsInAllocatedBlock ( int  i,
int  j,
int  k 
) const

Checks if a voxel is in an allocated block.

Definition at line 1175 of file SparseField.h.

{
  int bi, bj, bk;
  applyDataWindowOffset(i, j, k);
  getBlockCoord(i, j, k, bi, bj, bk);
  return blockIsAllocated(bi, bj, bk);
}
template<class Data_T >
bool SparseField< Data_T >::blockIsAllocated ( int  bi,
int  bj,
int  bk 
) const

Checks if a block is allocated.

Definition at line 1186 of file SparseField.h.

References Sparse::SparseBlock< Data_T >::isAllocated.

{
  const Block &block = m_blocks[blockId(bi, bj, bk)];
  return block.isAllocated;
}
template<class Data_T >
const Data_T SparseField< Data_T >::getBlockEmptyValue ( int  bi,
int  bj,
int  bk 
) const

Returns the constant value of an block, whether it's allocated already or not..

Definition at line 1195 of file SparseField.h.

{
  return m_blocks[blockId(bi, bj, bk)].emptyValue;
}
template<class Data_T >
void SparseField< Data_T >::setBlockEmptyValue ( int  bi,
int  bj,
int  bk,
const Data_T &  val 
)

Sets the constant value of an block. If the block is already allocated, it gets deallocated.

Definition at line 1203 of file SparseField.h.

References Sparse::SparseBlock< Data_T >::emptyValue, and Sparse::SparseBlock< Data_T >::isAllocated.

{
  Block &block = m_blocks[blockId(bi, bj, bk)];
  if (block.isAllocated) {
    deallocBlock(block, val);
  } else {
    block.emptyValue = val;
  }
}
template<class Data_T >
bool SparseField< Data_T >::blockIndexIsValid ( int  bi,
int  bj,
int  bk 
) const

Returns whether a block index is valid.

Definition at line 1217 of file SparseField.h.

{
  return bi >= 0 && bj >= 0 && bk >= 0 && 
    bi < m_blockRes.x && bj < m_blockRes.y && bk < m_blockRes.z;
}
template<class Data_T >
V3i SparseField< Data_T >::blockRes ( ) const

Returns the resolution of the block array.

Definition at line 1226 of file SparseField.h.

{
  return m_blockRes;
}
template<class Data_T >
template<typename Functor_T >
int SparseField< Data_T >::releaseBlocks ( Functor_T  func)

Releases any blocks that are deemed empty. This can be used to clean up after algorithms that write "zero" values to the buffer, as well as after any narrow band levelset algorithms.

Parameters:
funcA function object with the method "bool check(SparseBlock&)"
Returns:
Number of released blocks

Definition at line 1235 of file SparseField.h.

References FieldRes::dataResolution().

{
  Data_T emptyValue;
  int numDeallocs = 0;
  typename std::vector<Block>::iterator i;

  // If the block is on the edge of the field, it may have unused
  // voxels, with undefined values.  We need to pass the range of
  // valid voxels into the check function, so it only looks at valid
  // voxels.
  V3i dataRes = FieldRes::dataResolution();
  V3i validSize;
  V3i blockAllocSize(blockSize());
  int bx, by, bz;

  for (i = m_blocks.begin(), bx=0, by=0, bz=0; i != m_blocks.end(); ++i, ++bx) {
    if (bx >= m_blockRes.x) {
      bx = 0;
      ++by;
      if (by >= m_blockRes.y) {
        by = 0;
        ++bz;
      }
    }
    validSize = blockAllocSize;
    if (bx == m_blockRes.x-1) {
      validSize.x = dataRes.x - bx * blockAllocSize.x;
    }
    if (by == m_blockRes.y-1) {
      validSize.y = dataRes.y - by * blockAllocSize.y;
    }
    if (bz == m_blockRes.z-1) {
      validSize.z = dataRes.z - bz * blockAllocSize.z;
    }

    if (i->isAllocated) {
      if (func.check(*i, emptyValue, validSize, blockAllocSize)) {
        deallocBlock(*i, emptyValue);
        numDeallocs++;
      }
    }
  }
  return numDeallocs;
}
template<class Data_T >
int SparseField< Data_T >::blockId ( int  blockI,
int  blockJ,
int  blockK 
) const

Calculates the block number based on a block i,j,k index.

Definition at line 1534 of file SparseField.h.

{
  return blockK * m_blockXYSize + blockJ * m_blockRes.x + blockI;
}
template<class Data_T >
void SparseField< Data_T >::getBlockCoord ( int  i,
int  j,
int  k,
int &  bi,
int &  bj,
int &  bk 
) const

Calculates the block coordinates that a given set of voxel coords are in.

Note:
The i,j,k coordinates are strictly positive, and refer to the coordinates of a voxel -after- the data window offset has been applied.
Bit shift should be ok, indices are always positive.

Definition at line 1543 of file SparseField.h.

{
  assert(i >= 0);
  assert(j >= 0);
  assert(k >= 0);
  bi = i >> m_blockOrder;
  bj = j >> m_blockOrder;
  bk = k >> m_blockOrder;
}
template<class Data_T >
void SparseField< Data_T >::getVoxelInBlock ( int  i,
int  j,
int  k,
int &  vi,
int &  vj,
int &  vk 
) const

Calculates the coordinates in a block for the given voxel index.

Note:
The i,j,k coordinates are strictly positive, and refer to the coordinates of a voxel -after- the data window offset has been applied.
Bit shift should be ok, indices are always positive.

Definition at line 1558 of file SparseField.h.

{
  assert(i >= 0);
  assert(j >= 0);
  assert(k >= 0);
  vi = i & ((1 << m_blockOrder) - 1);
  vj = j & ((1 << m_blockOrder) - 1);
  vk = k & ((1 << m_blockOrder) - 1);
}
template<class Data_T>
void SparseField< Data_T >::applyDataWindowOffset ( int &  i,
int &  j,
int &  k 
) const [inline]

Applies data window offset.

Definition at line 250 of file SparseField.h.

References FieldRes::m_dataWindow.

  {
    i -= base::m_dataWindow.min.x;
    j -= base::m_dataWindow.min.y;
    k -= base::m_dataWindow.min.z;
  }
template<class Data_T >
Data_T SparseField< Data_T >::value ( int  i,
int  j,
int  k 
) const [virtual]

Read access to a voxel. The coordinates are in integer voxel space .

Note:
Before the internal storage is accessed, the subclass must compute the data window coordinates by looking at Field::m_dataWindow.
Virtual functions are known not to play nice with threading. Therefor, concrete classes can implement (by convention) fastValue() as a non-virtual function.

Implements Field< Data_T >.

Definition at line 1283 of file SparseField.h.

{
  return fastValue(i, j, k);
}
template<class Data_T >
long long int SparseField< Data_T >::memSize ( ) const [virtual]

Returns the memory usage (in bytes)

Note:
This needs to be re-implemented for any subclass that adds data members. Those classes should also call their superclass and add the combined memory use.

Reimplemented from FieldRes.

Definition at line 1381 of file SparseField.h.

{
  long long int blockSize = m_blocks.capacity() * sizeof(Block);
  long long int dataSize = 0;
  typename std::vector<Block>::const_iterator i;
  for (i = m_blocks.begin(); i != m_blocks.end(); ++i) {
    if (i->isAllocated) {
      dataSize += i->data.capacity() * sizeof(Data_T);
    }
  }
  return sizeof(*this) + dataSize + blockSize;
}
template<class Data_T >
Data_T & SparseField< Data_T >::lvalue ( int  i,
int  j,
int  k 
) [virtual]

Write access to a voxel. The coordinates are global coordinates.

Note:
Before the internal storage is accessed, the subclass must compute the crop window coordinates by looking at Field::m_dataWindow.
This is named differently from the const value so that non-const objects still have a clear way of accessing data in a const way.
Virtual functions are known not to play nice with threading. Therefor, concrete classes can implement (by convention) fastLValue() as a non-virtual function.

Implements WritableField< Data_T >.

Definition at line 1291 of file SparseField.h.

{
  return fastLValue(i, j, k);
}
template<class Data_T >
Data_T SparseField< Data_T >::fastValue ( int  i,
int  j,
int  k 
) const

Read access to voxel. Notice that this is non-virtual.

Definition at line 1299 of file SparseField.h.

References Sparse::SparseBlock< Data_T >::emptyValue, Sparse::SparseBlock< Data_T >::isAllocated, and Sparse::SparseBlock< Data_T >::value().

{
  assert (i >= base::m_dataWindow.min.x);
  assert (i <= base::m_dataWindow.max.x);
  assert (j >= base::m_dataWindow.min.y);
  assert (j <= base::m_dataWindow.max.y);
  assert (k >= base::m_dataWindow.min.z);
  assert (k <= base::m_dataWindow.max.z);
  // Add crop window offset
  applyDataWindowOffset(i, j, k);
  // Find block coord
  int bi, bj, bk;
  getBlockCoord(i, j, k, bi, bj, bk);
  // Find coord in block
  int vi, vj, vk;
  getVoxelInBlock(i, j, k, vi, vj, vk);
  // Get the actual block
  int id = blockId(bi, bj, bk);

  const Block &block = m_blocks[id];
  // Check if block data is allocated
  if (block.isAllocated) {
    if (m_fileManager) {
      m_fileManager->incBlockRef<Data_T>(m_fileId, id);
      m_fileManager->activateBlock<Data_T>(m_fileId, id);
      Data_T tmpValue = block.value(vi, vj, vk, m_blockOrder);
      m_fileManager->decBlockRef<Data_T>(m_fileId, id);
      return tmpValue;
    } else {
      return block.value(vi, vj, vk, m_blockOrder);
    }
  } else {
    return block.emptyValue;
  }
}
template<class Data_T >
Data_T & SparseField< Data_T >::fastLValue ( int  i,
int  j,
int  k 
)

Write access to voxel. Notice that this is non-virtual.

Note:
Bit shift should be ok, indices are always positive.

Definition at line 1339 of file SparseField.h.

References Sparse::SparseBlock< Data_T >::data, Sparse::SparseBlock< Data_T >::emptyValue, Sparse::SparseBlock< Data_T >::isAllocated, Msg::print(), Msg::SevWarning, and Sparse::SparseBlock< Data_T >::value().

{
  assert (i >= base::m_dataWindow.min.x);
  assert (i <= base::m_dataWindow.max.x);
  assert (j >= base::m_dataWindow.min.y);
  assert (j <= base::m_dataWindow.max.y);
  assert (k >= base::m_dataWindow.min.z);
  assert (k <= base::m_dataWindow.max.z);

  if (m_fileManager) {
    assert(false && "Called fastLValue() on a dynamic-read sparse field");
    Msg::print(Msg::SevWarning, "Called fastLValue() on a dynamic-read "
              "sparse field");
    return m_dummy;
  }

  // Add crop window offset
  applyDataWindowOffset(i, j, k);
  // Find block coord
  int bi, bj, bk;
  getBlockCoord(i, j, k, bi, bj, bk);
  // Find coord in block
  int vi, vj, vk;
  getVoxelInBlock(i, j, k, vi, vj, vk);
  // Get the actual block
  int id = blockId(bi, bj, bk);
  Block &block = m_blocks[id];
  // If block is allocated, return a reference to the data
  if (block.isAllocated) {
    return block.value(vi, vj, vk, m_blockOrder);
  } else {
    // ... Otherwise, allocate block
    block.isAllocated = true;
    block.data.resize(1 << m_blockOrder << m_blockOrder << m_blockOrder);
    std::fill(block.data.begin(), block.data.end(), block.emptyValue);
    return block.value(vi, vj, vk, m_blockOrder);
  }
}
template<class Data_T>
virtual std::string SparseField< Data_T >::className ( ) const [inline, virtual]

Returns the class name of the object. Used by the class pool and when writing the data to disk.

Implements FieldBase.

Definition at line 288 of file SparseField.h.

    { return std::string("SparseField"); }
template<class Data_T>
virtual FieldBase::Ptr SparseField< Data_T >::clone ( ) const [inline, virtual]

Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement it.

Implements FieldBase.

Definition at line 291 of file SparseField.h.

References SparseField< Data_T >::SparseField().

    { return Ptr(new SparseField(*this)); }
template<class Data_T >
SparseField< Data_T >::const_iterator SparseField< Data_T >::cbegin ( ) const

Const iterator to first element. "cbegin" matches the tr1 c++ standard.

Reimplemented from Field< Data_T >.

Definition at line 1398 of file SparseField.h.

References FieldRes::dataResolution().

{ 
  if (FieldRes::dataResolution() == V3i(0))
    return cend();
  return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min,
                        m_blockOrder); 
}
template<class Data_T >
SparseField< Data_T >::const_iterator SparseField< Data_T >::cbegin ( const Box3i subset) const

Const iterator to first element of specific subset.

Reimplemented from Field< Data_T >.

Definition at line 1410 of file SparseField.h.

{ 
  if (subset.isEmpty())
    return cend(subset);
  return const_iterator(*this, subset, subset.min, m_blockOrder); 
}
template<class Data_T >
SparseField< Data_T >::const_iterator SparseField< Data_T >::cend ( ) const

Const iterator pointing one element past the last valid one.

Reimplemented from Field< Data_T >.

Definition at line 1421 of file SparseField.h.

{ 
  return const_iterator(*this, base::m_dataWindow, 
                        V3i(base::m_dataWindow.min.x, 
                                   base::m_dataWindow.min.y,
                                   base::m_dataWindow.max.z + 1),
                        m_blockOrder);
}
template<class Data_T >
SparseField< Data_T >::const_iterator SparseField< Data_T >::cend ( const Box3i subset) const

Const iterator pointing one element past the last valid one (for a subset)

Reimplemented from Field< Data_T >.

Definition at line 1434 of file SparseField.h.

{ 
  return const_iterator(*this, subset, 
                        V3i(subset.min.x, 
                                   subset.min.y,
                                   subset.max.z + 1), m_blockOrder);
}
template<class Data_T >
SparseField< Data_T >::iterator SparseField< Data_T >::begin ( )

Iterator to first element.

Reimplemented from WritableField< Data_T >.

Definition at line 1446 of file SparseField.h.

References FieldRes::dataResolution().

{ 
  if (FieldRes::dataResolution() == V3i(0))
    return end();
  return iterator(*this, base::m_dataWindow, 
                  base::m_dataWindow.min, m_blockOrder); }
template<class Data_T >
SparseField< Data_T >::iterator SparseField< Data_T >::begin ( const Box3i subset)

Iterator to first element of specific subset.

Reimplemented from WritableField< Data_T >.

Definition at line 1457 of file SparseField.h.

{ 
  if (subset.isEmpty())
    return end(subset);
  return iterator(*this, subset, subset.min, m_blockOrder); 
}
template<class Data_T >
SparseField< Data_T >::iterator SparseField< Data_T >::end ( )

Iterator pointing one element past the last valid one.

Reimplemented from WritableField< Data_T >.

Definition at line 1468 of file SparseField.h.

{ 
  return iterator(*this, base::m_dataWindow, 
                  V3i(base::m_dataWindow.min.x, 
                             base::m_dataWindow.min.y,
                             base::m_dataWindow.max.z + 1), m_blockOrder);
}
template<class Data_T >
SparseField< Data_T >::iterator SparseField< Data_T >::end ( const Box3i subset)

Iterator pointing one element past the last valid one (for a subset)

Reimplemented from WritableField< Data_T >.

Definition at line 1480 of file SparseField.h.

{ 
  return iterator(*this, subset, 
                  V3i(subset.min.x, subset.min.y, subset.max.z + 1), 
                  m_blockOrder);
}
template<class Data_T >
SparseField< Data_T >::block_iterator SparseField< Data_T >::blockBegin ( ) const

Definition at line 1491 of file SparseField.h.

References FieldRes::dataResolution().

{ 
  if (FieldRes::dataResolution() == V3i(0))
    return blockEnd();
  return block_iterator(*this, Box3i(V3i(0), m_blockRes - V3i(1)), 
                        V3i(0)); 
}
template<class Data_T >
SparseField< Data_T >::block_iterator SparseField< Data_T >::blockEnd ( ) const

Const iterator pointing to element one past the last valid block.

Definition at line 1503 of file SparseField.h.

{ 
  return block_iterator(*this, Box3i(V3i(0), m_blockRes - V3i(1)), 
                        V3i(0, 0, m_blockRes.z));
}
template<class Data_T >
void SparseField< Data_T >::addReference ( const std::string &  filename,
const std::string &  layerPath,
int  valuesPerBlock,
int  occupiedBlocks 
)

Internal function to create a Reference for the current field, for use in dynamic reading.

Definition at line 1067 of file SparseField.h.

References SparseFileManager::singleton(), and SparseFile::Reference< Data_T >::valuesPerBlock.

Referenced by SparseFieldIO::readData().

{
  m_fileManager = &SparseFileManager::singleton();
  m_fileId = m_fileManager->getNextId<Data_T>(filename, layerPath);
  // Set up the manager data
  SparseFile::Reference<Data_T> &reference = 
    m_fileManager->reference<Data_T>(m_fileId);
  reference.valuesPerBlock = valuesPerBlock;
  reference.occupiedBlocks = occupiedBlocks;
  reference.setNumBlocks(m_blocks.size());
}
template<class Data_T >
void SparseField< Data_T >::setupReferenceBlocks ( )

Internal function to setup the Reference's block pointers, for use with dynamic reading.

Definition at line 1106 of file SparseField.h.

References SparseFile::Reference< Data_T >::blocks, and SparseFile::Reference< Data_T >::fileBlockIndices.

Referenced by SparseFieldIO::readData().

{
  if (!m_fileManager || m_fileId < 0) return;

  SparseFile::Reference<Data_T> &reference = 
    m_fileManager->reference<Data_T>(m_fileId);

  std::vector<int>::iterator fb = reference.fileBlockIndices.begin();
  typename SparseFile::Reference<Data_T>::BlockPtrs::iterator bp = 
    reference.blocks.begin();
  typename std::vector<Sparse::SparseBlock<Data_T> >::iterator b =
    m_blocks.begin();
  typename std::vector<Sparse::SparseBlock<Data_T> >::iterator bend =
    m_blocks.end();
  int nextBlockIdx = 0;

  for (; b != bend; ++b, ++fb, ++bp) {
    if (b->isAllocated) {
      *fb = nextBlockIdx;
      *bp = &(*b);
      nextBlockIdx++;
    } else {
      *fb = -1;
    }
  }
}
template<class Data_T>
virtual void SparseField< Data_T >::sizeChanged ( ) [inline, protected, virtual]

Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.

Note:
Make sure to call the base class version in subclasses!

Reimplemented from ResizableField< Data_T >.

Definition at line 361 of file SparseField.h.

References SparseField< Data_T >::setupBlocks(), and ResizableField< Data_T >::sizeChanged().

  { 
    // Call base class
    base::sizeChanged();
    setupBlocks(); 
  }
template<class Data_T >
void SparseField< Data_T >::setupBlocks ( ) [protected]

Initializes the block structure. Will clear any existing data.

Todo:
clear() won't resize. Do the swap trick.

Definition at line 1512 of file SparseField.h.

Referenced by SparseField< Data_T >::sizeChanged(), and SparseField< Data_T >::SparseField().

{
  // Do calculation in floating point so we can round up later
  V3f res(base::m_dataWindow.size() + V3i(1));
  V3f blockRes(res / (1 << m_blockOrder));
  blockRes.x = ceil(blockRes.x);
  blockRes.y = ceil(blockRes.y);
  blockRes.z = ceil(blockRes.z);
  V3i intBlockRes(static_cast<int>(blockRes.x),
                         static_cast<int>(blockRes.y),
                         static_cast<int>(blockRes.z));
  m_blockRes = intBlockRes;
  m_blockXYSize = m_blockRes.x * m_blockRes.y;
  m_blocks.clear();
  m_blocks.resize(intBlockRes.x * intBlockRes.y * intBlockRes.z);

}
template<class Data_T >
void SparseField< Data_T >::deallocBlock ( Block block,
const Data_T &  emptyValue 
) [protected]

Deallocated the data of the given block and sets its empty value.

Definition at line 1572 of file SparseField.h.

References Sparse::SparseBlock< Data_T >::clear(), Sparse::SparseBlock< Data_T >::emptyValue, and Sparse::SparseBlock< Data_T >::isAllocated.

{
  block.isAllocated = false;
  block.clear();
  block.emptyValue = emptyValue;
}
template<class Data_T >
void SparseField< Data_T >::copySparseField ( const SparseField< Data_T > &  o) [private]
template<class Data_T >
void SparseField< Data_T >::copyBlockStates ( const SparseField< Data_T > &  o) [private]

Internal function to copy empty values and allocated flags, without copying data, used when copying a dynamically read field.

Definition at line 1085 of file SparseField.h.

References SparseField< Data_T >::m_blocks.

{
  if (m_blocks.size() != o.m_blocks.size()) return;

  typename std::vector<Sparse::SparseBlock<Data_T> >::iterator b =
    m_blocks.begin();
  typename std::vector<Sparse::SparseBlock<Data_T> >::iterator bend = 
    m_blocks.end();
  typename std::vector<Sparse::SparseBlock<Data_T> >::const_iterator ob =
    o.m_blocks.begin();

  for (; b != bend; ++b, ++ob) {
    b->isAllocated = ob->isAllocated;
    b->emptyValue = ob->emptyValue;
    b->clear();
  }
}
template<class Data_T>
SparseField& SparseField< Data_T >::operator= ( const SparseField< Data_T > &  o)

Assignment operator. For cache-managed fields, it creates a new file reference, and for non-managed fields, it copies the data.

template<class Data_T>
virtual void SparseField< Data_T >::clear ( const Data_T &  value) [virtual]

Clears all the voxels in the storage.

Reimplemented from WritableField< Data_T >.

template<class Data_T>
void SparseField< Data_T >::setBlockOrder ( int  order)

Sets the block order (i.e. the power-of-2 to use as block size.

Note:
This will clear out any existing data.
template<class Data_T>
int SparseField< Data_T >::blockOrder ( ) const

Returns the block order.

template<class Data_T>
int SparseField< Data_T >::blockSize ( ) const

Returns the block size.

template<class Data_T>
bool SparseField< Data_T >::voxelIsInAllocatedBlock ( int  i,
int  j,
int  k 
) const

Checks if a voxel is in an allocated block.

template<class Data_T>
bool SparseField< Data_T >::blockIsAllocated ( int  bi,
int  bj,
int  bk 
) const

Checks if a block is allocated.

template<class Data_T>
const Data_T SparseField< Data_T >::getBlockEmptyValue ( int  bi,
int  bj,
int  bk 
) const

Returns the constant value of an block, whether it's allocated already or not..

template<class Data_T>
void SparseField< Data_T >::setBlockEmptyValue ( int  bi,
int  bj,
int  bk,
const Data_T &  val 
)

Sets the constant value of an block. If the block is already allocated, it gets deallocated.

template<class Data_T>
bool SparseField< Data_T >::blockIndexIsValid ( int  bi,
int  bj,
int  bk 
) const

Returns whether a block index is valid.

template<class Data_T>
V3i SparseField< Data_T >::blockRes ( ) const

Returns the resolution of the block array.

template<class Data_T>
template<typename Functor_T >
int SparseField< Data_T >::releaseBlocks ( Functor_T  func)

Releases any blocks that are deemed empty. This can be used to clean up after algorithms that write "zero" values to the buffer, as well as after any narrow band levelset algorithms.

Parameters:
funcA function object with the method "bool check(SparseBlock&)"
Returns:
Number of released blocks
template<class Data_T>
int SparseField< Data_T >::blockId ( int  blockI,
int  blockJ,
int  blockK 
) const

Calculates the block number based on a block i,j,k index.

template<class Data_T>
void SparseField< Data_T >::getBlockCoord ( int  i,
int  j,
int  k,
int &  bi,
int &  bj,
int &  bk 
) const

Calculates the block coordinates that a given set of voxel coords are in.

Note:
The i,j,k coordinates are strictly positive, and refer to the coordinates of a voxel -after- the data window offset has been applied.
template<class Data_T>
void SparseField< Data_T >::getVoxelInBlock ( int  i,
int  j,
int  k,
int &  vi,
int &  vj,
int &  vk 
) const

Calculates the coordinates in a block for the given voxel index.

Note:
The i,j,k coordinates are strictly positive, and refer to the coordinates of a voxel -after- the data window offset has been applied.
template<class Data_T>
void SparseField< Data_T >::applyDataWindowOffset ( int &  i,
int &  j,
int &  k 
) const [inline]

Applies data window offset.

Definition at line 250 of file SparseField.h.

References FieldRes::m_dataWindow.

  {
    i -= base::m_dataWindow.min.x;
    j -= base::m_dataWindow.min.y;
    k -= base::m_dataWindow.min.z;
  }
template<class Data_T>
virtual Data_T SparseField< Data_T >::value ( int  i,
int  j,
int  k 
) const [virtual]

Read access to a voxel. The coordinates are in integer voxel space .

Note:
Before the internal storage is accessed, the subclass must compute the data window coordinates by looking at Field::m_dataWindow.
Virtual functions are known not to play nice with threading. Therefor, concrete classes can implement (by convention) fastValue() as a non-virtual function.

Implements Field< Data_T >.

template<class Data_T>
virtual long long int SparseField< Data_T >::memSize ( ) const [virtual]

Returns the memory usage (in bytes)

Note:
This needs to be re-implemented for any subclass that adds data members. Those classes should also call their superclass and add the combined memory use.

Reimplemented from FieldRes.

template<class Data_T>
virtual Data_T& SparseField< Data_T >::lvalue ( int  i,
int  j,
int  k 
) [virtual]

Write access to a voxel. The coordinates are global coordinates.

Note:
Before the internal storage is accessed, the subclass must compute the crop window coordinates by looking at Field::m_dataWindow.
This is named differently from the const value so that non-const objects still have a clear way of accessing data in a const way.
Virtual functions are known not to play nice with threading. Therefor, concrete classes can implement (by convention) fastLValue() as a non-virtual function.

Implements WritableField< Data_T >.

template<class Data_T>
Data_T SparseField< Data_T >::fastValue ( int  i,
int  j,
int  k 
) const

Read access to voxel. Notice that this is non-virtual.

template<class Data_T>
Data_T& SparseField< Data_T >::fastLValue ( int  i,
int  j,
int  k 
)

Write access to voxel. Notice that this is non-virtual.

template<class Data_T>
virtual std::string SparseField< Data_T >::className ( ) const [inline, virtual]

Returns the class name of the object. Used by the class pool and when writing the data to disk.

Implements FieldBase.

Definition at line 288 of file SparseField.h.

    { return std::string("SparseField"); }
template<class Data_T>
virtual FieldBase::Ptr SparseField< Data_T >::clone ( ) const [inline, virtual]

Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement it.

Implements FieldBase.

Definition at line 291 of file SparseField.h.

References SparseField< Data_T >::SparseField().

    { return Ptr(new SparseField(*this)); }
template<class Data_T>
const_iterator SparseField< Data_T >::cbegin ( ) const

Const iterator to first element. "cbegin" matches the tr1 c++ standard.

Reimplemented from Field< Data_T >.

template<class Data_T>
const_iterator SparseField< Data_T >::cbegin ( const Box3i subset) const

Const iterator to first element of specific subset.

Reimplemented from Field< Data_T >.

template<class Data_T>
const_iterator SparseField< Data_T >::cend ( ) const

Const iterator pointing one element past the last valid one.

Reimplemented from Field< Data_T >.

template<class Data_T>
const_iterator SparseField< Data_T >::cend ( const Box3i subset) const

Const iterator pointing one element past the last valid one (for a subset)

Reimplemented from Field< Data_T >.

template<class Data_T>
iterator SparseField< Data_T >::begin ( )

Iterator to first element.

Reimplemented from WritableField< Data_T >.

template<class Data_T>
iterator SparseField< Data_T >::begin ( const Box3i subset)

Iterator to first element of specific subset.

Reimplemented from WritableField< Data_T >.

template<class Data_T>
iterator SparseField< Data_T >::end ( )

Iterator pointing one element past the last valid one.

Reimplemented from WritableField< Data_T >.

template<class Data_T>
iterator SparseField< Data_T >::end ( const Box3i subset)

Iterator pointing one element past the last valid one (for a subset)

Reimplemented from WritableField< Data_T >.

template<class Data_T>
block_iterator SparseField< Data_T >::blockBegin ( ) const
template<class Data_T>
block_iterator SparseField< Data_T >::blockEnd ( ) const

Const iterator pointing to element one past the last valid block.

template<class Data_T>
void SparseField< Data_T >::addReference ( const std::string &  filename,
const std::string &  layerPath,
int  valuesPerBlock,
int  occupiedBlocks 
)

Internal function to create a Reference for the current field, for use in dynamic reading.

template<class Data_T>
void SparseField< Data_T >::setupReferenceBlocks ( )

Internal function to setup the Reference's block pointers, for use with dynamic reading.

template<class Data_T>
virtual void SparseField< Data_T >::sizeChanged ( ) [inline, protected, virtual]

Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.

Note:
Make sure to call the base class version in subclasses!

Reimplemented from ResizableField< Data_T >.

Definition at line 361 of file SparseField.h.

References SparseField< Data_T >::setupBlocks(), and ResizableField< Data_T >::sizeChanged().

  { 
    // Call base class
    base::sizeChanged();
    setupBlocks(); 
  }
template<class Data_T>
void SparseField< Data_T >::setupBlocks ( ) [protected]

Initializes the block structure. Will clear any existing data.

template<class Data_T>
void SparseField< Data_T >::deallocBlock ( Block block,
const Data_T &  emptyValue 
) [protected]

Deallocated the data of the given block and sets its empty value.

template<class Data_T>
void SparseField< Data_T >::copySparseField ( const SparseField< Data_T > &  o) [private]

Copies internal data, including blocks, from another SparseField, used by copy constructor and operator=.

template<class Data_T>
void SparseField< Data_T >::copyBlockStates ( const SparseField< Data_T > &  o) [private]

Internal function to copy empty values and allocated flags, without copying data, used when copying a dynamically read field.


Friends And Related Function Documentation

template<class Data_T>
SparseFieldIO [friend]

Definition at line 352 of file SparseField.h.


Member Data Documentation

template<class Data_T>
SparseField< Data_T >::DEFINE_FIELD_RTTI_CONCRETE_CLASS

Definition at line 268 of file SparseField.h.

template<class Data_T>
V3i SparseField< Data_T >::m_blockRes [protected]

Block array resolution.

Definition at line 386 of file SparseField.h.

Referenced by SparseField< Data_T >::copySparseField(), and SparseFieldIO::writeInternal().

template<class Data_T>
int SparseField< Data_T >::m_blockXYSize [protected]

Block array res.x * res.y.

Definition at line 388 of file SparseField.h.

Referenced by SparseField< Data_T >::copySparseField().

template<class Data_T>
std::vector< Block > SparseField< Data_T >::m_blocks [protected]
template<class Data_T>
SparseFileManager * SparseField< Data_T >::m_fileManager [protected]

Pointer to SparseFileManager. Used when doing dynamic reading. NULL if not in use.

Definition at line 394 of file SparseField.h.

Referenced by SparseField< Data_T >::copySparseField().

template<class Data_T>
int SparseField< Data_T >::m_fileId [protected]

File id. Used with m_fileManager if active. Otherwise -1.

Definition at line 396 of file SparseField.h.

Referenced by SparseField< Data_T >::copySparseField().

template<class Data_T>
Data_T SparseField< Data_T >::m_dummy [protected]

Dummy value used when needing to return but indicating a failed call.

Definition at line 399 of file SparseField.h.


The documentation for this class was generated from the following files: