44#ifndef _INCLUDED_Field3D_DenseField_H_
45#define _INCLUDED_Field3D_DenseField_H_
49#include <boost/lexical_cast.hpp>
63template <
class Field_T>
65template <
class Field_T>
84template <
class Data_T>
92 typedef boost::intrusive_ptr<DenseField>
Ptr;
93 typedef std::vector<Ptr>
Vec;
126 virtual Data_T
value(
int i,
int j,
int k)
const;
127 virtual long long int memSize()
const;
149 virtual Data_T&
lvalue(
int i,
int j,
int k);
165 class const_iterator;
171 const_iterator
cbegin()
const;
175 const_iterator
cend()
const;
235 inline Data_T*
ptr(
int i,
int j,
int k);
237 inline const Data_T*
ptr(
int i,
int j,
int k)
const;
256template <
class Data_T>
260#if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
266 typedef const Data_T& reference;
278 m_window(
window), m_field(field)
281 m_p = m_field.ptr(x, y, z);
290 if (x == m_window.max.x) {
291 if (y == m_window.max.y) {
292 if (z == m_window.max.z) {
295 m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
298 m_p = m_field.ptr(x = m_window.min.x, ++y, z);
307 template <
class Iter_T>
310 return m_p == &(*rhs);
313 template <
class Iter_T>
316 return m_p != &(*rhs);
324 inline const Data_T* operator -> ()
const
351template <
class Data_T>
355#if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
361 typedef Data_T& reference;
373 m_window(
window), m_field(field)
376 m_p = m_field.ptr(x, y, z);
385 if (x == m_window.max.x) {
386 if (y == m_window.max.y) {
387 if (z == m_window.max.z) {
390 m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z);
393 m_p = m_field.ptr(x = m_window.min.x, ++y, z);
402 template <
class Iter_T>
405 return m_p == &(*rhs);
408 template <
class Iter_T>
411 return m_p != &(*rhs);
419 inline Data_T* operator -> ()
const
445template <
class Data_T>
448 m_memSize(0), m_memSizeXY(0)
455template <
class Data_T>
458 std::fill(m_data.begin(), m_data.end(), value);
463template <
class Data_T>
467 const V3i res = base::m_dataWindow.size() +
V3i(1);
474template <
class Data_T>
478 const V3i res = base::m_dataWindow.size() +
V3i(1);
480 const int y =
idx %
res.y;
481 const int z =
idx /
res.y;
483 const V3i start = base::m_dataWindow.min +
V3i(0, y, z);
484 const V3i end = base::m_dataWindow.min +
V3i(
res.x, y, z);
492template <
class Data_T>
495 return fastValue(
i,
j,
k);
500template <
class Data_T>
504 long long int vectorMemSize = m_data.capacity() *
sizeof(Data_T);
510template <
class Data_T>
513 return fastLValue(
i,
j,
k);
518template <
class Data_T>
521 assert (
i >= base::m_dataWindow.min.x);
522 assert (
i <= base::m_dataWindow.max.x);
523 assert (
j >= base::m_dataWindow.min.y);
524 assert (
j <= base::m_dataWindow.max.y);
525 assert (
k >= base::m_dataWindow.min.z);
526 assert (
k <= base::m_dataWindow.max.z);
528 i -= base::m_dataWindow.min.x;
529 j -= base::m_dataWindow.min.y;
530 k -= base::m_dataWindow.min.z;
532 return m_data[
i +
j * m_memSize.x +
k * m_memSizeXY];
537template <
class Data_T>
540 assert (
i >= base::m_dataWindow.min.x);
541 assert (
i <= base::m_dataWindow.max.x);
542 assert (
j >= base::m_dataWindow.min.y);
543 assert (
j <= base::m_dataWindow.max.y);
544 assert (
k >= base::m_dataWindow.min.z);
545 assert (
k <= base::m_dataWindow.max.z);
547 i -= base::m_dataWindow.min.x;
548 j -= base::m_dataWindow.min.y;
549 k -= base::m_dataWindow.min.z;
551 return m_data[
i +
j * m_memSize.x +
k * m_memSizeXY];
556template <
class Data_T>
562 return const_iterator(*
this, base::m_dataWindow, base::m_dataWindow.min);
567template <
class Data_T>
578template <
class Data_T>
583 V3i(base::m_dataWindow.min.x,
584 base::m_dataWindow.min.y,
585 base::m_dataWindow.max.z + 1));
590template <
class Data_T>
600template <
class Data_T>
606 return iterator(*
this, base::m_dataWindow, base::m_dataWindow.min); }
610template <
class Data_T>
621template <
class Data_T>
625 return iterator(*
this, base::m_dataWindow,
626 V3i(base::m_dataWindow.min.x,
627 base::m_dataWindow.min.y,
628 base::m_dataWindow.max.z + 1));
633template <
class Data_T>
643template <
class Data_T>
650 m_memSize = base::m_dataWindow.max - base::m_dataWindow.min +
V3i(1);
651 m_memSizeXY = m_memSize.x * m_memSize.y;
654 if (base::m_dataWindow.max.x < base::m_dataWindow.min.x ||
655 base::m_dataWindow.max.y < base::m_dataWindow.min.y ||
656 base::m_dataWindow.max.z < base::m_dataWindow.min.z)
657 throw Exc::ResizeException(
"Attempt to resize ResizableField object "
658 "using negative size. Data window was: " +
659 boost::lexical_cast<std::string>(
660 base::m_dataWindow.min) +
" - " +
661 boost::lexical_cast<std::string>(
662 base::m_dataWindow.max));
666 std::vector<Data_T>().swap(m_data);
667 m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z);
669 catch (std::bad_alloc &) {
670 throw Exc::MemoryException(
"Couldn't allocate DenseField of size " +
671 boost::lexical_cast<std::string>(m_memSize));
677template <
class Data_T>
681 i -= base::m_dataWindow.min.x;
682 j -= base::m_dataWindow.min.y;
683 k -= base::m_dataWindow.min.z;
685 return &m_data[
i +
j * m_memSize.x +
k * m_memSizeXY];
690template <
class Data_T>
694 i -= base::m_dataWindow.min.x;
695 j -= base::m_dataWindow.min.y;
696 k -= base::m_dataWindow.min.z;
698 return &m_data[
i +
j * m_memSize.x +
k * m_memSizeXY];
DenseField< V3d > DenseField3d
DenseField< float > DenseFieldf
DenseField< V3h > DenseField3h
DenseField< half > DenseFieldh
DenseField< V3f > DenseField3f
DenseField< double > DenseFieldd
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
Contains Field, WritableField and ResizableField classes.
#define FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(field)
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
const Data_T * m_p
Pointer to current element.
const_iterator(const class_type &field, const Box3i &window, const V3i ¤tPos)
const class_type & m_field
Reference to field being iterated over.
Box3i m_window
Window to traverse.
DenseField< Data_T > class_type
Data_T * m_p
Pointer to current element.
DenseField< Data_T > class_type
class_type & m_field
Reference to field being iterated over.
iterator(class_type &field, const Box3i &window, const V3i ¤tPos)
Box3i m_window
Window to traverse.
This subclass of Field stores data in a contiguous std::vector.
virtual long long int memSize() const
Returns the memory usage (in bytes)
iterator end()
Iterator pointing one element past the last valid one.
const Data_T & fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
std::vector< Data_T > m_data
Field storage.
virtual Data_T & lvalue(int i, int j, int k)
Write access to a voxel. The coordinates are global coordinates.
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
size_t m_memSizeXY
X scanline * Y scanline size.
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
DenseField()
Constructs an empty buffer.
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
LinearGenericFieldInterp< DenseField< Data_T > > LinearInterp
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
const_iterator cend() const
Const iterator pointing one element past the last valid one.
const FIELD3D_VEC3_T< size_t > & internalMemSize() const
Returns the internal memory size in each dimension. This is used for example in LinearInterpolator,...
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
iterator begin()
Iterator to first element.
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given 'grain'.
virtual void sizeChanged()
Subclasses should re-implement this if they need to perform memory allocations, etc....
Data_T * ptr(int i, int j, int k)
Returns a pointer to a given element. Used by the iterators mainly.
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
static TemplatedFieldType< DenseField< Data_T > > ms_classType
DenseField< Data_T > class_type
size_t numGrains() const
Number of 'grains' to use with threaded access.
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
static const char * staticClassType()
ResizableField< Data_T > base
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
boost::intrusive_ptr< DenseField > Ptr
boost::intrusive_ptr< FieldBase > Ptr
std::string name
Optional name of the field.
V3i const dataResolution() const
Data_T value_type
Allows us to reference the template class.
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Used to return a string for the name of a templated field.