44 #ifndef _INCLUDED_Field3D_DenseField_H_
45 #define _INCLUDED_Field3D_DenseField_H_
49 #include <boost/lexical_cast.hpp>
63 template <
class Field_T>
65 template <
class Field_T>
84 template <
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);
155 const Data_T&
fastValue(
int i,
int j,
int k)
const;
165 class const_iterator;
171 const_iterator
cbegin()
const;
175 const_iterator
cend()
const;
178 const_iterator
cend(
const Box3i &subset)
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;
256 template <
class Data_T>
260 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
261 typedef std::forward_iterator_tag iterator_category;
263 typedef ptrdiff_t difference_type;
264 typedef ptrdiff_t distance_type;
265 typedef const Data_T *pointer;
266 typedef const Data_T& reference;
276 const V3i ¤tPos)
277 : x(currentPos.x), y(currentPos.y), z(currentPos.z),
278 m_window(window), m_field(field)
280 if (window.intersects(currentPos))
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>
308 inline bool operator == (
const Iter_T &rhs)
const
310 return m_p == &(*rhs);
313 template <
class Iter_T>
314 inline bool operator != (
const Iter_T &rhs)
const
316 return m_p != &(*rhs);
324 inline const Data_T* operator -> ()
const
351 template <
class Data_T>
355 #if defined(WIN32) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
356 typedef std::forward_iterator_tag iterator_category;
358 typedef ptrdiff_t difference_type;
359 typedef ptrdiff_t distance_type;
360 typedef Data_T *pointer;
361 typedef Data_T& reference;
371 const V3i ¤tPos)
372 : x(currentPos.x), y(currentPos.y), z(currentPos.z),
373 m_window(window), m_field(field)
375 if (window.intersects(currentPos))
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>
403 inline bool operator == (
const Iter_T &rhs)
const
405 return m_p == &(*rhs);
408 template <
class Iter_T>
409 inline bool operator != (
const Iter_T &rhs)
const
411 return m_p != &(*rhs);
419 inline Data_T* operator -> ()
const
445 template <
class Data_T>
448 m_memSize(0), m_memSizeXY(0)
455 template <
class Data_T>
458 std::fill(m_data.begin(), m_data.end(), value);
463 template <
class Data_T>
467 const V3i res = base::m_dataWindow.size() +
V3i(1);
469 return res.y * res.z;
474 template <
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);
492 template <
class Data_T>
495 return fastValue(i, j, k);
500 template <
class Data_T>
503 long long int superClassMemSize = base::memSize();
504 long long int vectorMemSize = m_data.capacity() *
sizeof(Data_T);
505 return sizeof(*this) + vectorMemSize + superClassMemSize;
510 template <
class Data_T>
513 return fastLValue(i, j, k);
518 template <
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];
537 template <
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];
556 template <
class Data_T>
562 return const_iterator(*
this, base::m_dataWindow, base::m_dataWindow.min);
567 template <
class Data_T>
571 if (subset.isEmpty())
578 template <
class Data_T>
583 V3i(base::m_dataWindow.min.x,
584 base::m_dataWindow.min.y,
585 base::m_dataWindow.max.z + 1));
590 template <
class Data_T>
595 V3i(subset.min.x, subset.min.y, subset.max.z + 1));
600 template <
class Data_T>
606 return iterator(*
this, base::m_dataWindow, base::m_dataWindow.min); }
610 template <
class Data_T>
614 if (subset.isEmpty())
616 return iterator(*
this, subset, subset.min);
621 template <
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));
633 template <
class Data_T>
638 V3i(subset.min.x, subset.min.y, subset.max.z + 1));
643 template <
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));
677 template <
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];
690 template <
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];
713 #endif // Include guard
This subclass of Field stores data in a contiguous std::vector.
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Box3i clipBounds(const Box3i &bbox, const Box3i &bounds)
static DEFINE_FIELD_RTTI_CONCRETE_CLASS const char * staticClassName()
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
std::vector< Data_T > m_data
Field storage.
DenseField< double > DenseFieldd
FIELD3D_CLASSNAME_CLASSTYPE_IMPLEMENTATION
iterator begin()
Iterator to first element.
class_type & m_field
Reference to field being iterated over.
DenseField< V3d > DenseField3d
LinearGenericFieldInterp< DenseField< Data_T > > LinearInterp
boost::intrusive_ptr< FieldBase > Ptr
FIELD3D_VEC3_T< T > operator*(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
Data_T value_type
Allows us to reference the template class.
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
iterator end()
Iterator pointing one element past the last valid one.
DenseField< Data_T > class_type
const_iterator(const class_type &field, const Box3i &window, const V3i ¤tPos)
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given 'grain'.
size_t m_memSizeXY
X scanline * Y scanline size.
size_t numGrains() const
Number of 'grains' to use with threaded access.
const FIELD3D_VEC3_T< size_t > & internalMemSize() const
Returns the internal memory size in each dimension. This is used for example in LinearInterpolator, where it optimizes random access to voxels.
DenseField< Data_T > class_type
DenseField()
Constructs an empty buffer.
Data_T * ptr(int i, int j, int k)
Returns a pointer to a given element. Used by the iterators mainly.
Data_T * m_p
Pointer to current element.
const Data_T * m_p
Pointer to current element.
static const char * staticClassType()
ResizableField< Data_T > base
DenseField< half > DenseFieldh
const Data_T & fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
static TemplatedFieldType< DenseField< Data_T > > ms_classType
FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(DenseField)
virtual Data_T & lvalue(int i, int j, int k)
Write access to a voxel. The coordinates are global coordinates.
virtual long long int memSize() const
Returns the memory usage (in bytes)
DenseField< Data_T > class_type
Used to return a string for the name of a templated field.
V3i const dataResolution() const
iterator(class_type &field, const Box3i &window, const V3i ¤tPos)
virtual void clear(const Data_T &value)
Clears all the voxels in the storage.
Box3i m_window
Window to traverse.
Contains Field, WritableField and ResizableField classes.
boost::intrusive_ptr< DenseField > Ptr
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
DenseField< float > DenseFieldf
DenseField< V3h > DenseField3h
Box3i m_window
Window to traverse.
DenseField< V3f > DenseField3f
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
Data_T & fastLValue(int i, int j, int k)
Write access to voxel. Notice that this is non-virtual.
virtual void sizeChanged()
Subclasses should re-implement this if they need to perform memory allocations, etc. every time the size of the storage changes.
const class_type & m_field
Reference to field being iterated over.
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
std::string name
Optional name of the field.
const_iterator cend() const
Const iterator pointing one element past the last valid one.