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