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>
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()
const FIELD3D_VEC3_T< size_t > & internalMemSize() const
Returns the internal memory size in each dimension. This is used for example in LinearInterpolator,...
FIELD3D_VEC3_T< size_t > m_memSize
Memory allocation size in each dimension.
const_iterator cend() const
Const iterator pointing one element past the last valid one.
FIELD3D_VEC3_T< T > operator *(S s, const FIELD3D_VEC3_T< T > vec)
Scalar times Vec3 multiplication. Makes the interpolation calls cleaner.
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
Data_T value_type
Allows us to reference the template class.
iterator end()
Iterator pointing one element past the last valid one.
virtual long long int memSize() const
Returns the memory usage (in bytes)
DenseField< Data_T > class_type
const_iterator(const class_type &field, const Box3i &window, const V3i ¤tPos)
virtual FieldBase::Ptr clone() const
Returns a pointer to a copy of the field, pure virtual so ensure derived classes properly implement i...
size_t m_memSizeXY
X scanline * Y scanline size.
size_t numGrains() const
Number of 'grains' to use with threaded access.
DenseField< Data_T > class_type
DenseField()
Constructs an empty buffer.
T max(const T a, const T2 b)
Max operation on mixed types.
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.
virtual Data_T value(int i, int j, int k) const
Read access to a voxel. The coordinates are in integer voxel space .
const Data_T * m_p
Pointer to current element.
static const char * staticClassType()
ResizableField< Data_T > base
DenseField< half > DenseFieldh
static TemplatedFieldType< DenseField< Data_T > > ms_classType
const Data_T & fastValue(int i, int j, int k) const
Read access to voxel. Notice that this is non-virtual.
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.
DenseField< Data_T > class_type
Used to return a string for the name of a templated field.
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.
const_iterator cbegin() const
Const iterator to first element. "cbegin" matches the tr1 c++ standard.
boost::intrusive_ptr< DenseField > Ptr
DenseField< float > DenseFieldf
DenseField< V3h > DenseField3h
bool getGrainBounds(const size_t idx, Box3i &vsBounds) const
Bounding box of the given 'grain'.
Box3i m_window
Window to traverse.
DenseField< V3f > DenseField3f
#define DEFINE_FIELD_RTTI_CONCRETE_CLASS
V3i const dataResolution() const
T min(const T a, const T2 b)
Min operation on mixed types.
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....
const class_type & m_field
Reference to field being iterated over.
CubicGenericFieldInterp< DenseField< Data_T > > CubicInterp
std::string name
Optional name of the field.